]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/users.ts
Add ability to list imports of a channel sync
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / users.ts
CommitLineData
41fb13c3 1import express from 'express'
76314386 2import { body, param, query } from 'express-validator'
ecb4e35f 3import { omit } from 'lodash'
b49f22d8
C
4import { Hooks } from '@server/lib/plugins/hooks'
5import { MUserDefault } from '@server/types/models'
a37e9e74 6import { HttpStatusCode, UserRegister, UserRight, UserRole } from '@shared/models'
978c87e7 7import { isBooleanValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
b49f22d8 8import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
b60e5f38 9import {
1eddc9a7 10 isUserAdminFlagsValid,
c1e5bd23 11 isUserAutoPlayNextVideoValid,
1a12adcd
C
12 isUserAutoPlayVideoValid,
13 isUserBlockedReasonValid,
4bbfc6c6
C
14 isUserDescriptionValid,
15 isUserDisplayNameValid,
8f581725 16 isUserNoModal,
0883b324 17 isUserNSFWPolicyValid,
a9bfa85d 18 isUserP2PEnabledValid,
ecb4e35f 19 isUserPasswordValid,
45f1bd72 20 isUserPasswordValidOrEmpty,
ecb4e35f 21 isUserRoleValid,
3e753302
C
22 isUserUsernameValid,
23 isUserVideoLanguages,
1a12adcd 24 isUserVideoQuotaDailyValid,
dae86118
C
25 isUserVideoQuotaValid,
26 isUserVideosHistoryEnabledValid
3fd3ab2d 27} from '../../helpers/custom-validators/users'
27db7840 28import { isVideoChannelDisplayNameValid, isVideoChannelUsernameValid } from '../../helpers/custom-validators/video-channels'
da854ddd 29import { logger } from '../../helpers/logger'
b49f22d8 30import { isThemeRegistered } from '../../lib/plugins/theme-utils'
ecb4e35f 31import { Redis } from '../../lib/redis'
10363c74 32import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../lib/signup'
7d9ba5c0 33import { ActorModel } from '../../models/actor/actor'
10363c74 34import { UserModel } from '../../models/user/user'
978c87e7 35import { areValidationErrors, doesVideoChannelIdExist, doesVideoExist, isValidVideoIdParam } from './shared'
9bd26629 36
8491293b
RK
37const usersListValidator = [
38 query('blocked')
39 .optional()
f1273314 40 .customSanitizer(toBooleanOrNull)
8491293b
RK
41 .isBoolean().withMessage('Should be a valid boolean banned state'),
42
ea7337cf 43 (req: express.Request, res: express.Response, next: express.NextFunction) => {
8491293b
RK
44 logger.debug('Checking usersList parameters', { parameters: req.query })
45
46 if (areValidationErrors(req, res)) return
47
48 return next()
49 }
50]
51
b60e5f38 52const usersAddValidator = [
563d032e 53 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
45f1bd72 54 body('password').custom(isUserPasswordValidOrEmpty).withMessage('Should have a valid password'),
b60e5f38 55 body('email').isEmail().withMessage('Should have a valid email'),
27db7840
C
56
57 body('channelName').optional().custom(isVideoChannelUsernameValid).withMessage('Should have a valid channel name'),
58
b60e5f38 59 body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
bee0abff 60 body('videoQuotaDaily').custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'),
27db7840 61
dea16773
C
62 body('role')
63 .customSanitizer(toIntOrNull)
64 .custom(isUserRoleValid).withMessage('Should have a valid role'),
1eddc9a7 65 body('adminFlags').optional().custom(isUserAdminFlagsValid).withMessage('Should have a valid admin flags'),
9bd26629 66
a2431b7d 67 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
ce97fe36 68 logger.debug('Checking usersAdd parameters', { parameters: omit(req.body, 'password') })
9bd26629 69
a2431b7d
C
70 if (areValidationErrors(req, res)) return
71 if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
72
a95a4cc8
C
73 const authUser = res.locals.oauth.token.User
74 if (authUser.role !== UserRole.ADMINISTRATOR && req.body.role !== UserRole.USER) {
76148b27
RK
75 return res.fail({
76 status: HttpStatusCode.FORBIDDEN_403,
77 message: 'You can only create users (and not administrators or moderators)'
78 })
a95a4cc8
C
79 }
80
766d13b4 81 if (req.body.channelName) {
82 if (req.body.channelName === req.body.username) {
76148b27 83 return res.fail({ message: 'Channel name cannot be the same as user username.' })
766d13b4 84 }
4e68fc86 85
766d13b4 86 const existing = await ActorModel.loadLocalByName(req.body.channelName)
87 if (existing) {
76148b27
RK
88 return res.fail({
89 status: HttpStatusCode.CONFLICT_409,
90 message: `Channel with name ${req.body.channelName} already exists.`
91 })
766d13b4 92 }
4e68fc86 93 }
94
a2431b7d 95 return next()
b60e5f38
C
96 }
97]
6fcd19ba 98
b60e5f38
C
99const usersRegisterValidator = [
100 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username'),
101 body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
102 body('email').isEmail().withMessage('Should have a valid email'),
1f20622f
C
103 body('displayName')
104 .optional()
105 .custom(isUserDisplayNameValid).withMessage('Should have a valid display name'),
106
107 body('channel.name')
108 .optional()
27db7840 109 .custom(isVideoChannelUsernameValid).withMessage('Should have a valid channel name'),
1f20622f
C
110 body('channel.displayName')
111 .optional()
27db7840 112 .custom(isVideoChannelDisplayNameValid).withMessage('Should have a valid display name'),
77a5501f 113
a2431b7d 114 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
ce97fe36 115 logger.debug('Checking usersRegister parameters', { parameters: omit(req.body, 'password') })
77a5501f 116
a2431b7d
C
117 if (areValidationErrors(req, res)) return
118 if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
119
e590b4a5
C
120 const body: UserRegister = req.body
121 if (body.channel) {
122 if (!body.channel.name || !body.channel.displayName) {
76148b27 123 return res.fail({ message: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' })
e590b4a5
C
124 }
125
1d5342ab 126 if (body.channel.name === body.username) {
76148b27 127 return res.fail({ message: 'Channel name cannot be the same as user username.' })
1d5342ab
C
128 }
129
e590b4a5
C
130 const existing = await ActorModel.loadLocalByName(body.channel.name)
131 if (existing) {
76148b27
RK
132 return res.fail({
133 status: HttpStatusCode.CONFLICT_409,
134 message: `Channel with name ${body.channel.name} already exists.`
135 })
e590b4a5
C
136 }
137 }
138
a2431b7d 139 return next()
b60e5f38
C
140 }
141]
9bd26629 142
b60e5f38
C
143const usersRemoveValidator = [
144 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
9bd26629 145
a2431b7d 146 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
b60e5f38 147 logger.debug('Checking usersRemove parameters', { parameters: req.params })
9bd26629 148
a2431b7d
C
149 if (areValidationErrors(req, res)) return
150 if (!await checkUserIdExist(req.params.id, res)) return
151
152 const user = res.locals.user
153 if (user.username === 'root') {
76148b27 154 return res.fail({ message: 'Cannot remove the root user' })
a2431b7d
C
155 }
156
157 return next()
b60e5f38
C
158 }
159]
8094a898 160
e6921918
C
161const usersBlockingValidator = [
162 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
eacb25c4 163 body('reason').optional().custom(isUserBlockedReasonValid).withMessage('Should have a valid blocking reason'),
e6921918
C
164
165 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
eacb25c4 166 logger.debug('Checking usersBlocking parameters', { parameters: req.params })
e6921918
C
167
168 if (areValidationErrors(req, res)) return
169 if (!await checkUserIdExist(req.params.id, res)) return
170
171 const user = res.locals.user
172 if (user.username === 'root') {
76148b27 173 return res.fail({ message: 'Cannot block the root user' })
e6921918
C
174 }
175
176 return next()
177 }
178]
179
92b9d60c 180const deleteMeValidator = [
a1587156 181 (req: express.Request, res: express.Response, next: express.NextFunction) => {
dae86118 182 const user = res.locals.oauth.token.User
92b9d60c 183 if (user.username === 'root') {
76148b27 184 return res.fail({ message: 'You cannot delete your root account.' })
92b9d60c
C
185 }
186
187 return next()
188 }
189]
190
b60e5f38
C
191const usersUpdateValidator = [
192 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
b8375da9 193
b426edd4 194 body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'),
b60e5f38 195 body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
fc2ec87a 196 body('emailVerified').optional().isBoolean().withMessage('Should have a valid email verified attribute'),
b60e5f38 197 body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
bee0abff 198 body('videoQuotaDaily').optional().custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'),
6d989edc 199 body('pluginAuth').optional(),
dea16773
C
200 body('role')
201 .optional()
202 .customSanitizer(toIntOrNull)
203 .custom(isUserRoleValid).withMessage('Should have a valid role'),
1eddc9a7 204 body('adminFlags').optional().custom(isUserAdminFlagsValid).withMessage('Should have a valid admin flags'),
8094a898 205
a2431b7d 206 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
b60e5f38 207 logger.debug('Checking usersUpdate parameters', { parameters: req.body })
9bd26629 208
a2431b7d
C
209 if (areValidationErrors(req, res)) return
210 if (!await checkUserIdExist(req.params.id, res)) return
211
f8b8c36b
C
212 const user = res.locals.user
213 if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) {
76148b27 214 return res.fail({ message: 'Cannot change root role.' })
f8b8c36b
C
215 }
216
a2431b7d 217 return next()
b60e5f38
C
218 }
219]
9bd26629 220
b60e5f38 221const usersUpdateMeValidator = [
d1ab89de
C
222 body('displayName')
223 .optional()
224 .custom(isUserDisplayNameValid).withMessage('Should have a valid display name'),
225 body('description')
226 .optional()
227 .custom(isUserDescriptionValid).withMessage('Should have a valid description'),
228 body('currentPassword')
229 .optional()
230 .custom(isUserPasswordValid).withMessage('Should have a valid current password'),
231 body('password')
232 .optional()
233 .custom(isUserPasswordValid).withMessage('Should have a valid password'),
234 body('email')
235 .optional()
236 .isEmail().withMessage('Should have a valid email attribute'),
237 body('nsfwPolicy')
238 .optional()
239 .custom(isUserNSFWPolicyValid).withMessage('Should have a valid display Not Safe For Work policy'),
240 body('autoPlayVideo')
241 .optional()
242 .custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video attribute'),
a9bfa85d
C
243 body('p2pEnabled')
244 .optional()
245 .custom(isUserP2PEnabledValid).withMessage('Should have a valid p2p enabled boolean'),
3caf77d3
C
246 body('videoLanguages')
247 .optional()
248 .custom(isUserVideoLanguages).withMessage('Should have a valid video languages attribute'),
1a12adcd
C
249 body('videosHistoryEnabled')
250 .optional()
251 .custom(isUserVideosHistoryEnabledValid).withMessage('Should have a valid videos history enabled attribute'),
7cd4d2ba
C
252 body('theme')
253 .optional()
503c6f44 254 .custom(v => isThemeNameValid(v) && isThemeRegistered(v)).withMessage('Should have a valid theme'),
8f581725 255
43d0ea7f
C
256 body('noInstanceConfigWarningModal')
257 .optional()
8f581725 258 .custom(v => isUserNoModal(v)).withMessage('Should have a valid noInstanceConfigWarningModal boolean'),
43d0ea7f
C
259 body('noWelcomeModal')
260 .optional()
8f581725
C
261 .custom(v => isUserNoModal(v)).withMessage('Should have a valid noWelcomeModal boolean'),
262 body('noAccountSetupWarningModal')
263 .optional()
264 .custom(v => isUserNoModal(v)).withMessage('Should have a valid noAccountSetupWarningModal boolean'),
265
c1e5bd23
C
266 body('autoPlayNextVideo')
267 .optional()
268 .custom(v => isUserAutoPlayNextVideoValid(v)).withMessage('Should have a valid autoPlayNextVideo boolean'),
9bd26629 269
a890d1e0 270 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
ce97fe36 271 logger.debug('Checking usersUpdateMe parameters', { parameters: omit(req.body, 'password') })
8094a898 272
9a7fd960
C
273 const user = res.locals.oauth.token.User
274
0ba5f5ba 275 if (req.body.password || req.body.email) {
9a7fd960 276 if (user.pluginAuth !== null) {
76148b27 277 return res.fail({ message: 'You cannot update your email or password that is associated with an external auth system.' })
9a7fd960
C
278 }
279
a890d1e0 280 if (!req.body.currentPassword) {
76148b27 281 return res.fail({ message: 'currentPassword parameter is missing.' })
a890d1e0
C
282 }
283
a890d1e0 284 if (await user.isPasswordMatch(req.body.currentPassword) !== true) {
76148b27
RK
285 return res.fail({
286 status: HttpStatusCode.UNAUTHORIZED_401,
287 message: 'currentPassword is invalid.'
288 })
a890d1e0
C
289 }
290 }
291
a2431b7d
C
292 if (areValidationErrors(req, res)) return
293
294 return next()
b60e5f38
C
295 }
296]
8094a898 297
b60e5f38
C
298const usersGetValidator = [
299 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
76314386 300 query('withStats').optional().isBoolean().withMessage('Should have a valid stats flag'),
d38b8281 301
a2431b7d 302 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
ce97fe36 303 logger.debug('Checking usersGet parameters', { parameters: req.params })
a2431b7d
C
304
305 if (areValidationErrors(req, res)) return
76314386 306 if (!await checkUserIdExist(req.params.id, res, req.query.withStats)) return
a2431b7d
C
307
308 return next()
b60e5f38
C
309 }
310]
d38b8281 311
b60e5f38 312const usersVideoRatingValidator = [
d4a8e7a6 313 isValidVideoIdParam('videoId'),
0a6658fd 314
a2431b7d 315 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
b60e5f38 316 logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
0a6658fd 317
a2431b7d 318 if (areValidationErrors(req, res)) return
0f6acda1 319 if (!await doesVideoExist(req.params.videoId, res, 'id')) return
a2431b7d
C
320
321 return next()
b60e5f38
C
322 }
323]
324
978c87e7
C
325const usersVideosValidator = [
326 query('isLive')
327 .optional()
328 .customSanitizer(toBooleanOrNull)
329 .custom(isBooleanValid).withMessage('Should have a valid live boolean'),
330
331 query('channelId')
332 .optional()
333 .customSanitizer(toIntOrNull)
334 .custom(isIdValid).withMessage('Should have a valid channel id'),
335
336 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
c4c0c311 337 logger.debug('Checking usersVideosValidator parameters', { parameters: req.query })
978c87e7
C
338
339 if (areValidationErrors(req, res)) return
340
341 if (req.query.channelId && !await doesVideoChannelIdExist(req.query.channelId, res)) return
342
343 return next()
344 }
345]
346
b60e5f38 347const ensureUserRegistrationAllowed = [
a2431b7d 348 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
4ce7eb71 349 const allowedParams = {
ba7b7e57
RK
350 body: req.body,
351 ip: req.ip
4ce7eb71
C
352 }
353
354 const allowedResult = await Hooks.wrapPromiseFun(
355 isSignupAllowed,
356 allowedParams,
357 'filter:api.user.signup.allowed.result'
358 )
359
360 if (allowedResult.allowed === false) {
76148b27
RK
361 return res.fail({
362 status: HttpStatusCode.FORBIDDEN_403,
363 message: allowedResult.errorMessage || 'User registration is not enabled or user limit is reached.'
364 })
a2431b7d
C
365 }
366
367 return next()
b60e5f38
C
368 }
369]
291e8d3e 370
ff2c1fe8 371const ensureUserRegistrationAllowedForIP = [
a1587156 372 (req: express.Request, res: express.Response, next: express.NextFunction) => {
ff2c1fe8
RK
373 const allowed = isSignupAllowedForCurrentIP(req.ip)
374
375 if (allowed === false) {
76148b27
RK
376 return res.fail({
377 status: HttpStatusCode.FORBIDDEN_403,
378 message: 'You are not on a network authorized for registration.'
379 })
ff2c1fe8
RK
380 }
381
382 return next()
383 }
384]
385
ecb4e35f
C
386const usersAskResetPasswordValidator = [
387 body('email').isEmail().not().isEmpty().withMessage('Should have a valid email'),
388
389 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
390 logger.debug('Checking usersAskResetPassword parameters', { parameters: req.body })
391
392 if (areValidationErrors(req, res)) return
b426edd4 393
ecb4e35f
C
394 const exists = await checkUserEmailExist(req.body.email, res, false)
395 if (!exists) {
396 logger.debug('User with email %s does not exist (asking reset password).', req.body.email)
397 // Do not leak our emails
2d53be02 398 return res.status(HttpStatusCode.NO_CONTENT_204).end()
ecb4e35f
C
399 }
400
401 return next()
402 }
403]
404
405const usersResetPasswordValidator = [
406 param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
407 body('verificationString').not().isEmpty().withMessage('Should have a valid verification string'),
408 body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
409
410 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
411 logger.debug('Checking usersResetPassword parameters', { parameters: req.params })
412
413 if (areValidationErrors(req, res)) return
414 if (!await checkUserIdExist(req.params.id, res)) return
415
dae86118 416 const user = res.locals.user
ecb4e35f
C
417 const redisVerificationString = await Redis.Instance.getResetPasswordLink(user.id)
418
419 if (redisVerificationString !== req.body.verificationString) {
76148b27
RK
420 return res.fail({
421 status: HttpStatusCode.FORBIDDEN_403,
422 message: 'Invalid verification string.'
423 })
ecb4e35f
C
424 }
425
426 return next()
427 }
428]
429
d9eaee39
JM
430const usersAskSendVerifyEmailValidator = [
431 body('email').isEmail().not().isEmpty().withMessage('Should have a valid email'),
432
433 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
434 logger.debug('Checking askUsersSendVerifyEmail parameters', { parameters: req.body })
435
436 if (areValidationErrors(req, res)) return
437 const exists = await checkUserEmailExist(req.body.email, res, false)
438 if (!exists) {
439 logger.debug('User with email %s does not exist (asking verify email).', req.body.email)
440 // Do not leak our emails
2d53be02 441 return res.status(HttpStatusCode.NO_CONTENT_204).end()
d9eaee39
JM
442 }
443
444 return next()
445 }
446]
447
448const usersVerifyEmailValidator = [
d1ab89de
C
449 param('id')
450 .isInt().not().isEmpty().withMessage('Should have a valid id'),
451
452 body('verificationString')
453 .not().isEmpty().withMessage('Should have a valid verification string'),
454 body('isPendingEmail')
455 .optional()
2b65c4e5 456 .customSanitizer(toBooleanOrNull),
d9eaee39
JM
457
458 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
459 logger.debug('Checking usersVerifyEmail parameters', { parameters: req.params })
460
461 if (areValidationErrors(req, res)) return
462 if (!await checkUserIdExist(req.params.id, res)) return
463
dae86118 464 const user = res.locals.user
d9eaee39
JM
465 const redisVerificationString = await Redis.Instance.getVerifyEmailLink(user.id)
466
467 if (redisVerificationString !== req.body.verificationString) {
76148b27
RK
468 return res.fail({
469 status: HttpStatusCode.FORBIDDEN_403,
470 message: 'Invalid verification string.'
471 })
d9eaee39
JM
472 }
473
474 return next()
475 }
476]
477
74d63469
GR
478const userAutocompleteValidator = [
479 param('search').isString().not().isEmpty().withMessage('Should have a search parameter')
480]
481
c100a614 482const ensureAuthUserOwnsAccountValidator = [
a1587156 483 (req: express.Request, res: express.Response, next: express.NextFunction) => {
c100a614
YB
484 const user = res.locals.oauth.token.User
485
486 if (res.locals.account.id !== user.Account.id) {
76148b27
RK
487 return res.fail({
488 status: HttpStatusCode.FORBIDDEN_403,
7a4fd56c 489 message: 'Only owner of this account can access this resource.'
4beda9e1
C
490 })
491 }
492
493 return next()
494 }
495]
496
a37e9e74 497const ensureCanManageChannel = [
4beda9e1 498 (req: express.Request, res: express.Response, next: express.NextFunction) => {
a37e9e74 499 const user = res.locals.oauth.token.user
500 const isUserOwner = res.locals.videoChannel.Account.userId === user.id
501
502 if (!isUserOwner && user.hasRight(UserRight.MANAGE_ANY_VIDEO_CHANNEL) === false) {
503 const message = `User ${user.username} does not have right to manage channel ${req.params.nameWithHost}.`
4beda9e1 504
4beda9e1
C
505 return res.fail({
506 status: HttpStatusCode.FORBIDDEN_403,
a37e9e74 507 message
76148b27 508 })
c100a614
YB
509 }
510
511 return next()
512 }
513]
514
a95a4cc8
C
515const ensureCanManageUser = [
516 (req: express.Request, res: express.Response, next: express.NextFunction) => {
517 const authUser = res.locals.oauth.token.User
518 const onUser = res.locals.user
519
520 if (authUser.role === UserRole.ADMINISTRATOR) return next()
521 if (authUser.role === UserRole.MODERATOR && onUser.role === UserRole.USER) return next()
522
76148b27
RK
523 return res.fail({
524 status: HttpStatusCode.FORBIDDEN_403,
525 message: 'A moderator can only manager users.'
526 })
a95a4cc8
C
527 }
528]
529
9bd26629
C
530// ---------------------------------------------------------------------------
531
65fcc311 532export {
8491293b 533 usersListValidator,
65fcc311 534 usersAddValidator,
92b9d60c 535 deleteMeValidator,
77a5501f 536 usersRegisterValidator,
e6921918 537 usersBlockingValidator,
65fcc311
C
538 usersRemoveValidator,
539 usersUpdateValidator,
8094a898 540 usersUpdateMeValidator,
291e8d3e 541 usersVideoRatingValidator,
8094a898 542 ensureUserRegistrationAllowed,
ff2c1fe8 543 ensureUserRegistrationAllowedForIP,
c5911fd3 544 usersGetValidator,
978c87e7 545 usersVideosValidator,
ecb4e35f 546 usersAskResetPasswordValidator,
d9eaee39
JM
547 usersResetPasswordValidator,
548 usersAskSendVerifyEmailValidator,
74d63469 549 usersVerifyEmailValidator,
c100a614 550 userAutocompleteValidator,
a95a4cc8 551 ensureAuthUserOwnsAccountValidator,
a37e9e74 552 ensureCanManageUser,
553 ensureCanManageChannel
8094a898
C
554}
555
556// ---------------------------------------------------------------------------
557
76314386 558function checkUserIdExist (idArg: number | string, res: express.Response, withStats = false) {
d5d9b6d7 559 const id = parseInt(idArg + '', 10)
fb719404 560 return checkUserExist(() => UserModel.loadByIdWithChannels(id, withStats), res)
ecb4e35f 561}
a2431b7d 562
ecb4e35f
C
563function checkUserEmailExist (email: string, res: express.Response, abortResponse = true) {
564 return checkUserExist(() => UserModel.loadByEmail(email), res, abortResponse)
65fcc311 565}
77a5501f 566
a2431b7d 567async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
3fd3ab2d 568 const user = await UserModel.loadByUsernameOrEmail(username, email)
a2431b7d
C
569
570 if (user) {
76148b27
RK
571 res.fail({
572 status: HttpStatusCode.CONFLICT_409,
573 message: 'User with this username or email already exists.'
574 })
a2431b7d
C
575 return false
576 }
577
2ef6a063
C
578 const actor = await ActorModel.loadLocalByName(username)
579 if (actor) {
76148b27
RK
580 res.fail({
581 status: HttpStatusCode.CONFLICT_409,
582 message: 'Another actor (account/channel) with this name on this instance already exists or has already existed.'
583 })
2ef6a063
C
584 return false
585 }
586
a2431b7d 587 return true
77a5501f 588}
ecb4e35f 589
b49f22d8 590async function checkUserExist (finder: () => Promise<MUserDefault>, res: express.Response, abortResponse = true) {
ecb4e35f
C
591 const user = await finder()
592
593 if (!user) {
594 if (abortResponse === true) {
76148b27
RK
595 res.fail({
596 status: HttpStatusCode.NOT_FOUND_404,
597 message: 'User not found'
598 })
ecb4e35f
C
599 }
600
601 return false
602 }
603
604 res.locals.user = user
ecb4e35f
C
605 return true
606}