diff options
Diffstat (limited to 'server/lib/activitypub/send-request.ts')
-rw-r--r-- | server/lib/activitypub/send-request.ts | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts deleted file mode 100644 index 261ff04ab..000000000 --- a/server/lib/activitypub/send-request.ts +++ /dev/null | |||
@@ -1,275 +0,0 @@ | |||
1 | import { Transaction } from 'sequelize' | ||
2 | import { | ||
3 | ActivityAccept, | ||
4 | ActivityAdd, | ||
5 | ActivityCreate, | ||
6 | ActivityDelete, | ||
7 | ActivityFollow, | ||
8 | ActivityUpdate | ||
9 | } from '../../../shared/models/activitypub/activity' | ||
10 | import { getActivityPubUrl } from '../../helpers/activitypub' | ||
11 | import { logger } from '../../helpers/logger' | ||
12 | import { database as db } from '../../initializers' | ||
13 | import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../models' | ||
14 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' | ||
15 | import { activitypubHttpJobScheduler } from '../jobs' | ||
16 | import { ACTIVITY_PUB } from '../../initializers/constants' | ||
17 | import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' | ||
18 | |||
19 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { | ||
20 | const byAccount = videoChannel.Account | ||
21 | |||
22 | const videoChannelObject = videoChannel.toActivityPubObject() | ||
23 | const data = await createActivityData(videoChannel.url, byAccount, videoChannelObject) | ||
24 | |||
25 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | ||
26 | } | ||
27 | |||
28 | async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { | ||
29 | const byAccount = videoChannel.Account | ||
30 | |||
31 | const videoChannelObject = videoChannel.toActivityPubObject() | ||
32 | const data = await updateActivityData(videoChannel.url, byAccount, videoChannelObject) | ||
33 | |||
34 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) | ||
35 | accountsInvolved.push(byAccount) | ||
36 | |||
37 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) | ||
38 | } | ||
39 | |||
40 | async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { | ||
41 | const byAccount = videoChannel.Account | ||
42 | |||
43 | const data = await deleteActivityData(videoChannel.url, byAccount) | ||
44 | |||
45 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) | ||
46 | accountsInvolved.push(byAccount) | ||
47 | |||
48 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) | ||
49 | } | ||
50 | |||
51 | async function sendAddVideo (video: VideoInstance, t: Transaction) { | ||
52 | const byAccount = video.VideoChannel.Account | ||
53 | |||
54 | const videoObject = video.toActivityPubObject() | ||
55 | const data = await addActivityData(video.url, byAccount, video, video.VideoChannel.url, videoObject) | ||
56 | |||
57 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | ||
58 | } | ||
59 | |||
60 | async function sendUpdateVideo (video: VideoInstance, t: Transaction) { | ||
61 | const byAccount = video.VideoChannel.Account | ||
62 | |||
63 | const videoObject = video.toActivityPubObject() | ||
64 | const data = await updateActivityData(video.url, byAccount, videoObject) | ||
65 | |||
66 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) | ||
67 | accountsInvolved.push(byAccount) | ||
68 | |||
69 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) | ||
70 | } | ||
71 | |||
72 | async function sendDeleteVideo (video: VideoInstance, t: Transaction) { | ||
73 | const byAccount = video.VideoChannel.Account | ||
74 | |||
75 | const data = await deleteActivityData(video.url, byAccount) | ||
76 | |||
77 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) | ||
78 | accountsInvolved.push(byAccount) | ||
79 | |||
80 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) | ||
81 | } | ||
82 | |||
83 | async function sendDeleteAccount (account: AccountInstance, t: Transaction) { | ||
84 | const data = await deleteActivityData(account.url, account) | ||
85 | |||
86 | return broadcastToFollowers(data, account, [ account ], t) | ||
87 | } | ||
88 | |||
89 | async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { | ||
90 | const url = getActivityPubUrl('videoChannel', videoChannel.uuid) + '#announce' | ||
91 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject()) | ||
92 | |||
93 | const data = await announceActivityData(url, byAccount, announcedActivity) | ||
94 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | ||
95 | } | ||
96 | |||
97 | async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { | ||
98 | const url = getActivityPubUrl('video', video.uuid) + '#announce' | ||
99 | |||
100 | const videoChannel = video.VideoChannel | ||
101 | const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) | ||
102 | |||
103 | const data = await announceActivityData(url, byAccount, announcedActivity) | ||
104 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | ||
105 | } | ||
106 | |||
107 | async function sendVideoAbuse (byAccount: AccountInstance, videoAbuse: VideoAbuseInstance, video: VideoInstance, t: Transaction) { | ||
108 | const url = getActivityPubUrl('videoAbuse', videoAbuse.id.toString()) | ||
109 | const data = await createActivityData(url, byAccount, videoAbuse.toActivityPubObject()) | ||
110 | |||
111 | return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) | ||
112 | } | ||
113 | |||
114 | async function sendAccept (byAccount: AccountInstance, toAccount: AccountInstance, t: Transaction) { | ||
115 | const data = await acceptActivityData(byAccount) | ||
116 | |||
117 | return unicastTo(data, byAccount, toAccount.inboxUrl, t) | ||
118 | } | ||
119 | |||
120 | async function sendFollow (byAccount: AccountInstance, toAccount: AccountInstance, t: Transaction) { | ||
121 | const data = await followActivityData(toAccount.url, byAccount) | ||
122 | |||
123 | return unicastTo(data, byAccount, toAccount.inboxUrl, t) | ||
124 | } | ||
125 | |||
126 | // --------------------------------------------------------------------------- | ||
127 | |||
128 | export { | ||
129 | sendCreateVideoChannel, | ||
130 | sendUpdateVideoChannel, | ||
131 | sendDeleteVideoChannel, | ||
132 | sendAddVideo, | ||
133 | sendUpdateVideo, | ||
134 | sendDeleteVideo, | ||
135 | sendDeleteAccount, | ||
136 | sendAccept, | ||
137 | sendFollow, | ||
138 | sendVideoAbuse, | ||
139 | sendVideoChannelAnnounce, | ||
140 | sendVideoAnnounce | ||
141 | } | ||
142 | |||
143 | // --------------------------------------------------------------------------- | ||
144 | |||
145 | async function broadcastToFollowers (data: any, byAccount: AccountInstance, toAccountFollowers: AccountInstance[], t: Transaction) { | ||
146 | const toAccountFollowerIds = toAccountFollowers.map(a => a.id) | ||
147 | const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds) | ||
148 | if (result.data.length === 0) { | ||
149 | logger.info('Not broadcast because of 0 followers for %s.', toAccountFollowerIds.join(', ')) | ||
150 | return undefined | ||
151 | } | ||
152 | |||
153 | const jobPayload = { | ||
154 | uris: result.data, | ||
155 | signatureAccountId: byAccount.id, | ||
156 | body: data | ||
157 | } | ||
158 | |||
159 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpBroadcastHandler', jobPayload) | ||
160 | } | ||
161 | |||
162 | async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: string, t: Transaction) { | ||
163 | const jobPayload = { | ||
164 | uris: [ toAccountUrl ], | ||
165 | signatureAccountId: byAccount.id, | ||
166 | body: data | ||
167 | } | ||
168 | |||
169 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) | ||
170 | } | ||
171 | |||
172 | async function getAudience (accountSender: AccountInstance, isPublic = true) { | ||
173 | const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls() | ||
174 | |||
175 | // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47 | ||
176 | let to = [] | ||
177 | let cc = [] | ||
178 | |||
179 | if (isPublic) { | ||
180 | to = [ ACTIVITY_PUB.PUBLIC ] | ||
181 | cc = followerInboxUrls | ||
182 | } else { // Unlisted | ||
183 | to = followerInboxUrls | ||
184 | cc = [ ACTIVITY_PUB.PUBLIC ] | ||
185 | } | ||
186 | |||
187 | return { to, cc } | ||
188 | } | ||
189 | |||
190 | async function createActivityData (url: string, byAccount: AccountInstance, object: any) { | ||
191 | const { to, cc } = await getAudience(byAccount) | ||
192 | const activity: ActivityCreate = { | ||
193 | type: 'Create', | ||
194 | id: url, | ||
195 | actor: byAccount.url, | ||
196 | to, | ||
197 | cc, | ||
198 | object | ||
199 | } | ||
200 | |||
201 | return activity | ||
202 | } | ||
203 | |||
204 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { | ||
205 | const { to, cc } = await getAudience(byAccount) | ||
206 | const activity: ActivityUpdate = { | ||
207 | type: 'Update', | ||
208 | id: url, | ||
209 | actor: byAccount.url, | ||
210 | to, | ||
211 | cc, | ||
212 | object | ||
213 | } | ||
214 | |||
215 | return activity | ||
216 | } | ||
217 | |||
218 | async function deleteActivityData (url: string, byAccount: AccountInstance) { | ||
219 | const activity: ActivityDelete = { | ||
220 | type: 'Delete', | ||
221 | id: url, | ||
222 | actor: byAccount.url | ||
223 | } | ||
224 | |||
225 | return activity | ||
226 | } | ||
227 | |||
228 | async function addActivityData (url: string, byAccount: AccountInstance, video: VideoInstance, target: string, object: any) { | ||
229 | const videoPublic = video.privacy === VideoPrivacy.PUBLIC | ||
230 | |||
231 | const { to, cc } = await getAudience(byAccount, videoPublic) | ||
232 | const activity: ActivityAdd = { | ||
233 | type: 'Add', | ||
234 | id: url, | ||
235 | actor: byAccount.url, | ||
236 | to, | ||
237 | cc, | ||
238 | object, | ||
239 | target | ||
240 | } | ||
241 | |||
242 | return activity | ||
243 | } | ||
244 | |||
245 | async function announceActivityData (url: string, byAccount: AccountInstance, object: any) { | ||
246 | const activity = { | ||
247 | type: 'Announce', | ||
248 | id: url, | ||
249 | actor: byAccount.url, | ||
250 | object | ||
251 | } | ||
252 | |||
253 | return activity | ||
254 | } | ||
255 | |||
256 | async function followActivityData (url: string, byAccount: AccountInstance) { | ||
257 | const activity: ActivityFollow = { | ||
258 | type: 'Follow', | ||
259 | id: byAccount.url, | ||
260 | actor: byAccount.url, | ||
261 | object: url | ||
262 | } | ||
263 | |||
264 | return activity | ||
265 | } | ||
266 | |||
267 | async function acceptActivityData (byAccount: AccountInstance) { | ||
268 | const activity: ActivityAccept = { | ||
269 | type: 'Accept', | ||
270 | id: byAccount.url, | ||
271 | actor: byAccount.url | ||
272 | } | ||
273 | |||
274 | return activity | ||
275 | } | ||