diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2021-06-01 01:36:53 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2021-06-02 16:57:07 +0200 |
commit | 76148b27f7501bac061992136852be4303370c8d (patch) | |
tree | fc0559253e833c9252fa14ebaec5321d88bfb4e8 /server/middlewares/validators/users.ts | |
parent | 5ed25fb76e920dac364cb9ef46f14ec4bd372949 (diff) | |
download | PeerTube-76148b27f7501bac061992136852be4303370c8d.tar.gz PeerTube-76148b27f7501bac061992136852be4303370c8d.tar.zst PeerTube-76148b27f7501bac061992136852be4303370c8d.zip |
refactor API errors to standard error format
Diffstat (limited to 'server/middlewares/validators/users.ts')
-rw-r--r-- | server/middlewares/validators/users.ts | 113 |
1 files changed, 61 insertions, 52 deletions
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 548d5df4d..0eb9172c4 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -73,23 +73,23 @@ const usersAddValidator = [ | |||
73 | 73 | ||
74 | const authUser = res.locals.oauth.token.User | 74 | const authUser = res.locals.oauth.token.User |
75 | if (authUser.role !== UserRole.ADMINISTRATOR && req.body.role !== UserRole.USER) { | 75 | if (authUser.role !== UserRole.ADMINISTRATOR && req.body.role !== UserRole.USER) { |
76 | return res | 76 | return res.fail({ |
77 | .status(HttpStatusCode.FORBIDDEN_403) | 77 | status: HttpStatusCode.FORBIDDEN_403, |
78 | .json({ error: 'You can only create users (and not administrators or moderators)' }) | 78 | message: 'You can only create users (and not administrators or moderators)' |
79 | }) | ||
79 | } | 80 | } |
80 | 81 | ||
81 | if (req.body.channelName) { | 82 | if (req.body.channelName) { |
82 | if (req.body.channelName === req.body.username) { | 83 | if (req.body.channelName === req.body.username) { |
83 | return res | 84 | return res.fail({ message: 'Channel name cannot be the same as user username.' }) |
84 | .status(HttpStatusCode.BAD_REQUEST_400) | ||
85 | .json({ error: 'Channel name cannot be the same as user username.' }) | ||
86 | } | 85 | } |
87 | 86 | ||
88 | const existing = await ActorModel.loadLocalByName(req.body.channelName) | 87 | const existing = await ActorModel.loadLocalByName(req.body.channelName) |
89 | if (existing) { | 88 | if (existing) { |
90 | return res | 89 | return res.fail({ |
91 | .status(HttpStatusCode.CONFLICT_409) | 90 | status: HttpStatusCode.CONFLICT_409, |
92 | .json({ error: `Channel with name ${req.body.channelName} already exists.` }) | 91 | message: `Channel with name ${req.body.channelName} already exists.` |
92 | }) | ||
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
@@ -121,20 +121,19 @@ const usersRegisterValidator = [ | |||
121 | const body: UserRegister = req.body | 121 | const body: UserRegister = req.body |
122 | if (body.channel) { | 122 | if (body.channel) { |
123 | if (!body.channel.name || !body.channel.displayName) { | 123 | if (!body.channel.name || !body.channel.displayName) { |
124 | return res | 124 | return res.fail({ message: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' }) |
125 | .status(HttpStatusCode.BAD_REQUEST_400) | ||
126 | .json({ error: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' }) | ||
127 | } | 125 | } |
128 | 126 | ||
129 | if (body.channel.name === body.username) { | 127 | if (body.channel.name === body.username) { |
130 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 128 | return res.fail({ message: 'Channel name cannot be the same as user username.' }) |
131 | .json({ error: 'Channel name cannot be the same as user username.' }) | ||
132 | } | 129 | } |
133 | 130 | ||
134 | const existing = await ActorModel.loadLocalByName(body.channel.name) | 131 | const existing = await ActorModel.loadLocalByName(body.channel.name) |
135 | if (existing) { | 132 | if (existing) { |
136 | return res.status(HttpStatusCode.CONFLICT_409) | 133 | return res.fail({ |
137 | .json({ error: `Channel with name ${body.channel.name} already exists.` }) | 134 | status: HttpStatusCode.CONFLICT_409, |
135 | message: `Channel with name ${body.channel.name} already exists.` | ||
136 | }) | ||
138 | } | 137 | } |
139 | } | 138 | } |
140 | 139 | ||
@@ -153,8 +152,7 @@ const usersRemoveValidator = [ | |||
153 | 152 | ||
154 | const user = res.locals.user | 153 | const user = res.locals.user |
155 | if (user.username === 'root') { | 154 | if (user.username === 'root') { |
156 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 155 | return res.fail({ message: 'Cannot remove the root user' }) |
157 | .json({ error: 'Cannot remove the root user' }) | ||
158 | } | 156 | } |
159 | 157 | ||
160 | return next() | 158 | return next() |
@@ -173,8 +171,7 @@ const usersBlockingValidator = [ | |||
173 | 171 | ||
174 | const user = res.locals.user | 172 | const user = res.locals.user |
175 | if (user.username === 'root') { | 173 | if (user.username === 'root') { |
176 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 174 | return res.fail({ message: 'Cannot block the root user' }) |
177 | .json({ error: 'Cannot block the root user' }) | ||
178 | } | 175 | } |
179 | 176 | ||
180 | return next() | 177 | return next() |
@@ -185,9 +182,7 @@ const deleteMeValidator = [ | |||
185 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 182 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
186 | const user = res.locals.oauth.token.User | 183 | const user = res.locals.oauth.token.User |
187 | if (user.username === 'root') { | 184 | if (user.username === 'root') { |
188 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 185 | return res.fail({ message: 'You cannot delete your root account.' }) |
189 | .json({ error: 'You cannot delete your root account.' }) | ||
190 | .end() | ||
191 | } | 186 | } |
192 | 187 | ||
193 | return next() | 188 | return next() |
@@ -217,8 +212,7 @@ const usersUpdateValidator = [ | |||
217 | 212 | ||
218 | const user = res.locals.user | 213 | const user = res.locals.user |
219 | if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) { | 214 | if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) { |
220 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 215 | return res.fail({ message: 'Cannot change root role.' }) |
221 | .json({ error: 'Cannot change root role.' }) | ||
222 | } | 216 | } |
223 | 217 | ||
224 | return next() | 218 | return next() |
@@ -273,18 +267,18 @@ const usersUpdateMeValidator = [ | |||
273 | 267 | ||
274 | if (req.body.password || req.body.email) { | 268 | if (req.body.password || req.body.email) { |
275 | if (user.pluginAuth !== null) { | 269 | if (user.pluginAuth !== null) { |
276 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 270 | return res.fail({ message: 'You cannot update your email or password that is associated with an external auth system.' }) |
277 | .json({ error: 'You cannot update your email or password that is associated with an external auth system.' }) | ||
278 | } | 271 | } |
279 | 272 | ||
280 | if (!req.body.currentPassword) { | 273 | if (!req.body.currentPassword) { |
281 | return res.status(HttpStatusCode.BAD_REQUEST_400) | 274 | return res.fail({ message: 'currentPassword parameter is missing.' }) |
282 | .json({ error: 'currentPassword parameter is missing.' }) | ||
283 | } | 275 | } |
284 | 276 | ||
285 | if (await user.isPasswordMatch(req.body.currentPassword) !== true) { | 277 | if (await user.isPasswordMatch(req.body.currentPassword) !== true) { |
286 | return res.status(HttpStatusCode.UNAUTHORIZED_401) | 278 | return res.fail({ |
287 | .json({ error: 'currentPassword is invalid.' }) | 279 | status: HttpStatusCode.UNAUTHORIZED_401, |
280 | message: 'currentPassword is invalid.' | ||
281 | }) | ||
288 | } | 282 | } |
289 | } | 283 | } |
290 | 284 | ||
@@ -335,8 +329,10 @@ const ensureUserRegistrationAllowed = [ | |||
335 | ) | 329 | ) |
336 | 330 | ||
337 | if (allowedResult.allowed === false) { | 331 | if (allowedResult.allowed === false) { |
338 | return res.status(HttpStatusCode.FORBIDDEN_403) | 332 | return res.fail({ |
339 | .json({ error: allowedResult.errorMessage || 'User registration is not enabled or user limit is reached.' }) | 333 | status: HttpStatusCode.FORBIDDEN_403, |
334 | message: allowedResult.errorMessage || 'User registration is not enabled or user limit is reached.' | ||
335 | }) | ||
340 | } | 336 | } |
341 | 337 | ||
342 | return next() | 338 | return next() |
@@ -348,8 +344,10 @@ const ensureUserRegistrationAllowedForIP = [ | |||
348 | const allowed = isSignupAllowedForCurrentIP(req.ip) | 344 | const allowed = isSignupAllowedForCurrentIP(req.ip) |
349 | 345 | ||
350 | if (allowed === false) { | 346 | if (allowed === false) { |
351 | return res.status(HttpStatusCode.FORBIDDEN_403) | 347 | return res.fail({ |
352 | .json({ error: 'You are not on a network authorized for registration.' }) | 348 | status: HttpStatusCode.FORBIDDEN_403, |
349 | message: 'You are not on a network authorized for registration.' | ||
350 | }) | ||
353 | } | 351 | } |
354 | 352 | ||
355 | return next() | 353 | return next() |
@@ -390,9 +388,10 @@ const usersResetPasswordValidator = [ | |||
390 | const redisVerificationString = await Redis.Instance.getResetPasswordLink(user.id) | 388 | const redisVerificationString = await Redis.Instance.getResetPasswordLink(user.id) |
391 | 389 | ||
392 | if (redisVerificationString !== req.body.verificationString) { | 390 | if (redisVerificationString !== req.body.verificationString) { |
393 | return res | 391 | return res.fail({ |
394 | .status(HttpStatusCode.FORBIDDEN_403) | 392 | status: HttpStatusCode.FORBIDDEN_403, |
395 | .json({ error: 'Invalid verification string.' }) | 393 | message: 'Invalid verification string.' |
394 | }) | ||
396 | } | 395 | } |
397 | 396 | ||
398 | return next() | 397 | return next() |
@@ -437,9 +436,10 @@ const usersVerifyEmailValidator = [ | |||
437 | const redisVerificationString = await Redis.Instance.getVerifyEmailLink(user.id) | 436 | const redisVerificationString = await Redis.Instance.getVerifyEmailLink(user.id) |
438 | 437 | ||
439 | if (redisVerificationString !== req.body.verificationString) { | 438 | if (redisVerificationString !== req.body.verificationString) { |
440 | return res | 439 | return res.fail({ |
441 | .status(HttpStatusCode.FORBIDDEN_403) | 440 | status: HttpStatusCode.FORBIDDEN_403, |
442 | .json({ error: 'Invalid verification string.' }) | 441 | message: 'Invalid verification string.' |
442 | }) | ||
443 | } | 443 | } |
444 | 444 | ||
445 | return next() | 445 | return next() |
@@ -455,8 +455,10 @@ const ensureAuthUserOwnsAccountValidator = [ | |||
455 | const user = res.locals.oauth.token.User | 455 | const user = res.locals.oauth.token.User |
456 | 456 | ||
457 | if (res.locals.account.id !== user.Account.id) { | 457 | if (res.locals.account.id !== user.Account.id) { |
458 | return res.status(HttpStatusCode.FORBIDDEN_403) | 458 | return res.fail({ |
459 | .json({ error: 'Only owner can access ratings list.' }) | 459 | status: HttpStatusCode.FORBIDDEN_403, |
460 | message: 'Only owner can access ratings list.' | ||
461 | }) | ||
460 | } | 462 | } |
461 | 463 | ||
462 | return next() | 464 | return next() |
@@ -471,8 +473,10 @@ const ensureCanManageUser = [ | |||
471 | if (authUser.role === UserRole.ADMINISTRATOR) return next() | 473 | if (authUser.role === UserRole.ADMINISTRATOR) return next() |
472 | if (authUser.role === UserRole.MODERATOR && onUser.role === UserRole.USER) return next() | 474 | if (authUser.role === UserRole.MODERATOR && onUser.role === UserRole.USER) return next() |
473 | 475 | ||
474 | return res.status(HttpStatusCode.FORBIDDEN_403) | 476 | return res.fail({ |
475 | .json({ error: 'A moderator can only manager users.' }) | 477 | status: HttpStatusCode.FORBIDDEN_403, |
478 | message: 'A moderator can only manager users.' | ||
479 | }) | ||
476 | } | 480 | } |
477 | ] | 481 | ] |
478 | 482 | ||
@@ -515,15 +519,19 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: | |||
515 | const user = await UserModel.loadByUsernameOrEmail(username, email) | 519 | const user = await UserModel.loadByUsernameOrEmail(username, email) |
516 | 520 | ||
517 | if (user) { | 521 | if (user) { |
518 | res.status(HttpStatusCode.CONFLICT_409) | 522 | res.fail({ |
519 | .json({ error: 'User with this username or email already exists.' }) | 523 | status: HttpStatusCode.CONFLICT_409, |
524 | message: 'User with this username or email already exists.' | ||
525 | }) | ||
520 | return false | 526 | return false |
521 | } | 527 | } |
522 | 528 | ||
523 | const actor = await ActorModel.loadLocalByName(username) | 529 | const actor = await ActorModel.loadLocalByName(username) |
524 | if (actor) { | 530 | if (actor) { |
525 | res.status(HttpStatusCode.CONFLICT_409) | 531 | res.fail({ |
526 | .json({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' }) | 532 | status: HttpStatusCode.CONFLICT_409, |
533 | message: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' | ||
534 | }) | ||
527 | return false | 535 | return false |
528 | } | 536 | } |
529 | 537 | ||
@@ -535,14 +543,15 @@ async function checkUserExist (finder: () => Promise<MUserDefault>, res: express | |||
535 | 543 | ||
536 | if (!user) { | 544 | if (!user) { |
537 | if (abortResponse === true) { | 545 | if (abortResponse === true) { |
538 | res.status(HttpStatusCode.NOT_FOUND_404) | 546 | res.fail({ |
539 | .json({ error: 'User not found' }) | 547 | status: HttpStatusCode.NOT_FOUND_404, |
548 | message: 'User not found' | ||
549 | }) | ||
540 | } | 550 | } |
541 | 551 | ||
542 | return false | 552 | return false |
543 | } | 553 | } |
544 | 554 | ||
545 | res.locals.user = user | 555 | res.locals.user = user |
546 | |||
547 | return true | 556 | return true |
548 | } | 557 | } |