diff options
Diffstat (limited to 'server/helpers/custom-validators')
18 files changed, 203 insertions, 178 deletions
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 @@ | |||
1 | import * as validator from 'validator' | 1 | import * as validator from 'validator' |
2 | import { Activity, ActivityType } from '../../../../shared/models/activitypub' | 2 | import { Activity, ActivityType } from '../../../../shared/models/activitypub' |
3 | import { | 3 | import { sanitizeAndCheckActorObject } from './actor' |
4 | isActorAcceptActivityValid, | 4 | import { isActivityPubUrlValid, isBaseActivityValid, isObjectValid } from './misc' |
5 | isActorDeleteActivityValid, | 5 | import { isDislikeActivityValid } from './rate' |
6 | isActorFollowActivityValid, | 6 | import { sanitizeAndCheckVideoCommentObject } from './video-comments' |
7 | isActorRejectActivityValid, | 7 | import { sanitizeAndCheckVideoTorrentObject } from './videos' |
8 | isActorUpdateActivityValid | ||
9 | } from './actor' | ||
10 | import { isAnnounceActivityValid } from './announce' | ||
11 | import { isActivityPubUrlValid } from './misc' | ||
12 | import { isDislikeActivityValid, isLikeActivityValid } from './rate' | ||
13 | import { isUndoActivityValid } from './undo' | ||
14 | import { isVideoCommentCreateActivityValid, isVideoCommentDeleteActivityValid } from './video-comments' | ||
15 | import { | ||
16 | isVideoFlagValid, | ||
17 | isVideoTorrentDeleteActivityValid, | ||
18 | sanitizeAndCheckVideoTorrentCreateActivity, | ||
19 | sanitizeAndCheckVideoTorrentUpdateActivity | ||
20 | } from './videos' | ||
21 | import { isViewActivityValid } from './view' | 8 | import { isViewActivityValid } from './view' |
22 | import { exists } from '../misc' | 9 | import { exists } from '../misc' |
23 | import { isCacheFileCreateActivityValid, isCacheFileUpdateActivityValid } from './cache-file' | 10 | import { isCacheFileObjectValid } from './cache-file' |
11 | import { isFlagActivityValid } from './flag' | ||
24 | 12 | ||
25 | function isRootActivityValid (activity: any) { | 13 | function isRootActivityValid (activity: any) { |
26 | return Array.isArray(activity['@context']) && ( | 14 | return Array.isArray(activity['@context']) && ( |
@@ -46,7 +34,10 @@ const activityCheckers: { [ P in ActivityType ]: (activity: Activity) => boolean | |||
46 | Reject: checkRejectActivity, | 34 | Reject: checkRejectActivity, |
47 | Announce: checkAnnounceActivity, | 35 | Announce: checkAnnounceActivity, |
48 | Undo: checkUndoActivity, | 36 | Undo: checkUndoActivity, |
49 | Like: checkLikeActivity | 37 | Like: checkLikeActivity, |
38 | View: checkViewActivity, | ||
39 | Flag: checkFlagActivity, | ||
40 | Dislike: checkDislikeActivity | ||
50 | } | 41 | } |
51 | 42 | ||
52 | function isActivityValid (activity: any) { | 43 | function isActivityValid (activity: any) { |
@@ -66,47 +57,79 @@ export { | |||
66 | 57 | ||
67 | // --------------------------------------------------------------------------- | 58 | // --------------------------------------------------------------------------- |
68 | 59 | ||
60 | function checkViewActivity (activity: any) { | ||
61 | return isBaseActivityValid(activity, 'View') && | ||
62 | isViewActivityValid(activity) | ||
63 | } | ||
64 | |||
65 | function checkFlagActivity (activity: any) { | ||
66 | return isBaseActivityValid(activity, 'Flag') && | ||
67 | isFlagActivityValid(activity) | ||
68 | } | ||
69 | |||
70 | function checkDislikeActivity (activity: any) { | ||
71 | return isBaseActivityValid(activity, 'Dislike') && | ||
72 | isDislikeActivityValid(activity) | ||
73 | } | ||
74 | |||
69 | function checkCreateActivity (activity: any) { | 75 | function checkCreateActivity (activity: any) { |
70 | return isViewActivityValid(activity) || | 76 | return isBaseActivityValid(activity, 'Create') && |
71 | isDislikeActivityValid(activity) || | 77 | ( |
72 | sanitizeAndCheckVideoTorrentCreateActivity(activity) || | 78 | isViewActivityValid(activity.object) || |
73 | isVideoFlagValid(activity) || | 79 | isDislikeActivityValid(activity.object) || |
74 | isVideoCommentCreateActivityValid(activity) || | 80 | isFlagActivityValid(activity.object) || |
75 | isCacheFileCreateActivityValid(activity) | 81 | |
82 | isCacheFileObjectValid(activity.object) || | ||
83 | sanitizeAndCheckVideoCommentObject(activity.object) || | ||
84 | sanitizeAndCheckVideoTorrentObject(activity.object) | ||
85 | ) | ||
76 | } | 86 | } |
77 | 87 | ||
78 | function checkUpdateActivity (activity: any) { | 88 | function checkUpdateActivity (activity: any) { |
79 | return isCacheFileUpdateActivityValid(activity) || | 89 | return isBaseActivityValid(activity, 'Update') && |
80 | sanitizeAndCheckVideoTorrentUpdateActivity(activity) || | 90 | ( |
81 | isActorUpdateActivityValid(activity) | 91 | isCacheFileObjectValid(activity.object) || |
92 | sanitizeAndCheckVideoTorrentObject(activity.object) || | ||
93 | sanitizeAndCheckActorObject(activity.object) | ||
94 | ) | ||
82 | } | 95 | } |
83 | 96 | ||
84 | function checkDeleteActivity (activity: any) { | 97 | function checkDeleteActivity (activity: any) { |
85 | return isVideoTorrentDeleteActivityValid(activity) || | 98 | // We don't really check objects |
86 | isActorDeleteActivityValid(activity) || | 99 | return isBaseActivityValid(activity, 'Delete') && |
87 | isVideoCommentDeleteActivityValid(activity) | 100 | isObjectValid(activity.object) |
88 | } | 101 | } |
89 | 102 | ||
90 | function checkFollowActivity (activity: any) { | 103 | function checkFollowActivity (activity: any) { |
91 | return isActorFollowActivityValid(activity) | 104 | return isBaseActivityValid(activity, 'Follow') && |
105 | isObjectValid(activity.object) | ||
92 | } | 106 | } |
93 | 107 | ||
94 | function checkAcceptActivity (activity: any) { | 108 | function checkAcceptActivity (activity: any) { |
95 | return isActorAcceptActivityValid(activity) | 109 | return isBaseActivityValid(activity, 'Accept') |
96 | } | 110 | } |
97 | 111 | ||
98 | function checkRejectActivity (activity: any) { | 112 | function checkRejectActivity (activity: any) { |
99 | return isActorRejectActivityValid(activity) | 113 | return isBaseActivityValid(activity, 'Reject') |
100 | } | 114 | } |
101 | 115 | ||
102 | function checkAnnounceActivity (activity: any) { | 116 | function checkAnnounceActivity (activity: any) { |
103 | return isAnnounceActivityValid(activity) | 117 | return isBaseActivityValid(activity, 'Announce') && |
118 | isObjectValid(activity.object) | ||
104 | } | 119 | } |
105 | 120 | ||
106 | function checkUndoActivity (activity: any) { | 121 | function checkUndoActivity (activity: any) { |
107 | return isUndoActivityValid(activity) | 122 | return isBaseActivityValid(activity, 'Undo') && |
123 | ( | ||
124 | checkFollowActivity(activity.object) || | ||
125 | checkLikeActivity(activity.object) || | ||
126 | checkDislikeActivity(activity.object) || | ||
127 | checkAnnounceActivity(activity.object) || | ||
128 | checkCreateActivity(activity.object) | ||
129 | ) | ||
108 | } | 130 | } |
109 | 131 | ||
110 | function checkLikeActivity (activity: any) { | 132 | function checkLikeActivity (activity: any) { |
111 | return isLikeActivityValid(activity) | 133 | return isBaseActivityValid(activity, 'Like') && |
134 | isObjectValid(activity.object) | ||
112 | } | 135 | } |
diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts index 77c003cdf..c05f60f14 100644 --- a/server/helpers/custom-validators/activitypub/actor.ts +++ b/server/helpers/custom-validators/activitypub/actor.ts | |||
@@ -27,7 +27,8 @@ function isActorPublicKeyValid (publicKey: string) { | |||
27 | validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY) | 27 | validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY) |
28 | } | 28 | } |
29 | 29 | ||
30 | const actorNameRegExp = new RegExp('^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_\.]+$') | 30 | const actorNameAlphabet = '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.]' |
31 | const actorNameRegExp = new RegExp(`^${actorNameAlphabet}+$`) | ||
31 | function isActorPreferredUsernameValid (preferredUsername: string) { | 32 | function isActorPreferredUsernameValid (preferredUsername: string) { |
32 | return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp) | 33 | return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp) |
33 | } | 34 | } |
@@ -72,24 +73,10 @@ function isActorDeleteActivityValid (activity: any) { | |||
72 | return isBaseActivityValid(activity, 'Delete') | 73 | return isBaseActivityValid(activity, 'Delete') |
73 | } | 74 | } |
74 | 75 | ||
75 | function isActorFollowActivityValid (activity: any) { | 76 | function sanitizeAndCheckActorObject (object: any) { |
76 | return isBaseActivityValid(activity, 'Follow') && | 77 | normalizeActor(object) |
77 | isActivityPubUrlValid(activity.object) | ||
78 | } | ||
79 | |||
80 | function isActorAcceptActivityValid (activity: any) { | ||
81 | return isBaseActivityValid(activity, 'Accept') | ||
82 | } | ||
83 | |||
84 | function isActorRejectActivityValid (activity: any) { | ||
85 | return isBaseActivityValid(activity, 'Reject') | ||
86 | } | ||
87 | |||
88 | function isActorUpdateActivityValid (activity: any) { | ||
89 | normalizeActor(activity.object) | ||
90 | 78 | ||
91 | return isBaseActivityValid(activity, 'Update') && | 79 | return isActorObjectValid(object) |
92 | isActorObjectValid(activity.object) | ||
93 | } | 80 | } |
94 | 81 | ||
95 | function normalizeActor (actor: any) { | 82 | function normalizeActor (actor: any) { |
@@ -127,6 +114,7 @@ function areValidActorHandles (handles: string[]) { | |||
127 | 114 | ||
128 | export { | 115 | export { |
129 | normalizeActor, | 116 | normalizeActor, |
117 | actorNameAlphabet, | ||
130 | areValidActorHandles, | 118 | areValidActorHandles, |
131 | isActorEndpointsObjectValid, | 119 | isActorEndpointsObjectValid, |
132 | isActorPublicKeyObjectValid, | 120 | isActorPublicKeyObjectValid, |
@@ -137,10 +125,7 @@ export { | |||
137 | isActorObjectValid, | 125 | isActorObjectValid, |
138 | isActorFollowingCountValid, | 126 | isActorFollowingCountValid, |
139 | isActorFollowersCountValid, | 127 | isActorFollowersCountValid, |
140 | isActorFollowActivityValid, | ||
141 | isActorAcceptActivityValid, | ||
142 | isActorRejectActivityValid, | ||
143 | isActorDeleteActivityValid, | 128 | isActorDeleteActivityValid, |
144 | isActorUpdateActivityValid, | 129 | sanitizeAndCheckActorObject, |
145 | isValidActorHandle | 130 | isValidActorHandle |
146 | } | 131 | } |
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 @@ | |||
1 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | ||
2 | |||
3 | function isAnnounceActivityValid (activity: any) { | ||
4 | return isBaseActivityValid(activity, 'Announce') && | ||
5 | ( | ||
6 | isActivityPubUrlValid(activity.object) || | ||
7 | (activity.object && isActivityPubUrlValid(activity.object.id)) | ||
8 | ) | ||
9 | } | ||
10 | |||
11 | export { | ||
12 | isAnnounceActivityValid | ||
13 | } | ||
diff --git a/server/helpers/custom-validators/activitypub/cache-file.ts b/server/helpers/custom-validators/activitypub/cache-file.ts index bd70934c8..21d5c53ca 100644 --- a/server/helpers/custom-validators/activitypub/cache-file.ts +++ b/server/helpers/custom-validators/activitypub/cache-file.ts | |||
@@ -1,28 +1,26 @@ | |||
1 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 1 | import { isActivityPubUrlValid } from './misc' |
2 | import { isRemoteVideoUrlValid } from './videos' | 2 | import { isRemoteVideoUrlValid } from './videos' |
3 | import { isDateValid, exists } from '../misc' | 3 | import { exists, isDateValid } from '../misc' |
4 | import { CacheFileObject } from '../../../../shared/models/activitypub/objects' | 4 | import { CacheFileObject } from '../../../../shared/models/activitypub/objects' |
5 | 5 | ||
6 | function isCacheFileCreateActivityValid (activity: any) { | ||
7 | return isBaseActivityValid(activity, 'Create') && | ||
8 | isCacheFileObjectValid(activity.object) | ||
9 | } | ||
10 | |||
11 | function isCacheFileUpdateActivityValid (activity: any) { | ||
12 | return isBaseActivityValid(activity, 'Update') && | ||
13 | isCacheFileObjectValid(activity.object) | ||
14 | } | ||
15 | |||
16 | function isCacheFileObjectValid (object: CacheFileObject) { | 6 | function isCacheFileObjectValid (object: CacheFileObject) { |
17 | return exists(object) && | 7 | return exists(object) && |
18 | object.type === 'CacheFile' && | 8 | object.type === 'CacheFile' && |
19 | isDateValid(object.expires) && | 9 | isDateValid(object.expires) && |
20 | isActivityPubUrlValid(object.object) && | 10 | isActivityPubUrlValid(object.object) && |
21 | isRemoteVideoUrlValid(object.url) | 11 | (isRemoteVideoUrlValid(object.url) || isPlaylistRedundancyUrlValid(object.url)) |
22 | } | 12 | } |
23 | 13 | ||
14 | // --------------------------------------------------------------------------- | ||
15 | |||
24 | export { | 16 | export { |
25 | isCacheFileUpdateActivityValid, | ||
26 | isCacheFileCreateActivityValid, | ||
27 | isCacheFileObjectValid | 17 | isCacheFileObjectValid |
28 | } | 18 | } |
19 | |||
20 | // --------------------------------------------------------------------------- | ||
21 | |||
22 | function isPlaylistRedundancyUrlValid (url: any) { | ||
23 | return url.type === 'Link' && | ||
24 | (url.mediaType || url.mimeType) === 'application/x-mpegURL' && | ||
25 | isActivityPubUrlValid(url.href) | ||
26 | } | ||
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 @@ | |||
1 | import { isActivityPubUrlValid } from './misc' | ||
2 | import { isVideoAbuseReasonValid } from '../video-abuses' | ||
3 | |||
4 | function isFlagActivityValid (activity: any) { | ||
5 | return activity.type === 'Flag' && | ||
6 | isVideoAbuseReasonValid(activity.content) && | ||
7 | isActivityPubUrlValid(activity.object) | ||
8 | } | ||
9 | |||
10 | // --------------------------------------------------------------------------- | ||
11 | |||
12 | export { | ||
13 | isFlagActivityValid | ||
14 | } | ||
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) { | |||
28 | return (activity['@context'] === undefined || Array.isArray(activity['@context'])) && | 28 | return (activity['@context'] === undefined || Array.isArray(activity['@context'])) && |
29 | activity.type === type && | 29 | activity.type === type && |
30 | isActivityPubUrlValid(activity.id) && | 30 | isActivityPubUrlValid(activity.id) && |
31 | exists(activity.actor) && | 31 | isObjectValid(activity.actor) && |
32 | (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id)) && | 32 | isUrlCollectionValid(activity.to) && |
33 | ( | 33 | isUrlCollectionValid(activity.cc) |
34 | activity.to === undefined || | 34 | } |
35 | (Array.isArray(activity.to) && activity.to.every(t => isActivityPubUrlValid(t))) | 35 | |
36 | ) && | 36 | function isUrlCollectionValid (collection: any) { |
37 | return collection === undefined || | ||
38 | (Array.isArray(collection) && collection.every(t => isActivityPubUrlValid(t))) | ||
39 | } | ||
40 | |||
41 | function isObjectValid (object: any) { | ||
42 | return exists(object) && | ||
37 | ( | 43 | ( |
38 | activity.cc === undefined || | 44 | isActivityPubUrlValid(object) || isActivityPubUrlValid(object.id) |
39 | (Array.isArray(activity.cc) && activity.cc.every(t => isActivityPubUrlValid(t))) | ||
40 | ) | 45 | ) |
41 | } | 46 | } |
42 | 47 | ||
@@ -57,5 +62,6 @@ export { | |||
57 | isUrlValid, | 62 | isUrlValid, |
58 | isActivityPubUrlValid, | 63 | isActivityPubUrlValid, |
59 | isBaseActivityValid, | 64 | isBaseActivityValid, |
60 | setValidAttributedTo | 65 | setValidAttributedTo, |
66 | isObjectValid | ||
61 | } | 67 | } |
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 @@ | |||
1 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 1 | import { isActivityPubUrlValid, isObjectValid } from './misc' |
2 | |||
3 | function isLikeActivityValid (activity: any) { | ||
4 | return isBaseActivityValid(activity, 'Like') && | ||
5 | isActivityPubUrlValid(activity.object) | ||
6 | } | ||
7 | 2 | ||
8 | function isDislikeActivityValid (activity: any) { | 3 | function isDislikeActivityValid (activity: any) { |
9 | return isBaseActivityValid(activity, 'Create') && | 4 | return activity.type === 'Dislike' && |
10 | activity.object.type === 'Dislike' && | 5 | isActivityPubUrlValid(activity.actor) && |
11 | isActivityPubUrlValid(activity.object.actor) && | 6 | isObjectValid(activity.object) |
12 | isActivityPubUrlValid(activity.object.object) | ||
13 | } | 7 | } |
14 | 8 | ||
15 | // --------------------------------------------------------------------------- | 9 | // --------------------------------------------------------------------------- |
16 | 10 | ||
17 | export { | 11 | export { |
18 | isLikeActivityValid, | ||
19 | isDislikeActivityValid | 12 | isDislikeActivityValid |
20 | } | 13 | } |
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 @@ | |||
1 | import { isActorFollowActivityValid } from './actor' | ||
2 | import { isBaseActivityValid } from './misc' | ||
3 | import { isDislikeActivityValid, isLikeActivityValid } from './rate' | ||
4 | import { isAnnounceActivityValid } from './announce' | ||
5 | import { isCacheFileCreateActivityValid } from './cache-file' | ||
6 | |||
7 | function isUndoActivityValid (activity: any) { | ||
8 | return isBaseActivityValid(activity, 'Undo') && | ||
9 | ( | ||
10 | isActorFollowActivityValid(activity.object) || | ||
11 | isLikeActivityValid(activity.object) || | ||
12 | isDislikeActivityValid(activity.object) || | ||
13 | isAnnounceActivityValid(activity.object) || | ||
14 | isCacheFileCreateActivityValid(activity.object) | ||
15 | ) | ||
16 | } | ||
17 | |||
18 | export { | ||
19 | isUndoActivityValid | ||
20 | } | ||
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' | |||
3 | import { exists, isArray, isDateValid } from '../misc' | 3 | import { exists, isArray, isDateValid } from '../misc' |
4 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 4 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' |
5 | 5 | ||
6 | function isVideoCommentCreateActivityValid (activity: any) { | ||
7 | return isBaseActivityValid(activity, 'Create') && | ||
8 | sanitizeAndCheckVideoCommentObject(activity.object) | ||
9 | } | ||
10 | |||
11 | function sanitizeAndCheckVideoCommentObject (comment: any) { | 6 | function sanitizeAndCheckVideoCommentObject (comment: any) { |
12 | if (!comment || comment.type !== 'Note') return false | 7 | if (!comment || comment.type !== 'Note') return false |
13 | 8 | ||
@@ -25,15 +20,9 @@ function sanitizeAndCheckVideoCommentObject (comment: any) { | |||
25 | ) // Only accept public comments | 20 | ) // Only accept public comments |
26 | } | 21 | } |
27 | 22 | ||
28 | function isVideoCommentDeleteActivityValid (activity: any) { | ||
29 | return isBaseActivityValid(activity, 'Delete') | ||
30 | } | ||
31 | |||
32 | // --------------------------------------------------------------------------- | 23 | // --------------------------------------------------------------------------- |
33 | 24 | ||
34 | export { | 25 | export { |
35 | isVideoCommentCreateActivityValid, | ||
36 | isVideoCommentDeleteActivityValid, | ||
37 | sanitizeAndCheckVideoCommentObject | 26 | sanitizeAndCheckVideoCommentObject |
38 | } | 27 | } |
39 | 28 | ||
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 5015c59dd..53ad0588d 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as validator from 'validator' | 1 | import * as validator from 'validator' |
2 | import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers' | 2 | import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers' |
3 | import { peertubeTruncate } from '../../core-utils' | 3 | import { peertubeTruncate } from '../../core-utils' |
4 | import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc' | 4 | import { exists, isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc' |
5 | import { | 5 | import { |
6 | isVideoDurationValid, | 6 | isVideoDurationValid, |
7 | isVideoNameValid, | 7 | isVideoNameValid, |
@@ -12,29 +12,12 @@ import { | |||
12 | } from '../videos' | 12 | } from '../videos' |
13 | import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' | 13 | import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' |
14 | import { VideoState } from '../../../../shared/models/videos' | 14 | import { VideoState } from '../../../../shared/models/videos' |
15 | import { isVideoAbuseReasonValid } from '../video-abuses' | ||
16 | |||
17 | function sanitizeAndCheckVideoTorrentCreateActivity (activity: any) { | ||
18 | return isBaseActivityValid(activity, 'Create') && | ||
19 | sanitizeAndCheckVideoTorrentObject(activity.object) | ||
20 | } | ||
21 | 15 | ||
22 | function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { | 16 | function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { |
23 | return isBaseActivityValid(activity, 'Update') && | 17 | return isBaseActivityValid(activity, 'Update') && |
24 | sanitizeAndCheckVideoTorrentObject(activity.object) | 18 | sanitizeAndCheckVideoTorrentObject(activity.object) |
25 | } | 19 | } |
26 | 20 | ||
27 | function isVideoTorrentDeleteActivityValid (activity: any) { | ||
28 | return isBaseActivityValid(activity, 'Delete') | ||
29 | } | ||
30 | |||
31 | function isVideoFlagValid (activity: any) { | ||
32 | return isBaseActivityValid(activity, 'Create') && | ||
33 | activity.object.type === 'Flag' && | ||
34 | isVideoAbuseReasonValid(activity.object.content) && | ||
35 | isActivityPubUrlValid(activity.object.object) | ||
36 | } | ||
37 | |||
38 | function isActivityPubVideoDurationValid (value: string) { | 21 | function isActivityPubVideoDurationValid (value: string) { |
39 | // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration | 22 | // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration |
40 | return exists(value) && | 23 | return exists(value) && |
@@ -83,32 +66,35 @@ function isRemoteVideoUrlValid (url: any) { | |||
83 | 66 | ||
84 | return url.type === 'Link' && | 67 | return url.type === 'Link' && |
85 | ( | 68 | ( |
86 | ACTIVITY_PUB.URL_MIME_TYPES.VIDEO.indexOf(url.mimeType) !== -1 && | 69 | // TODO: remove mimeType (backward compatibility, introduced in v1.1.0) |
70 | ACTIVITY_PUB.URL_MIME_TYPES.VIDEO.indexOf(url.mediaType || url.mimeType) !== -1 && | ||
87 | isActivityPubUrlValid(url.href) && | 71 | isActivityPubUrlValid(url.href) && |
88 | validator.isInt(url.height + '', { min: 0 }) && | 72 | validator.isInt(url.height + '', { min: 0 }) && |
89 | validator.isInt(url.size + '', { min: 0 }) && | 73 | validator.isInt(url.size + '', { min: 0 }) && |
90 | (!url.fps || validator.isInt(url.fps + '', { min: -1 })) | 74 | (!url.fps || validator.isInt(url.fps + '', { min: -1 })) |
91 | ) || | 75 | ) || |
92 | ( | 76 | ( |
93 | ACTIVITY_PUB.URL_MIME_TYPES.TORRENT.indexOf(url.mimeType) !== -1 && | 77 | ACTIVITY_PUB.URL_MIME_TYPES.TORRENT.indexOf(url.mediaType || url.mimeType) !== -1 && |
94 | isActivityPubUrlValid(url.href) && | 78 | isActivityPubUrlValid(url.href) && |
95 | validator.isInt(url.height + '', { min: 0 }) | 79 | validator.isInt(url.height + '', { min: 0 }) |
96 | ) || | 80 | ) || |
97 | ( | 81 | ( |
98 | ACTIVITY_PUB.URL_MIME_TYPES.MAGNET.indexOf(url.mimeType) !== -1 && | 82 | ACTIVITY_PUB.URL_MIME_TYPES.MAGNET.indexOf(url.mediaType || url.mimeType) !== -1 && |
99 | validator.isLength(url.href, { min: 5 }) && | 83 | validator.isLength(url.href, { min: 5 }) && |
100 | validator.isInt(url.height + '', { min: 0 }) | 84 | validator.isInt(url.height + '', { min: 0 }) |
85 | ) || | ||
86 | ( | ||
87 | (url.mediaType || url.mimeType) === 'application/x-mpegURL' && | ||
88 | isActivityPubUrlValid(url.href) && | ||
89 | isArray(url.tag) | ||
101 | ) | 90 | ) |
102 | } | 91 | } |
103 | 92 | ||
104 | // --------------------------------------------------------------------------- | 93 | // --------------------------------------------------------------------------- |
105 | 94 | ||
106 | export { | 95 | export { |
107 | sanitizeAndCheckVideoTorrentCreateActivity, | ||
108 | sanitizeAndCheckVideoTorrentUpdateActivity, | 96 | sanitizeAndCheckVideoTorrentUpdateActivity, |
109 | isVideoTorrentDeleteActivityValid, | ||
110 | isRemoteStringIdentifierValid, | 97 | isRemoteStringIdentifierValid, |
111 | isVideoFlagValid, | ||
112 | sanitizeAndCheckVideoTorrentObject, | 98 | sanitizeAndCheckVideoTorrentObject, |
113 | isRemoteVideoUrlValid | 99 | isRemoteVideoUrlValid |
114 | } | 100 | } |
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 @@ | |||
1 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 1 | import { isActivityPubUrlValid } from './misc' |
2 | 2 | ||
3 | function isViewActivityValid (activity: any) { | 3 | function isViewActivityValid (activity: any) { |
4 | return isBaseActivityValid(activity, 'Create') && | 4 | return activity.type === 'View' && |
5 | activity.object.type === 'View' && | 5 | isActivityPubUrlValid(activity.actor) && |
6 | isActivityPubUrlValid(activity.object.actor) && | 6 | isActivityPubUrlValid(activity.object) |
7 | isActivityPubUrlValid(activity.object.object) | ||
8 | } | 7 | } |
8 | |||
9 | // --------------------------------------------------------------------------- | 9 | // --------------------------------------------------------------------------- |
10 | 10 | ||
11 | export { | 11 | export { |
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 6d10a65a8..76647fea2 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -9,6 +9,14 @@ function isArray (value: any) { | |||
9 | return Array.isArray(value) | 9 | return Array.isArray(value) |
10 | } | 10 | } |
11 | 11 | ||
12 | function isNotEmptyIntArray (value: any) { | ||
13 | return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0 | ||
14 | } | ||
15 | |||
16 | function isArrayOf (value: any, validator: (value: any) => boolean) { | ||
17 | return isArray(value) && value.every(v => validator(v)) | ||
18 | } | ||
19 | |||
12 | function isDateValid (value: string) { | 20 | function isDateValid (value: string) { |
13 | return exists(value) && validator.isISO8601(value) | 21 | return exists(value) && validator.isISO8601(value) |
14 | } | 22 | } |
@@ -78,6 +86,8 @@ function isFileValid ( | |||
78 | 86 | ||
79 | export { | 87 | export { |
80 | exists, | 88 | exists, |
89 | isArrayOf, | ||
90 | isNotEmptyIntArray, | ||
81 | isArray, | 91 | isArray, |
82 | isIdValid, | 92 | isIdValid, |
83 | isUUIDValid, | 93 | isUUIDValid, |
diff --git a/server/helpers/custom-validators/servers.ts b/server/helpers/custom-validators/servers.ts index d5021bf38..18c80ec8f 100644 --- a/server/helpers/custom-validators/servers.ts +++ b/server/helpers/custom-validators/servers.ts | |||
@@ -3,6 +3,7 @@ import 'express-validator' | |||
3 | 3 | ||
4 | import { isArray, exists } from './misc' | 4 | import { isArray, exists } from './misc' |
5 | import { isTestInstance } from '../core-utils' | 5 | import { isTestInstance } from '../core-utils' |
6 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
6 | 7 | ||
7 | function isHostValid (host: string) { | 8 | function isHostValid (host: string) { |
8 | const isURLOptions = { | 9 | const isURLOptions = { |
@@ -26,9 +27,19 @@ function isEachUniqueHostValid (hosts: string[]) { | |||
26 | }) | 27 | }) |
27 | } | 28 | } |
28 | 29 | ||
30 | function isValidContactBody (value: any) { | ||
31 | return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.BODY) | ||
32 | } | ||
33 | |||
34 | function isValidContactFromName (value: any) { | ||
35 | return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.FROM_NAME) | ||
36 | } | ||
37 | |||
29 | // --------------------------------------------------------------------------- | 38 | // --------------------------------------------------------------------------- |
30 | 39 | ||
31 | export { | 40 | export { |
41 | isValidContactBody, | ||
42 | isValidContactFromName, | ||
32 | isEachUniqueHostValid, | 43 | isEachUniqueHostValid, |
33 | isHostValid | 44 | isHostValid |
34 | } | 45 | } |
diff --git a/server/helpers/custom-validators/user-notifications.ts b/server/helpers/custom-validators/user-notifications.ts new file mode 100644 index 000000000..02ea3bbc2 --- /dev/null +++ b/server/helpers/custom-validators/user-notifications.ts | |||
@@ -0,0 +1,23 @@ | |||
1 | import { exists } from './misc' | ||
2 | import * as validator from 'validator' | ||
3 | import { UserNotificationType } from '../../../shared/models/users' | ||
4 | import { UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model' | ||
5 | |||
6 | function isUserNotificationTypeValid (value: any) { | ||
7 | return exists(value) && validator.isInt('' + value) && UserNotificationType[value] !== undefined | ||
8 | } | ||
9 | |||
10 | function isUserNotificationSettingValid (value: any) { | ||
11 | return exists(value) && | ||
12 | validator.isInt('' + value) && ( | ||
13 | value === UserNotificationSettingValue.NONE || | ||
14 | value === UserNotificationSettingValue.WEB || | ||
15 | value === UserNotificationSettingValue.EMAIL || | ||
16 | value === (UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL) | ||
17 | ) | ||
18 | } | ||
19 | |||
20 | export { | ||
21 | isUserNotificationSettingValid, | ||
22 | isUserNotificationTypeValid | ||
23 | } | ||
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index 90fc74a48..80652b479 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts | |||
@@ -42,6 +42,14 @@ function isUserNSFWPolicyValid (value: any) { | |||
42 | return exists(value) && nsfwPolicies.indexOf(value) !== -1 | 42 | return exists(value) && nsfwPolicies.indexOf(value) !== -1 |
43 | } | 43 | } |
44 | 44 | ||
45 | function isUserWebTorrentEnabledValid (value: any) { | ||
46 | return isBooleanValid(value) | ||
47 | } | ||
48 | |||
49 | function isUserVideosHistoryEnabledValid (value: any) { | ||
50 | return isBooleanValid(value) | ||
51 | } | ||
52 | |||
45 | function isUserAutoPlayVideoValid (value: any) { | 53 | function isUserAutoPlayVideoValid (value: any) { |
46 | return isBooleanValid(value) | 54 | return isBooleanValid(value) |
47 | } | 55 | } |
@@ -69,6 +77,7 @@ function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | | |||
69 | // --------------------------------------------------------------------------- | 77 | // --------------------------------------------------------------------------- |
70 | 78 | ||
71 | export { | 79 | export { |
80 | isUserVideosHistoryEnabledValid, | ||
72 | isUserBlockedValid, | 81 | isUserBlockedValid, |
73 | isUserPasswordValid, | 82 | isUserPasswordValid, |
74 | isUserBlockedReasonValid, | 83 | isUserBlockedReasonValid, |
@@ -78,6 +87,7 @@ export { | |||
78 | isUserUsernameValid, | 87 | isUserUsernameValid, |
79 | isUserEmailVerifiedValid, | 88 | isUserEmailVerifiedValid, |
80 | isUserNSFWPolicyValid, | 89 | isUserNSFWPolicyValid, |
90 | isUserWebTorrentEnabledValid, | ||
81 | isUserAutoPlayVideoValid, | 91 | isUserAutoPlayVideoValid, |
82 | isUserDisplayNameValid, | 92 | isUserDisplayNameValid, |
83 | isUserDescriptionValid, | 93 | isUserDescriptionValid, |
diff --git a/server/helpers/custom-validators/video-captions.ts b/server/helpers/custom-validators/video-captions.ts index 177e9e86e..b33d90e18 100644 --- a/server/helpers/custom-validators/video-captions.ts +++ b/server/helpers/custom-validators/video-captions.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES } from '../../initializers' | 1 | import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_LANGUAGES } from '../../initializers' |
2 | import { exists, isFileValid } from './misc' | 2 | import { exists, isFileValid } from './misc' |
3 | import { Response } from 'express' | 3 | import { Response } from 'express' |
4 | import { VideoModel } from '../../models/video/video' | 4 | import { VideoModel } from '../../models/video/video' |
@@ -8,7 +8,7 @@ function isVideoCaptionLanguageValid (value: any) { | |||
8 | return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined | 8 | return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined |
9 | } | 9 | } |
10 | 10 | ||
11 | const videoCaptionTypes = Object.keys(VIDEO_CAPTIONS_MIMETYPE_EXT) | 11 | const videoCaptionTypes = Object.keys(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT) |
12 | .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream >< | 12 | .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream >< |
13 | .map(m => `(${m})`) | 13 | .map(m => `(${m})`) |
14 | const videoCaptionTypesRegex = videoCaptionTypes.join('|') | 14 | const videoCaptionTypesRegex = videoCaptionTypes.join('|') |
diff --git a/server/helpers/custom-validators/video-imports.ts b/server/helpers/custom-validators/video-imports.ts index 4d6ab1fa4..ce9e9193c 100644 --- a/server/helpers/custom-validators/video-imports.ts +++ b/server/helpers/custom-validators/video-imports.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import 'express-validator' | 1 | import 'express-validator' |
2 | import 'multer' | 2 | import 'multer' |
3 | import * as validator from 'validator' | 3 | import * as validator from 'validator' |
4 | import { CONSTRAINTS_FIELDS, TORRENT_MIMETYPE_EXT, VIDEO_IMPORT_STATES } from '../../initializers' | 4 | import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers' |
5 | import { exists, isFileValid } from './misc' | 5 | import { exists, isFileValid } from './misc' |
6 | import * as express from 'express' | 6 | import * as express from 'express' |
7 | import { VideoImportModel } from '../../models/video/video-import' | 7 | import { VideoImportModel } from '../../models/video/video-import' |
@@ -24,7 +24,7 @@ function isVideoImportStateValid (value: any) { | |||
24 | return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined | 24 | return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined |
25 | } | 25 | } |
26 | 26 | ||
27 | const videoTorrentImportTypes = Object.keys(TORRENT_MIMETYPE_EXT).map(m => `(${m})`) | 27 | const videoTorrentImportTypes = Object.keys(MIMETYPES.TORRENT.MIMETYPE_EXT).map(m => `(${m})`) |
28 | const videoTorrentImportRegex = videoTorrentImportTypes.join('|') | 28 | const videoTorrentImportRegex = videoTorrentImportTypes.join('|') |
29 | function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { | 29 | function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { |
30 | return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) | 30 | return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) |
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 714f7ac95..95e256b8f 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -3,12 +3,11 @@ import 'express-validator' | |||
3 | import { values } from 'lodash' | 3 | import { values } from 'lodash' |
4 | import 'multer' | 4 | import 'multer' |
5 | import * as validator from 'validator' | 5 | import * as validator from 'validator' |
6 | import { UserRight, VideoPrivacy, VideoRateType } from '../../../shared' | 6 | import { UserRight, VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared' |
7 | import { | 7 | import { |
8 | CONSTRAINTS_FIELDS, | 8 | CONSTRAINTS_FIELDS, MIMETYPES, |
9 | VIDEO_CATEGORIES, | 9 | VIDEO_CATEGORIES, |
10 | VIDEO_LICENCES, | 10 | VIDEO_LICENCES, |
11 | VIDEO_MIMETYPE_EXT, | ||
12 | VIDEO_PRIVACIES, | 11 | VIDEO_PRIVACIES, |
13 | VIDEO_RATE_TYPES, | 12 | VIDEO_RATE_TYPES, |
14 | VIDEO_STATES | 13 | VIDEO_STATES |
@@ -22,6 +21,10 @@ import { fetchVideo, VideoFetchType } from '../video' | |||
22 | 21 | ||
23 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | 22 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
24 | 23 | ||
24 | function isVideoFilterValid (filter: VideoFilter) { | ||
25 | return filter === 'local' || filter === 'all-local' | ||
26 | } | ||
27 | |||
25 | function isVideoCategoryValid (value: any) { | 28 | function isVideoCategoryValid (value: any) { |
26 | return value === null || VIDEO_CATEGORIES[ value ] !== undefined | 29 | return value === null || VIDEO_CATEGORIES[ value ] !== undefined |
27 | } | 30 | } |
@@ -79,10 +82,15 @@ function isVideoRatingTypeValid (value: string) { | |||
79 | return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 | 82 | return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 |
80 | } | 83 | } |
81 | 84 | ||
82 | const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`) | 85 | function isVideoFileExtnameValid (value: string) { |
83 | const videoFileTypesRegex = videoFileTypes.join('|') | 86 | return exists(value) && MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined |
87 | } | ||
84 | 88 | ||
85 | function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { | 89 | function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { |
90 | const videoFileTypesRegex = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT) | ||
91 | .map(m => `(${m})`) | ||
92 | .join('|') | ||
93 | |||
86 | return isFileValid(files, videoFileTypesRegex, 'videofile', null) | 94 | return isFileValid(files, videoFileTypesRegex, 'videofile', null) |
87 | } | 95 | } |
88 | 96 | ||
@@ -217,6 +225,7 @@ export { | |||
217 | isVideoStateValid, | 225 | isVideoStateValid, |
218 | isVideoViewsValid, | 226 | isVideoViewsValid, |
219 | isVideoRatingTypeValid, | 227 | isVideoRatingTypeValid, |
228 | isVideoFileExtnameValid, | ||
220 | isVideoDurationValid, | 229 | isVideoDurationValid, |
221 | isVideoTagValid, | 230 | isVideoTagValid, |
222 | isVideoPrivacyValid, | 231 | isVideoPrivacyValid, |
@@ -225,5 +234,6 @@ export { | |||
225 | isVideoExist, | 234 | isVideoExist, |
226 | isVideoImage, | 235 | isVideoImage, |
227 | isVideoChannelOfAccountExist, | 236 | isVideoChannelOfAccountExist, |
228 | isVideoSupportValid | 237 | isVideoSupportValid, |
238 | isVideoFilterValid | ||
229 | } | 239 | } |