diff options
Diffstat (limited to 'server/lib/activitypub')
-rw-r--r-- | server/lib/activitypub/misc.ts | 16 | ||||
-rw-r--r-- | server/lib/activitypub/process-add.ts | 15 | ||||
-rw-r--r-- | server/lib/activitypub/process-update.ts | 1 | ||||
-rw-r--r-- | server/lib/activitypub/send-request.ts | 37 |
4 files changed, 48 insertions, 21 deletions
diff --git a/server/lib/activitypub/misc.ts b/server/lib/activitypub/misc.ts index c07d9f654..4c210eb10 100644 --- a/server/lib/activitypub/misc.ts +++ b/server/lib/activitypub/misc.ts | |||
@@ -2,11 +2,12 @@ import * as magnetUtil from 'magnet-uri' | |||
2 | import { VideoTorrentObject } from '../../../shared' | 2 | import { VideoTorrentObject } from '../../../shared' |
3 | import { VideoChannelObject } from '../../../shared/models/activitypub/objects/video-channel-object' | 3 | import { VideoChannelObject } from '../../../shared/models/activitypub/objects/video-channel-object' |
4 | import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' | 4 | import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' |
5 | import { VIDEO_MIMETYPE_EXT } from '../../initializers/constants' | 5 | import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../initializers/constants' |
6 | import { AccountInstance } from '../../models/account/account-interface' | 6 | import { AccountInstance } from '../../models/account/account-interface' |
7 | import { VideoChannelInstance } from '../../models/video/video-channel-interface' | 7 | import { VideoChannelInstance } from '../../models/video/video-channel-interface' |
8 | import { VideoFileAttributes } from '../../models/video/video-file-interface' | 8 | import { VideoFileAttributes } from '../../models/video/video-file-interface' |
9 | import { VideoAttributes, VideoInstance } from '../../models/video/video-interface' | 9 | import { VideoAttributes, VideoInstance } from '../../models/video/video-interface' |
10 | import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' | ||
10 | 11 | ||
11 | function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { | 12 | function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { |
12 | return { | 13 | return { |
@@ -23,8 +24,14 @@ function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChan | |||
23 | 24 | ||
24 | async function videoActivityObjectToDBAttributes ( | 25 | async function videoActivityObjectToDBAttributes ( |
25 | videoChannel: VideoChannelInstance, | 26 | videoChannel: VideoChannelInstance, |
26 | videoObject: VideoTorrentObject | 27 | videoObject: VideoTorrentObject, |
28 | to: string[] = [], | ||
29 | cc: string[] = [] | ||
27 | ) { | 30 | ) { |
31 | let privacy = VideoPrivacy.PRIVATE | ||
32 | if (to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.PUBLIC | ||
33 | else if (cc.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.UNLISTED | ||
34 | |||
28 | const duration = videoObject.duration.replace(/[^\d]+/, '') | 35 | const duration = videoObject.duration.replace(/[^\d]+/, '') |
29 | const videoData: VideoAttributes = { | 36 | const videoData: VideoAttributes = { |
30 | name: videoObject.name, | 37 | name: videoObject.name, |
@@ -43,11 +50,8 @@ async function videoActivityObjectToDBAttributes ( | |||
43 | views: videoObject.views, | 50 | views: videoObject.views, |
44 | likes: 0, | 51 | likes: 0, |
45 | dislikes: 0, | 52 | dislikes: 0, |
46 | // likes: videoToCreateData.likes, | ||
47 | // dislikes: videoToCreateData.dislikes, | ||
48 | remote: true, | 53 | remote: true, |
49 | privacy: 1 | 54 | privacy |
50 | // privacy: videoToCreateData.privacy | ||
51 | } | 55 | } |
52 | 56 | ||
53 | return videoData | 57 | return videoData |
diff --git a/server/lib/activitypub/process-add.ts b/server/lib/activitypub/process-add.ts index 72c5b1932..c83d9e98e 100644 --- a/server/lib/activitypub/process-add.ts +++ b/server/lib/activitypub/process-add.ts | |||
@@ -17,7 +17,7 @@ async function processAddActivity (activity: ActivityAdd) { | |||
17 | const videoChannelUrl = activity.target | 17 | const videoChannelUrl = activity.target |
18 | const videoChannel = await getOrCreateVideoChannel(account, videoChannelUrl) | 18 | const videoChannel = await getOrCreateVideoChannel(account, videoChannelUrl) |
19 | 19 | ||
20 | return processAddVideo(account, videoChannel, activityObject as VideoTorrentObject) | 20 | return processAddVideo(account, activity, videoChannel, activityObject as VideoTorrentObject) |
21 | } | 21 | } |
22 | 22 | ||
23 | logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id }) | 23 | logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id }) |
@@ -32,16 +32,21 @@ export { | |||
32 | 32 | ||
33 | // --------------------------------------------------------------------------- | 33 | // --------------------------------------------------------------------------- |
34 | 34 | ||
35 | function processAddVideo (account: AccountInstance, videoChannel: VideoChannelInstance, video: VideoTorrentObject) { | 35 | function processAddVideo (account: AccountInstance, activity: ActivityAdd, videoChannel: VideoChannelInstance, video: VideoTorrentObject) { |
36 | const options = { | 36 | const options = { |
37 | arguments: [ account, videoChannel, video ], | 37 | arguments: [ account, activity, videoChannel, video ], |
38 | errorMessage: 'Cannot insert the remote video with many retries.' | 38 | errorMessage: 'Cannot insert the remote video with many retries.' |
39 | } | 39 | } |
40 | 40 | ||
41 | return retryTransactionWrapper(addRemoteVideo, options) | 41 | return retryTransactionWrapper(addRemoteVideo, options) |
42 | } | 42 | } |
43 | 43 | ||
44 | function addRemoteVideo (account: AccountInstance, videoChannel: VideoChannelInstance, videoToCreateData: VideoTorrentObject) { | 44 | function addRemoteVideo ( |
45 | account: AccountInstance, | ||
46 | activity: ActivityAdd, | ||
47 | videoChannel: VideoChannelInstance, | ||
48 | videoToCreateData: VideoTorrentObject | ||
49 | ) { | ||
45 | logger.debug('Adding remote video %s.', videoToCreateData.url) | 50 | logger.debug('Adding remote video %s.', videoToCreateData.url) |
46 | 51 | ||
47 | return db.sequelize.transaction(async t => { | 52 | return db.sequelize.transaction(async t => { |
@@ -54,7 +59,7 @@ function addRemoteVideo (account: AccountInstance, videoChannel: VideoChannelIns | |||
54 | const videoFromDatabase = await db.Video.loadByUUIDOrURL(videoToCreateData.uuid, videoToCreateData.id, t) | 59 | const videoFromDatabase = await db.Video.loadByUUIDOrURL(videoToCreateData.uuid, videoToCreateData.id, t) |
55 | if (videoFromDatabase) throw new Error('Video with this UUID/Url already exists.') | 60 | if (videoFromDatabase) throw new Error('Video with this UUID/Url already exists.') |
56 | 61 | ||
57 | const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData) | 62 | const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData, activity.to, activity.cc) |
58 | const video = db.Video.build(videoData) | 63 | const video = db.Video.build(videoData) |
59 | 64 | ||
60 | // Don't block on request | 65 | // Don't block on request |
diff --git a/server/lib/activitypub/process-update.ts b/server/lib/activitypub/process-update.ts index 4aefd1b9b..b732fce33 100644 --- a/server/lib/activitypub/process-update.ts +++ b/server/lib/activitypub/process-update.ts | |||
@@ -70,7 +70,6 @@ async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpd | |||
70 | videoInstance.set('views', videoData.views) | 70 | videoInstance.set('views', videoData.views) |
71 | // videoInstance.set('likes', videoData.likes) | 71 | // videoInstance.set('likes', videoData.likes) |
72 | // videoInstance.set('dislikes', videoData.dislikes) | 72 | // videoInstance.set('dislikes', videoData.dislikes) |
73 | // videoInstance.set('privacy', videoData.privacy) | ||
74 | 73 | ||
75 | await videoInstance.save(sequelizeOptions) | 74 | await videoInstance.save(sequelizeOptions) |
76 | 75 | ||
diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts index 8d013fa87..68a631a36 100644 --- a/server/lib/activitypub/send-request.ts +++ b/server/lib/activitypub/send-request.ts | |||
@@ -13,6 +13,8 @@ import { database as db } from '../../initializers' | |||
13 | import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../models' | 13 | import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../models' |
14 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' | 14 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' |
15 | import { activitypubHttpJobScheduler } from '../jobs' | 15 | import { activitypubHttpJobScheduler } from '../jobs' |
16 | import { ACTIVITY_PUB } from '../../initializers/constants' | ||
17 | import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum' | ||
16 | 18 | ||
17 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { | 19 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { |
18 | const byAccount = videoChannel.Account | 20 | const byAccount = videoChannel.Account |
@@ -50,7 +52,7 @@ async function sendAddVideo (video: VideoInstance, t: Transaction) { | |||
50 | const byAccount = video.VideoChannel.Account | 52 | const byAccount = video.VideoChannel.Account |
51 | 53 | ||
52 | const videoObject = video.toActivityPubObject() | 54 | const videoObject = video.toActivityPubObject() |
53 | const data = await addActivityData(video.url, byAccount, video.VideoChannel.url, videoObject) | 55 | const data = await addActivityData(video.url, byAccount, video, video.VideoChannel.url, videoObject) |
54 | 56 | ||
55 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | 57 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
56 | } | 58 | } |
@@ -96,7 +98,7 @@ async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstan | |||
96 | const url = getActivityPubUrl('video', video.uuid) + '#announce' | 98 | const url = getActivityPubUrl('video', video.uuid) + '#announce' |
97 | 99 | ||
98 | const videoChannel = video.VideoChannel | 100 | const videoChannel = video.VideoChannel |
99 | const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject()) | 101 | const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) |
100 | 102 | ||
101 | const data = await announceActivityData(url, byAccount, announcedActivity) | 103 | const data = await announceActivityData(url, byAccount, announcedActivity) |
102 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | 104 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
@@ -167,19 +169,32 @@ async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: s | |||
167 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) | 169 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) |
168 | } | 170 | } |
169 | 171 | ||
170 | async function getPublicActivityTo (account: AccountInstance) { | 172 | async function getAudience (accountSender: AccountInstance, isPublic = true) { |
171 | const inboxUrls = await account.getFollowerSharedInboxUrls() | 173 | const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls() |
172 | 174 | ||
173 | return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') | 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 } | ||
174 | } | 188 | } |
175 | 189 | ||
176 | async function createActivityData (url: string, byAccount: AccountInstance, object: any) { | 190 | async function createActivityData (url: string, byAccount: AccountInstance, object: any) { |
177 | const to = await getPublicActivityTo(byAccount) | 191 | const { to, cc } = await getAudience(byAccount) |
178 | const activity: ActivityCreate = { | 192 | const activity: ActivityCreate = { |
179 | type: 'Create', | 193 | type: 'Create', |
180 | id: url, | 194 | id: url, |
181 | actor: byAccount.url, | 195 | actor: byAccount.url, |
182 | to, | 196 | to, |
197 | cc, | ||
183 | object | 198 | object |
184 | } | 199 | } |
185 | 200 | ||
@@ -187,12 +202,13 @@ async function createActivityData (url: string, byAccount: AccountInstance, obje | |||
187 | } | 202 | } |
188 | 203 | ||
189 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { | 204 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { |
190 | const to = await getPublicActivityTo(byAccount) | 205 | const { to, cc } = await getAudience(byAccount) |
191 | const activity: ActivityUpdate = { | 206 | const activity: ActivityUpdate = { |
192 | type: 'Update', | 207 | type: 'Update', |
193 | id: url, | 208 | id: url, |
194 | actor: byAccount.url, | 209 | actor: byAccount.url, |
195 | to, | 210 | to, |
211 | cc, | ||
196 | object | 212 | object |
197 | } | 213 | } |
198 | 214 | ||
@@ -209,13 +225,16 @@ async function deleteActivityData (url: string, byAccount: AccountInstance) { | |||
209 | return activity | 225 | return activity |
210 | } | 226 | } |
211 | 227 | ||
212 | async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any) { | 228 | async function addActivityData (url: string, byAccount: AccountInstance, video: VideoInstance, target: string, object: any) { |
213 | const to = await getPublicActivityTo(byAccount) | 229 | const videoPublic = video.privacy === VideoPrivacy.PUBLIC |
230 | |||
231 | const { to, cc } = await getAudience(byAccount, videoPublic) | ||
214 | const activity: ActivityAdd = { | 232 | const activity: ActivityAdd = { |
215 | type: 'Add', | 233 | type: 'Add', |
216 | id: url, | 234 | id: url, |
217 | actor: byAccount.url, | 235 | actor: byAccount.url, |
218 | to, | 236 | to, |
237 | cc, | ||
219 | object, | 238 | object, |
220 | target | 239 | target |
221 | } | 240 | } |