Refractor validators
authorChocobozzz <florian.bigard@gmail.com>
Mon, 27 Nov 2017 16:30:46 +0000 (17:30 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 27 Nov 2017 18:43:01 +0000 (19:43 +0100)
33 files changed:
server/controllers/activitypub/client.ts
server/controllers/api/server/follows.ts
server/controllers/api/users.ts
server/controllers/api/videos/abuse.ts
server/controllers/api/videos/blacklist.ts
server/controllers/api/videos/channel.ts
server/controllers/api/videos/index.ts
server/controllers/api/videos/rate.ts
server/controllers/services.ts
server/controllers/webfinger.ts
server/helpers/custom-validators/accounts.ts
server/helpers/custom-validators/activitypub/account.ts
server/helpers/custom-validators/activitypub/videos.ts
server/helpers/custom-validators/video-channels.ts
server/helpers/custom-validators/videos.ts
server/middlewares/async.ts
server/middlewares/validators/account.ts
server/middlewares/validators/activitypub/activity.ts
server/middlewares/validators/activitypub/signature.ts
server/middlewares/validators/follows.ts
server/middlewares/validators/oembed.ts
server/middlewares/validators/pagination.ts
server/middlewares/validators/sort.ts
server/middlewares/validators/users.ts
server/middlewares/validators/utils.ts
server/middlewares/validators/video-blacklist.ts
server/middlewares/validators/video-channels.ts
server/middlewares/validators/videos.ts
server/middlewares/validators/webfinger.ts
server/models/account/account.ts
server/models/video/video-channel.ts
server/models/video/video.ts
support/doc/server/code.md

index 41272bca08ec070fcbe99065873070b7096d7e02..62cde1fc7aaa6aa182c40e11730a1e29d2377c80 100644 (file)
@@ -19,22 +19,22 @@ import { VideoShareInstance } from '../../models/video/video-share-interface'
 const activityPubClientRouter = express.Router()
 
 activityPubClientRouter.get('/account/:name',
-  executeIfActivityPub(localAccountValidator),
+  executeIfActivityPub(asyncMiddleware(localAccountValidator)),
   executeIfActivityPub(accountController)
 )
 
 activityPubClientRouter.get('/account/:name/followers',
-  executeIfActivityPub(localAccountValidator),
+  executeIfActivityPub(asyncMiddleware(localAccountValidator)),
   executeIfActivityPub(asyncMiddleware(accountFollowersController))
 )
 
 activityPubClientRouter.get('/account/:name/following',
-  executeIfActivityPub(localAccountValidator),
+  executeIfActivityPub(asyncMiddleware(localAccountValidator)),
   executeIfActivityPub(asyncMiddleware(accountFollowingController))
 )
 
 activityPubClientRouter.get('/videos/watch/:id',
-  executeIfActivityPub(videosGetValidator),
+  executeIfActivityPub(asyncMiddleware(videosGetValidator)),
   executeIfActivityPub(videoController)
 )
 
@@ -44,7 +44,7 @@ activityPubClientRouter.get('/videos/watch/:id/announces/:accountId',
 )
 
 activityPubClientRouter.get('/video-channels/:id',
-  executeIfActivityPub(videoChannelsGetValidator),
+  executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)),
   executeIfActivityPub(asyncMiddleware(videoChannelController))
 )
 
index 535d530f75a4cbbd7c52f6a001c2696bbb02d407..c2fb37c39a451059931ec5609be50a4a1e81a535 100644 (file)
@@ -41,7 +41,7 @@ serverFollowsRouter.post('/following',
 serverFollowsRouter.delete('/following/:accountId',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
-  removeFollowingValidator,
+  asyncMiddleware(removeFollowingValidator),
   asyncMiddleware(removeFollow)
 )
 
index ac7c87517d8d0e9458f4c450edacba9d9aa433db..721b233010eae6c68d3f2bf93702da4bf6359d1b 100644 (file)
@@ -43,7 +43,7 @@ usersRouter.get('/me/videos',
 
 usersRouter.get('/me/videos/:videoId/rating',
   authenticate,
-  usersVideoRatingValidator,
+  asyncMiddleware(usersVideoRatingValidator),
   asyncMiddleware(getUserVideoRating)
 )
 
@@ -56,20 +56,20 @@ usersRouter.get('/',
 )
 
 usersRouter.get('/:id',
-  usersGetValidator,
+  asyncMiddleware(usersGetValidator),
   getUser
 )
 
 usersRouter.post('/',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_USERS),
-  usersAddValidator,
-  createUserRetryWrapper
+  asyncMiddleware(usersAddValidator),
+  asyncMiddleware(createUserRetryWrapper)
 )
 
 usersRouter.post('/register',
-  ensureUserRegistrationAllowed,
-  usersRegisterValidator,
+  asyncMiddleware(ensureUserRegistrationAllowed),
+  asyncMiddleware(usersRegisterValidator),
   asyncMiddleware(registerUserRetryWrapper)
 )
 
@@ -82,14 +82,14 @@ usersRouter.put('/me',
 usersRouter.put('/:id',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_USERS),
-  usersUpdateValidator,
+  asyncMiddleware(usersUpdateValidator),
   asyncMiddleware(updateUser)
 )
 
 usersRouter.delete('/:id',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_USERS),
-  usersRemoveValidator,
+  asyncMiddleware(usersRemoveValidator),
   asyncMiddleware(removeUser)
 )
 
index 88b3d538deeb78c987e19d6e68e7e71ef23643b8..29e1175c5a0d3adba97df17ff9550a6745504ed1 100644 (file)
@@ -33,7 +33,7 @@ abuseVideoRouter.get('/abuse',
 )
 abuseVideoRouter.post('/:id/abuse',
   authenticate,
-  videoAbuseReportValidator,
+  asyncMiddleware(videoAbuseReportValidator),
   asyncMiddleware(reportVideoAbuseRetryWrapper)
 )
 
index be7cf6ea4ada4602c57b7c8d50b6c64bdfb4eefe..06333c271244dfae0ac9c8a7163bd69b626bd188 100644 (file)
@@ -21,7 +21,7 @@ const blacklistRouter = express.Router()
 blacklistRouter.post('/:videoId/blacklist',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST),
-  videosBlacklistAddValidator,
+  asyncMiddleware(videosBlacklistAddValidator),
   asyncMiddleware(addVideoToBlacklist)
 )
 
@@ -38,7 +38,7 @@ blacklistRouter.get('/blacklist',
 blacklistRouter.delete('/:videoId/blacklist',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST),
-  videosBlacklistRemoveValidator,
+  asyncMiddleware(videosBlacklistRemoveValidator),
   asyncMiddleware(removeVideoFromBlacklistController)
 )
 
index ce2656e71b2d20677b7a2f8f2990c821f92c8369..d99f47c32d8a27cdbe16688614053648dae5c1df 100644 (file)
@@ -3,6 +3,7 @@ import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared'
 import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers'
 import { database as db } from '../../../initializers'
 import { createVideoChannel } from '../../../lib'
