diff options
Diffstat (limited to 'server/lib/activitypub/context.ts')
-rw-r--r-- | server/lib/activitypub/context.ts | 275 |
1 files changed, 153 insertions, 122 deletions
diff --git a/server/lib/activitypub/context.ts b/server/lib/activitypub/context.ts index 71f08da80..3bc40e2aa 100644 --- a/server/lib/activitypub/context.ts +++ b/server/lib/activitypub/context.ts | |||
@@ -1,137 +1,168 @@ | |||
1 | import { ContextType } from '@shared/models' | 1 | import { ContextType } from '@shared/models' |
2 | 2 | ||
3 | function getContextData (type: ContextType) { | 3 | function activityPubContextify <T> (data: T, type: ContextType) { |
4 | const context: any[] = [ | 4 | return { ...getContextData(type), ...data } |
5 | 'https://www.w3.org/ns/activitystreams', | 5 | } |
6 | 'https://w3id.org/security/v1', | 6 | |
7 | { | 7 | // --------------------------------------------------------------------------- |
8 | RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' | 8 | |
9 | export { | ||
10 | getContextData, | ||
11 | activityPubContextify | ||
12 | } | ||
13 | |||
14 | // --------------------------------------------------------------------------- | ||
15 | |||
16 | type ContextValue = { [ id: string ]: (string | { '@type': string, '@id': string }) } | ||
17 | |||
18 | const contextStore = { | ||
19 | Video: buildContext({ | ||
20 | Hashtag: 'as:Hashtag', | ||
21 | uuid: 'sc:identifier', | ||
22 | category: 'sc:category', | ||
23 | licence: 'sc:license', | ||
24 | subtitleLanguage: 'sc:subtitleLanguage', | ||
25 | sensitive: 'as:sensitive', | ||
26 | language: 'sc:inLanguage', | ||
27 | |||
28 | // TODO: remove in a few versions, introduced in 4.2 | ||
29 | icons: 'as:icon', | ||
30 | |||
31 | isLiveBroadcast: 'sc:isLiveBroadcast', | ||
32 | liveSaveReplay: { | ||
33 | '@type': 'sc:Boolean', | ||
34 | '@id': 'pt:liveSaveReplay' | ||
35 | }, | ||
36 | permanentLive: { | ||
37 | '@type': 'sc:Boolean', | ||
38 | '@id': 'pt:permanentLive' | ||
39 | }, | ||
40 | latencyMode: { | ||
41 | '@type': 'sc:Number', | ||
42 | '@id': 'pt:latencyMode' | ||
43 | }, | ||
44 | |||
45 | Infohash: 'pt:Infohash', | ||
46 | |||
47 | originallyPublishedAt: 'sc:datePublished', | ||
48 | views: { | ||
49 | '@type': 'sc:Number', | ||
50 | '@id': 'pt:views' | ||
51 | }, | ||
52 | state: { | ||
53 | '@type': 'sc:Number', | ||
54 | '@id': 'pt:state' | ||
55 | }, | ||
56 | size: { | ||
57 | '@type': 'sc:Number', | ||
58 | '@id': 'pt:size' | ||
59 | }, | ||
60 | fps: { | ||
61 | '@type': 'sc:Number', | ||
62 | '@id': 'pt:fps' | ||
63 | }, | ||
64 | commentsEnabled: { | ||
65 | '@type': 'sc:Boolean', | ||
66 | '@id': 'pt:commentsEnabled' | ||
67 | }, | ||
68 | downloadEnabled: { | ||
69 | '@type': 'sc:Boolean', | ||
70 | '@id': 'pt:downloadEnabled' | ||
71 | }, | ||
72 | waitTranscoding: { | ||
73 | '@type': 'sc:Boolean', | ||
74 | '@id': 'pt:waitTranscoding' | ||
75 | }, | ||
76 | support: { | ||
77 | '@type': 'sc:Text', | ||
78 | '@id': 'pt:support' | ||
79 | }, | ||
80 | likes: { | ||
81 | '@id': 'as:likes', | ||
82 | '@type': '@id' | ||
83 | }, | ||
84 | dislikes: { | ||
85 | '@id': 'as:dislikes', | ||
86 | '@type': '@id' | ||
87 | }, | ||
88 | shares: { | ||
89 | '@id': 'as:shares', | ||
90 | '@type': '@id' | ||
91 | }, | ||
92 | comments: { | ||
93 | '@id': 'as:comments', | ||
94 | '@type': '@id' | ||
9 | } | 95 | } |
10 | ] | 96 | }), |
11 | 97 | ||
12 | if (type !== 'View' && type !== 'Announce') { | 98 | Playlist: buildContext({ |
13 | const additional = { | 99 | Playlist: 'pt:Playlist', |
14 | pt: 'https://joinpeertube.org/ns#', | 100 | PlaylistElement: 'pt:PlaylistElement', |
15 | sc: 'http://schema.org#' | 101 | position: { |
102 | '@type': 'sc:Number', | ||
103 | '@id': 'pt:position' | ||
104 | }, | ||
105 | startTimestamp: { | ||
106 | '@type': 'sc:Number', | ||
107 | '@id': 'pt:startTimestamp' | ||
108 | }, | ||
109 | stopTimestamp: { | ||
110 | '@type': 'sc:Number', | ||
111 | '@id': 'pt:stopTimestamp' | ||
16 | } | 112 | } |
113 | }), | ||
114 | |||
115 | CacheFile: buildContext({ | ||
116 | expires: 'sc:expires', | ||
117 | CacheFile: 'pt:CacheFile' | ||
118 | }), | ||
17 | 119 | ||
18 | if (type === 'CacheFile') { | 120 | Flag: buildContext({ |
19 | Object.assign(additional, { | 121 | Hashtag: 'as:Hashtag' |
20 | expires: 'sc:expires', | 122 | }), |
21 | CacheFile: 'pt:CacheFile' | 123 | |
22 | }) | 124 | Actor: buildContext({ |
23 | } else { | 125 | playlists: { |
24 | Object.assign(additional, { | 126 | '@id': 'pt:playlists', |
25 | Hashtag: 'as:Hashtag', | 127 | '@type': '@id' |
26 | uuid: 'sc:identifier', | ||
27 | category: 'sc:category', | ||
28 | licence: 'sc:license', | ||
29 | subtitleLanguage: 'sc:subtitleLanguage', | ||
30 | sensitive: 'as:sensitive', | ||
31 | language: 'sc:inLanguage', | ||
32 | |||
33 | // TODO: remove in a few versions, introduced in 4.2 | ||
34 | icons: 'as:icon', | ||
35 | |||
36 | isLiveBroadcast: 'sc:isLiveBroadcast', | ||
37 | liveSaveReplay: { | ||
38 | '@type': 'sc:Boolean', | ||
39 | '@id': 'pt:liveSaveReplay' | ||
40 | }, | ||
41 | permanentLive: { | ||
42 | '@type': 'sc:Boolean', | ||
43 | '@id': 'pt:permanentLive' | ||
44 | }, | ||
45 | latencyMode: { | ||
46 | '@type': 'sc:Number', | ||
47 | '@id': 'pt:latencyMode' | ||
48 | }, | ||
49 | |||
50 | Infohash: 'pt:Infohash', | ||
51 | Playlist: 'pt:Playlist', | ||
52 | PlaylistElement: 'pt:PlaylistElement', | ||
53 | |||
54 | originallyPublishedAt: 'sc:datePublished', | ||
55 | views: { | ||
56 | '@type': 'sc:Number', | ||
57 | '@id': 'pt:views' | ||
58 | }, | ||
59 | state: { | ||
60 | '@type': 'sc:Number', | ||
61 | '@id': 'pt:state' | ||
62 | }, | ||
63 | size: { | ||
64 | '@type': 'sc:Number', | ||
65 | '@id': 'pt:size' | ||
66 | }, | ||
67 | fps: { | ||
68 | '@type': 'sc:Number', | ||
69 | '@id': 'pt:fps' | ||
70 | }, | ||
71 | startTimestamp: { | ||
72 | '@type': 'sc:Number', | ||
73 | '@id': 'pt:startTimestamp' | ||
74 | }, | ||
75 | stopTimestamp: { | ||
76 | '@type': 'sc:Number', | ||
77 | '@id': 'pt:stopTimestamp' | ||
78 | }, | ||
79 | position: { | ||
80 | '@type': 'sc:Number', | ||
81 | '@id': 'pt:position' | ||
82 | }, | ||
83 | commentsEnabled: { | ||
84 | '@type': 'sc:Boolean', | ||
85 | '@id': 'pt:commentsEnabled' | ||
86 | }, | ||
87 | downloadEnabled: { | ||
88 | '@type': 'sc:Boolean', | ||
89 | '@id': 'pt:downloadEnabled' | ||
90 | }, | ||
91 | waitTranscoding: { | ||
92 | '@type': 'sc:Boolean', | ||
93 | '@id': 'pt:waitTranscoding' | ||
94 | }, | ||
95 | support: { | ||
96 | '@type': 'sc:Text', | ||
97 | '@id': 'pt:support' | ||
98 | }, | ||
99 | likes: { | ||
100 | '@id': 'as:likes', | ||
101 | '@type': '@id' | ||
102 | }, | ||
103 | dislikes: { | ||
104 | '@id': 'as:dislikes', | ||
105 | '@type': '@id' | ||
106 | }, | ||
107 | playlists: { | ||
108 | '@id': 'pt:playlists', | ||
109 | '@type': '@id' | ||
110 | }, | ||
111 | shares: { | ||
112 | '@id': 'as:shares', | ||
113 | '@type': '@id' | ||
114 | }, | ||
115 | comments: { | ||
116 | '@id': 'as:comments', | ||
117 | '@type': '@id' | ||
118 | } | ||
119 | }) | ||
120 | } | 128 | } |
129 | }), | ||
121 | 130 | ||
122 | context.push(additional) | 131 | Follow: buildContext(), |
123 | } | 132 | Reject: buildContext(), |
133 | Accept: buildContext(), | ||
134 | View: buildContext(), | ||
135 | Announce: buildContext(), | ||
136 | Comment: buildContext(), | ||
137 | Delete: buildContext(), | ||
138 | Rate: buildContext() | ||
139 | } | ||
124 | 140 | ||
141 | function getContextData (type: ContextType) { | ||
125 | return { | 142 | return { |
126 | '@context': context | 143 | '@context': contextStore[type] |
127 | } | 144 | } |
128 | } | 145 | } |
129 | 146 | ||
130 | function activityPubContextify <T> (data: T, type: ContextType = 'All') { | 147 | function buildContext (contextValue?: ContextValue) { |
131 | return Object.assign({}, data, getContextData(type)) | 148 | const baseContext = [ |
132 | } | 149 | 'https://www.w3.org/ns/activitystreams', |
150 | 'https://w3id.org/security/v1', | ||
151 | { | ||
152 | RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' | ||
153 | } | ||
154 | ] | ||
133 | 155 | ||
134 | export { | 156 | if (!contextValue) return baseContext |
135 | getContextData, | 157 | |
136 | activityPubContextify | 158 | return [ |
159 | ...baseContext, | ||
160 | |||
161 | { | ||
162 | pt: 'https://joinpeertube.org/ns#', | ||
163 | sc: 'http://schema.org#', | ||
164 | |||
165 | ...contextValue | ||
166 | } | ||
167 | ] | ||
137 | } | 168 | } |