diff options
Diffstat (limited to 'server/middlewares/validators/users.ts')
-rw-r--r-- | server/middlewares/validators/users.ts | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index da92c715d..16d297047 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -30,6 +30,7 @@ import { UserRegister } from '../../../shared/models/users/user-register.model' | |||
30 | import { isThemeNameValid } from '../../helpers/custom-validators/plugins' | 30 | import { isThemeNameValid } from '../../helpers/custom-validators/plugins' |
31 | import { isThemeRegistered } from '../../lib/plugins/theme-utils' | 31 | import { isThemeRegistered } from '../../lib/plugins/theme-utils' |
32 | import { doesVideoExist } from '../../helpers/middlewares' | 32 | import { doesVideoExist } from '../../helpers/middlewares' |
33 | import { UserRole } from '../../../shared/models/users' | ||
33 | 34 | ||
34 | const usersAddValidator = [ | 35 | const usersAddValidator = [ |
35 | body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), | 36 | body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), |
@@ -46,6 +47,12 @@ const usersAddValidator = [ | |||
46 | if (areValidationErrors(req, res)) return | 47 | if (areValidationErrors(req, res)) return |
47 | if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return | 48 | if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return |
48 | 49 | ||
50 | const authUser = res.locals.oauth.token.User | ||
51 | if (authUser.role !== UserRole.ADMINISTRATOR && req.body.role !== UserRole.USER) { | ||
52 | return res.status(403) | ||
53 | .json({ error: 'You can only create users (and not administrators or moderators' }) | ||
54 | } | ||
55 | |||
49 | return next() | 56 | return next() |
50 | } | 57 | } |
51 | ] | 58 | ] |
@@ -75,21 +82,18 @@ const usersRegisterValidator = [ | |||
75 | if (body.channel) { | 82 | if (body.channel) { |
76 | if (!body.channel.name || !body.channel.displayName) { | 83 | if (!body.channel.name || !body.channel.displayName) { |
77 | return res.status(400) | 84 | return res.status(400) |
78 | .send({ error: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' }) | 85 | .json({ error: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' }) |
79 | .end() | ||
80 | } | 86 | } |
81 | 87 | ||
82 | if (body.channel.name === body.username) { | 88 | if (body.channel.name === body.username) { |
83 | return res.status(400) | 89 | return res.status(400) |
84 | .send({ error: 'Channel name cannot be the same than user username.' }) | 90 | .json({ error: 'Channel name cannot be the same than user username.' }) |
85 | .end() | ||
86 | } | 91 | } |
87 | 92 | ||
88 | const existing = await ActorModel.loadLocalByName(body.channel.name) | 93 | const existing = await ActorModel.loadLocalByName(body.channel.name) |
89 | if (existing) { | 94 | if (existing) { |
90 | return res.status(409) | 95 | return res.status(409) |
91 | .send({ error: `Channel with name ${body.channel.name} already exists.` }) | 96 | .json({ error: `Channel with name ${body.channel.name} already exists.` }) |
92 | .end() | ||
93 | } | 97 | } |
94 | } | 98 | } |
95 | 99 | ||
@@ -109,8 +113,7 @@ const usersRemoveValidator = [ | |||
109 | const user = res.locals.user | 113 | const user = res.locals.user |
110 | if (user.username === 'root') { | 114 | if (user.username === 'root') { |
111 | return res.status(400) | 115 | return res.status(400) |
112 | .send({ error: 'Cannot remove the root user' }) | 116 | .json({ error: 'Cannot remove the root user' }) |
113 | .end() | ||
114 | } | 117 | } |
115 | 118 | ||
116 | return next() | 119 | return next() |
@@ -130,8 +133,7 @@ const usersBlockingValidator = [ | |||
130 | const user = res.locals.user | 133 | const user = res.locals.user |
131 | if (user.username === 'root') { | 134 | if (user.username === 'root') { |
132 | return res.status(400) | 135 | return res.status(400) |
133 | .send({ error: 'Cannot block the root user' }) | 136 | .json({ error: 'Cannot block the root user' }) |
134 | .end() | ||
135 | } | 137 | } |
136 | 138 | ||
137 | return next() | 139 | return next() |
@@ -143,7 +145,7 @@ const deleteMeValidator = [ | |||
143 | const user = res.locals.oauth.token.User | 145 | const user = res.locals.oauth.token.User |
144 | if (user.username === 'root') { | 146 | if (user.username === 'root') { |
145 | return res.status(400) | 147 | return res.status(400) |
146 | .send({ error: 'You cannot delete your root account.' }) | 148 | .json({ error: 'You cannot delete your root account.' }) |
147 | .end() | 149 | .end() |
148 | } | 150 | } |
149 | 151 | ||
@@ -170,8 +172,7 @@ const usersUpdateValidator = [ | |||
170 | const user = res.locals.user | 172 | const user = res.locals.user |
171 | if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) { | 173 | if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) { |
172 | return res.status(400) | 174 | return res.status(400) |
173 | .send({ error: 'Cannot change root role.' }) | 175 | .json({ error: 'Cannot change root role.' }) |
174 | .end() | ||
175 | } | 176 | } |
176 | 177 | ||
177 | return next() | 178 | return next() |
@@ -216,15 +217,14 @@ const usersUpdateMeValidator = [ | |||
216 | if (req.body.password || req.body.email) { | 217 | if (req.body.password || req.body.email) { |
217 | if (!req.body.currentPassword) { | 218 | if (!req.body.currentPassword) { |
218 | return res.status(400) | 219 | return res.status(400) |
219 | .send({ error: 'currentPassword parameter is missing.' }) | 220 | .json({ error: 'currentPassword parameter is missing.' }) |
220 | .end() | 221 | .end() |
221 | } | 222 | } |
222 | 223 | ||
223 | const user = res.locals.oauth.token.User | 224 | const user = res.locals.oauth.token.User |
224 | if (await user.isPasswordMatch(req.body.currentPassword) !== true) { | 225 | if (await user.isPasswordMatch(req.body.currentPassword) !== true) { |
225 | return res.status(401) | 226 | return res.status(401) |
226 | .send({ error: 'currentPassword is invalid.' }) | 227 | .json({ error: 'currentPassword is invalid.' }) |
227 | .end() | ||
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
@@ -265,8 +265,7 @@ const ensureUserRegistrationAllowed = [ | |||
265 | const allowed = await isSignupAllowed() | 265 | const allowed = await isSignupAllowed() |
266 | if (allowed === false) { | 266 | if (allowed === false) { |
267 | return res.status(403) | 267 | return res.status(403) |
268 | .send({ error: 'User registration is not enabled or user limit is reached.' }) | 268 | .json({ error: 'User registration is not enabled or user limit is reached.' }) |
269 | .end() | ||
270 | } | 269 | } |
271 | 270 | ||
272 | return next() | 271 | return next() |
@@ -279,8 +278,7 @@ const ensureUserRegistrationAllowedForIP = [ | |||
279 | 278 | ||
280 | if (allowed === false) { | 279 | if (allowed === false) { |
281 | return res.status(403) | 280 | return res.status(403) |
282 | .send({ error: 'You are not on a network authorized for registration.' }) | 281 | .json({ error: 'You are not on a network authorized for registration.' }) |
283 | .end() | ||
284 | } | 282 | } |
285 | 283 | ||
286 | return next() | 284 | return next() |
@@ -323,8 +321,7 @@ const usersResetPasswordValidator = [ | |||
323 | if (redisVerificationString !== req.body.verificationString) { | 321 | if (redisVerificationString !== req.body.verificationString) { |
324 | return res | 322 | return res |
325 | .status(403) | 323 | .status(403) |
326 | .send({ error: 'Invalid verification string.' }) | 324 | .json({ error: 'Invalid verification string.' }) |
327 | .end() | ||
328 | } | 325 | } |
329 | 326 | ||
330 | return next() | 327 | return next() |
@@ -371,8 +368,7 @@ const usersVerifyEmailValidator = [ | |||
371 | if (redisVerificationString !== req.body.verificationString) { | 368 | if (redisVerificationString !== req.body.verificationString) { |
372 | return res | 369 | return res |
373 | .status(403) | 370 | .status(403) |
374 | .send({ error: 'Invalid verification string.' }) | 371 | .json({ error: 'Invalid verification string.' }) |
375 | .end() | ||
376 | } | 372 | } |
377 | 373 | ||
378 | return next() | 374 | return next() |
@@ -389,14 +385,26 @@ const ensureAuthUserOwnsAccountValidator = [ | |||
389 | 385 | ||
390 | if (res.locals.account.id !== user.Account.id) { | 386 | if (res.locals.account.id !== user.Account.id) { |
391 | return res.status(403) | 387 | return res.status(403) |
392 | .send({ error: 'Only owner can access ratings list.' }) | 388 | .json({ error: 'Only owner can access ratings list.' }) |
393 | .end() | ||
394 | } | 389 | } |
395 | 390 | ||
396 | return next() | 391 | return next() |
397 | } | 392 | } |
398 | ] | 393 | ] |
399 | 394 | ||
395 | const ensureCanManageUser = [ | ||
396 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
397 | const authUser = res.locals.oauth.token.User | ||
398 | const onUser = res.locals.user | ||
399 | |||
400 | if (authUser.role === UserRole.ADMINISTRATOR) return next() | ||
401 | if (authUser.role === UserRole.MODERATOR && onUser.role === UserRole.USER) return next() | ||
402 | |||
403 | return res.status(403) | ||
404 | .json({ error: 'A moderator can only manager users.' }) | ||
405 | } | ||
406 | ] | ||
407 | |||
400 | // --------------------------------------------------------------------------- | 408 | // --------------------------------------------------------------------------- |
401 | 409 | ||
402 | export { | 410 | export { |
@@ -416,7 +424,8 @@ export { | |||
416 | usersAskSendVerifyEmailValidator, | 424 | usersAskSendVerifyEmailValidator, |
417 | usersVerifyEmailValidator, | 425 | usersVerifyEmailValidator, |
418 | userAutocompleteValidator, | 426 | userAutocompleteValidator, |
419 | ensureAuthUserOwnsAccountValidator | 427 | ensureAuthUserOwnsAccountValidator, |
428 | ensureCanManageUser | ||
420 | } | 429 | } |
421 | 430 | ||
422 | // --------------------------------------------------------------------------- | 431 | // --------------------------------------------------------------------------- |
@@ -434,16 +443,14 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: | |||
434 | 443 | ||
435 | if (user) { | 444 | if (user) { |
436 | res.status(409) | 445 | res.status(409) |
437 | .send({ error: 'User with this username or email already exists.' }) | 446 | .json({ error: 'User with this username or email already exists.' }) |
438 | .end() | ||
439 | return false | 447 | return false |
440 | } | 448 | } |
441 | 449 | ||
442 | const actor = await ActorModel.loadLocalByName(username) | 450 | const actor = await ActorModel.loadLocalByName(username) |
443 | if (actor) { | 451 | if (actor) { |
444 | res.status(409) | 452 | res.status(409) |
445 | .send({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' }) | 453 | .json({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' }) |
446 | .end() | ||
447 | return false | 454 | return false |
448 | } | 455 | } |
449 | 456 | ||
@@ -456,8 +463,7 @@ async function checkUserExist (finder: () => Bluebird<UserModel>, res: express.R | |||
456 | if (!user) { | 463 | if (!user) { |
457 | if (abortResponse === true) { | 464 | if (abortResponse === true) { |
458 | res.status(404) | 465 | res.status(404) |
459 | .send({ error: 'User not found' }) | 466 | .json({ error: 'User not found' }) |
460 | .end() | ||
461 | } | 467 | } |
462 | 468 | ||
463 | return false | 469 | return false |