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