aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers/custom-validators/activitypub
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers/custom-validators/activitypub')
-rw-r--r--server/helpers/custom-validators/activitypub/activity.ts2
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts11
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts14
-rw-r--r--server/helpers/custom-validators/activitypub/watch-action.ts37
4 files changed, 52 insertions, 12 deletions
diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts
index b5c96f6e7..90a918523 100644
--- a/server/helpers/custom-validators/activitypub/activity.ts
+++ b/server/helpers/custom-validators/activitypub/activity.ts
@@ -8,6 +8,7 @@ import { isActivityPubUrlValid, isBaseActivityValid, isObjectValid } from './mis
8import { isPlaylistObjectValid } from './playlist' 8import { isPlaylistObjectValid } from './playlist'
9import { sanitizeAndCheckVideoCommentObject } from './video-comments' 9import { sanitizeAndCheckVideoCommentObject } from './video-comments'
10import { sanitizeAndCheckVideoTorrentObject } from './videos' 10import { sanitizeAndCheckVideoTorrentObject } from './videos'
11import { isWatchActionObjectValid } from './watch-action'
11 12
12function isRootActivityValid (activity: any) { 13function isRootActivityValid (activity: any) {
13 return isCollection(activity) || isActivity(activity) 14 return isCollection(activity) || isActivity(activity)
@@ -82,6 +83,7 @@ function isCreateActivityValid (activity: any) {
82 isDislikeActivityValid(activity.object) || 83 isDislikeActivityValid(activity.object) ||
83 isFlagActivityValid(activity.object) || 84 isFlagActivityValid(activity.object) ||
84 isPlaylistObjectValid(activity.object) || 85 isPlaylistObjectValid(activity.object) ||
86 isWatchActionObjectValid(activity.object) ||
85 87
86 isCacheFileObjectValid(activity.object) || 88 isCacheFileObjectValid(activity.object) ||
87 sanitizeAndCheckVideoCommentObject(activity.object) || 89 sanitizeAndCheckVideoCommentObject(activity.object) ||
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 4ee8e6fee..9d823299f 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -57,10 +57,19 @@ function setValidAttributedTo (obj: any) {
57 return true 57 return true
58} 58}
59 59
60function isActivityPubVideoDurationValid (value: string) {
61 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
62 return exists(value) &&
63 typeof value === 'string' &&
64 value.startsWith('PT') &&
65 value.endsWith('S')
66}
67
60export { 68export {
61 isUrlValid, 69 isUrlValid,
62 isActivityPubUrlValid, 70 isActivityPubUrlValid,
63 isBaseActivityValid, 71 isBaseActivityValid,
64 setValidAttributedTo, 72 setValidAttributedTo,
65 isObjectValid 73 isObjectValid,
74 isActivityPubVideoDurationValid
66} 75}
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 80a321117..2a2f008b9 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -4,7 +4,7 @@ import { ActivityTrackerUrlObject, ActivityVideoFileMetadataUrlObject } from '@s
4import { LiveVideoLatencyMode, VideoState } from '../../../../shared/models/videos' 4import { LiveVideoLatencyMode, VideoState } from '../../../../shared/models/videos'
5import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers/constants' 5import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers/constants'
6import { peertubeTruncate } from '../../core-utils' 6import { peertubeTruncate } from '../../core-utils'
7import { exists, isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc' 7import { isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc'
8import { isLiveLatencyModeValid } from '../video-lives' 8import { isLiveLatencyModeValid } from '../video-lives'
9import { 9import {
10 isVideoDurationValid, 10 isVideoDurationValid,
@@ -14,22 +14,13 @@ import {
14 isVideoTruncatedDescriptionValid, 14 isVideoTruncatedDescriptionValid,
15 isVideoViewsValid 15 isVideoViewsValid
16} from '../videos' 16} from '../videos'
17import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' 17import { isActivityPubUrlValid, isActivityPubVideoDurationValid, isBaseActivityValid, setValidAttributedTo } from './misc'
18 18
19function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { 19function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) {
20 return isBaseActivityValid(activity, 'Update') && 20 return isBaseActivityValid(activity, 'Update') &&
21 sanitizeAndCheckVideoTorrentObject(activity.object) 21 sanitizeAndCheckVideoTorrentObject(activity.object)
22} 22}
23 23
24function isActivityPubVideoDurationValid (value: string) {
25 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
26 return exists(value) &&
27 typeof value === 'string' &&
28 value.startsWith('PT') &&
29 value.endsWith('S') &&
30 isVideoDurationValid(value.replace(/[^0-9]+/g, ''))
31}
32
33function sanitizeAndCheckVideoTorrentObject (video: any) { 24function sanitizeAndCheckVideoTorrentObject (video: any) {
34 if (!video || video.type !== 'Video') return false 25 if (!video || video.type !== 'Video') return false
35 26
@@ -71,6 +62,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) {
71 return isActivityPubUrlValid(video.id) && 62 return isActivityPubUrlValid(video.id) &&
72 isVideoNameValid(video.name) && 63 isVideoNameValid(video.name) &&
73 isActivityPubVideoDurationValid(video.duration) && 64 isActivityPubVideoDurationValid(video.duration) &&
65 isVideoDurationValid(video.duration.replace(/[^0-9]+/g, '')) &&
74 isUUIDValid(video.uuid) && 66 isUUIDValid(video.uuid) &&
75 (!video.category || isRemoteNumberIdentifierValid(video.category)) && 67 (!video.category || isRemoteNumberIdentifierValid(video.category)) &&
76 (!video.licence || isRemoteNumberIdentifierValid(video.licence)) && 68 (!video.licence || isRemoteNumberIdentifierValid(video.licence)) &&
diff --git a/server/helpers/custom-validators/activitypub/watch-action.ts b/server/helpers/custom-validators/activitypub/watch-action.ts
new file mode 100644
index 000000000..b9ffa63f6
--- /dev/null
+++ b/server/helpers/custom-validators/activitypub/watch-action.ts
@@ -0,0 +1,37 @@
1import { WatchActionObject } from '@shared/models'
2import { exists, isDateValid, isUUIDValid } from '../misc'
3import { isVideoTimeValid } from '../video-view'
4import { isActivityPubVideoDurationValid, isObjectValid } from './misc'
5
6function isWatchActionObjectValid (action: WatchActionObject) {
7 return exists(action) &&
8 action.type === 'WatchAction' &&
9 isObjectValid(action.id) &&
10 isActivityPubVideoDurationValid(action.duration) &&
11 isDateValid(action.startTime) &&
12 isDateValid(action.endTime) &&
13 isLocationValid(action.location) &&
14 isUUIDValid(action.uuid) &&
15 isObjectValid(action.object) &&
16 isWatchSectionsValid(action.watchSections)
17}
18
19// ---------------------------------------------------------------------------
20
21export {
22 isWatchActionObjectValid
23}
24
25// ---------------------------------------------------------------------------
26
27function isLocationValid (location: any) {
28 if (!location) return true
29
30 return typeof location === 'object' && typeof location.addressCountry === 'string'
31}
32
33function isWatchSectionsValid (sections: WatchActionObject['watchSections']) {
34 return Array.isArray(sections) && sections.every(s => {
35 return isVideoTimeValid(s.startTimestamp) && isVideoTimeValid(s.endTimestamp)
36 })
37}