Merge pull request '#15-invite-user' (#16) from #15-invite-user into main
Reviewed-on: Ehrenamt/member-administration-server#16
This commit is contained in:
commit
fa411027e9
10 changed files with 145 additions and 10 deletions
|
@ -37,7 +37,7 @@ export default abstract class InviteCommandHandler {
|
|||
|
||||
/**
|
||||
* @description delete invite by mail and token
|
||||
* @param DeleteRefreshCommand
|
||||
* @param DeleteInviteCommand
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
static async deleteByTokenAndMail(deleteInvite: DeleteInviteCommand): Promise<any> {
|
||||
|
@ -53,4 +53,22 @@ export default abstract class InviteCommandHandler {
|
|||
throw new InternalException("failed invite removal", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete invite by mail
|
||||
* @param DeleteByMailInviteCommand
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
static async deleteByMail(mail: string): Promise<any> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(invite)
|
||||
.where("invite.mail = :mail", { mail })
|
||||
.execute()
|
||||
.then((res) => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("failed invite removal", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,19 @@ import CustomRequestException from "../exceptions/customRequestException";
|
|||
import { CLUB_NAME } from "../env.defaults";
|
||||
import { CreateUserPermissionCommand } from "../command/userPermissionCommand";
|
||||
import UserPermissionCommandHandler from "../command/userPermissionCommandHandler";
|
||||
import InviteFactory from "../factory/admin/invite";
|
||||
|
||||
/**
|
||||
* @description get all invites
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function getInvites(req: Request, res: Response): Promise<any> {
|
||||
let invites = await InviteService.getAll();
|
||||
|
||||
res.json(InviteFactory.mapToBase(invites));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description start first user
|
||||
|
@ -78,7 +91,7 @@ export async function verifyInvite(req: Request, res: Response): Promise<any> {
|
|||
let mail = req.body.mail;
|
||||
let token = req.body.token;
|
||||
|
||||
let { secret } = await InviteService.getByMailAndToken(mail, token);
|
||||
let { secret, username } = await InviteService.getByMailAndToken(mail, token);
|
||||
|
||||
const url = `otpauth://totp/Mitgliederverwaltung ${CLUB_NAME}?secret=${secret}`;
|
||||
|
||||
|
@ -87,6 +100,7 @@ export async function verifyInvite(req: Request, res: Response): Promise<any> {
|
|||
res.json({
|
||||
dataUrl: result,
|
||||
otp: secret,
|
||||
username,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
|
@ -146,3 +160,17 @@ export async function finishInvite(req: Request, res: Response, grantAdmin: bool
|
|||
refreshToken,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete invite by mail
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function deleteInvite(req: Request, res: Response): Promise<any> {
|
||||
const mail = req.params.mail;
|
||||
|
||||
await InviteCommandHandler.deleteByMail(mail);
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
|
27
src/factory/admin/invite.ts
Normal file
27
src/factory/admin/invite.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { invite } from "../../entity/invite";
|
||||
import { InviteViewModel } from "../../viewmodel/admin/invite.models";
|
||||
|
||||
export default abstract class InviteFactory {
|
||||
/**
|
||||
* @description map record to invite
|
||||
* @param {invite} record
|
||||
* @returns {InviteViewModel}
|
||||
*/
|
||||
public static mapToSingle(record: invite): InviteViewModel {
|
||||
return {
|
||||
mail: record.mail,
|
||||
username: record.username,
|
||||
firstname: record.firstname,
|
||||
lastname: record.lastname,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description map records to invite
|
||||
* @param {Array<invite>} records
|
||||
* @returns {Array<InviteViewModel>}
|
||||
*/
|
||||
public static mapToBase(records: Array<invite>): Array<InviteViewModel> {
|
||||
return records.map((r) => this.mapToSingle(r));
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import calendar from "./calendar";
|
|||
|
||||
import role from "./role";
|
||||
import user from "./user";
|
||||
import invite from "./invite";
|
||||
|
||||
var router = express.Router({ mergeParams: true });
|
||||
|
||||
|
@ -42,5 +43,6 @@ router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "ca
|
|||
|
||||
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
|
||||
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);
|
||||
router.use("/invite", PermissionHelper.passCheckMiddleware("read", "user", "user"), invite);
|
||||
|
||||
export default router;
|
||||
|
|
27
src/routes/admin/invite.ts
Normal file
27
src/routes/admin/invite.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import express, { Request, Response } from "express";
|
||||
import PermissionHelper from "../../helpers/permissionHelper";
|
||||
import { deleteInvite, getInvites, inviteUser } from "../../controller/inviteController";
|
||||
|
||||
var router = express.Router({ mergeParams: true });
|
||||
|
||||
router.get("/", async (req: Request, res: Response) => {
|
||||
await getInvites(req, res);
|
||||
});
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
PermissionHelper.passCheckMiddleware("create", "user", "user"),
|
||||
async (req: Request, res: Response) => {
|
||||
await inviteUser(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:mail",
|
||||
PermissionHelper.passCheckMiddleware("delete", "user", "user"),
|
||||
async (req: Request, res: Response) => {
|
||||
await deleteInvite(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
export default router;
|
|
@ -30,14 +30,6 @@ router.get("/:id/roles", async (req: Request, res: Response) => {
|
|||
await getUserRoles(req, res);
|
||||
});
|
||||
|
||||
router.post(
|
||||
"/invite",
|
||||
PermissionHelper.passCheckMiddleware("create", "user", "user"),
|
||||
async (req: Request, res: Response) => {
|
||||
await inviteUser(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/:id",
|
||||
PermissionHelper.passCheckMiddleware("update", "user", "user"),
|
||||
|
|
|
@ -8,6 +8,7 @@ import errorHandler from "../middleware/errorHandler";
|
|||
|
||||
import publicAvailable from "./public";
|
||||
import setup from "./setup";
|
||||
import invite from "./invite";
|
||||
import reset from "./reset";
|
||||
import auth from "./auth";
|
||||
import admin from "./admin/index";
|
||||
|
@ -27,6 +28,7 @@ export default (app: Express) => {
|
|||
app.use("/public", publicAvailable);
|
||||
app.use("/setup", allowSetup, setup);
|
||||
app.use("/reset", reset);
|
||||
app.use("/invite", invite);
|
||||
app.use("/auth", auth);
|
||||
app.use(authenticate);
|
||||
app.use("/admin", admin);
|
||||
|
|
16
src/routes/invite.ts
Normal file
16
src/routes/invite.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import express from "express";
|
||||
import { isSetup } from "../controller/setupController";
|
||||
import { finishInvite, inviteUser, verifyInvite } from "../controller/inviteController";
|
||||
import ParamaterPassCheckHelper from "../helpers/parameterPassCheckHelper";
|
||||
|
||||
var router = express.Router({ mergeParams: true });
|
||||
|
||||
router.post("/verify", ParamaterPassCheckHelper.requiredIncludedMiddleware(["mail", "token"]), async (req, res) => {
|
||||
await verifyInvite(req, res);
|
||||
});
|
||||
|
||||
router.put("/", ParamaterPassCheckHelper.requiredIncludedMiddleware(["mail", "token", "totp"]), async (req, res) => {
|
||||
await finishInvite(req, res);
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -3,6 +3,23 @@ import { invite } from "../entity/invite";
|
|||
import InternalException from "../exceptions/internalException";
|
||||
|
||||
export default abstract class InviteService {
|
||||
/**
|
||||
* @description get all invites
|
||||
* @returns {Promise<Array<invite>>}
|
||||
*/
|
||||
static async getAll(): Promise<Array<invite>> {
|
||||
return await dataSource
|
||||
.getRepository(invite)
|
||||
.createQueryBuilder("invite")
|
||||
.getMany()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("invites not found", err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description get invite by id
|
||||
* @param mail string
|
||||
|
|
6
src/viewmodel/admin/invite.models.ts
Normal file
6
src/viewmodel/admin/invite.models.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export interface InviteViewModel {
|
||||
mail: string;
|
||||
username: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
}
|
Loading…
Reference in a new issue