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