56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
|
import { Request, Response } from "express";
|
||
|
import speakeasy from "speakeasy";
|
||
|
import QRCode from "qrcode";
|
||
|
import InternalException from "../exceptions/internalException";
|
||
|
import { CLUB_NAME } from "../env.defaults";
|
||
|
import UserService from "../service/userService";
|
||
|
|
||
|
/**
|
||
|
* @description get user totp
|
||
|
* @param req {Request} Express req object
|
||
|
* @param res {Response} Express res object
|
||
|
* @returns {Promise<*>}
|
||
|
*/
|
||
|
export async function getUserTotp(req: Request, res: Response): Promise<any> {
|
||
|
const userId = parseInt(req.userId);
|
||
|
|
||
|
let { secret } = await UserService.getById(userId);
|
||
|
|
||
|
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 verify user totp
|
||
|
* @param req {Request} Express req object
|
||
|
* @param res {Response} Express res object
|
||
|
* @returns {Promise<*>}
|
||
|
*/
|
||
|
export async function verifyUserTotp(req: Request, res: Response): Promise<any> {
|
||
|
const userId = parseInt(req.userId);
|
||
|
let totp = req.body.totp;
|
||
|
|
||
|
let { secret } = await UserService.getById(userId);
|
||
|
let valid = speakeasy.totp.verify({
|
||
|
secret: secret,
|
||
|
encoding: "base32",
|
||
|
token: totp,
|
||
|
window: 2,
|
||
|
});
|
||
|
|
||
|
if (!valid) {
|
||
|
throw new InternalException("Token not valid or expired");
|
||
|
}
|
||
|
res.sendStatus(204);
|
||
|
}
|