Fix tests
[oweals/peertube.git] / server / middlewares / validators / users.ts
1 import * as express from 'express'
2 import 'express-validator'
3 import { body, param } from 'express-validator/check'
4 import { isSignupAllowed, logger } from '../../helpers'
5 import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
6 import {
7   isUserDisplayNSFWValid,
8   isUserPasswordValid,
9   isUserRoleValid,
10   isUserUsernameValid,
11   isUserVideoQuotaValid
12 } from '../../helpers/custom-validators/users'
13 import { isVideoExist } from '../../helpers/custom-validators/videos'
14 import { UserModel } from '../../models/account/user'
15 import { areValidationErrors } from './utils'
16
17 const usersAddValidator = [
18   body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
19   body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
20   body('email').isEmail().withMessage('Should have a valid email'),
21   body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
22   body('role').custom(isUserRoleValid).withMessage('Should have a valid role'),
23
24   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
25     logger.debug('Checking usersAdd parameters', { parameters: req.body })
26
27     if (areValidationErrors(req, res)) return
28     if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
29
30     return next()
31   }
32 ]
33
34 const usersRegisterValidator = [
35   body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'),
36   body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
37   body('email').isEmail().withMessage('Should have a valid email'),
38
39   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
40     logger.debug('Checking usersRegister parameters', { parameters: req.body })
41
42     if (areValidationErrors(req, res)) return
43     if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
44
45     return next()
46   }
47 ]
48
49 const usersRemoveValidator = [
50   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
51
52   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
53     logger.debug('Checking usersRemove parameters', { parameters: req.params })
54
55     if (areValidationErrors(req, res)) return
56     if (!await checkUserIdExist(req.params.id, res)) return
57
58     const user = res.locals.user
59     if (user.username === 'root') {
60       return res.status(400)
61                 .send({ error: 'Cannot remove the root user' })
62                 .end()
63     }
64
65     return next()
66   }
67 ]
68
69 const usersUpdateValidator = [
70   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
71   body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
72   body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
73   body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'),
74
75   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
76     logger.debug('Checking usersUpdate parameters', { parameters: req.body })
77
78     if (areValidationErrors(req, res)) return
79     if (!await checkUserIdExist(req.params.id, res)) return
80
81     return next()
82   }
83 ]
84
85 const usersUpdateMeValidator = [
86   body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'),
87   body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
88   body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'),
89
90   (req: express.Request, res: express.Response, next: express.NextFunction) => {
91     // TODO: Add old password verification
92     logger.debug('Checking usersUpdateMe parameters', { parameters: req.body })
93
94     if (areValidationErrors(req, res)) return
95
96     return next()
97   }
98 ]
99
100 const usersGetValidator = [
101   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
102
103   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
104     logger.debug('Checking usersGet parameters', { parameters: req.body })
105
106     if (areValidationErrors(req, res)) return
107     if (!await checkUserIdExist(req.params.id, res)) return
108
109     return next()
110   }
111 ]
112
113 const usersVideoRatingValidator = [
114   param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
115
116   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
117     logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
118
119     if (areValidationErrors(req, res)) return
120     if (!await isVideoExist(req.params.videoId, res)) return
121
122     return next()
123   }
124 ]
125
126 const ensureUserRegistrationAllowed = [
127   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
128     const allowed = await isSignupAllowed()
129     if (allowed === false) {
130       return res.status(403)
131                 .send({ error: 'User registration is not enabled or user limit is reached.' })
132                 .end()
133     }
134
135     return next()
136   }
137 ]
138
139 // ---------------------------------------------------------------------------
140
141 export {
142   usersAddValidator,
143   usersRegisterValidator,
144   usersRemoveValidator,
145   usersUpdateValidator,
146   usersUpdateMeValidator,
147   usersVideoRatingValidator,
148   ensureUserRegistrationAllowed,
149   usersGetValidator
150 }
151
152 // ---------------------------------------------------------------------------
153
154 async function checkUserIdExist (id: number, res: express.Response) {
155   const user = await UserModel.loadById(id)
156
157   if (!user) {
158     res.status(404)
159               .send({ error: 'User not found' })
160               .end()
161
162     return false
163   }
164
165   res.locals.user = user
166   return true
167 }
168
169 async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
170   const user = await UserModel.loadByUsernameOrEmail(username, email)
171
172   if (user) {
173     res.status(409)
174               .send({ error: 'User with this username of email already exists.' })
175               .end()
176     return false
177   }
178
179   return true
180 }