From 2d53be0267acc49cda46707b885096193a1f4e9c Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Mon, 7 Dec 2020 14:32:36 +0100 Subject: replace numbers with typed http status codes (#3409) --- server/middlewares/activitypub.ts | 15 +++--- server/middlewares/oauth.ts | 3 +- server/middlewares/servers.ts | 3 +- server/middlewares/user-right.ts | 4 +- server/middlewares/validators/abuse.ts | 21 +++++---- .../middlewares/validators/activitypub/activity.ts | 7 ++- server/middlewares/validators/blocklist.ts | 9 ++-- server/middlewares/validators/bulk.ts | 3 +- server/middlewares/validators/config.ts | 11 +++-- server/middlewares/validators/feeds.ts | 5 +- server/middlewares/validators/follows.ts | 15 ++++-- server/middlewares/validators/oembed.ts | 15 +++--- server/middlewares/validators/plugins.ts | 23 ++++----- server/middlewares/validators/redundancy.ts | 23 ++++----- server/middlewares/validators/server.ts | 13 ++--- server/middlewares/validators/themes.ts | 5 +- .../middlewares/validators/user-subscriptions.ts | 3 +- server/middlewares/validators/users.ts | 55 ++++++++++++---------- server/middlewares/validators/utils.ts | 4 +- .../validators/videos/video-blacklist.ts | 3 +- .../validators/videos/video-channels.ts | 19 ++++---- .../validators/videos/video-comments.ts | 13 ++--- .../middlewares/validators/videos/video-imports.ts | 9 ++-- server/middlewares/validators/videos/video-live.ts | 21 +++++---- .../validators/videos/video-playlists.ts | 27 ++++++----- .../middlewares/validators/videos/video-rates.ts | 3 +- .../middlewares/validators/videos/video-shares.ts | 3 +- .../middlewares/validators/videos/video-watch.ts | 3 +- server/middlewares/validators/videos/videos.ts | 23 ++++----- server/middlewares/validators/webfinger.ts | 7 +-- 30 files changed, 208 insertions(+), 160 deletions(-) (limited to 'server/middlewares') diff --git a/server/middlewares/activitypub.ts b/server/middlewares/activitypub.ts index d00594059..ce94a2129 100644 --- a/server/middlewares/activitypub.ts +++ b/server/middlewares/activitypub.ts @@ -7,6 +7,7 @@ import { getOrCreateActorAndServerAndModel } from '../lib/activitypub/actor' import { loadActorUrlOrGetFromWebfinger } from '../helpers/webfinger' import { isActorDeleteActivityValid } from '@server/helpers/custom-validators/activitypub/actor' import { getAPId } from '@server/helpers/activitypub' +import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' async function checkSignature (req: Request, res: Response, next: NextFunction) { try { @@ -28,11 +29,11 @@ async function checkSignature (req: Request, res: Response, next: NextFunction) const activity: ActivityDelete = req.body if (isActorDeleteActivityValid(activity) && activity.object === activity.actor) { logger.debug('Handling signature error on actor delete activity', { err }) - return res.sendStatus(204) + return res.sendStatus(HttpStatusCode.NO_CONTENT_204) } logger.warn('Error in ActivityPub signature checker.', { err }) - return res.sendStatus(403) + return res.sendStatus(HttpStatusCode.FORBIDDEN_403) } } @@ -70,13 +71,13 @@ async function checkHttpSignature (req: Request, res: Response) { } catch (err) { logger.warn('Invalid signature because of exception in signature parser', { reqBody: req.body, err }) - res.status(403).json({ error: err.message }) + res.status(HttpStatusCode.FORBIDDEN_403).json({ error: err.message }) return false } const keyId = parsed.keyId if (!keyId) { - res.sendStatus(403) + res.sendStatus(HttpStatusCode.FORBIDDEN_403) return false } @@ -93,7 +94,7 @@ async function checkHttpSignature (req: Request, res: Response) { if (verified !== true) { logger.warn('Signature from %s is invalid', actorUrl, { parsed }) - res.sendStatus(403) + res.sendStatus(HttpStatusCode.FORBIDDEN_403) return false } @@ -106,7 +107,7 @@ async function checkJsonLDSignature (req: Request, res: Response) { const signatureObject: ActivityPubSignature = req.body.signature if (!signatureObject || !signatureObject.creator) { - res.sendStatus(403) + res.sendStatus(HttpStatusCode.FORBIDDEN_403) return false } @@ -120,7 +121,7 @@ async function checkJsonLDSignature (req: Request, res: Response) { if (verified !== true) { logger.warn('Signature not verified.', req.body) - res.sendStatus(403) + res.sendStatus(HttpStatusCode.FORBIDDEN_403) return false } diff --git a/server/middlewares/oauth.ts b/server/middlewares/oauth.ts index bd60a3639..ab5301415 100644 --- a/server/middlewares/oauth.ts +++ b/server/middlewares/oauth.ts @@ -3,6 +3,7 @@ import { Socket } from 'socket.io' import { oAuthServer } from '@server/lib/auth' import { logger } from '../helpers/logger' import { getAccessToken } from '../lib/oauth-model' +import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' function authenticate (req: express.Request, res: express.Response, next: express.NextFunction, authenticateInQuery = false) { const options = authenticateInQuery ? { allowBearerTokensInQueryString: true } : {} @@ -50,7 +51,7 @@ function authenticatePromiseIfNeeded (req: express.Request, res: express.Respons // Already authenticated? (or tried to) if (res.locals.oauth?.token.User) return resolve() - if (res.locals.authenticated === false) return res.sendStatus(401) + if (res.locals.authenticated === false) return res.sendStatus(HttpStatusCode.UNAUTHORIZED_401) authenticate(req, res, () => resolve(), authenticateInQuery) }) diff --git a/server/middlewares/servers.ts b/server/middlewares/servers.ts index 9c0af443a..5e1c165f0 100644 --- a/server/middlewares/servers.ts +++ b/server/middlewares/servers.ts @@ -1,5 +1,6 @@ import * as express from 'express' import { getHostWithPort } from '../helpers/express-utils' +import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' function setBodyHostsPort (req: express.Request, res: express.Response, next: express.NextFunction) { if (!req.body.hosts) return next() @@ -9,7 +10,7 @@ function setBodyHostsPort (req: express.Request, res: express.Response, next: ex // Problem with the url parsing? if (hostWithPort === null) { - return res.sendStatus(500) + return res.sendStatus(HttpStatusCode.INTERNAL_SERVER_ERROR_500) } req.body.hosts[i] = hostWithPort diff --git a/server/middlewares/user-right.ts b/server/middlewares/user-right.ts index aaf0b323a..45dda4781 100644 --- a/server/middlewares/user-right.ts +++ b/server/middlewares/user-right.ts @@ -1,6 +1,7 @@ import * as express from 'express' import { UserRight } from '../../shared' import { logger } from '../helpers/logger' +import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' function ensureUserHasRight (userRight: UserRight) { return function (req: express.Request, res: express.Response, next: express.NextFunction) { @@ -9,7 +10,8 @@ function ensureUserHasRight (userRight: UserRight) { const message = `User ${user.username} does not have right ${userRight} to access to ${req.path}.` logger.info(message) - return res.status(403).json({ error: message }) + return res.status(HttpStatusCode.FORBIDDEN_403) + .json({ error: message }) } return next() diff --git a/server/middlewares/validators/abuse.ts b/server/middlewares/validators/abuse.ts index 99403ca40..3b897fdef 100644 --- a/server/middlewares/validators/abuse.ts +++ b/server/middlewares/validators/abuse.ts @@ -19,6 +19,7 @@ import { doesAbuseExist, doesAccountIdExist, doesVideoExist } from '@server/help import { AbuseMessageModel } from '@server/models/abuse/abuse-message' import { AbuseCreate, UserRight } from '@shared/models' import { areValidationErrors } from './utils' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const abuseReportValidator = [ body('account.id') @@ -70,8 +71,8 @@ const abuseReportValidator = [ if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return if (!body.video?.id && !body.account?.id && !body.comment?.id) { - res.status(400) - .json({ error: 'video id or account id or comment id is required.' }) + res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ error: 'video id or account id or comment id is required.' }) return } @@ -194,7 +195,8 @@ const getAbuseValidator = [ const message = `User ${user.username} does not have right to get abuse ${abuse.id}` logger.warn(message) - return res.status(403).json({ error: message }) + return res.status(HttpStatusCode.FORBIDDEN_403) + .json({ error: message }) } return next() @@ -207,9 +209,10 @@ const checkAbuseValidForMessagesValidator = [ const abuse = res.locals.abuse if (abuse.ReporterAccount.isOwned() === false) { - return res.status(400).json({ - error: 'This abuse was created by a user of your instance.' - }) + return res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ + error: 'This abuse was created by a user of your instance.' + }) } return next() @@ -243,11 +246,13 @@ const deleteAbuseMessageValidator = [ const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id) if (!abuseMessage) { - return res.status(404).json({ error: 'Abuse message not found' }) + return res.status(HttpStatusCode.NOT_FOUND_404) + .json({ error: 'Abuse message not found' }) } if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) { - return res.status(403).json({ error: 'Cannot delete this abuse message' }) + return res.status(HttpStatusCode.FORBIDDEN_403) + .json({ error: 'Cannot delete this abuse message' }) } res.locals.abuseMessage = abuseMessage diff --git a/server/middlewares/validators/activitypub/activity.ts b/server/middlewares/validators/activitypub/activity.ts index 7350be5d5..255d8eb17 100644 --- a/server/middlewares/validators/activitypub/activity.ts +++ b/server/middlewares/validators/activitypub/activity.ts @@ -2,20 +2,23 @@ import * as express from 'express' import { isRootActivityValid } from '../../../helpers/custom-validators/activitypub/activity' import { logger } from '../../../helpers/logger' import { getServerActor } from '@server/models/application/application' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' async function activityPubValidator (req: express.Request, res: express.Response, next: express.NextFunction) { logger.debug('Checking activity pub parameters') if (!isRootActivityValid(req.body)) { logger.warn('Incorrect activity parameters.', { activity: req.body }) - return res.status(400).json({ error: 'Incorrect activity.' }) + return res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ error: 'Incorrect activity.' }) } const serverActor = await getServerActor() const remoteActor = res.locals.signature.actor if (serverActor.id === remoteActor.id) { logger.error('Receiving request in INBOX by ourselves!', req.body) - return res.status(409).end() + return res.status(HttpStatusCode.CONFLICT_409) + .end() } return next() diff --git a/server/middlewares/validators/blocklist.ts b/server/middlewares/validators/blocklist.ts index c24fa9609..f61811a1a 100644 --- a/server/middlewares/validators/blocklist.ts +++ b/server/middlewares/validators/blocklist.ts @@ -9,6 +9,7 @@ import { ServerModel } from '../../models/server/server' import { WEBSERVER } from '../../initializers/constants' import { doesAccountNameWithHostExist } from '../../helpers/middlewares' import { getServerActor } from '@server/models/application/application' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const blockAccountValidator = [ body('accountName').exists().withMessage('Should have an account name with host'), @@ -23,7 +24,7 @@ const blockAccountValidator = [ const accountToBlock = res.locals.account if (user.Account.id === accountToBlock.id) { - res.status(409) + res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'You cannot block yourself.' }) return @@ -78,7 +79,7 @@ const blockServerValidator = [ const host: string = req.body.host if (host === WEBSERVER.HOST) { - return res.status(409) + return res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'You cannot block your own server.' }) } @@ -136,7 +137,7 @@ export { async function doesUnblockAccountExist (accountId: number, targetAccountId: number, res: express.Response) { const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(accountId, targetAccountId) if (!accountBlock) { - res.status(404) + res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Account block entry not found.' }) return false @@ -150,7 +151,7 @@ async function doesUnblockAccountExist (accountId: number, targetAccountId: numb async function doesUnblockServerExist (accountId: number, host: string, res: express.Response) { const serverBlock = await ServerBlocklistModel.loadByAccountAndHost(accountId, host) if (!serverBlock) { - res.status(404) + res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Server block entry not found.' }) return false diff --git a/server/middlewares/validators/bulk.ts b/server/middlewares/validators/bulk.ts index f9b0f565a..cfb16d352 100644 --- a/server/middlewares/validators/bulk.ts +++ b/server/middlewares/validators/bulk.ts @@ -6,6 +6,7 @@ import { UserRight } from '@shared/models' import { BulkRemoveCommentsOfBody } from '@shared/models/bulk/bulk-remove-comments-of-body.model' import { logger } from '../../helpers/logger' import { areValidationErrors } from './utils' +import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' const bulkRemoveCommentsOfValidator = [ body('accountName').exists().withMessage('Should have an account name with host'), @@ -22,7 +23,7 @@ const bulkRemoveCommentsOfValidator = [ const body = req.body as BulkRemoveCommentsOfBody if (body.scope === 'instance' && user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) !== true) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'User cannot remove any comments of this instance.' }) diff --git a/server/middlewares/validators/config.ts b/server/middlewares/validators/config.ts index d0071ccc1..93de453a7 100644 --- a/server/middlewares/validators/config.ts +++ b/server/middlewares/validators/config.ts @@ -8,6 +8,7 @@ import { isUserNSFWPolicyValid, isUserVideoQuotaDailyValid, isUserVideoQuotaVali import { logger } from '../../helpers/logger' import { isThemeRegistered } from '../../lib/plugins/theme-utils' import { areValidationErrors } from './utils' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const customConfigUpdateValidator = [ body('instance.name').exists().withMessage('Should have a valid instance name'), @@ -105,9 +106,9 @@ function checkInvalidConfigIfEmailDisabled (customConfig: CustomConfig, res: exp if (isEmailEnabled()) return true if (customConfig.signup.requiresEmailVerification === true) { - res.status(400) - .send({ error: 'Emailer is disabled but you require signup email verification.' }) - .end() + res.status(HttpStatusCode.BAD_REQUEST_400) + .send({ error: 'Emailer is disabled but you require signup email verification.' }) + .end() return false } @@ -118,7 +119,7 @@ function checkInvalidTranscodingConfig (customConfig: CustomConfig, res: express if (customConfig.transcoding.enabled === false) return true if (customConfig.transcoding.webtorrent.enabled === false && customConfig.transcoding.hls.enabled === false) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .send({ error: 'You need to enable at least webtorrent transcoding or hls transcoding' }) .end() return false @@ -131,7 +132,7 @@ function checkInvalidLiveConfig (customConfig: CustomConfig, res: express.Respon if (customConfig.live.enabled === false) return true if (customConfig.live.allowReplay === true && customConfig.transcoding.enabled === false) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .send({ error: 'You cannot allow live replay if transcoding is not enabled' }) .end() return false diff --git a/server/middlewares/validators/feeds.ts b/server/middlewares/validators/feeds.ts index 18469bad3..617661813 100644 --- a/server/middlewares/validators/feeds.ts +++ b/server/middlewares/validators/feeds.ts @@ -12,6 +12,7 @@ import { } from '../../helpers/middlewares' import { doesVideoExist } from '../../helpers/middlewares/videos' import { areValidationErrors } from './utils' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const feedsFormatValidator = [ param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'), @@ -35,7 +36,7 @@ function setFeedFormatContentType (req: express.Request, res: express.Response, if (req.accepts(acceptableContentTypes)) { res.set('Content-Type', req.accepts(acceptableContentTypes) as string) } else { - return res.status(406) + return res.status(HttpStatusCode.NOT_ACCEPTABLE_406) .json({ message: `You should accept at least one of the following content-types: ${acceptableContentTypes.join(', ')}` }) @@ -105,7 +106,7 @@ const videoCommentsFeedsValidator = [ if (areValidationErrors(req, res)) return if (req.query.videoId && (req.query.videoChannelId || req.query.videoChannelName)) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ message: 'videoId cannot be mixed with a channel filter' }) diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts index 2c1ddf2df..a590aca99 100644 --- a/server/middlewares/validators/follows.ts +++ b/server/middlewares/validators/follows.ts @@ -12,6 +12,7 @@ import { isActorTypeValid, isValidActorHandle } from '../../helpers/custom-valid import { MActorFollowActorsDefault } from '@server/types/models' import { isFollowStateValid } from '@server/helpers/custom-validators/follows' import { getServerActor } from '@server/models/application/application' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const listFollowsValidator = [ query('state') @@ -34,7 +35,8 @@ const followValidator = [ (req: express.Request, res: express.Response, next: express.NextFunction) => { // Force https if the administrator wants to make friends if (isTestInstance() === false && WEBSERVER.SCHEME === 'http') { - return res.status(500) + return res + .status(HttpStatusCode.INTERNAL_SERVER_ERROR_500) .json({ error: 'Cannot follow on a non HTTPS web server.' }) @@ -62,7 +64,7 @@ const removeFollowingValidator = [ if (!follow) { return res - .status(404) + .status(HttpStatusCode.NOT_FOUND_404) .json({ error: `Following ${req.params.host} not found.` }) @@ -95,7 +97,7 @@ const getFollowerValidator = [ if (!follow) { return res - .status(404) + .status(HttpStatusCode.NOT_FOUND_404) .json({ error: `Follower ${req.params.nameWithHost} not found.` }) @@ -113,7 +115,12 @@ const acceptOrRejectFollowerValidator = [ const follow = res.locals.follow if (follow.state !== 'pending') { - return res.status(400).json({ error: 'Follow is not in pending state.' }).end() + return res + .status(HttpStatusCode.BAD_REQUEST_400) + .json({ + error: 'Follow is not in pending state.' + }) + .end() } return next() diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts index c9f9ea0c0..86623efcd 100644 --- a/server/middlewares/validators/oembed.ts +++ b/server/middlewares/validators/oembed.ts @@ -9,6 +9,7 @@ import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' import { logger } from '../../helpers/logger' import { WEBSERVER } from '../../initializers/constants' import { areValidationErrors } from './utils' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const startVideoPlaylistsURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch', 'playlist') + '/' const startVideosURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch') + '/' @@ -36,7 +37,7 @@ const oembedValidator = [ if (areValidationErrors(req, res)) return if (req.query.format !== undefined && req.query.format !== 'json') { - return res.status(501) + return res.status(HttpStatusCode.NOT_IMPLEMENTED_501) .json({ error: 'Requested format is not implemented on server.' }) } @@ -50,13 +51,13 @@ const oembedValidator = [ const matches = watchRegex.exec(url) if (startIsOk === false || matches === null) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Invalid url.' }) } const elementId = matches[1] if (isIdOrUUIDValid(elementId) === false) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Invalid video or playlist id.' }) } @@ -64,12 +65,12 @@ const oembedValidator = [ const video = await fetchVideo(elementId, 'all') if (!video) { - return res.status(404) + return res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video not found' }) } if (video.privacy !== VideoPrivacy.PUBLIC) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Video is not public' }) } @@ -81,12 +82,12 @@ const oembedValidator = [ const videoPlaylist = await VideoPlaylistModel.loadWithAccountAndChannelSummary(elementId, undefined) if (!videoPlaylist) { - return res.status(404) + return res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video playlist not found' }) } if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PUBLIC) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Playlist is not public' }) } diff --git a/server/middlewares/validators/plugins.ts b/server/middlewares/validators/plugins.ts index cba261dc0..bbac55a50 100644 --- a/server/middlewares/validators/plugins.ts +++ b/server/middlewares/validators/plugins.ts @@ -9,6 +9,7 @@ import { PluginModel } from '../../models/server/plugin' import { InstallOrUpdatePlugin } from '../../../shared/models/plugins/install-plugin.model' import { PluginType } from '../../../shared/models/plugins/plugin.type' import { CONFIG } from '../../initializers/config' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const getPluginValidator = (pluginType: PluginType, withVersion = true) => { const validators: (ValidationChain | express.Handler)[] = [ @@ -30,8 +31,8 @@ const getPluginValidator = (pluginType: PluginType, withVersion = true) => { const npmName = PluginModel.buildNpmName(req.params.pluginName, pluginType) const plugin = PluginManager.Instance.getRegisteredPluginOrTheme(npmName) - if (!plugin) return res.sendStatus(404) - if (withVersion && plugin.version !== req.params.pluginVersion) return res.sendStatus(404) + if (!plugin) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) + if (withVersion && plugin.version !== req.params.pluginVersion) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) res.locals.registeredPlugin = plugin @@ -49,10 +50,10 @@ const getExternalAuthValidator = [ if (areValidationErrors(req, res)) return const plugin = res.locals.registeredPlugin - if (!plugin.registerHelpersStore) return res.sendStatus(404) + if (!plugin.registerHelpersStore) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) const externalAuth = plugin.registerHelpersStore.getExternalAuths().find(a => a.authName === req.params.authName) - if (!externalAuth) return res.sendStatus(404) + if (!externalAuth) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) res.locals.externalAuth = externalAuth @@ -106,7 +107,7 @@ const installOrUpdatePluginValidator = [ const body: InstallOrUpdatePlugin = req.body if (!body.path && !body.npmName) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Should have either a npmName or a path' }) .end() } @@ -137,9 +138,9 @@ const existingPluginValidator = [ const plugin = await PluginModel.loadByNpmName(req.params.npmName) if (!plugin) { - return res.status(404) - .json({ error: 'Plugin not found' }) - .end() + return res.status(HttpStatusCode.NOT_FOUND_404) + .json({ error: 'Plugin not found' }) + .end() } res.locals.plugin = plugin @@ -178,9 +179,9 @@ const listAvailablePluginsValidator = [ if (areValidationErrors(req, res)) return if (CONFIG.PLUGINS.INDEX.ENABLED === false) { - return res.status(400) - .json({ error: 'Plugin index is not enabled' }) - .end() + return res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ error: 'Plugin index is not enabled' }) + .end() } return next() diff --git a/server/middlewares/validators/redundancy.ts b/server/middlewares/validators/redundancy.ts index 8cd3bc33d..6d2dd39c9 100644 --- a/server/middlewares/validators/redundancy.ts +++ b/server/middlewares/validators/redundancy.ts @@ -8,6 +8,7 @@ import { isHostValid } from '../../helpers/custom-validators/servers' import { ServerModel } from '../../models/server/server' import { doesVideoExist } from '../../helpers/middlewares' import { isVideoRedundancyTarget } from '@server/helpers/custom-validators/video-redundancies' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const videoFileRedundancyGetValidator = [ param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), @@ -34,11 +35,11 @@ const videoFileRedundancyGetValidator = [ return f.resolution === paramResolution && (!req.params.fps || paramFPS) }) - if (!videoFile) return res.status(404).json({ error: 'Video file not found.' }) + if (!videoFile) return res.status(HttpStatusCode.NOT_FOUND_404).json({ error: 'Video file not found.' }) res.locals.videoFile = videoFile const videoRedundancy = await VideoRedundancyModel.loadLocalByFileId(videoFile.id) - if (!videoRedundancy) return res.status(404).json({ error: 'Video redundancy not found.' }) + if (!videoRedundancy) return res.status(HttpStatusCode.NOT_FOUND_404).json({ error: 'Video redundancy not found.' }) res.locals.videoRedundancy = videoRedundancy return next() @@ -64,11 +65,11 @@ const videoPlaylistRedundancyGetValidator = [ const paramPlaylistType = req.params.streamingPlaylistType as unknown as number // We casted to int above const videoStreamingPlaylist = video.VideoStreamingPlaylists.find(p => p.type === paramPlaylistType) - if (!videoStreamingPlaylist) return res.status(404).json({ error: 'Video playlist not found.' }) + if (!videoStreamingPlaylist) return res.status(HttpStatusCode.NOT_FOUND_404).json({ error: 'Video playlist not found.' }) res.locals.videoStreamingPlaylist = videoStreamingPlaylist const videoRedundancy = await VideoRedundancyModel.loadLocalByStreamingPlaylistId(videoStreamingPlaylist.id) - if (!videoRedundancy) return res.status(404).json({ error: 'Video redundancy not found.' }) + if (!videoRedundancy) return res.status(HttpStatusCode.NOT_FOUND_404).json({ error: 'Video redundancy not found.' }) res.locals.videoRedundancy = videoRedundancy return next() @@ -90,7 +91,7 @@ const updateServerRedundancyValidator = [ if (!server) { return res - .status(404) + .status(HttpStatusCode.NOT_FOUND_404) .json({ error: `Server ${req.params.host} not found.` }) @@ -128,15 +129,15 @@ const addVideoRedundancyValidator = [ if (!await doesVideoExist(req.body.videoId, res, 'only-video')) return if (res.locals.onlyVideo.remote === false) { - return res.status(400) - .json({ error: 'Cannot create a redundancy on a local video' }) - .end() + return res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ error: 'Cannot create a redundancy on a local video' }) + .end() } const alreadyExists = await VideoRedundancyModel.isLocalByVideoUUIDExists(res.locals.onlyVideo.uuid) if (alreadyExists) { - return res.status(409) - .json({ error: 'This video is already duplicated by your instance.' }) + return res.status(HttpStatusCode.CONFLICT_409) + .json({ error: 'This video is already duplicated by your instance.' }) } return next() @@ -155,7 +156,7 @@ const removeVideoRedundancyValidator = [ const redundancy = await VideoRedundancyModel.loadByIdWithVideo(parseInt(req.params.redundancyId, 10)) if (!redundancy) { - return res.status(404) + return res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video redundancy not found' }) .end() } diff --git a/server/middlewares/validators/server.ts b/server/middlewares/validators/server.ts index 6158c3363..fe6704716 100644 --- a/server/middlewares/validators/server.ts +++ b/server/middlewares/validators/server.ts @@ -7,6 +7,7 @@ import { body } from 'express-validator' import { isUserDisplayNameValid } from '../../helpers/custom-validators/users' import { Redis } from '../../lib/redis' import { CONFIG, isEmailEnabled } from '../../initializers/config' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const serverGetValidator = [ body('host').custom(isHostValid).withMessage('Should have a valid host'), @@ -18,9 +19,9 @@ const serverGetValidator = [ const server = await ServerModel.loadByHost(req.body.host) if (!server) { - return res.status(404) - .send({ error: 'Server host not found.' }) - .end() + return res.status(HttpStatusCode.NOT_FOUND_404) + .send({ error: 'Server host not found.' }) + .end() } res.locals.server = server @@ -44,14 +45,14 @@ const contactAdministratorValidator = [ if (CONFIG.CONTACT_FORM.ENABLED === false) { return res - .status(409) + .status(HttpStatusCode.CONFLICT_409) .send({ error: 'Contact form is not enabled on this instance.' }) .end() } if (isEmailEnabled() === false) { return res - .status(409) + .status(HttpStatusCode.CONFLICT_409) .send({ error: 'Emailer is not enabled on this instance.' }) .end() } @@ -60,7 +61,7 @@ const contactAdministratorValidator = [ logger.info('Refusing a contact form by %s: already sent one recently.', req.ip) return res - .status(403) + .status(HttpStatusCode.FORBIDDEN_403) .send({ error: 'You already sent a contact form recently.' }) .end() } diff --git a/server/middlewares/validators/themes.ts b/server/middlewares/validators/themes.ts index 82794656d..a726a567b 100644 --- a/server/middlewares/validators/themes.ts +++ b/server/middlewares/validators/themes.ts @@ -5,6 +5,7 @@ import { areValidationErrors } from './utils' import { isPluginNameValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins' import { PluginManager } from '../../lib/plugins/plugin-manager' import { isSafePath } from '../../helpers/custom-validators/misc' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const serveThemeCSSValidator = [ param('themeName').custom(isPluginNameValid).withMessage('Should have a valid theme name'), @@ -19,11 +20,11 @@ const serveThemeCSSValidator = [ const theme = PluginManager.Instance.getRegisteredThemeByShortName(req.params.themeName) if (!theme || theme.version !== req.params.themeVersion) { - return res.sendStatus(404) + return res.sendStatus(HttpStatusCode.NOT_FOUND_404) } if (theme.css.includes(req.params.staticEndpoint) === false) { - return res.sendStatus(404) + return res.sendStatus(HttpStatusCode.NOT_FOUND_404) } res.locals.registeredPlugin = theme diff --git a/server/middlewares/validators/user-subscriptions.ts b/server/middlewares/validators/user-subscriptions.ts index a54ecb704..0d0c8ccbf 100644 --- a/server/middlewares/validators/user-subscriptions.ts +++ b/server/middlewares/validators/user-subscriptions.ts @@ -6,6 +6,7 @@ import { ActorFollowModel } from '../../models/activitypub/actor-follow' import { areValidActorHandles, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' import { toArray } from '../../helpers/custom-validators/misc' import { WEBSERVER } from '../../initializers/constants' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const userSubscriptionListValidator = [ query('search').optional().not().isEmpty().withMessage('Should have a valid search'), @@ -61,7 +62,7 @@ const userSubscriptionGetValidator = [ if (!subscription || !subscription.ActorFollowing.VideoChannel) { return res - .status(404) + .status(HttpStatusCode.NOT_FOUND_404) .json({ error: `Subscription ${req.params.uri} not found.` }) diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index c91c378b3..c93895f2f 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -37,6 +37,7 @@ import { doesVideoExist } from '../../helpers/middlewares' import { UserRole } from '../../../shared/models/users' import { MUserDefault } from '@server/types/models' import { Hooks } from '@server/lib/plugins/hooks' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const usersListValidator = [ query('blocked') @@ -73,19 +74,22 @@ const usersAddValidator = [ const authUser = res.locals.oauth.token.User if (authUser.role !== UserRole.ADMINISTRATOR && req.body.role !== UserRole.USER) { - return res.status(403) + return res + .status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'You can only create users (and not administrators or moderators)' }) } if (req.body.channelName) { if (req.body.channelName === req.body.username) { - return res.status(400) + return res + .status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Channel name cannot be the same as user username.' }) } const existing = await ActorModel.loadLocalByName(req.body.channelName) if (existing) { - return res.status(409) + return res + .status(HttpStatusCode.CONFLICT_409) .json({ error: `Channel with name ${req.body.channelName} already exists.` }) } } @@ -118,18 +122,19 @@ const usersRegisterValidator = [ const body: UserRegister = req.body if (body.channel) { if (!body.channel.name || !body.channel.displayName) { - return res.status(400) + return res + .status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Channel is optional but if you specify it, channel.name and channel.displayName are required.' }) } if (body.channel.name === body.username) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Channel name cannot be the same as user username.' }) } const existing = await ActorModel.loadLocalByName(body.channel.name) if (existing) { - return res.status(409) + return res.status(HttpStatusCode.CONFLICT_409) .json({ error: `Channel with name ${body.channel.name} already exists.` }) } } @@ -149,7 +154,7 @@ const usersRemoveValidator = [ const user = res.locals.user if (user.username === 'root') { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot remove the root user' }) } @@ -169,7 +174,7 @@ const usersBlockingValidator = [ const user = res.locals.user if (user.username === 'root') { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot block the root user' }) } @@ -181,7 +186,7 @@ const deleteMeValidator = [ (req: express.Request, res: express.Response, next: express.NextFunction) => { const user = res.locals.oauth.token.User if (user.username === 'root') { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'You cannot delete your root account.' }) .end() } @@ -211,8 +216,8 @@ const usersUpdateValidator = [ const user = res.locals.user if (user.username === 'root' && req.body.role !== undefined && user.role !== req.body.role) { - return res.status(400) - .json({ error: 'Cannot change root role.' }) + return res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ error: 'Cannot change root role.' }) } return next() @@ -267,17 +272,17 @@ const usersUpdateMeValidator = [ if (req.body.password || req.body.email) { if (user.pluginAuth !== null) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'You cannot update your email or password that is associated with an external auth system.' }) } if (!req.body.currentPassword) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'currentPassword parameter is missing.' }) } if (await user.isPasswordMatch(req.body.currentPassword) !== true) { - return res.status(401) + return res.status(HttpStatusCode.UNAUTHORIZED_401) .json({ error: 'currentPassword is invalid.' }) } } @@ -329,7 +334,7 @@ const ensureUserRegistrationAllowed = [ ) if (allowedResult.allowed === false) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: allowedResult.errorMessage || 'User registration is not enabled or user limit is reached.' }) } @@ -342,7 +347,7 @@ const ensureUserRegistrationAllowedForIP = [ const allowed = isSignupAllowedForCurrentIP(req.ip) if (allowed === false) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'You are not on a network authorized for registration.' }) } @@ -362,7 +367,7 @@ const usersAskResetPasswordValidator = [ if (!exists) { logger.debug('User with email %s does not exist (asking reset password).', req.body.email) // Do not leak our emails - return res.status(204).end() + return res.status(HttpStatusCode.NO_CONTENT_204).end() } return next() @@ -385,7 +390,7 @@ const usersResetPasswordValidator = [ if (redisVerificationString !== req.body.verificationString) { return res - .status(403) + .status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Invalid verification string.' }) } @@ -404,7 +409,7 @@ const usersAskSendVerifyEmailValidator = [ if (!exists) { logger.debug('User with email %s does not exist (asking verify email).', req.body.email) // Do not leak our emails - return res.status(204).end() + return res.status(HttpStatusCode.NO_CONTENT_204).end() } return next() @@ -432,7 +437,7 @@ const usersVerifyEmailValidator = [ if (redisVerificationString !== req.body.verificationString) { return res - .status(403) + .status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Invalid verification string.' }) } @@ -449,7 +454,7 @@ const ensureAuthUserOwnsAccountValidator = [ const user = res.locals.oauth.token.User if (res.locals.account.id !== user.Account.id) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Only owner can access ratings list.' }) } @@ -465,7 +470,7 @@ const ensureCanManageUser = [ if (authUser.role === UserRole.ADMINISTRATOR) return next() if (authUser.role === UserRole.MODERATOR && onUser.role === UserRole.USER) return next() - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'A moderator can only manager users.' }) } ] @@ -509,14 +514,14 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: const user = await UserModel.loadByUsernameOrEmail(username, email) if (user) { - res.status(409) + res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'User with this username or email already exists.' }) return false } const actor = await ActorModel.loadLocalByName(username) if (actor) { - res.status(409) + res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' }) return false } @@ -529,7 +534,7 @@ async function checkUserExist (finder: () => Bluebird, res: expres if (!user) { if (abortResponse === true) { - res.status(404) + res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'User not found' }) } diff --git a/server/middlewares/validators/utils.ts b/server/middlewares/validators/utils.ts index 43e5652fa..2899bed6f 100644 --- a/server/middlewares/validators/utils.ts +++ b/server/middlewares/validators/utils.ts @@ -1,13 +1,15 @@ import * as express from 'express' import { query, validationResult } from 'express-validator' import { logger } from '../../helpers/logger' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' function areValidationErrors (req: express.Request, res: express.Response) { const errors = validationResult(req) if (!errors.isEmpty()) { logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() }) - res.status(400).json({ errors: errors.mapped() }) + res.status(HttpStatusCode.BAD_REQUEST_400) + .json({ errors: errors.mapped() }) return true } diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts index 808fefc25..88c788a43 100644 --- a/server/middlewares/validators/videos/video-blacklist.ts +++ b/server/middlewares/validators/videos/video-blacklist.ts @@ -5,6 +5,7 @@ import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../.. import { logger } from '../../../helpers/logger' import { doesVideoBlacklistExist, doesVideoExist } from '../../../helpers/middlewares' import { areValidationErrors } from '../utils' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videosBlacklistRemoveValidator = [ param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), @@ -39,7 +40,7 @@ const videosBlacklistAddValidator = [ const video = res.locals.videoAll if (req.body.unfederate === true && video.remote === true) { return res - .status(409) + .status(HttpStatusCode.CONFLICT_409) .send({ error: 'You cannot unfederate a remote video.' }) .end() } diff --git a/server/middlewares/validators/videos/video-channels.ts b/server/middlewares/validators/videos/video-channels.ts index 2e4e755e7..57ac548b9 100644 --- a/server/middlewares/validators/videos/video-channels.ts +++ b/server/middlewares/validators/videos/video-channels.ts @@ -15,6 +15,7 @@ import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } fro import { ActorModel } from '../../../models/activitypub/actor' import { VideoChannelModel } from '../../../models/video/video-channel' import { areValidationErrors } from '../utils' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videoChannelsAddValidator = [ body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'), @@ -29,7 +30,7 @@ const videoChannelsAddValidator = [ const actor = await ActorModel.loadLocalByName(req.body.name) if (actor) { - res.status(409) + res.status(HttpStatusCode.CONFLICT_409) .send({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' }) .end() return false @@ -37,7 +38,7 @@ const videoChannelsAddValidator = [ const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id) if (count >= VIDEO_CHANNELS.MAX_PER_USER) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .send({ error: `You cannot create more than ${VIDEO_CHANNELS.MAX_PER_USER} channels` }) .end() return false @@ -70,13 +71,13 @@ const videoChannelsUpdateValidator = [ // We need to make additional checks if (res.locals.videoChannel.Actor.isOwned() === false) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot update video channel of another server' }) .end() } if (res.locals.videoChannel.Account.userId !== res.locals.oauth.token.User.id) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot update video channel of another user' }) .end() } @@ -155,7 +156,7 @@ export { function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelAccountDefault, res: express.Response) { if (videoChannel.Actor.isOwned() === false) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot remove video channel of another server.' }) .end() @@ -166,7 +167,7 @@ function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelAcco // The user can delete it if s/he is an admin // Or if s/he is the video channel's account if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && videoChannel.Account.userId !== user.id) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot remove video channel of another user' }) .end() @@ -180,9 +181,9 @@ async function checkVideoChannelIsNotTheLastOne (res: express.Response) { const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id) if (count <= 1) { - res.status(409) - .json({ error: 'Cannot remove the last channel of this user' }) - .end() + res.status(HttpStatusCode.CONFLICT_409) + .json({ error: 'Cannot remove the last channel of this user' }) + .end() return false } diff --git a/server/middlewares/validators/videos/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts index a3c9febc4..226c9d436 100644 --- a/server/middlewares/validators/videos/video-comments.ts +++ b/server/middlewares/validators/videos/video-comments.ts @@ -14,6 +14,7 @@ import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccep import { Hooks } from '../../../lib/plugins/hooks' import { MCommentOwnerVideoReply, MVideo, MVideoFullLight } from '../../../types/models/video' import { areValidationErrors } from '../utils' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const listVideoCommentsValidator = [ query('isLocal') @@ -154,8 +155,8 @@ export { function isVideoCommentsEnabled (video: MVideo, res: express.Response) { if (video.commentsEnabled !== true) { - res.status(409) - .json({ error: 'Video comments are disabled for this video.' }) + res.status(HttpStatusCode.CONFLICT_409) + .json({ error: 'Video comments are disabled for this video.' }) return false } @@ -165,8 +166,8 @@ function isVideoCommentsEnabled (video: MVideo, res: express.Response) { function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) { if (videoComment.isDeleted()) { - res.status(409) - .json({ error: 'This comment is already deleted' }) + res.status(HttpStatusCode.CONFLICT_409) + .json({ error: 'This comment is already deleted' }) return false } @@ -178,7 +179,7 @@ function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MC videoComment.accountId !== userAccount.id && // Not the comment owner videoComment.Video.VideoChannel.accountId !== userAccount.id // Not the video owner ) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot remove video comment of another user' }) return false @@ -214,7 +215,7 @@ async function isVideoCommentAccepted (req: express.Request, res: express.Respon if (!acceptedResult || acceptedResult.accepted !== true) { logger.info('Refused local comment.', { acceptedResult, acceptParameters }) - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: acceptedResult.errorMessage || 'Refused local comment' }) return false diff --git a/server/middlewares/validators/videos/video-imports.ts b/server/middlewares/validators/videos/video-imports.ts index d69aff118..0d41933a6 100644 --- a/server/middlewares/validators/videos/video-imports.ts +++ b/server/middlewares/validators/videos/video-imports.ts @@ -13,6 +13,7 @@ import { CONFIG } from '../../../initializers/config' import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' import { areValidationErrors } from '../utils' import { getCommonVideoEditAttributes } from './videos' +import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' const videoImportAddValidator = getCommonVideoEditAttributes().concat([ body('channelId') @@ -44,14 +45,14 @@ const videoImportAddValidator = getCommonVideoEditAttributes().concat([ if (req.body.targetUrl && CONFIG.IMPORT.VIDEOS.HTTP.ENABLED !== true) { cleanUpReqFiles(req) - return res.status(409) + return res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'HTTP import is not enabled on this instance.' }) .end() } if (CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED !== true && (req.body.magnetUri || torrentFile)) { cleanUpReqFiles(req) - return res.status(409) + return res.status(HttpStatusCode.CONFLICT_409) .json({ error: 'Torrent/magnet URI import is not enabled on this instance.' }) .end() } @@ -62,7 +63,7 @@ const videoImportAddValidator = getCommonVideoEditAttributes().concat([ if (!req.body.targetUrl && !req.body.magnetUri && !torrentFile) { cleanUpReqFiles(req) - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Should have a magnetUri or a targetUrl or a torrent file.' }) .end() } @@ -100,7 +101,7 @@ async function isImportAccepted (req: express.Request, res: express.Response) { if (!acceptedResult || acceptedResult.accepted !== true) { logger.info('Refused to import video.', { acceptedResult, acceptParameters }) - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: acceptedResult.errorMessage || 'Refused to import video' }) return false diff --git a/server/middlewares/validators/videos/video-live.ts b/server/middlewares/validators/videos/video-live.ts index 69a14ccb1..3a73e1272 100644 --- a/server/middlewares/validators/videos/video-live.ts +++ b/server/middlewares/validators/videos/video-live.ts @@ -13,6 +13,7 @@ import { getCommonVideoEditAttributes } from './videos' import { VideoModel } from '@server/models/video/video' import { Hooks } from '@server/lib/plugins/hooks' import { isLocalLiveVideoAccepted } from '@server/lib/moderation' +import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' const videoLiveGetValidator = [ param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), @@ -28,7 +29,7 @@ const videoLiveGetValidator = [ if (!checkUserCanManageVideo(user, res.locals.videoAll, UserRight.GET_ANY_LIVE, res, false)) return const videoLive = await VideoLiveModel.loadByVideoId(res.locals.videoAll.id) - if (!videoLive) return res.sendStatus(404) + if (!videoLive) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) res.locals.videoLive = videoLive @@ -62,21 +63,21 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ if (CONFIG.LIVE.ENABLED !== true) { cleanUpReqFiles(req) - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Live is not enabled on this instance' }) } if (CONFIG.LIVE.ALLOW_REPLAY !== true && req.body.saveReplay === true) { cleanUpReqFiles(req) - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Saving live replay is not allowed instance' }) } if (req.body.permanentLive && req.body.saveReplay) { cleanUpReqFiles(req) - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot set this live as permanent while saving its replay' }) } @@ -89,7 +90,7 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ if (totalInstanceLives >= CONFIG.LIVE.MAX_INSTANCE_LIVES) { cleanUpReqFiles(req) - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ code: ServerErrorCode.MAX_INSTANCE_LIVES_LIMIT_REACHED, error: 'Cannot create this live because the max instance lives limit is reached.' @@ -103,7 +104,7 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ if (totalUserLives >= CONFIG.LIVE.MAX_USER_LIVES) { cleanUpReqFiles(req) - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ code: ServerErrorCode.MAX_USER_LIVES_LIMIT_REACHED, error: 'Cannot create this live because the max user lives limit is reached.' @@ -129,17 +130,17 @@ const videoLiveUpdateValidator = [ if (areValidationErrors(req, res)) return if (req.body.permanentLive && req.body.saveReplay) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot set this live as permanent while saving its replay' }) } if (CONFIG.LIVE.ALLOW_REPLAY !== true && req.body.saveReplay === true) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Saving live replay is not allowed instance' }) } if (res.locals.videoAll.state !== VideoState.WAITING_FOR_LIVE) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot update a live that has already started' }) } @@ -176,7 +177,7 @@ async function isLiveVideoAccepted (req: express.Request, res: express.Response) if (!acceptedResult || acceptedResult.accepted !== true) { logger.info('Refused local live video.', { acceptedResult, acceptParameters }) - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: acceptedResult.errorMessage || 'Refused local live video' }) return false diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts index 4647eae44..c7a6f68e3 100644 --- a/server/middlewares/validators/videos/video-playlists.ts +++ b/server/middlewares/validators/videos/video-playlists.ts @@ -29,6 +29,7 @@ import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/vid import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist, VideoPlaylistFetchType } from '../../../helpers/middlewares' import { MVideoPlaylist } from '../../../types/models/video/video-playlist' import { MUserAccountId } from '@server/types/models' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([ body('displayName') @@ -44,7 +45,7 @@ const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([ if (body.privacy === VideoPlaylistPrivacy.PUBLIC && !body.videoChannelId) { cleanUpReqFiles(req) - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot set "public" a playlist that is not assigned to a channel.' }) } @@ -83,13 +84,13 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([ ) ) { cleanUpReqFiles(req) - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot set "public" a playlist that is not assigned to a channel.' }) } if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) { cleanUpReqFiles(req) - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot update a watch later playlist.' }) } @@ -112,7 +113,7 @@ const videoPlaylistsDeleteValidator = [ const videoPlaylist = getPlaylist(res) if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) { - return res.status(400) + return res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Cannot delete a watch later playlist.' }) } @@ -142,7 +143,7 @@ const videoPlaylistsGetValidator = (fetchType: VideoPlaylistFetchType) => { if (videoPlaylist.privacy === VideoPlaylistPrivacy.UNLISTED) { if (isUUIDValid(req.params.playlistId)) return next() - return res.status(404).end() + return res.status(HttpStatusCode.NOT_FOUND_404).end() } if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) { @@ -154,7 +155,7 @@ const videoPlaylistsGetValidator = (fetchType: VideoPlaylistFetchType) => { !user || (videoPlaylist.OwnerAccount.id !== user.Account.id && !user.hasRight(UserRight.UPDATE_ANY_VIDEO_PLAYLIST)) ) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot get this private video playlist.' }) } @@ -231,7 +232,7 @@ const videoPlaylistsUpdateOrRemoveVideoValidator = [ const videoPlaylistElement = await VideoPlaylistElementModel.loadById(req.params.playlistElementId) if (!videoPlaylistElement) { - res.status(404) + res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video playlist element not found' }) .end() @@ -261,7 +262,7 @@ const videoPlaylistElementAPGetValidator = [ const videoPlaylistElement = await VideoPlaylistElementModel.loadByPlaylistAndElementIdForAP(playlistId, playlistElementId) if (!videoPlaylistElement) { - res.status(404) + res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video playlist element not found' }) .end() @@ -269,7 +270,7 @@ const videoPlaylistElementAPGetValidator = [ } if (videoPlaylistElement.VideoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) { - return res.status(403).end() + return res.status(HttpStatusCode.FORBIDDEN_403).end() } res.locals.videoPlaylistElementAP = videoPlaylistElement @@ -305,7 +306,7 @@ const videoPlaylistsReorderVideosValidator = [ const reorderLength: number = req.body.reorderLength if (startPosition >= nextPosition || insertAfterPosition >= nextPosition) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: `Start position or insert after position exceed the playlist limits (max: ${nextPosition - 1})` }) .end() @@ -313,7 +314,7 @@ const videoPlaylistsReorderVideosValidator = [ } if (reorderLength && reorderLength + startPosition > nextPosition) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: `Reorder length with this start position exceeds the playlist limits (max: ${nextPosition - startPosition})` }) .end() @@ -399,7 +400,7 @@ function getCommonPlaylistEditAttributes () { function checkUserCanManageVideoPlaylist (user: MUserAccountId, videoPlaylist: MVideoPlaylist, right: UserRight, res: express.Response) { if (videoPlaylist.isOwned() === false) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot manage video playlist of another server.' }) .end() @@ -410,7 +411,7 @@ function checkUserCanManageVideoPlaylist (user: MUserAccountId, videoPlaylist: M // The user can delete it if s/he is an admin // Or if s/he is the video playlist's owner if (user.hasRight(right) === false && videoPlaylist.ownerAccountId !== user.Account.id) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot manage video playlist of another user' }) .end() diff --git a/server/middlewares/validators/videos/video-rates.ts b/server/middlewares/validators/videos/video-rates.ts index 15a8c7983..7dcba15f1 100644 --- a/server/middlewares/validators/videos/video-rates.ts +++ b/server/middlewares/validators/videos/video-rates.ts @@ -9,6 +9,7 @@ import { AccountVideoRateModel } from '../../../models/account/account-video-rat import { VideoRateType } from '../../../../shared/models/videos' import { isAccountNameValid } from '../../../helpers/custom-validators/accounts' import { doesVideoExist } from '../../../helpers/middlewares' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videoUpdateRateValidator = [ param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), @@ -36,7 +37,7 @@ const getAccountVideoRateValidatorFactory = function (rateType: VideoRateType) { const rate = await AccountVideoRateModel.loadLocalAndPopulateVideo(rateType, req.params.name, req.params.videoId) if (!rate) { - return res.status(404) + return res.status(HttpStatusCode.NOT_FOUND_404) .json({ error: 'Video rate not found' }) } diff --git a/server/middlewares/validators/videos/video-shares.ts b/server/middlewares/validators/videos/video-shares.ts index 20fc96243..f0d8e0c36 100644 --- a/server/middlewares/validators/videos/video-shares.ts +++ b/server/middlewares/validators/videos/video-shares.ts @@ -5,6 +5,7 @@ import { logger } from '../../../helpers/logger' import { VideoShareModel } from '../../../models/video/video-share' import { areValidationErrors } from '../utils' import { doesVideoExist } from '../../../helpers/middlewares' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videosShareValidator = [ param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), @@ -20,7 +21,7 @@ const videosShareValidator = [ const share = await VideoShareModel.load(req.params.actorId, video.id) if (!share) { - return res.status(404) + return res.status(HttpStatusCode.NOT_FOUND_404) .end() } diff --git a/server/middlewares/validators/videos/video-watch.ts b/server/middlewares/validators/videos/video-watch.ts index d6ca1d341..29ce0dab6 100644 --- a/server/middlewares/validators/videos/video-watch.ts +++ b/server/middlewares/validators/videos/video-watch.ts @@ -4,6 +4,7 @@ import { isIdOrUUIDValid, toIntOrNull } from '../../../helpers/custom-validators import { areValidationErrors } from '../utils' import { logger } from '../../../helpers/logger' import { doesVideoExist } from '../../../helpers/middlewares' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videoWatchingValidator = [ param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), @@ -20,7 +21,7 @@ const videoWatchingValidator = [ const user = res.locals.oauth.token.User if (user.videosHistoryEnabled === false) { logger.warn('Cannot set videos to watch by user %d: videos history is disabled.', user.id) - return res.status(409).end() + return res.status(HttpStatusCode.CONFLICT_409).end() } return next() diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index af0072d73..9834f714b 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts @@ -51,6 +51,7 @@ import { AccountModel } from '../../../models/account/account' import { VideoModel } from '../../../models/video/video' import { authenticatePromiseIfNeeded } from '../../oauth' import { areValidationErrors } from '../utils' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const videosAddValidator = getCommonVideoEditAttributes().concat([ body('videofile') @@ -75,7 +76,7 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([ if (!await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req) if (await isAbleToUploadVideo(user.id, videoFile.size) === false) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'The user video quota is exceeded with this video.' }) return cleanUpReqFiles(req) @@ -87,7 +88,7 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([ duration = await getDurationFromVideoFile(videoFile.path) } catch (err) { logger.error('Invalid input file in videosAddValidator.', { err }) - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Invalid input file.' }) return cleanUpReqFiles(req) @@ -147,7 +148,7 @@ async function checkVideoFollowConstraints (req: express.Request, res: express.R const serverActor = await getServerActor() if (await VideoModel.checkVideoHasInstanceFollow(video.id, serverActor.id) === true) return next() - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ errorCode: ServerErrorCode.DOES_NOT_RESPECT_FOLLOW_CONSTRAINTS, error: 'Cannot get this video regarding follow constraints.', @@ -182,7 +183,7 @@ const videosCustomGetValidator = ( // Only the owner or a user that have blacklist rights can see the video if (!user || !user.canGetVideo(videoAll)) { - return res.status(403) + return res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Cannot get this private/internal or blacklisted video.' }) } @@ -197,7 +198,7 @@ const videosCustomGetValidator = ( if (isUUIDValid(req.params.id)) return next() // Don't leak this unlisted video - return res.status(404).end() + return res.status(HttpStatusCode.NOT_FOUND_404).end() } } ] @@ -250,7 +251,7 @@ const videosChangeOwnershipValidator = [ const nextOwner = await AccountModel.loadLocalByName(req.body.username) if (!nextOwner) { - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Changing video ownership to a remote account is not supported yet' }) return @@ -276,7 +277,7 @@ const videosTerminateChangeOwnershipValidator = [ const videoChangeOwnership = res.locals.videoChangeOwnership if (videoChangeOwnership.status !== VideoChangeOwnershipStatus.WAITING) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'Ownership already accepted or refused' }) return } @@ -294,7 +295,7 @@ const videosAcceptChangeOwnershipValidator = [ const videoChangeOwnership = res.locals.videoChangeOwnership const isAble = await isAbleToUploadVideo(user.id, videoChangeOwnership.Video.getMaxQualityFile().size) if (isAble === false) { - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: 'The user video quota is exceeded with this video.' }) return @@ -433,7 +434,7 @@ const commonVideosFiltersValidator = [ (req.query.filter === 'all-local' || req.query.filter === 'all') && (!user || user.hasRight(UserRight.SEE_ALL_VIDEOS) === false) ) { - res.status(401) + res.status(HttpStatusCode.UNAUTHORIZED_401) .json({ error: 'You are not allowed to see all local videos.' }) return @@ -473,7 +474,7 @@ function areErrorsInScheduleUpdate (req: express.Request, res: express.Response) if (!req.body.scheduleUpdate.updateAt) { logger.warn('Invalid parameters: scheduleUpdate.updateAt is mandatory.') - res.status(400) + res.status(HttpStatusCode.BAD_REQUEST_400) .json({ error: 'Schedule update at is mandatory.' }) return true @@ -498,7 +499,7 @@ async function isVideoAccepted (req: express.Request, res: express.Response, vid if (!acceptedResult || acceptedResult.accepted !== true) { logger.info('Refused local video.', { acceptedResult, acceptParameters }) - res.status(403) + res.status(HttpStatusCode.FORBIDDEN_403) .json({ error: acceptedResult.errorMessage || 'Refused local video' }) return false diff --git a/server/middlewares/validators/webfinger.ts b/server/middlewares/validators/webfinger.ts index 5fe864f8b..a71422ed8 100644 --- a/server/middlewares/validators/webfinger.ts +++ b/server/middlewares/validators/webfinger.ts @@ -5,6 +5,7 @@ import { logger } from '../../helpers/logger' import { ActorModel } from '../../models/activitypub/actor' import { areValidationErrors } from './utils' import { getHostWithPort } from '../../helpers/express-utils' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' const webfingerValidator = [ query('resource').custom(isWebfingerLocalResourceValid).withMessage('Should have a valid webfinger resource'), @@ -20,9 +21,9 @@ const webfingerValidator = [ const actor = await ActorModel.loadLocalUrlByName(name) if (!actor) { - return res.status(404) - .send({ error: 'Actor not found' }) - .end() + return res.status(HttpStatusCode.NOT_FOUND_404) + .send({ error: 'Actor not found' }) + .end() } res.locals.actorUrl = actor -- cgit v1.2.3