import { getServerActor } from '@server/models/application/application'
import { ExpressPromiseHandler } from '@server/types/express'
import { MUserAccountId, MVideoFullLight } from '@server/types/models'
+import { getAllPrivacies } from '@shared/core-utils'
import { VideoInclude } from '@shared/models'
import { ServerErrorCode, UserRight, VideoPrivacy } from '../../../../shared'
import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
import { isLocalVideoAccepted } from '../../../lib/moderation'
import { Hooks } from '../../../lib/plugins/hooks'
import { VideoModel } from '../../../models/video/video'
-import { authenticatePromiseIfNeeded } from '../../auth'
import {
areValidationErrors,
+ checkCanSeePrivateVideo,
checkUserCanManageVideo,
doesVideoChannelOfAccountExist,
doesVideoExist,
}
])
+const videosResumableUploadIdValidator = [
+ (req: express.Request, res: express.Response, next: express.NextFunction) => {
+ const user = res.locals.oauth.token.User
+ const uploadId = req.query.upload_id
+
+ if (uploadId.startsWith(user.id + '-') !== true) {
+ return res.fail({
+ status: HttpStatusCode.FORBIDDEN_403,
+ message: 'You cannot send chunks in another user upload'
+ })
+ }
+
+ return next()
+ }
+]
+
/**
* Gets called after the last PUT request
*/
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
const user = res.locals.oauth.token.User
const body: express.CustomUploadXFile<express.UploadXFileMetadata> = req.body
- const file = { ...body, duration: undefined, path: getResumableUploadPath(body.id), filename: body.metadata.filename }
+ const file = { ...body, duration: undefined, path: getResumableUploadPath(body.name), filename: body.metadata.filename }
const cleanup = () => deleteFileAndCatch(file.path)
const uploadId = req.query.upload_id
const videoFileMetadata = {
mimetype: req.headers['x-upload-content-type'] as string,
size: +req.headers['x-upload-content-length'],
- originalname: req.body.name
+ originalname: req.body.filename
}
const user = res.locals.oauth.token.User
// Video private or blacklisted
if (video.requiresAuth()) {
- await authenticatePromiseIfNeeded(req, res, authenticateInQuery)
-
- const user = res.locals.oauth ? res.locals.oauth.token.User : null
-
- // Only the owner or a user that have blocklist rights can see the video
- if (!user || !user.canGetVideo(video)) {
- return res.fail({
- status: HttpStatusCode.FORBIDDEN_403,
- message: 'Cannot get this private/internal or blocklisted video'
- })
- }
+ if (await checkCanSeePrivateVideo(req, res, video, authenticateInQuery)) return next()
- return next()
+ return res.fail({
+ status: HttpStatusCode.FORBIDDEN_403,
+ message: 'Cannot get this private/internal or blocklisted video'
+ })
}
// Video is public, anyone can access it
.optional()
.customSanitizer(toArray)
.custom(isStringArray).withMessage('Should have a valid one of language array'),
+ query('privacyOneOf')
+ .optional()
+ .customSanitizer(toArray)
+ .custom(isNumberArray).withMessage('Should have a valid one of privacy array'),
query('tagsOneOf')
.optional()
.customSanitizer(toArray)
.optional()
.customSanitizer(toBooleanOrNull)
.custom(isBooleanValid).withMessage('Should have a valid local boolean'),
+ query('hasHLSFiles')
+ .optional()
+ .customSanitizer(toBooleanOrNull)
+ .custom(isBooleanValid).withMessage('Should have a valid has hls boolean'),
+ query('hasWebtorrentFiles')
+ .optional()
+ .customSanitizer(toBooleanOrNull)
+ .custom(isBooleanValid).withMessage('Should have a valid has webtorrent boolean'),
query('skipCount')
.optional()
.customSanitizer(toBooleanOrNull)
// FIXME: deprecated in 4.0, to remove
{
if (req.query.filter === 'all-local') {
- req.query.include = VideoInclude.NOT_PUBLISHED_STATE | VideoInclude.HIDDEN_PRIVACY
+ req.query.include = VideoInclude.NOT_PUBLISHED_STATE
req.query.isLocal = true
+ req.query.privacyOneOf = getAllPrivacies()
} else if (req.query.filter === 'all') {
- req.query.include = VideoInclude.NOT_PUBLISHED_STATE | VideoInclude.HIDDEN_PRIVACY
+ req.query.include = VideoInclude.NOT_PUBLISHED_STATE
+ req.query.privacyOneOf = getAllPrivacies()
} else if (req.query.filter === 'local') {
req.query.isLocal = true
}
const user = res.locals.oauth?.token.User
- if (req.query.include && (!user || user.hasRight(UserRight.SEE_ALL_VIDEOS) !== true)) {
- res.fail({
- status: HttpStatusCode.UNAUTHORIZED_401,
- message: 'You are not allowed to see all local videos.'
- })
- return
+ if ((!user || user.hasRight(UserRight.SEE_ALL_VIDEOS) !== true)) {
+ if (req.query.include || req.query.privacyOneOf) {
+ return res.fail({
+ status: HttpStatusCode.UNAUTHORIZED_401,
+ message: 'You are not allowed to see all videos.'
+ })
+ }
}
return next()
videosAddLegacyValidator,
videosAddResumableValidator,
videosAddResumableInitValidator,
+ videosResumableUploadIdValidator,
videosUpdateValidator,
videosGetValidator,