From 156c50af3085468a47b8ae73fe8cfcae46b42398 Mon Sep 17 00:00:00 2001 From: Lucas Declercq Date: Sat, 6 Oct 2018 19:17:21 +0200 Subject: Add downloadingEnabled property to video model --- server/helpers/activitypub.ts | 1 + server/helpers/audit-logger.ts | 3 ++- server/helpers/custom-validators/activitypub/videos.ts | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index 1304c7559..7f903e486 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -28,6 +28,7 @@ function activityPubContextify (data: T) { size: 'schema:Number', fps: 'schema:Number', commentsEnabled: 'schema:Boolean', + downloadingEnabled: 'schema:Boolean', waitTranscoding: 'schema:Boolean', expires: 'schema:expires', support: 'schema:Text', diff --git a/server/helpers/audit-logger.ts b/server/helpers/audit-logger.ts index 00311fce1..d2c9aee01 100644 --- a/server/helpers/audit-logger.ts +++ b/server/helpers/audit-logger.ts @@ -117,7 +117,8 @@ const videoKeysToKeep = [ 'channel-uuid', 'channel-name', 'support', - 'commentsEnabled' + 'commentsEnabled', + 'downloadingEnabled' ] class VideoAuditView extends EntityAuditView { constructor (private video: VideoDetails) { diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index f88d26561..34e4cdff9 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -67,6 +67,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) { isVideoViewsValid(video.views) && isBooleanValid(video.sensitive) && isBooleanValid(video.commentsEnabled) && + isBooleanValid(video.downloadingEnabled) && isDateValid(video.published) && isDateValid(video.updated) && (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) && -- cgit v1.2.3 From 4ffdcfc63b8c804a0aea20609544c859ab57318b Mon Sep 17 00:00:00 2001 From: Lucas Declercq Date: Mon, 8 Oct 2018 14:42:55 +0200 Subject: Fix some defaults values + indentation --- server/helpers/custom-validators/activitypub/videos.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'server/helpers') diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 34e4cdff9..59964f91a 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -56,6 +56,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) { // Default attributes if (!isVideoStateValid(video.state)) video.state = VideoState.PUBLISHED if (!isBooleanValid(video.waitTranscoding)) video.waitTranscoding = false + if (!isBooleanValid(video.downloadingEnabled)) video.downloadingEnabled = true return isActivityPubUrlValid(video.id) && isVideoNameValid(video.name) && -- cgit v1.2.3 From 7f2cfe3a792856f7de6f1d13688aa3d06ec1bf70 Mon Sep 17 00:00:00 2001 From: Lucas Declercq Date: Mon, 8 Oct 2018 14:45:22 +0200 Subject: Rename downloadingEnabled property to downloadEnabled --- server/helpers/activitypub.ts | 2 +- server/helpers/audit-logger.ts | 2 +- server/helpers/custom-validators/activitypub/videos.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index 7f903e486..2469b37b1 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -28,7 +28,7 @@ function activityPubContextify (data: T) { size: 'schema:Number', fps: 'schema:Number', commentsEnabled: 'schema:Boolean', - downloadingEnabled: 'schema:Boolean', + downloadEnabled: 'schema:Boolean', waitTranscoding: 'schema:Boolean', expires: 'schema:expires', support: 'schema:Text', diff --git a/server/helpers/audit-logger.ts b/server/helpers/audit-logger.ts index d2c9aee01..a121f0b8a 100644 --- a/server/helpers/audit-logger.ts +++ b/server/helpers/audit-logger.ts @@ -118,7 +118,7 @@ const videoKeysToKeep = [ 'channel-name', 'support', 'commentsEnabled', - 'downloadingEnabled' + 'downloadEnabled' ] class VideoAuditView extends EntityAuditView { constructor (private video: VideoDetails) { diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 59964f91a..5015c59dd 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -56,7 +56,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) { // Default attributes if (!isVideoStateValid(video.state)) video.state = VideoState.PUBLISHED if (!isBooleanValid(video.waitTranscoding)) video.waitTranscoding = false - if (!isBooleanValid(video.downloadingEnabled)) video.downloadingEnabled = true + if (!isBooleanValid(video.downloadEnabled)) video.downloadEnabled = true return isActivityPubUrlValid(video.id) && isVideoNameValid(video.name) && @@ -68,7 +68,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) { isVideoViewsValid(video.views) && isBooleanValid(video.sensitive) && isBooleanValid(video.commentsEnabled) && - isBooleanValid(video.downloadingEnabled) && + isBooleanValid(video.downloadEnabled) && isDateValid(video.published) && isDateValid(video.updated) && (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) && -- cgit v1.2.3 From 848f499def54db2dd36437ef0dfb74dd5041c23b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 15 Jan 2019 11:14:12 +0100 Subject: Prepare Dislike/Flag/View fixes For now we Create these activities, but we should just send them directly. This fix handles correctly direct Dislikes/Flags/Views, we'll implement the sending correctly these activities in the next peertube version --- server/helpers/activitypub.ts | 4 +- .../custom-validators/activitypub/activity.ts | 99 +++++++++++++--------- .../helpers/custom-validators/activitypub/actor.ts | 25 +----- .../custom-validators/activitypub/announce.ts | 13 --- .../custom-validators/activitypub/cache-file.ts | 16 +--- .../helpers/custom-validators/activitypub/flag.ts | 14 +++ .../helpers/custom-validators/activitypub/misc.ts | 24 ++++-- .../helpers/custom-validators/activitypub/rate.ts | 15 +--- .../helpers/custom-validators/activitypub/undo.ts | 20 ----- .../activitypub/video-comments.ts | 11 --- .../custom-validators/activitypub/videos.ts | 19 ----- .../helpers/custom-validators/activitypub/view.ts | 10 +-- 12 files changed, 107 insertions(+), 163 deletions(-) delete mode 100644 server/helpers/custom-validators/activitypub/announce.ts create mode 100644 server/helpers/custom-validators/activitypub/flag.ts delete mode 100644 server/helpers/custom-validators/activitypub/undo.ts (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index 79b76fa0b..f1430055f 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -106,7 +106,7 @@ function buildSignedActivity (byActor: ActorModel, data: Object) { return signJsonLDObject(byActor, activity) as Promise } -function getAPUrl (activity: string | { id: string }) { +function getAPId (activity: string | { id: string }) { if (typeof activity === 'string') return activity return activity.id @@ -123,7 +123,7 @@ function checkUrlsSameHost (url1: string, url2: string) { export { checkUrlsSameHost, - getAPUrl, + getAPId, activityPubContextify, activityPubCollectionPagination, buildSignedActivity diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts index 2562ead9b..b24590d9d 100644 --- a/server/helpers/custom-validators/activitypub/activity.ts +++ b/server/helpers/custom-validators/activitypub/activity.ts @@ -1,26 +1,14 @@ import * as validator from 'validator' import { Activity, ActivityType } from '../../../../shared/models/activitypub' -import { - isActorAcceptActivityValid, - isActorDeleteActivityValid, - isActorFollowActivityValid, - isActorRejectActivityValid, - isActorUpdateActivityValid -} from './actor' -import { isAnnounceActivityValid } from './announce' -import { isActivityPubUrlValid } from './misc' -import { isDislikeActivityValid, isLikeActivityValid } from './rate' -import { isUndoActivityValid } from './undo' -import { isVideoCommentCreateActivityValid, isVideoCommentDeleteActivityValid } from './video-comments' -import { - isVideoFlagValid, - isVideoTorrentDeleteActivityValid, - sanitizeAndCheckVideoTorrentCreateActivity, - sanitizeAndCheckVideoTorrentUpdateActivity -} from './videos' +import { sanitizeAndCheckActorObject } from './actor' +import { isActivityPubUrlValid, isBaseActivityValid, isObjectValid } from './misc' +import { isDislikeActivityValid } from './rate' +import { sanitizeAndCheckVideoCommentObject } from './video-comments' +import { sanitizeAndCheckVideoTorrentObject } from './videos' import { isViewActivityValid } from './view' import { exists } from '../misc' -import { isCacheFileCreateActivityValid, isCacheFileUpdateActivityValid } from './cache-file' +import { isCacheFileObjectValid } from './cache-file' +import { isFlagActivityValid } from './flag' function isRootActivityValid (activity: any) { return Array.isArray(activity['@context']) && ( @@ -46,7 +34,10 @@ const activityCheckers: { [ P in ActivityType ]: (activity: Activity) => boolean Reject: checkRejectActivity, Announce: checkAnnounceActivity, Undo: checkUndoActivity, - Like: checkLikeActivity + Like: checkLikeActivity, + View: checkViewActivity, + Flag: checkFlagActivity, + Dislike: checkDislikeActivity } function isActivityValid (activity: any) { @@ -66,47 +57,79 @@ export { // --------------------------------------------------------------------------- +function checkViewActivity (activity: any) { + return isBaseActivityValid(activity, 'View') && + isViewActivityValid(activity) +} + +function checkFlagActivity (activity: any) { + return isBaseActivityValid(activity, 'Flag') && + isFlagActivityValid(activity) +} + +function checkDislikeActivity (activity: any) { + return isBaseActivityValid(activity, 'Dislike') && + isDislikeActivityValid(activity) +} + function checkCreateActivity (activity: any) { - return isViewActivityValid(activity) || - isDislikeActivityValid(activity) || - sanitizeAndCheckVideoTorrentCreateActivity(activity) || - isVideoFlagValid(activity) || - isVideoCommentCreateActivityValid(activity) || - isCacheFileCreateActivityValid(activity) + return isBaseActivityValid(activity, 'Create') && + ( + isViewActivityValid(activity.object) || + isDislikeActivityValid(activity.object) || + isFlagActivityValid(activity.object) || + + isCacheFileObjectValid(activity.object) || + sanitizeAndCheckVideoCommentObject(activity.object) || + sanitizeAndCheckVideoTorrentObject(activity.object) + ) } function checkUpdateActivity (activity: any) { - return isCacheFileUpdateActivityValid(activity) || - sanitizeAndCheckVideoTorrentUpdateActivity(activity) || - isActorUpdateActivityValid(activity) + return isBaseActivityValid(activity, 'Update') && + ( + isCacheFileObjectValid(activity.object) || + sanitizeAndCheckVideoTorrentObject(activity.object) || + sanitizeAndCheckActorObject(activity.object) + ) } function checkDeleteActivity (activity: any) { - return isVideoTorrentDeleteActivityValid(activity) || - isActorDeleteActivityValid(activity) || - isVideoCommentDeleteActivityValid(activity) + // We don't really check objects + return isBaseActivityValid(activity, 'Delete') && + isObjectValid(activity.object) } function checkFollowActivity (activity: any) { - return isActorFollowActivityValid(activity) + return isBaseActivityValid(activity, 'Follow') && + isObjectValid(activity.object) } function checkAcceptActivity (activity: any) { - return isActorAcceptActivityValid(activity) + return isBaseActivityValid(activity, 'Accept') } function checkRejectActivity (activity: any) { - return isActorRejectActivityValid(activity) + return isBaseActivityValid(activity, 'Reject') } function checkAnnounceActivity (activity: any) { - return isAnnounceActivityValid(activity) + return isBaseActivityValid(activity, 'Announce') && + isObjectValid(activity.object) } function checkUndoActivity (activity: any) { - return isUndoActivityValid(activity) + return isBaseActivityValid(activity, 'Undo') && + ( + checkFollowActivity(activity.object) || + checkLikeActivity(activity.object) || + checkDislikeActivity(activity.object) || + checkAnnounceActivity(activity.object) || + checkCreateActivity(activity.object) + ) } function checkLikeActivity (activity: any) { - return isLikeActivityValid(activity) + return isBaseActivityValid(activity, 'Like') && + isObjectValid(activity.object) } diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts index 070632a20..c05f60f14 100644 --- a/server/helpers/custom-validators/activitypub/actor.ts +++ b/server/helpers/custom-validators/activitypub/actor.ts @@ -73,24 +73,10 @@ function isActorDeleteActivityValid (activity: any) { return isBaseActivityValid(activity, 'Delete') } -function isActorFollowActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Follow') && - isActivityPubUrlValid(activity.object) -} - -function isActorAcceptActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Accept') -} - -function isActorRejectActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Reject') -} - -function isActorUpdateActivityValid (activity: any) { - normalizeActor(activity.object) +function sanitizeAndCheckActorObject (object: any) { + normalizeActor(object) - return isBaseActivityValid(activity, 'Update') && - isActorObjectValid(activity.object) + return isActorObjectValid(object) } function normalizeActor (actor: any) { @@ -139,10 +125,7 @@ export { isActorObjectValid, isActorFollowingCountValid, isActorFollowersCountValid, - isActorFollowActivityValid, - isActorAcceptActivityValid, - isActorRejectActivityValid, isActorDeleteActivityValid, - isActorUpdateActivityValid, + sanitizeAndCheckActorObject, isValidActorHandle } diff --git a/server/helpers/custom-validators/activitypub/announce.ts b/server/helpers/custom-validators/activitypub/announce.ts deleted file mode 100644 index 0519c6026..000000000 --- a/server/helpers/custom-validators/activitypub/announce.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { isActivityPubUrlValid, isBaseActivityValid } from './misc' - -function isAnnounceActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Announce') && - ( - isActivityPubUrlValid(activity.object) || - (activity.object && isActivityPubUrlValid(activity.object.id)) - ) -} - -export { - isAnnounceActivityValid -} diff --git a/server/helpers/custom-validators/activitypub/cache-file.ts b/server/helpers/custom-validators/activitypub/cache-file.ts index bd70934c8..e2bd0c55e 100644 --- a/server/helpers/custom-validators/activitypub/cache-file.ts +++ b/server/helpers/custom-validators/activitypub/cache-file.ts @@ -1,18 +1,8 @@ -import { isActivityPubUrlValid, isBaseActivityValid } from './misc' +import { isActivityPubUrlValid } from './misc' import { isRemoteVideoUrlValid } from './videos' -import { isDateValid, exists } from '../misc' +import { exists, isDateValid } from '../misc' import { CacheFileObject } from '../../../../shared/models/activitypub/objects' -function isCacheFileCreateActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Create') && - isCacheFileObjectValid(activity.object) -} - -function isCacheFileUpdateActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Update') && - isCacheFileObjectValid(activity.object) -} - function isCacheFileObjectValid (object: CacheFileObject) { return exists(object) && object.type === 'CacheFile' && @@ -22,7 +12,5 @@ function isCacheFileObjectValid (object: CacheFileObject) { } export { - isCacheFileUpdateActivityValid, - isCacheFileCreateActivityValid, isCacheFileObjectValid } diff --git a/server/helpers/custom-validators/activitypub/flag.ts b/server/helpers/custom-validators/activitypub/flag.ts new file mode 100644 index 000000000..6452e297c --- /dev/null +++ b/server/helpers/custom-validators/activitypub/flag.ts @@ -0,0 +1,14 @@ +import { isActivityPubUrlValid } from './misc' +import { isVideoAbuseReasonValid } from '../video-abuses' + +function isFlagActivityValid (activity: any) { + return activity.type === 'Flag' && + isVideoAbuseReasonValid(activity.content) && + isActivityPubUrlValid(activity.object) +} + +// --------------------------------------------------------------------------- + +export { + isFlagActivityValid +} diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts index 4e2c57f04..f1762d11c 100644 --- a/server/helpers/custom-validators/activitypub/misc.ts +++ b/server/helpers/custom-validators/activitypub/misc.ts @@ -28,15 +28,20 @@ function isBaseActivityValid (activity: any, type: string) { return (activity['@context'] === undefined || Array.isArray(activity['@context'])) && activity.type === type && isActivityPubUrlValid(activity.id) && - exists(activity.actor) && - (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id)) && - ( - activity.to === undefined || - (Array.isArray(activity.to) && activity.to.every(t => isActivityPubUrlValid(t))) - ) && + isObjectValid(activity.actor) && + isUrlCollectionValid(activity.to) && + isUrlCollectionValid(activity.cc) +} + +function isUrlCollectionValid (collection: any) { + return collection === undefined || + (Array.isArray(collection) && collection.every(t => isActivityPubUrlValid(t))) +} + +function isObjectValid (object: any) { + return exists(object) && ( - activity.cc === undefined || - (Array.isArray(activity.cc) && activity.cc.every(t => isActivityPubUrlValid(t))) + isActivityPubUrlValid(object) || isActivityPubUrlValid(object.id) ) } @@ -57,5 +62,6 @@ export { isUrlValid, isActivityPubUrlValid, isBaseActivityValid, - setValidAttributedTo + setValidAttributedTo, + isObjectValid } diff --git a/server/helpers/custom-validators/activitypub/rate.ts b/server/helpers/custom-validators/activitypub/rate.ts index e70bd94b8..ba68e8074 100644 --- a/server/helpers/custom-validators/activitypub/rate.ts +++ b/server/helpers/custom-validators/activitypub/rate.ts @@ -1,20 +1,13 @@ -import { isActivityPubUrlValid, isBaseActivityValid } from './misc' - -function isLikeActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Like') && - isActivityPubUrlValid(activity.object) -} +import { isActivityPubUrlValid, isObjectValid } from './misc' function isDislikeActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Create') && - activity.object.type === 'Dislike' && - isActivityPubUrlValid(activity.object.actor) && - isActivityPubUrlValid(activity.object.object) + return activity.type === 'Dislike' && + isActivityPubUrlValid(activity.actor) && + isObjectValid(activity.object) } // --------------------------------------------------------------------------- export { - isLikeActivityValid, isDislikeActivityValid } diff --git a/server/helpers/custom-validators/activitypub/undo.ts b/server/helpers/custom-validators/activitypub/undo.ts deleted file mode 100644 index 578035893..000000000 --- a/server/helpers/custom-validators/activitypub/undo.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { isActorFollowActivityValid } from './actor' -import { isBaseActivityValid } from './misc' -import { isDislikeActivityValid, isLikeActivityValid } from './rate' -import { isAnnounceActivityValid } from './announce' -import { isCacheFileCreateActivityValid } from './cache-file' - -function isUndoActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Undo') && - ( - isActorFollowActivityValid(activity.object) || - isLikeActivityValid(activity.object) || - isDislikeActivityValid(activity.object) || - isAnnounceActivityValid(activity.object) || - isCacheFileCreateActivityValid(activity.object) - ) -} - -export { - isUndoActivityValid -} diff --git a/server/helpers/custom-validators/activitypub/video-comments.ts b/server/helpers/custom-validators/activitypub/video-comments.ts index 051c4565a..0415db21c 100644 --- a/server/helpers/custom-validators/activitypub/video-comments.ts +++ b/server/helpers/custom-validators/activitypub/video-comments.ts @@ -3,11 +3,6 @@ import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers' import { exists, isArray, isDateValid } from '../misc' import { isActivityPubUrlValid, isBaseActivityValid } from './misc' -function isVideoCommentCreateActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Create') && - sanitizeAndCheckVideoCommentObject(activity.object) -} - function sanitizeAndCheckVideoCommentObject (comment: any) { if (!comment || comment.type !== 'Note') return false @@ -25,15 +20,9 @@ function sanitizeAndCheckVideoCommentObject (comment: any) { ) // Only accept public comments } -function isVideoCommentDeleteActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Delete') -} - // --------------------------------------------------------------------------- export { - isVideoCommentCreateActivityValid, - isVideoCommentDeleteActivityValid, sanitizeAndCheckVideoCommentObject } diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 95fe824b9..0f34aab21 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -14,27 +14,11 @@ import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from import { VideoState } from '../../../../shared/models/videos' import { isVideoAbuseReasonValid } from '../video-abuses' -function sanitizeAndCheckVideoTorrentCreateActivity (activity: any) { - return isBaseActivityValid(activity, 'Create') && - sanitizeAndCheckVideoTorrentObject(activity.object) -} - function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { return isBaseActivityValid(activity, 'Update') && sanitizeAndCheckVideoTorrentObject(activity.object) } -function isVideoTorrentDeleteActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Delete') -} - -function isVideoFlagValid (activity: any) { - return isBaseActivityValid(activity, 'Create') && - activity.object.type === 'Flag' && - isVideoAbuseReasonValid(activity.object.content) && - isActivityPubUrlValid(activity.object.object) -} - function isActivityPubVideoDurationValid (value: string) { // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration return exists(value) && @@ -103,11 +87,8 @@ function isRemoteVideoUrlValid (url: any) { // --------------------------------------------------------------------------- export { - sanitizeAndCheckVideoTorrentCreateActivity, sanitizeAndCheckVideoTorrentUpdateActivity, - isVideoTorrentDeleteActivityValid, isRemoteStringIdentifierValid, - isVideoFlagValid, sanitizeAndCheckVideoTorrentObject, isRemoteVideoUrlValid } diff --git a/server/helpers/custom-validators/activitypub/view.ts b/server/helpers/custom-validators/activitypub/view.ts index 7a3aca6f5..41d16469f 100644 --- a/server/helpers/custom-validators/activitypub/view.ts +++ b/server/helpers/custom-validators/activitypub/view.ts @@ -1,11 +1,11 @@ -import { isActivityPubUrlValid, isBaseActivityValid } from './misc' +import { isActivityPubUrlValid } from './misc' function isViewActivityValid (activity: any) { - return isBaseActivityValid(activity, 'Create') && - activity.object.type === 'View' && - isActivityPubUrlValid(activity.object.actor) && - isActivityPubUrlValid(activity.object.object) + return activity.type === 'View' && + isActivityPubUrlValid(activity.actor) && + isActivityPubUrlValid(activity.object) } + // --------------------------------------------------------------------------- export { -- cgit v1.2.3 From ef04ae20fe4155f516ab41959e312de093f98d0e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 17 Jan 2019 14:03:32 +0100 Subject: Prefer avg_frame_rate to fetch video FPS --- server/helpers/ffmpeg-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/helpers') diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index c7296054d..132f4690e 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts @@ -41,7 +41,7 @@ async function getVideoFileResolution (path: string) { async function getVideoFileFPS (path: string) { const videoStream = await getVideoFileStream(path) - for (const key of [ 'r_frame_rate' , 'avg_frame_rate' ]) { + for (const key of [ 'avg_frame_rate', 'r_frame_rate' ]) { const valuesText: string = videoStream[key] if (!valuesText) continue -- cgit v1.2.3 From 307902e2b3248073aeb677e420aafd8b5e041117 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 24 Jan 2019 15:23:06 +0100 Subject: Try to fix Mac video upload --- server/helpers/custom-validators/videos.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index e6f22e6c5..95e256b8f 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts @@ -88,8 +88,8 @@ function isVideoFileExtnameValid (value: string) { function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { const videoFileTypesRegex = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT) - .map(m => `(${m})`) - .join('|') + .map(m => `(${m})`) + .join('|') return isFileValid(files, videoFileTypesRegex, 'videofile', null) } -- cgit v1.2.3 From 092092969633bbcf6d4891a083ea497a7d5c3154 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 29 Jan 2019 08:37:25 +0100 Subject: Add hls support on server --- server/helpers/activitypub.ts | 5 ++-- server/helpers/core-utils.ts | 8 +++++- .../custom-validators/activitypub/cache-file.ts | 12 +++++++- .../custom-validators/activitypub/videos.ts | 8 ++++-- server/helpers/custom-validators/misc.ts | 5 ++++ server/helpers/ffmpeg-utils.ts | 32 ++++++++++++++++++---- server/helpers/video.ts | 4 ++- 7 files changed, 62 insertions(+), 12 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index f1430055f..eba552524 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -15,7 +15,7 @@ function activityPubContextify (data: T) { 'https://w3id.org/security/v1', { RsaSignature2017: 'https://w3id.org/security#RsaSignature2017', - pt: 'https://joinpeertube.org/ns', + pt: 'https://joinpeertube.org/ns#', sc: 'http://schema.org#', Hashtag: 'as:Hashtag', uuid: 'sc:identifier', @@ -32,7 +32,8 @@ function activityPubContextify (data: T) { waitTranscoding: 'sc:Boolean', expires: 'sc:expires', support: 'sc:Text', - CacheFile: 'pt:CacheFile' + CacheFile: 'pt:CacheFile', + Infohash: 'pt:Infohash' }, { likes: { diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts index 3fb824e36..f38b82d97 100644 --- a/server/helpers/core-utils.ts +++ b/server/helpers/core-utils.ts @@ -193,10 +193,14 @@ function peertubeTruncate (str: string, maxLength: number) { return truncate(str, options) } -function sha256 (str: string, encoding: HexBase64Latin1Encoding = 'hex') { +function sha256 (str: string | Buffer, encoding: HexBase64Latin1Encoding = 'hex') { return createHash('sha256').update(str).digest(encoding) } +function sha1 (str: string | Buffer, encoding: HexBase64Latin1Encoding = 'hex') { + return createHash('sha1').update(str).digest(encoding) +} + function promisify0 (func: (cb: (err: any, result: A) => void) => void): () => Promise { return function promisified (): Promise { return new Promise((resolve: (arg: A) => void, reject: (err: any) => void) => { @@ -262,7 +266,9 @@ export { sanitizeHost, buildPath, peertubeTruncate, + sha256, + sha1, promisify0, promisify1, diff --git a/server/helpers/custom-validators/activitypub/cache-file.ts b/server/helpers/custom-validators/activitypub/cache-file.ts index e2bd0c55e..21d5c53ca 100644 --- a/server/helpers/custom-validators/activitypub/cache-file.ts +++ b/server/helpers/custom-validators/activitypub/cache-file.ts @@ -8,9 +8,19 @@ function isCacheFileObjectValid (object: CacheFileObject) { object.type === 'CacheFile' && isDateValid(object.expires) && isActivityPubUrlValid(object.object) && - isRemoteVideoUrlValid(object.url) + (isRemoteVideoUrlValid(object.url) || isPlaylistRedundancyUrlValid(object.url)) } +// --------------------------------------------------------------------------- + export { isCacheFileObjectValid } + +// --------------------------------------------------------------------------- + +function isPlaylistRedundancyUrlValid (url: any) { + return url.type === 'Link' && + (url.mediaType || url.mimeType) === 'application/x-mpegURL' && + isActivityPubUrlValid(url.href) +} diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 0f34aab21..ad99c2724 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -1,7 +1,7 @@ import * as validator from 'validator' import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers' import { peertubeTruncate } from '../../core-utils' -import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc' +import { exists, isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc' import { isVideoDurationValid, isVideoNameValid, @@ -12,7 +12,6 @@ import { } from '../videos' import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' import { VideoState } from '../../../../shared/models/videos' -import { isVideoAbuseReasonValid } from '../video-abuses' function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { return isBaseActivityValid(activity, 'Update') && @@ -81,6 +80,11 @@ function isRemoteVideoUrlValid (url: any) { ACTIVITY_PUB.URL_MIME_TYPES.MAGNET.indexOf(url.mediaType || url.mimeType) !== -1 && validator.isLength(url.href, { min: 5 }) && validator.isInt(url.height + '', { min: 0 }) + ) || + ( + (url.mediaType || url.mimeType) === 'application/x-mpegURL' && + isActivityPubUrlValid(url.href) && + isArray(url.tag) ) } diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index b6f0ebe6f..76647fea2 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts @@ -13,6 +13,10 @@ function isNotEmptyIntArray (value: any) { return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0 } +function isArrayOf (value: any, validator: (value: any) => boolean) { + return isArray(value) && value.every(v => validator(v)) +} + function isDateValid (value: string) { return exists(value) && validator.isISO8601(value) } @@ -82,6 +86,7 @@ function isFileValid ( export { exists, + isArrayOf, isNotEmptyIntArray, isArray, isIdValid, diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 132f4690e..5ad8ed48e 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts @@ -1,5 +1,5 @@ import * as ffmpeg from 'fluent-ffmpeg' -import { join } from 'path' +import { dirname, join } from 'path' import { getTargetBitrate, VideoResolution } from '../../shared/models/videos' import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants' import { processImage } from './image-utils' @@ -29,12 +29,21 @@ function computeResolutionsToTranscode (videoFileHeight: number) { return resolutionsEnabled } -async function getVideoFileResolution (path: string) { +async function getVideoFileSize (path: string) { const videoStream = await getVideoFileStream(path) return { - videoFileResolution: Math.min(videoStream.height, videoStream.width), - isPortraitMode: videoStream.height > videoStream.width + width: videoStream.width, + height: videoStream.height + } +} + +async function getVideoFileResolution (path: string) { + const size = await getVideoFileSize(path) + + return { + videoFileResolution: Math.min(size.height, size.width), + isPortraitMode: size.height > size.width } } @@ -110,8 +119,10 @@ async function generateImageFromVideoFile (fromPath: string, folder: string, ima type TranscodeOptions = { inputPath: string outputPath: string - resolution?: VideoResolution + resolution: VideoResolution isPortraitMode?: boolean + + generateHlsPlaylist?: boolean } function transcode (options: TranscodeOptions) { @@ -150,6 +161,16 @@ function transcode (options: TranscodeOptions) { command = command.withFPS(fps) } + if (options.generateHlsPlaylist) { + const segmentFilename = `${dirname(options.outputPath)}/${options.resolution}_%03d.ts` + + command = command.outputOption('-hls_time 4') + .outputOption('-hls_list_size 0') + .outputOption('-hls_playlist_type vod') + .outputOption('-hls_segment_filename ' + segmentFilename) + .outputOption('-f hls') + } + command .on('error', (err, stdout, stderr) => { logger.error('Error in transcoding job.', { stdout, stderr }) @@ -166,6 +187,7 @@ function transcode (options: TranscodeOptions) { // --------------------------------------------------------------------------- export { + getVideoFileSize, getVideoFileResolution, getDurationFromVideoFile, generateImageFromVideoFile, diff --git a/server/helpers/video.ts b/server/helpers/video.ts index 1bd21467d..c90fe06c7 100644 --- a/server/helpers/video.ts +++ b/server/helpers/video.ts @@ -1,10 +1,12 @@ import { VideoModel } from '../models/video/video' -type VideoFetchType = 'all' | 'only-video' | 'id' | 'none' +type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' function fetchVideo (id: number | string, fetchType: VideoFetchType, userId?: number) { if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId) + if (fetchType === 'only-video-with-rights') return VideoModel.loadWithRights(id) + if (fetchType === 'only-video') return VideoModel.load(id) if (fetchType === 'id' || fetchType === 'none') return VideoModel.loadOnlyId(id) -- cgit v1.2.3 From 4c280004ce62bf11ddb091854c28f1e1d54a54d6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 7 Feb 2019 15:08:19 +0100 Subject: Use a single file instead of segments for HLS --- server/helpers/ffmpeg-utils.ts | 12 ++++++++---- server/helpers/requests.ts | 2 +- server/helpers/utils.ts | 1 - 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 5ad8ed48e..133b1b03b 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts @@ -122,7 +122,9 @@ type TranscodeOptions = { resolution: VideoResolution isPortraitMode?: boolean - generateHlsPlaylist?: boolean + hlsPlaylist?: { + videoFilename: string + } } function transcode (options: TranscodeOptions) { @@ -161,14 +163,16 @@ function transcode (options: TranscodeOptions) { command = command.withFPS(fps) } - if (options.generateHlsPlaylist) { - const segmentFilename = `${dirname(options.outputPath)}/${options.resolution}_%03d.ts` + if (options.hlsPlaylist) { + const videoPath = `${dirname(options.outputPath)}/${options.hlsPlaylist.videoFilename}` command = command.outputOption('-hls_time 4') .outputOption('-hls_list_size 0') .outputOption('-hls_playlist_type vod') - .outputOption('-hls_segment_filename ' + segmentFilename) + .outputOption('-hls_segment_filename ' + videoPath) + .outputOption('-hls_segment_type fmp4') .outputOption('-f hls') + .outputOption('-hls_flags single_file') } command diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts index 3fc776f1a..5c6dc5e19 100644 --- a/server/helpers/requests.ts +++ b/server/helpers/requests.ts @@ -7,7 +7,7 @@ import { join } from 'path' function doRequest ( requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean } -): Bluebird<{ response: request.RequestResponse, body: any }> { +): Bluebird<{ response: request.RequestResponse, body: T }> { if (requestOptions.activityPub === true) { if (!Array.isArray(requestOptions.headers)) requestOptions.headers = {} requestOptions.headers['accept'] = ACTIVITY_PUB.ACCEPT_HEADER diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index 3c3406e38..cb0e823c5 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts @@ -7,7 +7,6 @@ import { join } from 'path' import { Instance as ParseTorrent } from 'parse-torrent' import { remove } from 'fs-extra' import * as memoizee from 'memoizee' -import { isArray } from './custom-validators/misc' function deleteFileAsync (path: string) { remove(path) -- cgit v1.2.3