reset totp
This commit is contained in:
parent
48a8d1fb45
commit
fa1eb6a5f0
14 changed files with 354 additions and 83 deletions
|
@ -22,7 +22,7 @@ export async function login(req: Request, res: Response): Promise<any> {
|
|||
let username = req.body.username;
|
||||
let totp = req.body.totp;
|
||||
|
||||
let { id, secret, mail, firstname, lastname, isOwner } = await UserService.getByUsername(username);
|
||||
let { id, secret } = await UserService.getByUsername(username);
|
||||
|
||||
let valid = speakeasy.totp.verify({
|
||||
secret: secret,
|
||||
|
@ -35,39 +35,12 @@ export async function login(req: Request, res: Response): Promise<any> {
|
|||
throw new UnauthorizedRequestException("Token not valid or expired");
|
||||
}
|
||||
|
||||
let userPermissions = await UserPermissionService.getByUser(id);
|
||||
let userPermissionStrings = userPermissions.map((e) => e.permission);
|
||||
let userRoles = await UserService.getAssignedRolesByUserId(id);
|
||||
let rolePermissions = userRoles.length != 0 ? await RolePermissionService.getByRoles(userRoles.map((e) => e.id)) : [];
|
||||
let rolePermissionStrings = rolePermissions.map((e) => e.permission);
|
||||
let permissionObject = PermissionHelper.convertToObject([...userPermissionStrings, ...rolePermissionStrings]);
|
||||
|
||||
let jwtData: JWTToken = {
|
||||
userId: id,
|
||||
mail: mail,
|
||||
username: username,
|
||||
firstname: firstname,
|
||||
lastname: lastname,
|
||||
isOwner: isOwner,
|
||||
permissions: permissionObject,
|
||||
};
|
||||
|
||||
let accessToken: string;
|
||||
let refreshToken: string;
|
||||
|
||||
JWTHelper.create(jwtData)
|
||||
.then((result) => {
|
||||
accessToken = result;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
throw new InternalException("Failed accessToken creation", err);
|
||||
});
|
||||
let accessToken = await JWTHelper.buildToken(id);
|
||||
|
||||
let refreshCommand: CreateRefreshCommand = {
|
||||
userId: id,
|
||||
};
|
||||
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
|
||||
res.json({
|
||||
accessToken,
|
||||
|
@ -106,40 +79,15 @@ export async function refresh(req: Request, res: Response): Promise<any> {
|
|||
throw new UnauthorizedRequestException("user not identified with token and refresh");
|
||||
}
|
||||
|
||||
let { id, username, mail, firstname, lastname, isOwner } = await UserService.getById(tokenUserId);
|
||||
|
||||
let permissions = await UserPermissionService.getByUser(id);
|
||||
let permissionStrings = permissions.map((e) => e.permission);
|
||||
let permissionObject = PermissionHelper.convertToObject(permissionStrings);
|
||||
|
||||
let jwtData: JWTToken = {
|
||||
userId: id,
|
||||
mail: mail,
|
||||
username: username,
|
||||
firstname: firstname,
|
||||
lastname: lastname,
|
||||
isOwner: isOwner,
|
||||
permissions: permissionObject,
|
||||
};
|
||||
|
||||
let accessToken: string;
|
||||
let refreshToken: string;
|
||||
|
||||
JWTHelper.create(jwtData)
|
||||
.then((result) => {
|
||||
accessToken = result;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed accessToken creation", err);
|
||||
});
|
||||
let accessToken = await JWTHelper.buildToken(tokenUserId);
|
||||
|
||||
let refreshCommand: CreateRefreshCommand = {
|
||||
userId: id,
|
||||
userId: tokenUserId,
|
||||
};
|
||||
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
|
||||
let removeToken: DeleteRefreshCommand = {
|
||||
userId: id,
|
||||
userId: tokenUserId,
|
||||
token: refresh,
|
||||
};
|
||||
await RefreshCommandHandler.deleteByToken(removeToken);
|
||||
|
|
|
@ -128,33 +128,12 @@ export async function finishInvite(req: Request, res: Response, grantAdmin: bool
|
|||
};
|
||||
let id = await UserCommandHandler.create(createUser);
|
||||
|
||||
let jwtData: JWTToken = {
|
||||
userId: id,
|
||||
mail: mail,
|
||||
username: username,
|
||||
firstname: firstname,
|
||||
lastname: lastname,
|
||||
isOwner: grantAdmin,
|
||||
permissions: {
|
||||
...(grantAdmin ? { admin: true } : {}),
|
||||
},
|
||||
};
|
||||
|
||||
let accessToken: string;
|
||||
let refreshToken: string;
|
||||
|
||||
JWTHelper.create(jwtData)
|
||||
.then((result) => {
|
||||
accessToken = result;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("Failed accessToken creation", err);
|
||||
});
|
||||
let accessToken = await JWTHelper.buildToken(id);
|
||||
|
||||
let refreshCommand: CreateRefreshCommand = {
|
||||
userId: id,
|
||||
};
|
||||
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
|
||||
let deleteInvite: DeleteInviteCommand = {
|
||||
mail: mail,
|
||||
|
|
129
src/controller/resetController.ts
Normal file
129
src/controller/resetController.ts
Normal file
|
@ -0,0 +1,129 @@
|
|||
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,
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue