aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators/users.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-10-05 15:37:15 +0200
committerChocobozzz <me@florianbigard.com>2022-10-07 10:51:16 +0200
commit56f47830758ff8e92abcfcc5f35d474ab12fe215 (patch)
tree854e57ec1b800d6ad740c8e42bee00cbd21e1724 /server/middlewares/validators/users.ts
parent7dd7ff4cebc290b09fe00d82046bb58e4e8a800d (diff)
downloadPeerTube-56f47830758ff8e92abcfcc5f35d474ab12fe215.tar.gz
PeerTube-56f47830758ff8e92abcfcc5f35d474ab12fe215.tar.zst
PeerTube-56f47830758ff8e92abcfcc5f35d474ab12fe215.zip
Support two factor authentication in backend
Diffstat (limited to 'server/middlewares/validators/users.ts')
-rw-r--r--server/middlewares/validators/users.ts87
1 files changed, 30 insertions, 57 deletions
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts
index eb693318f..046029547 100644
--- a/server/middlewares/validators/users.ts
+++ b/server/middlewares/validators/users.ts
@@ -1,9 +1,8 @@
1import express from 'express' 1import express from 'express'
2import { body, param, query } from 'express-validator' 2import { body, param, query } from 'express-validator'
3import { Hooks } from '@server/lib/plugins/hooks' 3import { Hooks } from '@server/lib/plugins/hooks'
4import { MUserDefault } from '@server/types/models'
5import { HttpStatusCode, UserRegister, UserRight, UserRole } from '@shared/models' 4import { HttpStatusCode, UserRegister, UserRight, UserRole } from '@shared/models'
6import { isBooleanValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc' 5import { exists, isBooleanValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
7import { isThemeNameValid } from '../../helpers/custom-validators/plugins' 6import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
8import { 7import {
9 isUserAdminFlagsValid, 8 isUserAdminFlagsValid,
@@ -30,8 +29,15 @@ import { isThemeRegistered } from '../../lib/plugins/theme-utils'
30import { Redis } from '../../lib/redis' 29import { Redis } from '../../lib/redis'
31import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../lib/signup' 30import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../lib/signup'
32import { ActorModel } from '../../models/actor/actor' 31import { ActorModel } from '../../models/actor/actor'
33import { UserModel } from '../../models/user/user' 32import {
34import { areValidationErrors, doesVideoChannelIdExist, doesVideoExist, isValidVideoIdParam } from './shared' 33 areValidationErrors,
34 checkUserEmailExist,
35 checkUserIdExist,
36 checkUserNameOrEmailDoesNotAlreadyExist,
37 doesVideoChannelIdExist,
38 doesVideoExist,
39 isValidVideoIdParam
40} from './shared'
35 41
36const usersListValidator = [ 42const usersListValidator = [
37 query('blocked') 43 query('blocked')
@@ -435,7 +441,7 @@ const usersResetPasswordValidator = [
435 if (!await checkUserIdExist(req.params.id, res)) return 441 if (!await checkUserIdExist(req.params.id, res)) return
436 442
437 const user = res.locals.user 443 const user = res.locals.user
438 const redisVerificationString = await Redis.Instance.getResetPasswordLink(user.id) 444 const redisVerificationString = await Redis.Instance.getResetPasswordVerificationString(user.id)
439 445
440 if (redisVerificationString !== req.body.verificationString) { 446 if (redisVerificationString !== req.body.verificationString) {
441 return res.fail({ 447 return res.fail({
@@ -500,6 +506,24 @@ const usersVerifyEmailValidator = [
500 } 506 }
501] 507]
502 508
509const usersCheckCurrentPassword = [
510 body('currentPassword').custom(exists),
511
512 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
513 if (areValidationErrors(req, res)) return
514
515 const user = res.locals.oauth.token.User
516 if (await user.isPasswordMatch(req.body.currentPassword) !== true) {
517 return res.fail({
518 status: HttpStatusCode.FORBIDDEN_403,
519 message: 'currentPassword is invalid.'
520 })
521 }
522
523 return next()
524 }
525]
526
503const userAutocompleteValidator = [ 527const userAutocompleteValidator = [
504 param('search') 528 param('search')
505 .isString() 529 .isString()
@@ -567,6 +591,7 @@ export {
567 usersUpdateValidator, 591 usersUpdateValidator,
568 usersUpdateMeValidator, 592 usersUpdateMeValidator,
569 usersVideoRatingValidator, 593 usersVideoRatingValidator,
594 usersCheckCurrentPassword,
570 ensureUserRegistrationAllowed, 595 ensureUserRegistrationAllowed,
571 ensureUserRegistrationAllowedForIP, 596 ensureUserRegistrationAllowedForIP,
572 usersGetValidator, 597 usersGetValidator,
@@ -580,55 +605,3 @@ export {
580 ensureCanModerateUser, 605 ensureCanModerateUser,
581 ensureCanManageChannelOrAccount 606 ensureCanManageChannelOrAccount
582} 607}
583
584// ---------------------------------------------------------------------------
585
586function checkUserIdExist (idArg: number | string, res: express.Response, withStats = false) {
587 const id = parseInt(idArg + '', 10)
588 return checkUserExist(() => UserModel.loadByIdWithChannels(id, withStats), res)
589}
590
591function checkUserEmailExist (email: string, res: express.Response, abortResponse = true) {
592 return checkUserExist(() => UserModel.loadByEmail(email), res, abortResponse)
593}
594
595async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
596 const user = await UserModel.loadByUsernameOrEmail(username, email)
597
598 if (user) {
599 res.fail({
600 status: HttpStatusCode.CONFLICT_409,
601 message: 'User with this username or email already exists.'
602 })
603 return false
604 }
605
606 const actor = await ActorModel.loadLocalByName(username)
607 if (actor) {
608 res.fail({
609 status: HttpStatusCode.CONFLICT_409,
610 message: 'Another actor (account/channel) with this name on this instance already exists or has already existed.'
611 })
612 return false
613 }
614
615 return true
616}
617
618async function checkUserExist (finder: () => Promise<MUserDefault>, res: express.Response, abortResponse = true) {
619 const user = await finder()
620
621 if (!user) {
622 if (abortResponse === true) {
623 res.fail({
624 status: HttpStatusCode.NOT_FOUND_404,
625 message: 'User not found'
626 })
627 }
628
629 return false
630 }
631
632 res.locals.user = user
633 return true
634}