]>
Commit | Line | Data |
---|---|---|
e4f97bab C |
1 | import * as Sequelize from 'sequelize' |
2 | ||
571389d4 | 3 | import { database as db } from '../../initializers' |
e4f97bab C |
4 | import { |
5 | AccountInstance, | |
6 | VideoInstance, | |
7 | VideoChannelInstance | |
8 | } from '../../models' | |
9 | import { httpRequestJobScheduler } from '../jobs' | |
10 | import { signObject, activityPubContextify } from '../../helpers' | |
21e0727a | 11 | import { Activity, VideoAbuseObject } from '../../../shared' |
8e13fa7d C |
12 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' |
13 | import { getActivityPubUrl } from '../../helpers/activitypub' | |
8e10cf1a | 14 | import { logger } from '../../helpers/logger' |
e4f97bab | 15 | |
350e31d6 | 16 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { |
e4f97bab | 17 | const videoChannelObject = videoChannel.toActivityPubObject() |
350e31d6 | 18 | const data = await createActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) |
e4f97bab | 19 | |
efc32059 | 20 | return broadcastToFollowers(data, [ videoChannel.Account ], t) |
e4f97bab C |
21 | } |
22 | ||
350e31d6 | 23 | async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { |
e4f97bab | 24 | const videoChannelObject = videoChannel.toActivityPubObject() |
350e31d6 | 25 | const data = await updateActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) |
e4f97bab | 26 | |
d7d5611c C |
27 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) |
28 | accountsInvolved.push(videoChannel.Account) | |
29 | ||
30 | return broadcastToFollowers(data, accountsInvolved, t) | |
e4f97bab C |
31 | } |
32 | ||
350e31d6 C |
33 | async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { |
34 | const data = await deleteActivityData(videoChannel.url, videoChannel.Account) | |
e4f97bab | 35 | |
d7d5611c C |
36 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) |
37 | accountsInvolved.push(videoChannel.Account) | |
38 | ||
39 | return broadcastToFollowers(data, accountsInvolved, t) | |
e4f97bab C |
40 | } |
41 | ||
350e31d6 | 42 | async function sendAddVideo (video: VideoInstance, t: Sequelize.Transaction) { |
e4f97bab | 43 | const videoObject = video.toActivityPubObject() |
350e31d6 | 44 | const data = await addActivityData(video.url, video.VideoChannel.Account, video.VideoChannel.url, videoObject) |
e4f97bab | 45 | |
efc32059 | 46 | return broadcastToFollowers(data, [ video.VideoChannel.Account ], t) |
e4f97bab C |
47 | } |
48 | ||
350e31d6 | 49 | async function sendUpdateVideo (video: VideoInstance, t: Sequelize.Transaction) { |
e4f97bab | 50 | const videoObject = video.toActivityPubObject() |
350e31d6 | 51 | const data = await updateActivityData(video.url, video.VideoChannel.Account, videoObject) |
e4f97bab | 52 | |
d7d5611c C |
53 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) |
54 | accountsInvolved.push(video.VideoChannel.Account) | |
55 | ||
56 | return broadcastToFollowers(data, accountsInvolved, t) | |
e4f97bab C |
57 | } |
58 | ||
350e31d6 C |
59 | async function sendDeleteVideo (video: VideoInstance, t: Sequelize.Transaction) { |
60 | const data = await deleteActivityData(video.url, video.VideoChannel.Account) | |
e4f97bab | 61 | |
d7d5611c C |
62 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) |
63 | accountsInvolved.push(video.VideoChannel.Account) | |
64 | ||
65 | return broadcastToFollowers(data, accountsInvolved, t) | |
e4f97bab C |
66 | } |
67 | ||
350e31d6 C |
68 | async function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction) { |
69 | const data = await deleteActivityData(account.url, account) | |
7a7724e6 | 70 | |
efc32059 C |
71 | return broadcastToFollowers(data, [ account ], t) |
72 | } | |
73 | ||
20494f12 C |
74 | async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { |
75 | const url = getActivityPubUrl('videoChannel', videoChannel.uuid) + '#announce' | |
76 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), true) | |
77 | ||
78 | const data = await announceActivityData(url, byAccount, announcedActivity) | |
79 | return broadcastToFollowers(data, [ byAccount ], t) | |
80 | } | |
efc32059 | 81 | |
20494f12 C |
82 | async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Sequelize.Transaction) { |
83 | const url = getActivityPubUrl('video', video.uuid) + '#announce' | |
efc32059 | 84 | |
20494f12 C |
85 | const videoChannel = video.VideoChannel |
86 | const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject(), true) | |
87 | ||
88 | const data = await announceActivityData(url, byAccount, announcedActivity) | |
efc32059 | 89 | return broadcastToFollowers(data, [ byAccount ], t) |
7a7724e6 C |
90 | } |
91 | ||
8e13fa7d C |
92 | async function sendVideoAbuse ( |
93 | fromAccount: AccountInstance, | |
94 | videoAbuse: VideoAbuseInstance, | |
95 | video: VideoInstance, | |
96 | t: Sequelize.Transaction | |
97 | ) { | |
98 | const url = getActivityPubUrl('videoAbuse', videoAbuse.id.toString()) | |
21e0727a | 99 | const data = await createActivityData(url, fromAccount, videoAbuse.toActivityPubObject()) |
8e13fa7d C |
100 | |
101 | return unicastTo(data, video.VideoChannel.Account.sharedInboxUrl, t) | |
102 | } | |
103 | ||
350e31d6 C |
104 | async function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { |
105 | const data = await acceptActivityData(fromAccount) | |
ce548a10 | 106 | |
8e13fa7d | 107 | return unicastTo(data, toAccount.inboxUrl, t) |
ce548a10 C |
108 | } |
109 | ||
350e31d6 C |
110 | async function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { |
111 | const data = await followActivityData(toAccount.url, fromAccount) | |
ce548a10 | 112 | |
8e13fa7d | 113 | return unicastTo(data, toAccount.inboxUrl, t) |
ce548a10 C |
114 | } |
115 | ||
e4f97bab C |
116 | // --------------------------------------------------------------------------- |
117 | ||
118 | export { | |
571389d4 C |
119 | sendCreateVideoChannel, |
120 | sendUpdateVideoChannel, | |
121 | sendDeleteVideoChannel, | |
122 | sendAddVideo, | |
123 | sendUpdateVideo, | |
7a7724e6 | 124 | sendDeleteVideo, |
ce548a10 C |
125 | sendDeleteAccount, |
126 | sendAccept, | |
8e13fa7d | 127 | sendFollow, |
efc32059 | 128 | sendVideoAbuse, |
20494f12 C |
129 | sendVideoChannelAnnounce, |
130 | sendVideoAnnounce | |
e4f97bab C |
131 | } |
132 | ||
133 | // --------------------------------------------------------------------------- | |
134 | ||
efc32059 C |
135 | async function broadcastToFollowers (data: any, toAccountFollowers: AccountInstance[], t: Sequelize.Transaction) { |
136 | const toAccountFollowerIds = toAccountFollowers.map(a => a.id) | |
137 | const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds) | |
8e10cf1a | 138 | if (result.data.length === 0) { |
efc32059 | 139 | logger.info('Not broadcast because of 0 followers for %s.', toAccountFollowerIds.join(', ')) |
8e10cf1a C |
140 | return |
141 | } | |
571389d4 C |
142 | |
143 | const jobPayload = { | |
144 | uris: result.data, | |
145 | body: data | |
146 | } | |
147 | ||
148 | return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload) | |
e4f97bab C |
149 | } |
150 | ||
8e13fa7d | 151 | async function unicastTo (data: any, toAccountUrl: string, t: Sequelize.Transaction) { |
ce548a10 | 152 | const jobPayload = { |
8e13fa7d | 153 | uris: [ toAccountUrl ], |
ce548a10 C |
154 | body: data |
155 | } | |
156 | ||
157 | return httpRequestJobScheduler.createJob(t, 'httpRequestUnicastHandler', jobPayload) | |
158 | } | |
159 | ||
e4f97bab C |
160 | function buildSignedActivity (byAccount: AccountInstance, data: Object) { |
161 | const activity = activityPubContextify(data) | |
162 | ||
163 | return signObject(byAccount, activity) as Promise<Activity> | |
164 | } | |
165 | ||
166 | async function getPublicActivityTo (account: AccountInstance) { | |
167 | const inboxUrls = await account.getFollowerSharedInboxUrls() | |
168 | ||
169 | return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') | |
170 | } | |
171 | ||
20494f12 | 172 | async function createActivityData (url: string, byAccount: AccountInstance, object: any, raw = false) { |
e4f97bab C |
173 | const to = await getPublicActivityTo(byAccount) |
174 | const base = { | |
175 | type: 'Create', | |
176 | id: url, | |
177 | actor: byAccount.url, | |
178 | to, | |
179 | object | |
180 | } | |
181 | ||
20494f12 C |
182 | if (raw === true) return base |
183 | ||
e4f97bab C |
184 | return buildSignedActivity(byAccount, base) |
185 | } | |
186 | ||
187 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { | |
188 | const to = await getPublicActivityTo(byAccount) | |
189 | const base = { | |
190 | type: 'Update', | |
191 | id: url, | |
192 | actor: byAccount.url, | |
193 | to, | |
194 | object | |
195 | } | |
196 | ||
197 | return buildSignedActivity(byAccount, base) | |
198 | } | |
199 | ||
7a7724e6 | 200 | async function deleteActivityData (url: string, byAccount: AccountInstance) { |
e4f97bab | 201 | const base = { |
7a7724e6 | 202 | type: 'Delete', |
e4f97bab | 203 | id: url, |
7a7724e6 | 204 | actor: byAccount.url |
e4f97bab C |
205 | } |
206 | ||
207 | return buildSignedActivity(byAccount, base) | |
208 | } | |
209 | ||
20494f12 | 210 | async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any, raw = false) { |
e4f97bab C |
211 | const to = await getPublicActivityTo(byAccount) |
212 | const base = { | |
213 | type: 'Add', | |
214 | id: url, | |
215 | actor: byAccount.url, | |
216 | to, | |
217 | object, | |
218 | target | |
219 | } | |
220 | ||
20494f12 C |
221 | if (raw === true) return base |
222 | ||
e4f97bab C |
223 | return buildSignedActivity(byAccount, base) |
224 | } | |
ce548a10 | 225 | |
efc32059 C |
226 | async function announceActivityData (url: string, byAccount: AccountInstance, object: any) { |
227 | const base = { | |
228 | type: 'Announce', | |
229 | id: url, | |
230 | actor: byAccount.url, | |
231 | object | |
232 | } | |
233 | ||
234 | return buildSignedActivity(byAccount, base) | |
235 | } | |
236 | ||
ce548a10 C |
237 | async function followActivityData (url: string, byAccount: AccountInstance) { |
238 | const base = { | |
239 | type: 'Follow', | |
240 | id: byAccount.url, | |
241 | actor: byAccount.url, | |
242 | object: url | |
243 | } | |
244 | ||
245 | return buildSignedActivity(byAccount, base) | |
246 | } | |
247 | ||
248 | async function acceptActivityData (byAccount: AccountInstance) { | |
249 | const base = { | |
250 | type: 'Accept', | |
251 | id: byAccount.url, | |
252 | actor: byAccount.url | |
253 | } | |
254 | ||
255 | return buildSignedActivity(byAccount, base) | |
256 | } |