]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/activitypub/videos.ts
89c49b0dfd36d222839e84ebe4483829520c82bd
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / activitypub / videos.ts
1 import * as validator from 'validator'
2 import { ACTIVITY_PUB } from '../../../initializers'
3 import { exists, isDateValid, isUUIDValid } from '../misc'
4 import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels'
5 import {
6 isVideoAbuseReasonValid,
7 isVideoDurationValid,
8 isVideoNameValid,
9 isVideoNSFWValid,
10 isVideoTagValid,
11 isVideoTruncatedDescriptionValid,
12 isVideoUrlValid,
13 isVideoViewsValid
14 } from '../videos'
15 import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
16
17 function isVideoTorrentAddActivityValid (activity: any) {
18 return isBaseActivityValid(activity, 'Add') &&
19 isVideoTorrentObjectValid(activity.object)
20 }
21
22 function isVideoTorrentUpdateActivityValid (activity: any) {
23 return isBaseActivityValid(activity, 'Update') &&
24 isVideoTorrentObjectValid(activity.object)
25 }
26
27 function isVideoTorrentDeleteActivityValid (activity: any) {
28 return isBaseActivityValid(activity, 'Delete')
29 }
30
31 function isActivityPubVideoDurationValid (value: string) {
32 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
33 return exists(value) &&
34 typeof value === 'string' &&
35 value.startsWith('PT') &&
36 value.endsWith('S') &&
37 isVideoDurationValid(value.replace(/[^0-9]+/g, ''))
38 }
39
40 function isVideoTorrentObjectValid (video: any) {
41 return video.type === 'Video' &&
42 isVideoNameValid(video.name) &&
43 isActivityPubVideoDurationValid(video.duration) &&
44 isUUIDValid(video.uuid) &&
45 setValidRemoteTags(video) &&
46 isRemoteIdentifierValid(video.category) &&
47 isRemoteIdentifierValid(video.licence) &&
48 isRemoteIdentifierValid(video.language) &&
49 isVideoViewsValid(video.views) &&
50 isVideoNSFWValid(video.nsfw) &&
51 isDateValid(video.published) &&
52 isDateValid(video.updated) &&
53 isRemoteVideoContentValid(video.mediaType, video.content) &&
54 isRemoteVideoIconValid(video.icon) &&
55 setValidRemoteVideoUrls(video) &&
56 video.url.length !== 0
57 }
58
59 function isVideoFlagValid (activity: any) {
60 return isBaseActivityValid(activity, 'Flag') &&
61 isVideoAbuseReasonValid(activity.content) &&
62 isActivityPubUrlValid(activity.object)
63 }
64
65 function isVideoAnnounceValid (activity: any) {
66 return isBaseActivityValid(activity, 'Announce') &&
67 isVideoTorrentObjectValid(activity.object)
68 }
69
70 function isVideoChannelAnnounceValid (activity: any) {
71 return isBaseActivityValid(activity, 'Announce') &&
72 isVideoChannelObjectValid(activity.object)
73 }
74
75 function isVideoChannelCreateActivityValid (activity: any) {
76 return isBaseActivityValid(activity, 'Create') &&
77 isVideoChannelObjectValid(activity.object)
78 }
79
80 function isVideoChannelUpdateActivityValid (activity: any) {
81 return isBaseActivityValid(activity, 'Update') &&
82 isVideoChannelObjectValid(activity.object)
83 }
84
85 function isVideoChannelDeleteActivityValid (activity: any) {
86 return isBaseActivityValid(activity, 'Delete')
87 }
88
89 function isVideoChannelObjectValid (videoChannel: any) {
90 return videoChannel.type === 'VideoChannel' &&
91 isVideoChannelNameValid(videoChannel.name) &&
92 isVideoChannelDescriptionValid(videoChannel.description) &&
93 isUUIDValid(videoChannel.uuid)
94 }
95
96 // ---------------------------------------------------------------------------
97
98 export {
99 isVideoTorrentAddActivityValid,
100 isVideoChannelCreateActivityValid,
101 isVideoTorrentUpdateActivityValid,
102 isVideoChannelUpdateActivityValid,
103 isVideoChannelDeleteActivityValid,
104 isVideoTorrentDeleteActivityValid,
105 isVideoFlagValid,
106 isVideoAnnounceValid,
107 isVideoChannelAnnounceValid
108 }
109
110 // ---------------------------------------------------------------------------
111
112 function setValidRemoteTags (video: any) {
113 if (Array.isArray(video.tag) === false) return false
114
115 const newTag = video.tag.filter(t => {
116 return t.type === 'Hashtag' &&
117 isVideoTagValid(t.name)
118 })
119
120 video.tag = newTag
121 return true
122 }
123
124 function isRemoteIdentifierValid (data: any) {
125 return validator.isInt(data.identifier, { min: 0 })
126 }
127
128 function isRemoteVideoContentValid (mediaType: string, content: string) {
129 return mediaType === 'text/markdown' && isVideoTruncatedDescriptionValid(content)
130 }
131
132 function isRemoteVideoIconValid (icon: any) {
133 return icon.type === 'Image' &&
134 isVideoUrlValid(icon.url) &&
135 icon.mediaType === 'image/jpeg' &&
136 validator.isInt(icon.width + '', { min: 0 }) &&
137 validator.isInt(icon.height + '', { min: 0 })
138 }
139
140 function setValidRemoteVideoUrls (video: any) {
141 if (Array.isArray(video.url) === false) return false
142
143 const newUrl = video.url.filter(u => isRemoteVideoUrlValid(u))
144 video.url = newUrl
145
146 return true
147 }
148
149 function isRemoteVideoUrlValid (url: any) {
150 return url.type === 'Link' &&
151 ACTIVITY_PUB.VIDEO_URL_MIME_TYPES.indexOf(url.mimeType) !== -1 &&
152 isVideoUrlValid(url.url) &&
153 validator.isInt(url.width + '', { min: 0 }) &&
154 validator.isInt(url.size + '', { min: 0 })
155 }