diff options
author | Chocobozzz <me@florianbigard.com> | 2022-03-23 14:24:50 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-03-23 14:24:50 +0100 |
commit | 7e98a7df7d04e19ba67163a86c7b876d78d76839 (patch) | |
tree | 080c9bf63d2b00b43dca94e3c67cdc2a768308fc /server/helpers/activitypub.ts | |
parent | 5302f77d095c2188859ee463128aa59eec20ea88 (diff) | |
download | PeerTube-7e98a7df7d04e19ba67163a86c7b876d78d76839.tar.gz PeerTube-7e98a7df7d04e19ba67163a86c7b876d78d76839.tar.zst PeerTube-7e98a7df7d04e19ba67163a86c7b876d78d76839.zip |
Remove activitypub helper
Put functions in lib/activitypub instead
Diffstat (limited to 'server/helpers/activitypub.ts')
-rw-r--r-- | server/helpers/activitypub.ts | 229 |
1 files changed, 0 insertions, 229 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts deleted file mode 100644 index 9d6d8b2fa..000000000 --- a/server/helpers/activitypub.ts +++ /dev/null | |||
@@ -1,229 +0,0 @@ | |||
1 | import Bluebird from 'bluebird' | ||
2 | import { URL } from 'url' | ||
3 | import validator from 'validator' | ||
4 | import { ContextType } from '@shared/models/activitypub/context' | ||
5 | import { ResultList } from '../../shared/models' | ||
6 | import { ACTIVITY_PUB, REMOTE_SCHEME } from '../initializers/constants' | ||
7 | import { MActor, MVideoWithHost } from '../types/models' | ||
8 | import { pageToStartAndCount } from './core-utils' | ||
9 | import { signJsonLDObject } from './peertube-crypto' | ||
10 | |||
11 | function getContextData (type: ContextType) { | ||
12 | const context: any[] = [ | ||
13 | 'https://www.w3.org/ns/activitystreams', | ||
14 | 'https://w3id.org/security/v1', | ||
15 | { | ||
16 | RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' | ||
17 | } | ||
18 | ] | ||
19 | |||
20 | if (type !== 'View' && type !== 'Announce') { | ||
21 | const additional = { | ||
22 | pt: 'https://joinpeertube.org/ns#', | ||
23 | sc: 'http://schema.org#' | ||
24 | } | ||
25 | |||
26 | if (type === 'CacheFile') { | ||
27 | Object.assign(additional, { | ||
28 | expires: 'sc:expires', | ||
29 | CacheFile: 'pt:CacheFile' | ||
30 | }) | ||
31 | } else { | ||
32 | Object.assign(additional, { | ||
33 | Hashtag: 'as:Hashtag', | ||
34 | uuid: 'sc:identifier', | ||
35 | category: 'sc:category', | ||
36 | licence: 'sc:license', | ||
37 | subtitleLanguage: 'sc:subtitleLanguage', | ||
38 | sensitive: 'as:sensitive', | ||
39 | language: 'sc:inLanguage', | ||
40 | |||
41 | // TODO: remove in a few versions, introduced in 4.2 | ||
42 | icons: 'as:icon', | ||
43 | |||
44 | isLiveBroadcast: 'sc:isLiveBroadcast', | ||
45 | liveSaveReplay: { | ||
46 | '@type': 'sc:Boolean', | ||
47 | '@id': 'pt:liveSaveReplay' | ||
48 | }, | ||
49 | permanentLive: { | ||
50 | '@type': 'sc:Boolean', | ||
51 | '@id': 'pt:permanentLive' | ||
52 | }, | ||
53 | latencyMode: { | ||
54 | '@type': 'sc:Number', | ||
55 | '@id': 'pt:latencyMode' | ||
56 | }, | ||
57 | |||
58 | Infohash: 'pt:Infohash', | ||
59 | Playlist: 'pt:Playlist', | ||
60 | PlaylistElement: 'pt:PlaylistElement', | ||
61 | |||
62 | originallyPublishedAt: 'sc:datePublished', | ||
63 | views: { | ||
64 | '@type': 'sc:Number', | ||
65 | '@id': 'pt:views' | ||
66 | }, | ||
67 | state: { | ||
68 | '@type': 'sc:Number', | ||
69 | '@id': 'pt:state' | ||
70 | }, | ||
71 | size: { | ||
72 | '@type': 'sc:Number', | ||
73 | '@id': 'pt:size' | ||
74 | }, | ||
75 | fps: { | ||
76 | '@type': 'sc:Number', | ||
77 | '@id': 'pt:fps' | ||
78 | }, | ||
79 | startTimestamp: { | ||
80 | '@type': 'sc:Number', | ||
81 | '@id': 'pt:startTimestamp' | ||
82 | }, | ||
83 | stopTimestamp: { | ||
84 | '@type': 'sc:Number', | ||
85 | '@id': 'pt:stopTimestamp' | ||
86 | }, | ||
87 | position: { | ||
88 | '@type': 'sc:Number', | ||
89 | '@id': 'pt:position' | ||
90 | }, | ||
91 | commentsEnabled: { | ||
92 | '@type': 'sc:Boolean', | ||
93 | '@id': 'pt:commentsEnabled' | ||
94 | }, | ||
95 | downloadEnabled: { | ||
96 | '@type': 'sc:Boolean', | ||
97 | '@id': 'pt:downloadEnabled' | ||
98 | }, | ||
99 | waitTranscoding: { | ||
100 | '@type': 'sc:Boolean', | ||
101 | '@id': 'pt:waitTranscoding' | ||
102 | }, | ||
103 | support: { | ||
104 | '@type': 'sc:Text', | ||
105 | '@id': 'pt:support' | ||
106 | }, | ||
107 | likes: { | ||
108 | '@id': 'as:likes', | ||
109 | '@type': '@id' | ||
110 | }, | ||
111 | dislikes: { | ||
112 | '@id': 'as:dislikes', | ||
113 | '@type': '@id' | ||
114 | }, | ||
115 | playlists: { | ||
116 | '@id': 'pt:playlists', | ||
117 | '@type': '@id' | ||
118 | }, | ||
119 | shares: { | ||
120 | '@id': 'as:shares', | ||
121 | '@type': '@id' | ||
122 | }, | ||
123 | comments: { | ||
124 | '@id': 'as:comments', | ||
125 | '@type': '@id' | ||
126 | } | ||
127 | }) | ||
128 | } | ||
129 | |||
130 | context.push(additional) | ||
131 | } | ||
132 | |||
133 | return { | ||
134 | '@context': context | ||
135 | } | ||
136 | } | ||
137 | |||
138 | function activityPubContextify <T> (data: T, type: ContextType = 'All') { | ||
139 | return Object.assign({}, data, getContextData(type)) | ||
140 | } | ||
141 | |||
142 | type ActivityPubCollectionPaginationHandler = (start: number, count: number) => Bluebird<ResultList<any>> | Promise<ResultList<any>> | ||
143 | async function activityPubCollectionPagination ( | ||
144 | baseUrl: string, | ||
145 | handler: ActivityPubCollectionPaginationHandler, | ||
146 | page?: any, | ||
147 | size = ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE | ||
148 | ) { | ||
149 | if (!page || !validator.isInt(page)) { | ||
150 | // We just display the first page URL, we only need the total items | ||
151 | const result = await handler(0, 1) | ||
152 | |||
153 | return { | ||
154 | id: baseUrl, | ||
155 | type: 'OrderedCollectionPage', | ||
156 | totalItems: result.total, | ||
157 | first: result.data.length === 0 | ||
158 | ? undefined | ||
159 | : baseUrl + '?page=1' | ||
160 | } | ||
161 | } | ||
162 | |||
163 | const { start, count } = pageToStartAndCount(page, size) | ||
164 | const result = await handler(start, count) | ||
165 | |||
166 | let next: string | undefined | ||
167 | let prev: string | undefined | ||
168 | |||
169 | // Assert page is a number | ||
170 | page = parseInt(page, 10) | ||
171 | |||
172 | // There are more results | ||
173 | if (result.total > page * size) { | ||
174 | next = baseUrl + '?page=' + (page + 1) | ||
175 | } | ||
176 | |||
177 | if (page > 1) { | ||
178 | prev = baseUrl + '?page=' + (page - 1) | ||
179 | } | ||
180 | |||
181 | return { | ||
182 | id: baseUrl + '?page=' + page, | ||
183 | type: 'OrderedCollectionPage', | ||
184 | prev, | ||
185 | next, | ||
186 | partOf: baseUrl, | ||
187 | orderedItems: result.data, | ||
188 | totalItems: result.total | ||
189 | } | ||
190 | |||
191 | } | ||
192 | |||
193 | function buildSignedActivity <T> (byActor: MActor, data: T, contextType?: ContextType) { | ||
194 | const activity = activityPubContextify(data, contextType) | ||
195 | |||
196 | return signJsonLDObject(byActor, activity) | ||
197 | } | ||
198 | |||
199 | function getAPId (object: string | { id: string }) { | ||
200 | if (typeof object === 'string') return object | ||
201 | |||
202 | return object.id | ||
203 | } | ||
204 | |||
205 | function checkUrlsSameHost (url1: string, url2: string) { | ||
206 | const idHost = new URL(url1).host | ||
207 | const actorHost = new URL(url2).host | ||
208 | |||
209 | return idHost && actorHost && idHost.toLowerCase() === actorHost.toLowerCase() | ||
210 | } | ||
211 | |||
212 | function buildRemoteVideoBaseUrl (video: MVideoWithHost, path: string, scheme?: string) { | ||
213 | if (!scheme) scheme = REMOTE_SCHEME.HTTP | ||
214 | |||
215 | const host = video.VideoChannel.Actor.Server.host | ||
216 | |||
217 | return scheme + '://' + host + path | ||
218 | } | ||
219 | |||
220 | // --------------------------------------------------------------------------- | ||
221 | |||
222 | export { | ||
223 | checkUrlsSameHost, | ||
224 | getAPId, | ||
225 | activityPubContextify, | ||
226 | activityPubCollectionPagination, | ||
227 | buildSignedActivity, | ||
228 | buildRemoteVideoBaseUrl | ||
229 | } | ||