+import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update'
 import {
   asyncMiddleware,
   authenticate,
@@ -10,14 +11,13 @@ import {
   paginationValidator,
   setPagination,
   setVideoChannelsSort,
-  videoChannelsGetValidator,
   videoChannelsAddValidator,
+  videoChannelsGetValidator,
   videoChannelsRemoveValidator,
   videoChannelsSortValidator,
   videoChannelsUpdateValidator
 } from '../../../middlewares'
 import { AccountInstance, VideoChannelInstance } from '../../../models'
-import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update'
 
 const videoChannelRouter = express.Router()
 
@@ -30,7 +30,7 @@ videoChannelRouter.get('/channels',
 )
 
 videoChannelRouter.get('/accounts/:accountId/channels',
-  listVideoAccountChannelsValidator,
+  asyncMiddleware(listVideoAccountChannelsValidator),
   asyncMiddleware(listVideoAccountChannels)
 )
 
@@ -42,18 +42,18 @@ videoChannelRouter.post('/channels',
 
 videoChannelRouter.put('/channels/:id',
   authenticate,
-  videoChannelsUpdateValidator,
+  asyncMiddleware(videoChannelsUpdateValidator),
   updateVideoChannelRetryWrapper
 )
 
 videoChannelRouter.delete('/channels/:id',
   authenticate,
-  videoChannelsRemoveValidator,
+  asyncMiddleware(videoChannelsRemoveValidator),
   asyncMiddleware(removeVideoChannelRetryWrapper)
 )
 
 videoChannelRouter.get('/channels/:id',
-  videoChannelsGetValidator,
+  asyncMiddleware(videoChannelsGetValidator),
   asyncMiddleware(getVideoChannel)
 )
 
index 2b5afd632d1f3e92ecfd70972d8db1844bb5affa..244d9191408e172a9d9cb835e5047fce10d8aa4f 100644 (file)
@@ -86,7 +86,7 @@ videosRouter.get('/',
 )
 videosRouter.put('/:id',
   authenticate,
-  videosUpdateValidator,
+  asyncMiddleware(videosUpdateValidator),
   asyncMiddleware(updateVideoRetryWrapper)
 )
 videosRouter.post('/upload',
@@ -97,17 +97,17 @@ videosRouter.post('/upload',
 )
 
 videosRouter.get('/:id/description',
-  videosGetValidator,
+  asyncMiddleware(videosGetValidator),
   asyncMiddleware(getVideoDescription)
 )
 videosRouter.get('/:id',
-  videosGetValidator,
+  asyncMiddleware(videosGetValidator),
   getVideo
 )
 
 videosRouter.delete('/:id',
   authenticate,
-  videosRemoveValidator,
+  asyncMiddleware(videosRemoveValidator),
   asyncMiddleware(removeVideoRetryWrapper)
 )
 
index 134284df7d7cf168bdb80523f9b6e07793551e9a..0c6a988cfbdb0b69118cd4da662df7c7c301c009 100644 (file)
@@ -12,7 +12,7 @@ const rateVideoRouter = express.Router()
 
 rateVideoRouter.put('/:id/rate',
   authenticate,
-  videoRateValidator,
+  asyncMiddleware(videoRateValidator),
   asyncMiddleware(rateVideoRetryWrapper)
 )
 
index 0db6e5498bead933db47ea17619ec7679f2c9ab0..0c325678c78cf9a1e716d03e5fcec3a631e21d6f 100644 (file)
@@ -1,12 +1,16 @@
 import * as express from 'express'
 
-import { CONFIG, PREVIEWS_SIZE, EMBED_SIZE } from '../initializers'
+import { CONFIG, EMBED_SIZE, PREVIEWS_SIZE } from '../initializers'
 import { oembedValidator } from '../middlewares'
+import { asyncMiddleware } from '../middlewares/async'
 import { VideoInstance } from '../models'
 
 const servicesRouter = express.Router()
 
-servicesRouter.use('/oembed', oembedValidator, generateOEmbed)
+servicesRouter.use('/oembed',
+  asyncMiddleware(oembedValidator),
+  generateOEmbed
+)
 
 // ---------------------------------------------------------------------------
 
index cc28a8909663223b94acb42e4ff8f8423ed651da..1cea513a181e356d146b226c84180293480345dd 100644 (file)
@@ -1,11 +1,12 @@
 import * as express from 'express'
+import { asyncMiddleware } from '../middlewares/async'
 import { webfingerValidator } from '../middlewares/validators/webfinger'
 import { AccountInstance } from '../models/account/account-interface'
 
 const webfingerRouter = express.Router()
 
 webfingerRouter.get('/.well-known/webfinger',
-  webfingerValidator,
+  asyncMiddleware(webfingerValidator),
   webfingerController
 )
 
index a6d7f2b821a0ca773d00378d5df6fc1e587080dc..e3c4774149970c2525da1b50c5ab009d7abe9bff 100644 (file)
@@ -1,17 +1,16 @@
 import * as Bluebird from 'bluebird'
-import * as express from 'express'
+import { Response } from 'express'
 import 'express-validator'
 import * as validator from 'validator'
 import { database as db } from '../../initializers'
 import { AccountInstance } from '../../models'
-import { logger } from '../logger'
 import { isUserUsernameValid } from './users'
 
 function isAccountNameValid (value: string) {
   return isUserUsernameValid(value)
 }
 
-function checkAccountIdExists (id: number | string, res: express.Response, callback: (err: Error, account: AccountInstance) => any) {
+function isAccountIdExist (id: number | string, res: Response) {
   let promise: Bluebird<AccountInstance>
 
   if (validator.isInt('' + id)) {
@@ -20,36 +19,35 @@ function checkAccountIdExists (id: number | string, res: express.Response, callb
     promise = db.Account.loadByUUID('' + id)
   }
 
-  return checkAccountExists(promise, res, callback)
+  return isAccountExist(promise, res)
 }
 
-function checkLocalAccountNameExists (name: string, res: express.Response, callback: (err: Error, account: AccountInstance) => any) {
-  const p = db.Account.loadLocalByName(name)
+function isLocalAccountNameExist (name: string, res: Response) {
+  const promise = db.Account.loadLocalByName(name)
 
-  return checkAccountExists(p, res, callback)
+  return isAccountExist(promise, res)
 }
 
-function checkAccountExists (p: Bluebird<AccountInstance>, res: express.Response, callback: (err: Error, account: AccountInstance) => any) {
-  p.then(account => {
-    if (!account) {
-      return res.status(404)
-        .send({ error: 'Account not found' })
-        .end()
-    }
-
-    res.locals.account = account
-    return callback(null, account)
-  })
-    .catch(err => {
-      logger.error('Error in account request validator.', err)
-      return res.sendStatus(500)
-    })
+async function isAccountExist (p: Bluebird<AccountInstance>, res: Response) {
+  const account = await p
+
+  if (!account) {
+    res.status(404)
+      .send({ error: 'Account not found' })
+      .end()
+
+    return false
+  }
+
+  res.locals.account = account
+
+  return true
 }
 
 // ---------------------------------------------------------------------------
 
 export {
-  checkAccountIdExists,
-  checkLocalAccountNameExists,
+  isAccountIdExist,
+  isLocalAccountNameExist,
   isAccountNameValid
 }
index 645f55a5a70765527ddabda5ed56ebb95f88b793..cab39a6545aa3eefc8106572c4c7aa14147ae5f7 100644 (file)
@@ -5,31 +5,19 @@ import { exists, isUUIDValid } from '../misc'
 import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
 
 function isAccountEndpointsObjectValid (endpointObject: any) {
-  return isAccountSharedInboxValid(endpointObject.sharedInbox)
-}
-
-function isAccountSharedInboxValid (sharedInbox: string) {
-  return isActivityPubUrlValid(sharedInbox)
+  return isActivityPubUrlValid(endpointObject.sharedInbox)
 }
 
 function isAccountPublicKeyObjectValid (publicKeyObject: any) {
-  return isAccountPublicKeyIdValid(publicKeyObject.id) &&
-    isAccountPublicKeyOwnerValid(publicKeyObject.owner) &&
+  return isActivityPubUrlValid(publicKeyObject.id) &&
+    isActivityPubUrlValid(publicKeyObject.owner) &&
     isAccountPublicKeyValid(publicKeyObject.publicKeyPem)
 }
 
-function isAccountPublicKeyIdValid (id: string) {
-  return isActivityPubUrlValid(id)
-}
-
 function isAccountTypeValid (type: string) {
   return type === 'Person' || type === 'Application'
 }
 
-function isAccountPublicKeyOwnerValid (owner: string) {
-  return isActivityPubUrlValid(owner)
-}
-
 function isAccountPublicKeyValid (publicKey: string) {
   return exists(publicKey) &&
     typeof publicKey === 'string' &&
@@ -38,34 +26,10 @@ function isAccountPublicKeyValid (publicKey: string) {
     validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY)
 }
 
-function isAccountIdValid (id: string) {
-  return isActivityPubUrlValid(id)
-}
-
-function isAccountFollowingValid (id: string) {
-  return isActivityPubUrlValid(id)
-}
-
-function isAccountFollowersValid (id: string) {
-  return isActivityPubUrlValid(id)
-}
-
-function isAccountInboxValid (inbox: string) {
-  return isActivityPubUrlValid(inbox)
-}
-
-function isAccountOutboxValid (outbox: string) {
-  return isActivityPubUrlValid(outbox)
-}
-
 function isAccountPreferredUsernameValid (preferredUsername: string) {
   return isAccountNameValid(preferredUsername)
 }
 
-function isAccountUrlValid (url: string) {
-  return isActivityPubUrlValid(url)
-}
-
 function isAccountPrivateKeyValid (privateKey: string) {
   return exists(privateKey) &&
     typeof privateKey === 'string' &&
@@ -75,15 +39,15 @@ function isAccountPrivateKeyValid (privateKey: string) {
 }
 
 function isRemoteAccountValid (remoteAccount: any) {
-  return isAccountIdValid(remoteAccount.id) &&
+  return isActivityPubUrlValid(remoteAccount.id) &&
     isUUIDValid(remoteAccount.uuid) &&
     isAccountTypeValid(remoteAccount.type) &&
-    isAccountFollowingValid(remoteAccount.following) &&
-    isAccountFollowersValid(remoteAccount.followers) &&
-    isAccountInboxValid(remoteAccount.inbox) &&
-    isAccountOutboxValid(remoteAccount.outbox) &&
+    isActivityPubUrlValid(remoteAccount.following) &&
+    isActivityPubUrlValid(remoteAccount.followers) &&
+    isActivityPubUrlValid(remoteAccount.inbox) &&
+    isActivityPubUrlValid(remoteAccount.outbox) &&
     isAccountPreferredUsernameValid(remoteAccount.preferredUsername) &&
-    isAccountUrlValid(remoteAccount.url) &&
+    isActivityPubUrlValid(remoteAccount.url) &&
     isAccountPublicKeyObjectValid(remoteAccount.publicKey) &&
     isAccountEndpointsObjectValid(remoteAccount.endpoints)
 }
@@ -113,19 +77,10 @@ function isAccountAcceptActivityValid (activity: any) {
 
 export {
   isAccountEndpointsObjectValid,
-  isAccountSharedInboxValid,
   isAccountPublicKeyObjectValid,
-  isAccountPublicKeyIdValid,
   isAccountTypeValid,
-  isAccountPublicKeyOwnerValid,
   isAccountPublicKeyValid,
-  isAccountIdValid,
-  isAccountFollowingValid,
-  isAccountFollowersValid,
-  isAccountInboxValid,
-  isAccountOutboxValid,
   isAccountPreferredUsernameValid,
-  isAccountUrlValid,
   isAccountPrivateKeyValid,
   isRemoteAccountValid,
   isAccountFollowingCountValid,
index 55e79c4e8419de5ca27230f8a0127ff37b1d00a8..12c672fd2ea214fd3b3398da7ec488645d820f0e 100644 (file)
@@ -8,7 +8,6 @@ import {
   isVideoNSFWValid,
   isVideoTagValid,
   isVideoTruncatedDescriptionValid,
-  isVideoUrlValid,
   isVideoViewsValid
 } from '../videos'
 import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
@@ -77,12 +76,11 @@ export {
 function setValidRemoteTags (video: any) {
   if (Array.isArray(video.tag) === false) return false
 
-  const newTag = video.tag.filter(t => {
+  video.tag = video.tag.filter(t => {
     return t.type === 'Hashtag' &&
       isVideoTagValid(t.name)
   })
 
-  video.tag = newTag
   return true
 }
 
@@ -96,7 +94,7 @@ function isRemoteVideoContentValid (mediaType: string, content: string) {
 
 function isRemoteVideoIconValid (icon: any) {
   return icon.type === 'Image' &&
-    isVideoUrlValid(icon.url) &&
+    isActivityPubUrlValid(icon.url) &&
     icon.mediaType === 'image/jpeg' &&
     validator.isInt(icon.width + '', { min: 0 }) &&
     validator.isInt(icon.height + '', { min: 0 })
@@ -105,8 +103,7 @@ function isRemoteVideoIconValid (icon: any) {
 function setValidRemoteVideoUrls (video: any) {
   if (Array.isArray(video.url) === false) return false
 
-  const newUrl = video.url.filter(u => isRemoteVideoUrlValid(u))
-  video.url = newUrl
+  video.url = video.url.filter(u => isRemoteVideoUrlValid(u))
 
   return true
 }
@@ -115,13 +112,13 @@ function isRemoteVideoUrlValid (url: any) {
   return url.type === 'Link' &&
     (
       ACTIVITY_PUB.URL_MIME_TYPES.VIDEO.indexOf(url.mimeType) !== -1 &&
-      isVideoUrlValid(url.url) &&
+      isActivityPubUrlValid(url.url) &&
       validator.isInt(url.width + '', { min: 0 }) &&
       validator.isInt(url.size + '', { min: 0 })
     ) ||
     (
       ACTIVITY_PUB.URL_MIME_TYPES.TORRENT.indexOf(url.mimeType) !== -1 &&
-      isVideoUrlValid(url.url) &&
+      isActivityPubUrlValid(url.url) &&
       validator.isInt(url.width + '', { min: 0 })
     ) ||
     (
index 267d987fc658f22c10b9378b077860eb1dabf01a..3de9f041be57de1ae6395725ee9151637dab4367 100644 (file)
@@ -1,21 +1,13 @@
-import * as Bluebird from 'bluebird'
 import * as express from 'express'
 import 'express-validator'
 import 'multer'
 import * as validator from 'validator'
-
 import { CONSTRAINTS_FIELDS, database as db } from '../../initializers'
 import { VideoChannelInstance } from '../../models'
-import { logger } from '../logger'
-import { isActivityPubUrlValid } from './index'
 import { exists } from './misc'
 
 const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS
 
-function isVideoChannelUrlValid (value: string) {
-  return isActivityPubUrlValid(value)
-}
-
 function isVideoChannelDescriptionValid (value: string) {
   return value === null || validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.DESCRIPTION)
 }
@@ -24,31 +16,7 @@ function isVideoChannelNameValid (value: string) {
   return exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.NAME)
 }
 
-function checkVideoChannelExists (id: string, res: express.Response, callback: () => void) {
-  let promise: Bluebird<VideoChannelInstance>
-  if (validator.isInt(id)) {
-    promise = db.VideoChannel.loadAndPopulateAccount(+id)
-  } else { // UUID
-    promise = db.VideoChannel.loadByUUIDAndPopulateAccount(id)
-  }
-
-  promise.then(videoChannel => {
-    if (!videoChannel) {
-      return res.status(404)
-        .json({ error: 'Video channel not found' })
-        .end()
-    }
-
-    res.locals.videoChannel = videoChannel
-    callback()
-  })
-    .catch(err => {
-      logger.error('Error in video channel request validator.', err)
-      return res.sendStatus(500)
-    })
-}
-
-async function isVideoChannelExistsPromise (id: string, res: express.Response) {
+async function isVideoChannelExist (id: string, res: express.Response) {
   let videoChannel: VideoChannelInstance
   if (validator.isInt(id)) {
     videoChannel = await db.VideoChannel.loadAndPopulateAccount(+id)
@@ -72,8 +40,6 @@ async function isVideoChannelExistsPromise (id: string, res: express.Response) {
 
 export {
   isVideoChannelDescriptionValid,
-  checkVideoChannelExists,
   isVideoChannelNameValid,
-  isVideoChannelExistsPromise,
-  isVideoChannelUrlValid
+  isVideoChannelExist
 }
index 27635462608e6db2d1927e67b7c713fa38671f14..f13178c54d62fc195a176a985b9aea0184fa5eb4 100644 (file)
@@ -1,4 +1,3 @@
-import * as Bluebird from 'bluebird'
 import { Response } from 'express'
 import 'express-validator'
 import { values } from 'lodash'
@@ -6,12 +5,10 @@ import 'multer'
 import * as validator from 'validator'
 import { VideoRateType } from '../../../shared'
 import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers'
+import { VIDEO_PRIVACIES } from '../../initializers/constants'
 import { database as db } from '../../initializers/database'
 import { VideoInstance } from '../../models/video/video-interface'
-import { logger } from '../logger'
-import { isActivityPubUrlValid } from './activitypub/misc'
 import { exists, isArray } from './misc'
-import { VIDEO_PRIVACIES } from '../../initializers/constants'
 
 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
@@ -20,10 +17,6 @@ function isVideoCategoryValid (value: number) {
   return VIDEO_CATEGORIES[value] !== undefined
 }
 
-function isVideoUrlValid (value: string) {
-  return isActivityPubUrlValid(value)
-}
-
 function isVideoLicenceValid (value: number) {
   return VIDEO_LICENCES[value] !== undefined
 }
@@ -106,31 +99,7 @@ function isVideoFileSizeValid (value: string) {
   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
 }
 
-function checkVideoExists (id: string, res: Response, callback: () => void) {
-  let promise: Bluebird<VideoInstance>
-  if (validator.isInt(id)) {
-    promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
-  } else { // UUID
-    promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
-  }
-
-  promise.then(video => {
-    if (!video) {
-      return res.status(404)
-        .json({ error: 'Video not found' })
-        .end()
-    }
-
-    res.locals.video = video
-    callback()
-  })
-    .catch(err => {
-      logger.error('Error in video request validator.', err)
-      return res.sendStatus(500)
-    })
-}
-
-async function isVideoExistsPromise (id: string, res: Response) {
+async function isVideoExist (id: string, res: Response) {
   let video: VideoInstance
 
   if (validator.isInt(id)) {
@@ -169,10 +138,8 @@ export {
   isVideoRatingTypeValid,
   isVideoDurationValid,
   isVideoTagValid,
-  isVideoUrlValid,
   isVideoPrivacyValid,
   isVideoFileResolutionValid,
   isVideoFileSizeValid,
-  checkVideoExists,
-  isVideoExistsPromise
+  isVideoExist
 }
index 9692f9be732d99e649c6cf96d75a9af931e47c3e..534891899cab0364af5a41a0a37bf82a5b1dcf9c 100644 (file)
@@ -1,9 +1,12 @@
-import { Request, Response, NextFunction, RequestHandler } from 'express'
 import { eachSeries } from 'async'
+import { NextFunction, Request, RequestHandler, Response } from 'express'
 
 // Syntactic sugar to avoid try/catch in express controllers
 // Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
-function asyncMiddleware (fun: RequestHandler | RequestHandler[]) {
+
+export type RequestPromiseHandler = (req: Request, res: Response, next: NextFunction) => Promise<any>
+
+function asyncMiddleware (fun: RequestPromiseHandler | RequestPromiseHandler[]) {
   return (req: Request, res: Response, next: NextFunction) => {
     if (Array.isArray(fun) === true) {
       return eachSeries(fun as RequestHandler[], (f, cb) => {
index 47ed6a7bb1591ac56f7e5d9979baf3defee9fa13..70f4e4d3bc5e33a17b4adcc05ead4de5aac526d1 100644 (file)
@@ -1,18 +1,19 @@
 import * as express from 'express'
 import { param } from 'express-validator/check'
-import { logger } from '../../helpers'
-import { checkLocalAccountNameExists, isAccountNameValid } from '../../helpers/custom-validators/accounts'
-import { checkErrors } from './utils'
+import { logger, isLocalAccountNameExist } from '../../helpers'
+import { isAccountNameValid } from '../../helpers/custom-validators/accounts'
+import { areValidationErrors } from './utils'
 
 const localAccountValidator = [
   param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking localAccountValidator parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkLocalAccountNameExists(req.params.name, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isLocalAccountNameExist(req.params.name, res)) return
+
+    return next()
   }
 ]
 
index 0de8b2d85bb03a7278da550864766d1a27c62a88..8aa82298ccb1320def7c2d6083222a59dc9ee3c5 100644 (file)
@@ -1,7 +1,7 @@
 import * as express from 'express'
 import { body } from 'express-validator/check'
 import { isRootActivityValid, logger } from '../../../helpers'
-import { checkErrors } from '../utils'
+import { areValidationErrors } from '../utils'
 
 const activityPubValidator = [
   body('').custom((value, { req }) => isRootActivityValid(req.body)),
@@ -9,7 +9,9 @@ const activityPubValidator = [
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking activity pub parameters', { parameters: req.body })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
index 0ce15c1f6e735a88379eabb736b17037872bc0c1..360685512aae5c5b6955db256fc53e8fc0d16d1e 100644 (file)
@@ -1,14 +1,7 @@
-import { body } from 'express-validator/check'
 import * as express from 'express'
-
-import {
-  logger,
-  isDateValid,
-  isSignatureTypeValid,
-  isSignatureCreatorValid,
-  isSignatureValueValid
-} from '../../../helpers'
-import { checkErrors } from '../utils'
+import { body } from 'express-validator/check'
+import { isDateValid, isSignatureCreatorValid, isSignatureTypeValid, isSignatureValueValid, logger } from '../../../helpers'
+import { areValidationErrors } from '../utils'
 
 const signatureValidator = [
   body('signature.type').custom(isSignatureTypeValid).withMessage('Should have a valid signature type'),
@@ -19,7 +12,9 @@ const signatureValidator = [
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking activitypub signature parameter', { parameters: { signature: req.body.signature } })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
index ddc4c1de15cbf2ee09622eb85e02190f59754f8b..605872ecf9c70a55f2d42fde15167ccde6c7a871 100644 (file)
@@ -4,7 +4,7 @@ import { isTestInstance } from '../../helpers/core-utils'
 import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers'
 import { logger } from '../../helpers/logger'
 import { CONFIG, database as db } from '../../initializers'
-import { checkErrors } from './utils'
+import { areValidationErrors } from './utils'
 import { getServerAccount } from '../../helpers/utils'
 import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
 
@@ -23,34 +23,30 @@ const followValidator = [
 
     logger.debug('Checking follow parameters', { parameters: req.body })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
 const removeFollowingValidator = [
   param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking unfollow parameters', { parameters: req.params })
 
-    checkErrors(req, res, async () => {
-      try {
-        const serverAccount = await getServerAccount()
-        const follow = await db.AccountFollow.loadByAccountAndTarget(serverAccount.id, req.params.accountId)
+    if (areValidationErrors(req, res)) return
 
-        if (!follow) {
-          return res.status(404)
-            .end()
-        }
+    const serverAccount = await getServerAccount()
+    const follow = await db.AccountFollow.loadByAccountAndTarget(serverAccount.id, req.params.accountId)
 
-        res.locals.follow = follow
+    if (!follow) {
+      return res.status(404)
+        .end()
+    }
 
-        return next()
-      } catch (err) {
-        logger.error('Error in remove following validator.', err)
-        return res.sendStatus(500)
-      }
-    })
+    res.locals.follow = follow
+    return next()
   }
 ]
 
index f8e34d2d429f846cf6bd44b3934620b028e9c208..31f06dc65e9f747ecfbd19d70726b5fb879ba88a 100644 (file)
@@ -1,15 +1,10 @@
-import { query } from 'express-validator/check'
 import * as express from 'express'
+import { query } from 'express-validator/check'
 import { join } from 'path'
-
-import { checkErrors } from './utils'
+import { isIdOrUUIDValid, isTestInstance, logger } from '../../helpers'
 import { CONFIG } from '../../initializers'
-import {
-  logger,
-  isTestInstance,
-  checkVideoExists,
-  isIdOrUUIDValid
-} from '../../helpers'
+import { areValidationErrors } from './utils'
+import { isVideoExist } from '../../helpers/custom-validators/videos'
 
 const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/'
 const videoWatchRegex = new RegExp('([^/]+)$')
@@ -29,33 +24,35 @@ const oembedValidator = [
   query('maxheight').optional().isInt().withMessage('Should have a valid max height'),
   query('format').optional().isIn([ 'xml', 'json' ]).withMessage('Should have a valid format'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking oembed parameters', { parameters: req.query })
 
-    checkErrors(req, res, () => {
-      if (req.query.format !== undefined && req.query.format !== 'json') {
-        return res.status(501)
-                  .json({ error: 'Requested format is not implemented on server.' })
-                  .end()
-      }
+    if (areValidationErrors(req, res)) return
+
+    if (req.query.format !== undefined && req.query.format !== 'json') {
+      return res.status(501)
+                .json({ error: 'Requested format is not implemented on server.' })
+                .end()
+    }
+
+    const startIsOk = req.query.url.startsWith(urlShouldStartWith)
+    const matches = videoWatchRegex.exec(req.query.url)
+    if (startIsOk === false || matches === null) {
+      return res.status(400)
+                .json({ error: 'Invalid url.' })
+                .end()
+    }
 
-      const startIsOk = req.query.url.startsWith(urlShouldStartWith)
-      const matches = videoWatchRegex.exec(req.query.url)
-      if (startIsOk === false || matches === null) {
-        return res.status(400)
-                  .json({ error: 'Invalid url.' })
-                  .end()
-      }
+    const videoId = matches[1]
+    if (isIdOrUUIDValid(videoId) === false) {
+      return res.status(400)
+                .json({ error: 'Invalid video id.' })
+                .end()
+    }
 
-      const videoId = matches[1]
-      if (isIdOrUUIDValid(videoId) === false) {
-        return res.status(400)
-                  .json({ error: 'Invalid video id.' })
-                  .end()
-      }
+    if (!await isVideoExist(videoId, res)) return
 
-      checkVideoExists(videoId, res, next)
-    })
+    return next()
   }
 ]
 
index a5a542cdfe0f3fcf4ace19f879fbd6403750d406..0895b4eb8304695a1d5fbfd9f51c0d540f89532c 100644 (file)
@@ -1,8 +1,7 @@
-import { query } from 'express-validator/check'
 import * as express from 'express'
-
-import { checkErrors } from './utils'
+import { query } from 'express-validator/check'
 import { logger } from '../../helpers'
+import { areValidationErrors } from './utils'
 
 const paginationValidator = [
   query('start').optional().isInt().withMessage('Should have a number start'),
@@ -11,7 +10,9 @@ const paginationValidator = [
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking pagination parameters', { parameters: req.query })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
index 6fea41bb88c1116b5c070c4992da3fc4e080e8fa..636f68885ab106d6b47550fdf734ce307e5d1f87 100644 (file)
@@ -1,9 +1,9 @@
 import { query } from 'express-validator/check'
 import * as express from 'express'
 
-import { checkErrors } from './utils'
 import { logger } from '../../helpers'
 import { SORTABLE_COLUMNS } from '../../initializers'
+import { areValidationErrors } from './utils'
 
 // Initialize constants here for better performances
 const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
@@ -43,7 +43,9 @@ function checkSort (sortableColumns: string[]) {
     (req: express.Request, res: express.Response, next: express.NextFunction) => {
       logger.debug('Checking sort parameters', { parameters: req.query })
 
-      checkErrors(req, res, next)
+      if (areValidationErrors(req, res)) return
+
+      return next()
     }
   ]
 }
index 6b845f62bbbe3ed37520e466a71fc18a2012ae9d..ac7435b7d3c647157f8490f04c0159d8ec689012 100644 (file)
@@ -1,22 +1,19 @@
-import { body, param } from 'express-validator/check'
-import 'express-validator'
 import * as express from 'express'
-import * as Promise from 'bluebird'
-import * as validator from 'validator'
-
-import { database as db } from '../../initializers/database'
-import { checkErrors } from './utils'
+import 'express-validator'
+import { body, param } from 'express-validator/check'
 import {
+  isIdOrUUIDValid,
   isSignupAllowed,
-  logger,
-  isUserUsernameValid,
+  isUserDisplayNSFWValid,
   isUserPasswordValid,
+  isUserRoleValid,
+  isUserUsernameValid,
   isUserVideoQuotaValid,
-  isUserDisplayNSFWValid,
-  isIdOrUUIDValid,
-  isUserRoleValid
+  logger
 } from '../../helpers'
-import { UserInstance, VideoInstance } from '../../models'
+import { isVideoExist } from '../../helpers/custom-validators/videos'
+import { database as db } from '../../initializers/database'
+import { areValidationErrors } from './utils'
 
 const usersAddValidator = [
   body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
@@ -25,12 +22,13 @@ const usersAddValidator = [
   body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
   body('role').custom(isUserRoleValid).withMessage('Should have a valid role'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersAdd parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
+
+    return next()
   }
 ]
 
@@ -39,37 +37,33 @@ const usersRegisterValidator = [
   body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'),
   body('email').isEmail().withMessage('Should have a valid email'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersRegister parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return
+
+    return next()
   }
 ]
 
 const usersRemoveValidator = [
   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersRemove parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkUserExists(req.params.id, res, (err, user) => {
-        if (err) {
-          logger.error('Error in usersRemoveValidator.', err)
-          return res.sendStatus(500)
-        }
-
-        if (user.username === 'root') {
-          return res.status(400)
-                    .send({ error: 'Cannot remove the root user' })
-                    .end()
-        }
-
-        return next()
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    const user = res.locals.user
+    if (user.username === 'root') {
+      return res.status(400)
+                .send({ error: 'Cannot remove the root user' })
+                .end()
+    }
+
+    return next()
   }
 ]
 
@@ -79,12 +73,13 @@ const usersUpdateValidator = [
   body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'),
   body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersUpdate parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkUserExists(req.params.id, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
@@ -97,64 +92,48 @@ const usersUpdateMeValidator = [
     // TODO: Add old password verification
     logger.debug('Checking usersUpdateMe parameters', { parameters: req.body })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
 const usersGetValidator = [
   param('id').isInt().not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
-    checkErrors(req, res, () => {
-      checkUserExists(req.params.id, res, next)
-    })
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    logger.debug('Checking usersGet parameters', { parameters: req.body })
+
+    if (areValidationErrors(req, res)) return
+    if (!await checkUserIdExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
 const usersVideoRatingValidator = [
   param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      let videoPromise: Promise<VideoInstance>
-
-      if (validator.isUUID(req.params.videoId)) {
-        videoPromise = db.Video.loadByUUID(req.params.videoId)
-      } else {
-        videoPromise = db.Video.load(req.params.videoId)
-      }
-
-      videoPromise
-        .then(video => {
-          if (!video) {
-            return res.status(404)
-                      .json({ error: 'Video not found' })
-                      .end()
-          }
-
-          return next()
-        })
-        .catch(err => {
-          logger.error('Error in user request validator.', err)
-          return res.sendStatus(500)
-        })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.videoId, res)) return
+
+    return next()
   }
 ]
 
 const ensureUserRegistrationAllowed = [
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
-    isSignupAllowed().then(allowed => {
-      if (allowed === false) {
-        return res.status(403)
-                  .send({ error: 'User registration is not enabled or user limit is reached.' })
-                  .end()
-      }
-
-      return next()
-    })
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    const allowed = await isSignupAllowed()
+    if (allowed === false) {
+      return res.status(403)
+                .send({ error: 'User registration is not enabled or user limit is reached.' })
+                .end()
+    }
+
+    return next()
   }
 ]
 
@@ -173,37 +152,30 @@ export {
 
 // ---------------------------------------------------------------------------
 
-function checkUserExists (id: number, res: express.Response, callback: (err: Error, user: UserInstance) => void) {
-  db.User.loadById(id)
-    .then(user => {
-      if (!user) {
-        return res.status(404)
-                  .send({ error: 'User not found' })
-                  .end()
-      }
-
-      res.locals.user = user
-      return callback(null, user)
-    })
-    .catch(err => {
-      logger.error('Error in user request validator.', err)
-      return res.sendStatus(500)
-    })
+async function checkUserIdExist (id: number, res: express.Response) {
+  const user = await db.User.loadById(id)
+
+  if (!user) {
+    res.status(404)
+              .send({ error: 'User not found' })
+              .end()
+
+    return false
+  }
+
+  res.locals.user = user
+  return true
 }
 
-function checkUserDoesNotAlreadyExist (username: string, email: string, res: express.Response, callback: () => void) {
-  db.User.loadByUsernameOrEmail(username, email)
-      .then(user => {
-        if (user) {
-          return res.status(409)
-                    .send({ error: 'User with this username of email already exists.' })
-                    .end()
-        }
-
-        return callback()
-      })
-      .catch(err => {
-        logger.error('Error in usersAdd request validator.', err)
-        return res.sendStatus(500)
-      })
+async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
+  const user = await db.User.loadByUsernameOrEmail(username, email)
+
+  if (user) {
+    res.status(409)
+              .send({ error: 'User with this username of email already exists.' })
+              .end()
+    return false
+  }
+
+  return true
 }
index 77a1a0d4bfb4c5a7ded8dec4ccdaecd890fc85a9..ca80acf29100fde1e59ccc44ddfbe7aeecf3a9d3 100644 (file)
@@ -1,19 +1,8 @@
-import { validationResult } from 'express-validator/check'
 import * as express from 'express'
+import { validationResult } from 'express-validator/check'
 
 import { logger } from '../../helpers'
 
-function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction) {
-  const errors = validationResult(req)
-
-  if (!errors.isEmpty()) {
-    logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() })
-    return res.status(400).json({ errors: errors.mapped() })
-  }
-
-  return next()
-}
-
 function areValidationErrors (req: express.Request, res: express.Response) {
   const errors = validationResult(req)
 
@@ -30,6 +19,5 @@ function areValidationErrors (req: express.Request, res: express.Response) {
 // ---------------------------------------------------------------------------
 
 export {
-  checkErrors,
   areValidationErrors
 }
index 3c8c315195bbd24dc06ac4c0f527009f8e8129f7..f1cc0495042127b422a0f4db2162d67277caa82b 100644 (file)
@@ -1,35 +1,36 @@
-import { param } from 'express-validator/check'
 import * as express from 'express'
-
+import { param } from 'express-validator/check'
+import { isIdOrUUIDValid, logger } from '../../helpers'
+import { isVideoExist } from '../../helpers/custom-validators/videos'
 import { database as db } from '../../initializers/database'
-import { checkErrors } from './utils'
-import { logger, isIdOrUUIDValid, checkVideoExists } from '../../helpers'
+import { VideoInstance } from '../../models/video/video-interface'
+import { areValidationErrors } from './utils'
 
 const videosBlacklistRemoveValidator = [
   param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking blacklistRemove parameters.', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.videoId, res, () => {
-        checkVideoIsBlacklisted(req, res, next)
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.videoId, res)) return
+    if (!await checkVideoIsBlacklisted(res.locals.video, res)) return
+
+    return next()
   }
 ]
 
 const videosBlacklistAddValidator = [
   param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.videoId, res, () => {
-        checkVideoIsBlacklistable(req, res, next)
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.videoId, res)) return
+    if (!checkVideoIsBlacklistable(res.locals.video, res)) return
+
+    return next()
   }
 ]
 
@@ -41,27 +42,27 @@ export {
 }
 // ---------------------------------------------------------------------------
 
-function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) {
-  if (res.locals.video.isOwned() === true) {
-    return res.status(403)
+function checkVideoIsBlacklistable (video: VideoInstance, res: express.Response) {
+  if (video.isOwned() === true) {
+    res.status(403)
               .json({ error: 'Cannot blacklist a local video' })
               .end()
+
+    return false
   }
 
-  callback()
+  return true
 }
 
-function checkVideoIsBlacklisted (req: express.Request, res: express.Response, callback: () => void) {
-  db.BlacklistedVideo.loadByVideoId(res.locals.video.id)
-    .then(blacklistedVideo => {
-      if (!blacklistedVideo) return res.status(404).send('Blacklisted video not found')
+async function checkVideoIsBlacklisted (video: VideoInstance, res: express.Response) {
+  const blacklistedVideo = await db.BlacklistedVideo.loadByVideoId(video.id)
+  if (!blacklistedVideo) {
+    res.status(404)
+      .send('Blacklisted video not found')
 
-      res.locals.blacklistedVideo = blacklistedVideo
+    return false
+  }
 
-      callback()
-    })
-    .catch(err => {
-      logger.error('Error in blacklistRemove request validator', { error: err })
-      return res.sendStatus(500)
-    })
+  res.locals.blacklistedVideo = blacklistedVideo
+  return true
 }
index f30fbf0dcd9112803a841838f12afb7622492525..4683c91e139518f97ec7fc1c69a26ef15c8f6929 100644 (file)
@@ -1,29 +1,30 @@
 import * as express from 'express'
 import { body, param } from 'express-validator/check'
 import { UserRight } from '../../../shared'
-import { checkAccountIdExists } from '../../helpers/custom-validators/accounts'
 import { isIdValid } from '../../helpers/custom-validators/misc'
 import {
-  checkVideoChannelExists,
   isVideoChannelDescriptionValid,
-  isVideoChannelExistsPromise,
+  isVideoChannelExist,
   isVideoChannelNameValid
 } from '../../helpers/custom-validators/video-channels'
 import { isIdOrUUIDValid } from '../../helpers/index'
 import { logger } from '../../helpers/logger'
 import { database as db } from '../../initializers'
 import { UserInstance } from '../../models'
-import { areValidationErrors, checkErrors } from './utils'
+import { areValidationErrors } from './utils'
+import { isAccountIdExist } from '../../helpers/custom-validators/accounts'
+import { VideoChannelInstance } from '../../models/video/video-channel-interface'
 
 const listVideoAccountChannelsValidator = [
   param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkAccountIdExists(req.params.accountId, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isAccountIdExist(req.params.accountId, res)) return
+
+    return next()
   }
 ]
 
@@ -34,7 +35,9 @@ const videoChannelsAddValidator = [
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
@@ -43,56 +46,56 @@ const videoChannelsUpdateValidator = [
   body('name').optional().custom(isVideoChannelNameValid).withMessage('Should have a valid name'),
   body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkVideoChannelExists(req.params.id, res, () => {
-        // We need to make additional checks
-        if (res.locals.videoChannel.isOwned() === false) {
-          return res.status(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)
-            .json({ error: 'Cannot update video channel of another user' })
-            .end()
-        }
-
-        next()
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoChannelExist(req.params.id, res)) return
+
+    // We need to make additional checks
+    if (res.locals.videoChannel.isOwned() === false) {
+      return res.status(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)
+        .json({ error: 'Cannot update video channel of another user' })
+        .end()
+    }
+
+    return next()
   }
 ]
 
 const videoChannelsRemoveValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoChannelExists(req.params.id, res, () => {
-        // Check if the user who did the request is able to delete the video
-        checkUserCanDeleteVideoChannel(res, () => {
-          checkVideoChannelIsNotTheLastOne(res, next)
-        })
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoChannelExist(req.params.id, res)) return
+
+    // Check if the user who did the request is able to delete the video
+    if (!checkUserCanDeleteVideoChannel(res.locals.user, res.locals.videoChannel, res)) return
+    if (!await checkVideoChannelIsNotTheLastOne(res)) return
+
+    return next()
   }
 ]
 
 const videoChannelsGetValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoChannelsGet parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoChannelExists(req.params.id, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoChannelExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
@@ -104,7 +107,7 @@ const videoChannelsShareValidator = [
     logger.debug('Checking videoChannelShare parameters', { parameters: req.params })
 
     if (areValidationErrors(req, res)) return
-    if (!await isVideoChannelExistsPromise(req.params.id, res)) return
+    if (!await isVideoChannelExist(req.params.id, res)) return
 
     const share = await db.VideoChannelShare.load(res.locals.video.id, req.params.accountId)
     if (!share) {
@@ -131,38 +134,40 @@ export {
 
 // ---------------------------------------------------------------------------
 
-function checkUserCanDeleteVideoChannel (res: express.Response, callback: () => void) {
-  const user: UserInstance = res.locals.oauth.token.User
-
+function checkUserCanDeleteVideoChannel (user: UserInstance, videoChannel: VideoChannelInstance, res: express.Response) {
   // Retrieve the user who did the request
-  if (res.locals.videoChannel.isOwned() === false) {
-    return res.status(403)
+  if (videoChannel.isOwned() === false) {
+    res.status(403)
               .json({ error: 'Cannot remove video channel of another server.' })
               .end()
+
+    return false
   }
 
   // Check if the user can delete the video channel
   // 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 && res.locals.videoChannel.Account.userId !== user.id) {
-    return res.status(403)
+  if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && videoChannel.Account.userId !== user.id) {
+    res.status(403)
               .json({ error: 'Cannot remove video channel of another user' })
               .end()
+
+    return false
   }
 
-  // If we reach this comment, we can delete the video
-  callback()
+  return true
 }
 
-function checkVideoChannelIsNotTheLastOne (res: express.Response, callback: () => void) {
-  db.VideoChannel.countByAccount(res.locals.oauth.token.User.Account.id)
-    .then(count => {
-      if (count <= 1) {
-        return res.status(409)
-          .json({ error: 'Cannot remove the last channel of this user' })
-          .end()
-      }
-
-      callback()
-    })
+async function checkVideoChannelIsNotTheLastOne (res: express.Response) {
+  const count = await db.VideoChannel.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()
+
+    return false
+  }
+
+  return true
 }
index 5ffc85210502cf8062d98bbd4a820d89f9948f25..3cbf98312bb0a71c5658e76abb1c5d70f907647d 100644 (file)
@@ -3,11 +3,11 @@ import { body, param, query } from 'express-validator/check'
 import { UserRight, VideoPrivacy } from '../../../shared'
 import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
 import {
-  checkVideoExists,
   isVideoAbuseReasonValid,
   isVideoCategoryValid,
   isVideoDescriptionValid,
   isVideoDurationValid,
+  isVideoExist,
   isVideoFile,
   isVideoLanguageValid,
   isVideoLicenceValid,
@@ -20,12 +20,11 @@ import {
 import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
 import { logger } from '../../helpers/logger'
 import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
-
 import { database as db } from '../../initializers/database'
 import { UserInstance } from '../../models/account/user-interface'
+import { VideoInstance } from '../../models/video/video-interface'
 import { authenticate } from '../oauth'
-import { areValidationErrors, checkErrors } from './utils'
-import { isVideoExistsPromise } from '../../helpers/index'
+import { areValidationErrors } from './utils'
 
 const videosAddValidator = [
   body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage(
@@ -42,68 +41,58 @@ const videosAddValidator = [
   body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
   body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
 
-    checkErrors(req, res, () => {
-      const videoFile: Express.Multer.File = req.files['videofile'][0]
-      const user = res.locals.oauth.token.User
+    if (areValidationErrors(req, res)) return
+
+    const videoFile: Express.Multer.File = req.files['videofile'][0]
+    const user = res.locals.oauth.token.User
 
-      return db.VideoChannel.loadByIdAndAccount(req.body.channelId, user.Account.id)
-        .then(videoChannel => {
-          if (!videoChannel) {
-            res.status(400)
-              .json({ error: 'Unknown video video channel for this account.' })
-              .end()
+    const videoChannel = await db.VideoChannel.loadByIdAndAccount(req.body.channelId, user.Account.id)
+    if (!videoChannel) {
+      res.status(400)
+        .json({ error: 'Unknown video video channel for this account.' })
+        .end()
 
-            return undefined
-          }
-
-          res.locals.videoChannel = videoChannel
-
-          return user.isAbleToUploadVideo(videoFile)
-        })
-        .then(isAble => {
-          if (isAble === false) {
-            res.status(403)
-               .json({ error: 'The user video quota is exceeded with this video.' })
-               .end()
-
-            return undefined
-          }
-
-          return getDurationFromVideoFile(videoFile.path)
-            .catch(err => {
-              logger.error('Invalid input file in videosAddValidator.', err)
-              res.status(400)
-                 .json({ error: 'Invalid input file.' })
-                 .end()
-
-              return undefined
-            })
-        })
-        .then(duration => {
-          // Previous test failed, abort
-          if (duration === undefined) return undefined
-
-          if (!isVideoDurationValid('' + duration)) {
-            return res.status(400)
-                      .json({
-                        error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).'
-                      })
-                      .end()
-          }
-
-          videoFile['duration'] = duration
-          next()
-        })
-        .catch(err => {
-          logger.error('Error in video add validator', err)
-          res.sendStatus(500)
-
-          return undefined
-        })
-    })
+      return
+    }
+
+    res.locals.videoChannel = videoChannel
+
+    const isAble = await user.isAbleToUploadVideo(videoFile)
+    if (isAble === false) {
+      res.status(403)
+         .json({ error: 'The user video quota is exceeded with this video.' })
+         .end()
+
+      return
+    }
+
+    let duration: number
+
+    try {
+      duration = await getDurationFromVideoFile(videoFile.path)
+    } catch (err) {
+      logger.error('Invalid input file in videosAddValidator.', err)
+      res.status(400)
+         .json({ error: 'Invalid input file.' })
+         .end()
+
+      return
+    }
+
+    if (!isVideoDurationValid('' + duration)) {
+      return res.status(400)
+                .json({
+                  error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).'
+                })
+                .end()
+    }
+
+    videoFile['duration'] = duration
+
+    return next()
   }
 ]
 
@@ -118,61 +107,59 @@ const videosUpdateValidator = [
   body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
   body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosUpdate parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.id, res, () => {
-        const video = res.locals.video
-
-        // We need to make additional checks
-        if (video.isOwned() === false) {
-          return res.status(403)
-                    .json({ error: 'Cannot update video of another server' })
-                    .end()
-        }
-
-        if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
-          return res.status(403)
-                    .json({ error: 'Cannot update video of another user' })
-                    .end()
-        }
-
-        if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) {
-          return res.status(409)
-            .json({ error: 'Cannot set "private" a video that was not private anymore.' })
-            .end()
-        }
-
-        next()
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
+
+    const video = res.locals.video
+
+    // We need to make additional checks
+    if (video.isOwned() === false) {
+      return res.status(403)
+                .json({ error: 'Cannot update video of another server' })
+                .end()
+    }
+
+    if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
+      return res.status(403)
+                .json({ error: 'Cannot update video of another user' })
+                .end()
+    }
+
+    if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) {
+      return res.status(409)
+        .json({ error: 'Cannot set "private" a video that was not private anymore.' })
+        .end()
+    }
+
+    return next()
   }
 ]
 
 const videosGetValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosGet parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.id, res, () => {
-        const video = res.locals.video
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
 
-        // Video is not private, anyone can access it
-        if (video.privacy !== VideoPrivacy.PRIVATE) return next()
+    const video = res.locals.video
 
-        authenticate(req, res, () => {
-          if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
-            return res.status(403)
-              .json({ error: 'Cannot get this private video of another user' })
-              .end()
-          }
+    // Video is not private, anyone can access it
+    if (video.privacy !== VideoPrivacy.PRIVATE) return next()
 
-          next()
-        })
-      })
+    authenticate(req, res, () => {
+      if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
+        return res.status(403)
+          .json({ error: 'Cannot get this private video of another user' })
+          .end()
+      }
+
+      return next()
     })
   }
 ]
@@ -180,17 +167,16 @@ const videosGetValidator = [
 const videosRemoveValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosRemove parameters', { parameters: req.params })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.id, res, () => {
-        // Check if the user who did the request is able to delete the video
-        checkUserCanDeleteVideo(res.locals.oauth.token.User, res, () => {
-          next()
-        })
-      })
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
+
+    // Check if the user who did the request is able to delete the video
+    if (!checkUserCanDeleteVideo(res.locals.oauth.token.User, res.locals.video, res)) return
+
+    return next()
   }
 ]
 
@@ -201,7 +187,9 @@ const videosSearchValidator = [
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videosSearch parameters', { parameters: req.params })
 
-    checkErrors(req, res, next)
+    if (areValidationErrors(req, res)) return
+
+    return next()
   }
 ]
 
@@ -209,12 +197,13 @@ const videoAbuseReportValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
   body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.id, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
@@ -222,12 +211,13 @@ const videoRateValidator = [
   param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
   body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking videoRate parameters', { parameters: req.body })
 
-    checkErrors(req, res, () => {
-      checkVideoExists(req.params.id, res, next)
-    })
+    if (areValidationErrors(req, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
+
+    return next()
   }
 ]
 
@@ -239,7 +229,7 @@ const videosShareValidator = [
     logger.debug('Checking videoShare parameters', { parameters: req.params })
 
     if (areValidationErrors(req, res)) return
-    if (!await isVideoExistsPromise(req.params.id, res)) return
+    if (!await isVideoExist(req.params.id, res)) return
 
     const share = await db.VideoShare.load(req.params.accountId, res.locals.video.id)
     if (!share) {
@@ -248,7 +238,6 @@ const videosShareValidator = [
     }
 
     res.locals.videoShare = share
-
     return next()
   }
 ]
@@ -270,24 +259,25 @@ export {
 
 // ---------------------------------------------------------------------------
 
-function checkUserCanDeleteVideo (user: UserInstance, res: express.Response, callback: () => void) {
+function checkUserCanDeleteVideo (user: UserInstance, video: VideoInstance, res: express.Response) {
   // Retrieve the user who did the request
-  if (res.locals.video.isOwned() === false) {
-    return res.status(403)
+  if (video.isOwned() === false) {
+    res.status(403)
               .json({ error: 'Cannot remove video of another server, blacklist it' })
               .end()
+    return false
   }
 
   // Check if the user can delete the video
   // The user can delete it if s/he is an admin
   // Or if s/he is the video's account
-  const account = res.locals.video.VideoChannel.Account
+  const account = video.VideoChannel.Account
   if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && account.userId !== user.id) {
-    return res.status(403)
+    res.status(403)
               .json({ error: 'Cannot remove video of another user' })
               .end()
+    return false
   }
 
-  // If we reach this comment, we can delete the video
-  callback()
+  return true
 }
index 7852c1c2b43de881de9b72f8f66dacef3943775b..34e62c66dc6a5cfb0d7851891b8d8e0a40c05a4e 100644 (file)
@@ -1,37 +1,31 @@
 import * as express from 'express'
 import { query } from 'express-validator/check'
 import { isWebfingerResourceValid } from '../../helpers/custom-validators/webfinger'
-import { database as db } from '../../initializers'
-import { checkErrors } from './utils'
 import { logger } from '../../helpers/logger'
+import { database as db } from '../../initializers'
+import { areValidationErrors } from './utils'
 
 const webfingerValidator = [
   query('resource').custom(isWebfingerResourceValid).withMessage('Should have a valid webfinger resource'),
 
-  (req: express.Request, res: express.Response, next: express.NextFunction) => {
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking webfinger parameters', { parameters: req.query })
 
-    checkErrors(req, res, () => {
-      // Remove 'acct:' from the beginning of the string
-      const nameWithHost = req.query.resource.substr(5)
-      const [ name ] = nameWithHost.split('@')
-
-      db.Account.loadLocalByName(name)
-        .then(account => {
-          if (!account) {
-            return res.status(404)
-              .send({ error: 'Account not found' })
-              .end()
-          }
-
-          res.locals.account = account
-          return next()
-        })
-        .catch(err => {
-          logger.error('Error in webfinger validator.', err)
-          return res.sendStatus(500)
-        })
-    })
+    if (areValidationErrors(req, res)) return
+
+    // Remove 'acct:' from the beginning of the string
+    const nameWithHost = req.query.resource.substr(5)
+    const [ name ] = nameWithHost.split('@')
+
+    const account = await db.Account.loadLocalByName(name)
+    if (!account) {
+      return res.status(404)
+        .send({ error: 'Account not found' })
+        .end()
+    }
+
+    res.locals.account = account
+    return next()
   }
 ]
 
index fff3ce08799b147062c8f6df2dad8a33ca0da283..c721656cbe26ce1885ebfacc42941604ba58f15f 100644 (file)
@@ -2,17 +2,12 @@ import * as Sequelize from 'sequelize'
 import {
   activityPubContextify,
   isAccountFollowersCountValid,
-  isAccountFollowersValid,
   isAccountFollowingCountValid,
-  isAccountFollowingValid,
-  isAccountInboxValid,
-  isAccountOutboxValid,
   isAccountPrivateKeyValid,
   isAccountPublicKeyValid,
-  isAccountSharedInboxValid,
-  isAccountUrlValid,
   isUserUsernameValid
 } from '../../helpers'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants'
 import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete'
 
@@ -61,7 +56,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           urlValid: value => {
-            const res = isAccountUrlValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('URL is not valid.')
           }
         }
@@ -111,7 +106,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           inboxUrlValid: value => {
-            const res = isAccountInboxValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Inbox URL is not valid.')
           }
         }
@@ -121,7 +116,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           outboxUrlValid: value => {
-            const res = isAccountOutboxValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Outbox URL is not valid.')
           }
         }
@@ -131,7 +126,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           sharedInboxUrlValid: value => {
-            const res = isAccountSharedInboxValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Shared inbox URL is not valid.')
           }
         }
@@ -141,7 +136,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           followersUrlValid: value => {
-            const res = isAccountFollowersValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Followers URL is not valid.')
           }
         }
@@ -151,7 +146,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
         allowNull: false,
         validate: {
           followingUrlValid: value => {
-            const res = isAccountFollowingValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Following URL is not valid.')
           }
         }
index e11268b2c2d1e926636ccce0377adc904511e194..54f12dce3216273d17925ea1e2eaca21e1f9ebc2 100644 (file)
@@ -1,6 +1,5 @@
 import * as Sequelize from 'sequelize'
 import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers'
-import { isVideoChannelUrlValid } from '../../helpers/custom-validators/video-channels'
 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
 import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete'
 
@@ -8,6 +7,7 @@ import { addMethodsToModel, getSort } from '../utils'
 import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface'
 import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
 import { activityPubCollection } from '../../helpers/activitypub'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 
 let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes>
 let toFormattedJSON: VideoChannelMethods.ToFormattedJSON
@@ -66,7 +66,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
         allowNull: false,
         validate: {
           urlValid: value => {
-            const res = isVideoChannelUrlValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Video channel URL is not valid.')
           }
         }
index 4956b57eed975b920721f5aac9f607b0a785e284..3f416d04cc6655438133592ebbb1e69259b0c544 100644 (file)
@@ -7,7 +7,18 @@ import * as Sequelize from 'sequelize'
 import { VideoPrivacy, VideoResolution } from '../../../shared'
 import { VideoTorrentObject } from '../../../shared/models/activitypub/objects/video-torrent-object'
 import { activityPubCollection } from '../../helpers/activitypub'
-import { isVideoCategoryValid, isVideoLanguageValid, isVideoPrivacyValid, isVideoUrlValid } from '../../helpers/custom-validators/videos'
+import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils'
+import { isVideoCategoryValid, isVideoLanguageValid, isVideoPrivacyValid } from '../../helpers/custom-validators/videos'
+import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils'
+import {
+  isActivityPubUrlValid,
+  isVideoDescriptionValid,
+  isVideoDurationValid,
+  isVideoLicenceValid,
+  isVideoNameValid,
+  isVideoNSFWValid
+} from '../../helpers/index'
+import { logger } from '../../helpers/logger'
 import {
   API_VERSION,
   CONFIG,
@@ -21,18 +32,12 @@ import {
   VIDEO_LICENCES,
   VIDEO_PRIVACIES
 } from '../../initializers/constants'
+import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
 import { sendDeleteVideo } from '../../lib/index'
-
 import { addMethodsToModel, getSort } from '../utils'
-
 import { TagInstance } from './tag-interface'
 import { VideoFileInstance, VideoFileModel } from './video-file-interface'
 import { VideoAttributes, VideoInstance, VideoMethods } from './video-interface'
-import { isVideoNameValid, isVideoLicenceValid, isVideoNSFWValid, isVideoDescriptionValid, isVideoDurationValid } from '../../helpers/index'
-import { logger } from '../../helpers/logger'
-import { generateImageFromVideoFile, transcode, getVideoFileHeight } from '../../helpers/ffmpeg-utils'
-import { createTorrentPromise, writeFilePromise, unlinkPromise, renamePromise, statPromise } from '../../helpers/core-utils'
-import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
 
 let Video: Sequelize.Model<VideoInstance, VideoAttributes>
 let getOriginalFile: VideoMethods.GetOriginalFile
@@ -205,7 +210,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
         allowNull: false,
         validate: {
           urlValid: value => {
-            const res = isVideoUrlValid(value)
+            const res = isActivityPubUrlValid(value)
             if (res === false) throw new Error('Video URL is not valid.')
           }
         }
index f0ed62acc377ebc185e6ed2e3a20d340e66b05c5..7233eaf5bfb3814da54bfd34d412f2e3a2121d83 100644 (file)
@@ -55,10 +55,10 @@ If you want to test the decentralization feature, you can easily run 3 instances
 
 The server is composed by:
 
-  * a REST API (throught Express framework)
+  * a REST API (Express framework)
   * a WebTorrent Tracker
 
-A video is seeded by the server throught the [WebSeed](http://www.bittorrent.org/beps/bep_0019.html) protocol (HTTP).
+A video is seeded by the server with the [WebSeed](http://www.bittorrent.org/beps/bep_0019.html) protocol (HTTP).
 
 ![Architecture scheme](https://github.com/Chocobozzz/PeerTube/blob/master/support/doc/server/upload-video.png)