1 import express from 'express'
2 import { generateOTPSecret, isOTPValid } from '@server/helpers/otp'
3 import { Redis } from '@server/lib/redis'
4 import { asyncMiddleware, authenticate, usersCheckCurrentPassword } from '@server/middlewares'
6 confirmTwoFactorValidator,
7 disableTwoFactorValidator,
8 requestOrConfirmTwoFactorValidator
9 } from '@server/middlewares/validators/two-factor'
10 import { HttpStatusCode, TwoFactorEnableResult } from '@shared/models'
12 const twoFactorRouter = express.Router()
14 twoFactorRouter.post('/:id/two-factor/request',
16 asyncMiddleware(usersCheckCurrentPassword),
17 asyncMiddleware(requestOrConfirmTwoFactorValidator),
18 asyncMiddleware(requestTwoFactor)
21 twoFactorRouter.post('/:id/two-factor/confirm-request',
23 asyncMiddleware(requestOrConfirmTwoFactorValidator),
24 confirmTwoFactorValidator,
25 asyncMiddleware(confirmRequestTwoFactor)
28 twoFactorRouter.post('/:id/two-factor/disable',
30 asyncMiddleware(usersCheckCurrentPassword),
31 asyncMiddleware(disableTwoFactorValidator),
32 asyncMiddleware(disableTwoFactor)
35 // ---------------------------------------------------------------------------
41 // ---------------------------------------------------------------------------
43 async function requestTwoFactor (req: express.Request, res: express.Response) {
44 const user = res.locals.user
46 const { secret, uri } = generateOTPSecret(user.email)
47 const requestToken = await Redis.Instance.setTwoFactorRequest(user.id, secret)
55 } as TwoFactorEnableResult)
58 async function confirmRequestTwoFactor (req: express.Request, res: express.Response) {
59 const requestToken = req.body.requestToken
60 const otpToken = req.body.otpToken
61 const user = res.locals.user
63 const secret = await Redis.Instance.getTwoFactorRequestToken(user.id, requestToken)
66 message: 'Invalid request token',
67 status: HttpStatusCode.FORBIDDEN_403
71 if (isOTPValid({ secret, token: otpToken }) !== true) {
73 message: 'Invalid OTP token',
74 status: HttpStatusCode.FORBIDDEN_403
78 user.otpSecret = secret
81 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
84 async function disableTwoFactor (req: express.Request, res: express.Response) {
85 const user = res.locals.user
90 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)