Compare commits
No commits in common. "19655eca00d9e6089b032dfb8b96fe2cecf60770" and "48a8d1fb45f587369c8010da1f489dc8a47f6a33" have entirely different histories.
19655eca00
...
48a8d1fb45
14 changed files with 83 additions and 354 deletions
|
@ -1,10 +0,0 @@
|
||||||
export interface CreateResetCommand {
|
|
||||||
mail: string;
|
|
||||||
username: string;
|
|
||||||
secret: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeleteResetCommand {
|
|
||||||
token: string;
|
|
||||||
mail: string;
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
import { dataSource } from "../data-source";
|
|
||||||
import { reset } from "../entity/reset";
|
|
||||||
import InternalException from "../exceptions/internalException";
|
|
||||||
import { StringHelper } from "../helpers/stringHelper";
|
|
||||||
import { CreateResetCommand, DeleteResetCommand } from "./resetCommand";
|
|
||||||
|
|
||||||
export default abstract class ResetCommandHandler {
|
|
||||||
/**
|
|
||||||
* @description create user
|
|
||||||
* @param CreateResetCommand
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
static async create(createReset: CreateResetCommand): Promise<string> {
|
|
||||||
const token = StringHelper.random(32);
|
|
||||||
|
|
||||||
return await dataSource
|
|
||||||
.createQueryBuilder()
|
|
||||||
.insert()
|
|
||||||
.into(reset)
|
|
||||||
.values({
|
|
||||||
token: token,
|
|
||||||
mail: createReset.mail,
|
|
||||||
username: createReset.username,
|
|
||||||
secret: createReset.secret,
|
|
||||||
})
|
|
||||||
.orUpdate(["token", "secret"], ["mail"])
|
|
||||||
.execute()
|
|
||||||
.then((result) => {
|
|
||||||
return token;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
throw new InternalException("Failed saving reset", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description delete reset by mail and token
|
|
||||||
* @param DeleteRefreshCommand
|
|
||||||
* @returns {Promise<any>}
|
|
||||||
*/
|
|
||||||
static async deleteByTokenAndMail(deleteReset: DeleteResetCommand): Promise<any> {
|
|
||||||
return await dataSource
|
|
||||||
.createQueryBuilder()
|
|
||||||
.delete()
|
|
||||||
.from(reset)
|
|
||||||
.where("reset.token = :token", { token: deleteReset.token })
|
|
||||||
.andWhere("reset.mail = :mail", { mail: deleteReset.mail })
|
|
||||||
.execute()
|
|
||||||
.then((res) => {})
|
|
||||||
.catch((err) => {
|
|
||||||
throw new InternalException("failed reset removal", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,11 +15,6 @@ export interface UpdateUserCommand {
|
||||||
lastname: string;
|
lastname: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateUserSecretCommand {
|
|
||||||
id: number;
|
|
||||||
secret: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TransferUserOwnerCommand {
|
export interface TransferUserOwnerCommand {
|
||||||
fromId: number;
|
fromId: number;
|
||||||
toId: number;
|
toId: number;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
TransferUserOwnerCommand,
|
TransferUserOwnerCommand,
|
||||||
UpdateUserCommand,
|
UpdateUserCommand,
|
||||||
UpdateUserRolesCommand,
|
UpdateUserRolesCommand,
|
||||||
UpdateUserSecretCommand,
|
|
||||||
} from "./userCommand";
|
} from "./userCommand";
|
||||||
import UserService from "../service/userService";
|
import UserService from "../service/userService";
|
||||||
|
|
||||||
|
@ -63,26 +62,6 @@ export default abstract class UserCommandHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description update user
|
|
||||||
* @param UpdateUserSecretCommand
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
static async updateSecret(updateUser: UpdateUserSecretCommand): Promise<void> {
|
|
||||||
return await dataSource
|
|
||||||
.createQueryBuilder()
|
|
||||||
.update(user)
|
|
||||||
.set({
|
|
||||||
secret: updateUser.secret,
|
|
||||||
})
|
|
||||||
.where("id = :id", { id: updateUser.id })
|
|
||||||
.execute()
|
|
||||||
.then(() => {})
|
|
||||||
.catch((err) => {
|
|
||||||
throw new InternalException("Failed updating user secret", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description update user roles
|
* @description update user roles
|
||||||
* @param UpdateUserRolesCommand
|
* @param UpdateUserRolesCommand
|
||||||
|
|
|
@ -22,7 +22,7 @@ export async function login(req: Request, res: Response): Promise<any> {
|
||||||
let username = req.body.username;
|
let username = req.body.username;
|
||||||
let totp = req.body.totp;
|
let totp = req.body.totp;
|
||||||
|
|
||||||
let { id, secret } = await UserService.getByUsername(username);
|
let { id, secret, mail, firstname, lastname, isOwner } = await UserService.getByUsername(username);
|
||||||
|
|
||||||
let valid = speakeasy.totp.verify({
|
let valid = speakeasy.totp.verify({
|
||||||
secret: secret,
|
secret: secret,
|
||||||
|
@ -35,12 +35,39 @@ export async function login(req: Request, res: Response): Promise<any> {
|
||||||
throw new UnauthorizedRequestException("Token not valid or expired");
|
throw new UnauthorizedRequestException("Token not valid or expired");
|
||||||
}
|
}
|
||||||
|
|
||||||
let accessToken = await JWTHelper.buildToken(id);
|
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 refreshCommand: CreateRefreshCommand = {
|
let refreshCommand: CreateRefreshCommand = {
|
||||||
userId: id,
|
userId: id,
|
||||||
};
|
};
|
||||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
accessToken,
|
accessToken,
|
||||||
|
@ -79,15 +106,40 @@ export async function refresh(req: Request, res: Response): Promise<any> {
|
||||||
throw new UnauthorizedRequestException("user not identified with token and refresh");
|
throw new UnauthorizedRequestException("user not identified with token and refresh");
|
||||||
}
|
}
|
||||||
|
|
||||||
let accessToken = await JWTHelper.buildToken(tokenUserId);
|
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 refreshCommand: CreateRefreshCommand = {
|
let refreshCommand: CreateRefreshCommand = {
|
||||||
userId: tokenUserId,
|
userId: id,
|
||||||
};
|
};
|
||||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||||
|
|
||||||
let removeToken: DeleteRefreshCommand = {
|
let removeToken: DeleteRefreshCommand = {
|
||||||
userId: tokenUserId,
|
userId: id,
|
||||||
token: refresh,
|
token: refresh,
|
||||||
};
|
};
|
||||||
await RefreshCommandHandler.deleteByToken(removeToken);
|
await RefreshCommandHandler.deleteByToken(removeToken);
|
||||||
|
|
|
@ -128,12 +128,33 @@ export async function finishInvite(req: Request, res: Response, grantAdmin: bool
|
||||||
};
|
};
|
||||||
let id = await UserCommandHandler.create(createUser);
|
let id = await UserCommandHandler.create(createUser);
|
||||||
|
|
||||||
let accessToken = await JWTHelper.buildToken(id);
|
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 refreshCommand: CreateRefreshCommand = {
|
let refreshCommand: CreateRefreshCommand = {
|
||||||
userId: id,
|
userId: id,
|
||||||
};
|
};
|
||||||
let refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||||
|
|
||||||
let deleteInvite: DeleteInviteCommand = {
|
let deleteInvite: DeleteInviteCommand = {
|
||||||
mail: mail,
|
mail: mail,
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -40,8 +40,6 @@ import { Protocol1729347911107 } from "./migrations/1729347911107-protocol";
|
||||||
import { calendar } from "./entity/calendar";
|
import { calendar } from "./entity/calendar";
|
||||||
import { calendarType } from "./entity/calendarType";
|
import { calendarType } from "./entity/calendarType";
|
||||||
import { Calendar1729947763295 } from "./migrations/1729947763295-calendar";
|
import { Calendar1729947763295 } from "./migrations/1729947763295-calendar";
|
||||||
import { reset } from "./entity/reset";
|
|
||||||
import { ResetToken1732358596823 } from "./migrations/1732358596823-resetToken";
|
|
||||||
|
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
type: DB_TYPE as any,
|
type: DB_TYPE as any,
|
||||||
|
@ -57,7 +55,6 @@ const dataSource = new DataSource({
|
||||||
user,
|
user,
|
||||||
refresh,
|
refresh,
|
||||||
invite,
|
invite,
|
||||||
reset,
|
|
||||||
userPermission,
|
userPermission,
|
||||||
role,
|
role,
|
||||||
rolePermission,
|
rolePermission,
|
||||||
|
@ -93,7 +90,6 @@ const dataSource = new DataSource({
|
||||||
Ownership1728313041449,
|
Ownership1728313041449,
|
||||||
Protocol1729347911107,
|
Protocol1729347911107,
|
||||||
Calendar1729947763295,
|
Calendar1729947763295,
|
||||||
ResetToken1732358596823,
|
|
||||||
],
|
],
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
migrationsTransactionMode: "each",
|
migrationsTransactionMode: "each",
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
export class reset {
|
|
||||||
@PrimaryColumn({ type: "varchar", length: 255 })
|
|
||||||
mail: string;
|
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 255 })
|
|
||||||
token: string;
|
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 255 })
|
|
||||||
username: string;
|
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 255 })
|
|
||||||
secret: string;
|
|
||||||
}
|
|
|
@ -1,11 +1,6 @@
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import { JWTData, JWTToken } from "../type/jwtTypes";
|
import { JWTData } from "../type/jwtTypes";
|
||||||
import { JWT_SECRET, JWT_EXPIRATION } from "../env.defaults";
|
import { JWT_SECRET, JWT_EXPIRATION } from "../env.defaults";
|
||||||
import InternalException from "../exceptions/internalException";
|
|
||||||
import RolePermissionService from "../service/rolePermissionService";
|
|
||||||
import UserPermissionService from "../service/userPermissionService";
|
|
||||||
import UserService from "../service/userService";
|
|
||||||
import PermissionHelper from "./permissionHelper";
|
|
||||||
|
|
||||||
export abstract class JWTHelper {
|
export abstract class JWTHelper {
|
||||||
static validate(token: string): Promise<string | jwt.JwtPayload> {
|
static validate(token: string): Promise<string | jwt.JwtPayload> {
|
||||||
|
@ -43,33 +38,4 @@ export abstract class JWTHelper {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async buildToken(id: number): Promise<string> {
|
|
||||||
let { firstname, lastname, mail, username, isOwner } = await UserService.getById(id);
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
return await JWTHelper.create(jwtData)
|
|
||||||
.then((result) => {
|
|
||||||
return result;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
throw new InternalException("Failed accessToken creation", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
import { MigrationInterface, QueryRunner, Table } from "typeorm";
|
|
||||||
|
|
||||||
export class ResetToken1732358596823 implements MigrationInterface {
|
|
||||||
name = "ResetToken1732358596823";
|
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.createTable(
|
|
||||||
new Table({
|
|
||||||
name: "reset",
|
|
||||||
columns: [
|
|
||||||
{ name: "mail", type: "varchar", length: "255", isPrimary: true, isNullable: false },
|
|
||||||
{ name: "token", type: "varchar", length: "255", isNullable: false },
|
|
||||||
{ name: "username", type: "varchar", length: "255", isNullable: false },
|
|
||||||
{ name: "secret", type: "varchar", length: "255", isNullable: false },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
||||||
await queryRunner.dropTable("reset");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ import errorHandler from "../middleware/errorHandler";
|
||||||
|
|
||||||
import publicAvailable from "./public";
|
import publicAvailable from "./public";
|
||||||
import setup from "./setup";
|
import setup from "./setup";
|
||||||
import reset from "./reset";
|
|
||||||
import auth from "./auth";
|
import auth from "./auth";
|
||||||
import admin from "./admin/index";
|
import admin from "./admin/index";
|
||||||
import user from "./user";
|
import user from "./user";
|
||||||
|
@ -26,7 +25,6 @@ export default (app: Express) => {
|
||||||
|
|
||||||
app.use("/public", publicAvailable);
|
app.use("/public", publicAvailable);
|
||||||
app.use("/setup", allowSetup, setup);
|
app.use("/setup", allowSetup, setup);
|
||||||
app.use("/reset", reset);
|
|
||||||
app.use("/auth", auth);
|
app.use("/auth", auth);
|
||||||
app.use(authenticate);
|
app.use(authenticate);
|
||||||
app.use("/admin", admin);
|
app.use("/admin", admin);
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import express from "express";
|
|
||||||
import ParamaterPassCheckHelper from "../helpers/parameterPassCheckHelper";
|
|
||||||
import { finishReset, startReset, verifyReset } from "../controller/resetController";
|
|
||||||
|
|
||||||
var router = express.Router({ mergeParams: true });
|
|
||||||
|
|
||||||
router.post("/verify", ParamaterPassCheckHelper.requiredIncludedMiddleware(["mail", "token"]), async (req, res) => {
|
|
||||||
await verifyReset(req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post("/", ParamaterPassCheckHelper.requiredIncludedMiddleware(["username"]), async (req, res) => {
|
|
||||||
await startReset(req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.put("/", ParamaterPassCheckHelper.requiredIncludedMiddleware(["mail", "token", "totp"]), async (req, res) => {
|
|
||||||
await finishReset(req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default router;
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { dataSource } from "../data-source";
|
|
||||||
import { reset } from "../entity/reset";
|
|
||||||
import InternalException from "../exceptions/internalException";
|
|
||||||
|
|
||||||
export default abstract class ResetService {
|
|
||||||
/**
|
|
||||||
* @description get reset by id
|
|
||||||
* @param mail string
|
|
||||||
* @param token string
|
|
||||||
* @returns {Promise<reset>}
|
|
||||||
*/
|
|
||||||
static async getByMailAndToken(mail: string, token: string): Promise<reset> {
|
|
||||||
return await dataSource
|
|
||||||
.getRepository(reset)
|
|
||||||
.createQueryBuilder("reset")
|
|
||||||
.where("reset.mail = :mail", { mail: mail })
|
|
||||||
.andWhere("reset.token = :token", { token: token })
|
|
||||||
.getOneOrFail()
|
|
||||||
.then((res) => {
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
throw new InternalException("reset not found by mail and token", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue