]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/controllers/api/users/two-factor.ts
Add Podcast RSS feeds (#5487)
[github/Chocobozzz/PeerTube.git] / server / controllers / api / users / two-factor.ts
CommitLineData
56f47830
C
1import express from 'express'
2import { generateOTPSecret, isOTPValid } from '@server/helpers/otp'
a3e5f804
C
3import { encrypt } from '@server/helpers/peertube-crypto'
4import { CONFIG } from '@server/initializers/config'
56f47830 5import { Redis } from '@server/lib/redis'
2166c058 6import { asyncMiddleware, authenticate, usersCheckCurrentPasswordFactory } from '@server/middlewares'
56f47830
C
7import {
8 confirmTwoFactorValidator,
9 disableTwoFactorValidator,
10 requestOrConfirmTwoFactorValidator
11} from '@server/middlewares/validators/two-factor'
12import { HttpStatusCode, TwoFactorEnableResult } from '@shared/models'
13
14const twoFactorRouter = express.Router()
15
16twoFactorRouter.post('/:id/two-factor/request',
17 authenticate,
2166c058 18 asyncMiddleware(usersCheckCurrentPasswordFactory(req => req.params.id)),
56f47830
C
19 asyncMiddleware(requestOrConfirmTwoFactorValidator),
20 asyncMiddleware(requestTwoFactor)
21)
22
23twoFactorRouter.post('/:id/two-factor/confirm-request',
24 authenticate,
25 asyncMiddleware(requestOrConfirmTwoFactorValidator),
26 confirmTwoFactorValidator,
27 asyncMiddleware(confirmRequestTwoFactor)
28)
29
30twoFactorRouter.post('/:id/two-factor/disable',
31 authenticate,
2166c058 32 asyncMiddleware(usersCheckCurrentPasswordFactory(req => req.params.id)),
56f47830
C
33 asyncMiddleware(disableTwoFactorValidator),
34 asyncMiddleware(disableTwoFactor)
35)
36
37// ---------------------------------------------------------------------------
38
39export {
40 twoFactorRouter
41}
42
43// ---------------------------------------------------------------------------
44
45async function requestTwoFactor (req: express.Request, res: express.Response) {
46 const user = res.locals.user
47
48 const { secret, uri } = generateOTPSecret(user.email)
a3e5f804
C
49
50 const encryptedSecret = await encrypt(secret, CONFIG.SECRETS.PEERTUBE)
51 const requestToken = await Redis.Instance.setTwoFactorRequest(user.id, encryptedSecret)
56f47830
C
52
53 return res.json({
54 otpRequest: {
55 requestToken,
56 secret,
57 uri
58 }
59 } as TwoFactorEnableResult)
60}
61
62async function confirmRequestTwoFactor (req: express.Request, res: express.Response) {
63 const requestToken = req.body.requestToken
64 const otpToken = req.body.otpToken
65 const user = res.locals.user
66
a3e5f804
C
67 const encryptedSecret = await Redis.Instance.getTwoFactorRequestToken(user.id, requestToken)
68 if (!encryptedSecret) {
56f47830
C
69 return res.fail({
70 message: 'Invalid request token',
71 status: HttpStatusCode.FORBIDDEN_403
72 })
73 }
74
a3e5f804 75 if (await isOTPValid({ encryptedSecret, token: otpToken }) !== true) {
56f47830
C
76 return res.fail({
77 message: 'Invalid OTP token',
78 status: HttpStatusCode.FORBIDDEN_403
79 })
80 }
81
a3e5f804 82 user.otpSecret = encryptedSecret
56f47830
C
83 await user.save()
84
85 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
86}
87
88async function disableTwoFactor (req: express.Request, res: express.Response) {
89 const user = res.locals.user
90
91 user.otpSecret = null
92 await user.save()
93
94 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
95}