130 lines
3.9 KiB
TypeScript
130 lines
3.9 KiB
TypeScript
|
import { Request, Response } from "express";
|
||
|
import { JWTHelper } from "../helpers/jwtHelper";
|
||
|
import { JWTToken } from "../type/jwtTypes";
|
||
|
import InternalException from "../exceptions/internalException";
|
||
|
import RefreshCommandHandler from "../command/refreshCommandHandler";
|
||
|
import { CreateRefreshCommand } from "../command/refreshCommand";
|
||
|
import speakeasy from "speakeasy";
|
||
|
import UnauthorizedRequestException from "../exceptions/unauthorizedRequestException";
|
||
|
import QRCode from "qrcode";
|
||
|
import { CreateResetCommand, DeleteResetCommand } from "../command/resetCommand";
|
||
|
import ResetCommandHandler from "../command/resetCommandHandler";
|
||
|
import MailHelper from "../helpers/mailHelper";
|
||
|
import ResetService from "../service/resetService";
|
||
|
import UserService from "../service/userService";
|
||
|
import { CLUB_NAME } from "../env.defaults";
|
||
|
import PermissionHelper from "../helpers/permissionHelper";
|
||
|
import RolePermissionService from "../service/rolePermissionService";
|
||
|
import UserPermissionService from "../service/userPermissionService";
|
||
|
import { UpdateUserSecretCommand } from "../command/userCommand";
|
||
|
import UserCommandHandler from "../command/userCommandHandler";
|
||
|
|
||
|
/**
|
||
|
* @description request totp reset
|
||
|
* @param req {Request} Express req object
|
||
|
* @param res {Response} Express res object
|
||
|
* @returns {Promise<*>}
|
||
|
*/
|
||
|
export async function startReset(req: Request, res: Response): Promise<any> {
|
||
|
let origin = req.headers.origin;
|
||
|
let username = req.body.username;
|
||
|
|
||
|
let { mail } = await UserService.getByUsername(username);
|
||
|
|
||
|
var secret = speakeasy.generateSecret({ length: 20, name: `Mitgliederverwaltung ${CLUB_NAME}` });
|
||
|
|
||
|
let createReset: CreateResetCommand = {
|
||
|
username: username,
|
||
|
mail: mail,
|
||
|
secret: secret.base32,
|
||
|
};
|
||
|
let token = await ResetCommandHandler.create(createReset);
|
||
|
|
||
|
// sendmail
|
||
|
let mailhelper = new MailHelper();
|
||
|
await mailhelper.sendMail(
|
||
|
mail,
|
||
|
`Email Bestätigung für Mitglieder Admin-Portal von ${CLUB_NAME}`,
|
||
|
`Öffne folgenden Link: ${origin}/reset/reset?mail=${mail}&token=${token}`
|
||
|
);
|
||
|
|
||
|
res.sendStatus(204);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @description verify reset link
|
||
|
* @param req {Request} Express req object
|
||
|
* @param res {Response} Express res object
|
||
|
* @returns {Promise<*>}
|
||
|
*/
|
||
|
export async function verifyReset(req: Request, res: Response): Promise<any> {
|
||
|
let mail = req.body.mail;
|
||
|
let token = req.body.token;
|
||
|
|
||
|
let { secret } = await ResetService.getByMailAndToken(mail, token);
|
||
|
|
||
|
const url = `otpauth://totp/Mitgliederverwaltung ${CLUB_NAME}?secret=${secret}`;
|
||
|
|
||
|
QRCode.toDataURL(url)
|
||
|
.then((result) => {
|
||
|
res.json({
|
||
|
dataUrl: result,
|
||
|
otp: secret,
|
||
|
});
|
||
|
})
|
||
|
.catch((err) => {
|
||
|
throw new InternalException("QRCode not created", err);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @description finishReset
|
||
|
* @param req {Request} Express req object
|
||
|
* @param res {Response} Express res object
|
||
|
* @returns {Promise<*>}
|
||
|
*/
|
||
|
export async function finishReset(req: Request, res: Response): Promise<any> {
|
||
|
let mail = req.body.mail;
|
||
|
let token = req.body.token;
|
||
|
let totp = req.body.totp;
|
||
|
|
||
|
let { secret, username } = await ResetService.getByMailAndToken(mail, token);
|
||
|
|
||
|
let valid = speakeasy.totp.verify({
|
||
|
secret: secret,
|
||
|
encoding: "base32",
|
||
|
token: totp,
|
||
|
window: 2,
|
||
|
});
|
||
|
|
||
|
if (!valid) {
|
||
|
throw new UnauthorizedRequestException("Token not valid or expired");
|
||
|
}
|
||
|
|
||
|
let { id } = await UserService.getByUsername(username);
|
||
|
|
||
|
let updateUserSecret: UpdateUserSecretCommand = {
|
||
|
id,
|
||
|
secret,
|
||
|
};
|
||
|
await UserCommandHandler.updateSecret(updateUserSecret);
|
||
|
|
||
|
let accessToken = await JWTHelper.buildToken(id);
|
||
|
|
||
|
let refreshCommand: CreateRefreshCommand = {
|
||
|
userId: id,
|
||
|
};
|
||
|
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||
|
|
||
|
let deleteReset: DeleteResetCommand = {
|
||
|
mail: mail,
|
||
|
token: token,
|
||
|
};
|
||
|
await ResetCommandHandler.deleteByTokenAndMail(deleteReset);
|
||
|
|
||
|
res.json({
|
||
|
accessToken,
|
||
|
refreshToken,
|
||
|
});
|
||
|
}
|