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