aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/send
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/activitypub/send')
-rw-r--r--server/lib/activitypub/send/send-accept.ts8
-rw-r--r--server/lib/activitypub/send/send-announce.ts33
-rw-r--r--server/lib/activitypub/send/send-create.ts68
-rw-r--r--server/lib/activitypub/send/send-delete.ts25
-rw-r--r--server/lib/activitypub/send/send-follow.ts6
-rw-r--r--server/lib/activitypub/send/send-like.ts10
-rw-r--r--server/lib/activitypub/send/send-undo.ts63
-rw-r--r--server/lib/activitypub/send/send-update.ts38
-rw-r--r--server/lib/activitypub/send/utils.ts8
9 files changed, 153 insertions, 106 deletions
diff --git a/server/lib/activitypub/send/send-accept.ts b/server/lib/activitypub/send/send-accept.ts
index ef679707b..b6abde13d 100644
--- a/server/lib/activitypub/send/send-accept.ts
+++ b/server/lib/activitypub/send/send-accept.ts
@@ -3,7 +3,7 @@ import { ActorModel } from '../../../models/activitypub/actor'
3import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 3import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
4import { getActorFollowAcceptActivityPubUrl, getActorFollowActivityPubUrl } from '../url' 4import { getActorFollowAcceptActivityPubUrl, getActorFollowActivityPubUrl } from '../url'
5import { unicastTo } from './utils' 5import { unicastTo } from './utils'
6import { followActivityData } from './send-follow' 6import { buildFollowActivity } from './send-follow'
7import { logger } from '../../../helpers/logger' 7import { logger } from '../../../helpers/logger'
8 8
9async function sendAccept (actorFollow: ActorFollowModel) { 9async function sendAccept (actorFollow: ActorFollowModel) {
@@ -18,10 +18,10 @@ async function sendAccept (actorFollow: ActorFollowModel) {
18 logger.info('Creating job to accept follower %s.', follower.url) 18 logger.info('Creating job to accept follower %s.', follower.url)
19 19
20 const followUrl = getActorFollowActivityPubUrl(actorFollow) 20 const followUrl = getActorFollowActivityPubUrl(actorFollow)
21 const followData = followActivityData(followUrl, follower, me) 21 const followData = buildFollowActivity(followUrl, follower, me)
22 22
23 const url = getActorFollowAcceptActivityPubUrl(actorFollow) 23 const url = getActorFollowAcceptActivityPubUrl(actorFollow)
24 const data = acceptActivityData(url, me, followData) 24 const data = buildAcceptActivity(url, me, followData)
25 25
26 return unicastTo(data, me, follower.inboxUrl) 26 return unicastTo(data, me, follower.inboxUrl)
27} 27}
@@ -34,7 +34,7 @@ export {
34 34
35// --------------------------------------------------------------------------- 35// ---------------------------------------------------------------------------
36 36
37function acceptActivityData (url: string, byActor: ActorModel, followActivityData: ActivityFollow): ActivityAccept { 37function buildAcceptActivity (url: string, byActor: ActorModel, followActivityData: ActivityFollow): ActivityAccept {
38 return { 38 return {
39 type: 'Accept', 39 type: 'Accept',
40 id: url, 40 id: url,
diff --git a/server/lib/activitypub/send/send-announce.ts b/server/lib/activitypub/send/send-announce.ts
index 352813d73..f137217f8 100644
--- a/server/lib/activitypub/send/send-announce.ts
+++ b/server/lib/activitypub/send/send-announce.ts
@@ -4,45 +4,44 @@ import { ActorModel } from '../../../models/activitypub/actor'
4import { VideoModel } from '../../../models/video/video' 4import { VideoModel } from '../../../models/video/video'
5import { VideoShareModel } from '../../../models/video/video-share' 5import { VideoShareModel } from '../../../models/video/video-share'
6import { broadcastToFollowers } from './utils' 6import { broadcastToFollowers } from './utils'
7import { getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience' 7import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience'
8import { logger } from '../../../helpers/logger' 8import { logger } from '../../../helpers/logger'
9 9
10async function buildVideoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) { 10async function buildAnnounceWithVideoAudience (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
11 const announcedObject = video.url 11 const announcedObject = video.url
12 12
13 const accountsToForwardView = await getActorsInvolvedInVideo(video, t) 13 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
14 const audience = getObjectFollowersAudience(accountsToForwardView) 14 const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
15 return announceActivityData(videoShare.url, byActor, announcedObject, audience) 15
16 const activity = buildAnnounceActivity(videoShare.url, byActor, announcedObject, audience)
17
18 return { activity, actorsInvolvedInVideo }
16} 19}
17 20
18async function sendVideoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) { 21async function sendVideoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
19 const data = await buildVideoAnnounce(byActor, videoShare, video, t) 22 const { activity, actorsInvolvedInVideo } = await buildAnnounceWithVideoAudience(byActor, videoShare, video, t)
20 23
21 logger.info('Creating job to send announce %s.', videoShare.url) 24 logger.info('Creating job to send announce %s.', videoShare.url)
22 25
23 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
24 const followersException = [ byActor ] 26 const followersException = [ byActor ]
25 27 return broadcastToFollowers(activity, byActor, actorsInvolvedInVideo, t, followersException)
26 return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException)
27} 28}
28 29
29function announceActivityData (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce { 30function buildAnnounceActivity (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce {
30 if (!audience) audience = getAudience(byActor) 31 if (!audience) audience = getAudience(byActor)
31 32
32 return { 33 return audiencify({
33 type: 'Announce', 34 type: 'Announce' as 'Announce',
34 to: audience.to,
35 cc: audience.cc,
36 id: url, 35 id: url,
37 actor: byActor.url, 36 actor: byActor.url,
38 object 37 object
39 } 38 }, audience)
40} 39}
41 40
42// --------------------------------------------------------------------------- 41// ---------------------------------------------------------------------------
43 42
44export { 43export {
45 sendVideoAnnounce, 44 sendVideoAnnounce,
46 announceActivityData, 45 buildAnnounceActivity,
47 buildVideoAnnounce 46 buildAnnounceWithVideoAudience
48} 47}
diff --git a/server/lib/activitypub/send/send-create.ts b/server/lib/activitypub/send/send-create.ts
index fc76cdd8a..6f89b1a22 100644
--- a/server/lib/activitypub/send/send-create.ts
+++ b/server/lib/activitypub/send/send-create.ts
@@ -17,6 +17,7 @@ import {
17 getVideoCommentAudience 17 getVideoCommentAudience
18} from '../audience' 18} from '../audience'
19import { logger } from '../../../helpers/logger' 19import { logger } from '../../../helpers/logger'
20import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
20 21
21async function sendCreateVideo (video: VideoModel, t: Transaction) { 22async function sendCreateVideo (video: VideoModel, t: Transaction) {
22 if (video.privacy === VideoPrivacy.PRIVATE) return undefined 23 if (video.privacy === VideoPrivacy.PRIVATE) return undefined
@@ -27,12 +28,12 @@ async function sendCreateVideo (video: VideoModel, t: Transaction) {
27 const videoObject = video.toActivityPubObject() 28 const videoObject = video.toActivityPubObject()
28 29
29 const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC) 30 const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)
30 const data = createActivityData(video.url, byActor, videoObject, audience) 31 const createActivity = buildCreateActivity(video.url, byActor, videoObject, audience)
31 32
32 return broadcastToFollowers(data, byActor, [ byActor ], t) 33 return broadcastToFollowers(createActivity, byActor, [ byActor ], t)
33} 34}
34 35
35async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel, video: VideoModel, t: Transaction) { 36async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel, video: VideoModel) {
36 if (!video.VideoChannel.Account.Actor.serverId) return // Local 37 if (!video.VideoChannel.Account.Actor.serverId) return // Local
37 38
38 const url = getVideoAbuseActivityPubUrl(videoAbuse) 39 const url = getVideoAbuseActivityPubUrl(videoAbuse)
@@ -40,9 +41,23 @@ async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel,
40 logger.info('Creating job to send video abuse %s.', url) 41 logger.info('Creating job to send video abuse %s.', url)
41 42
42 const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] } 43 const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] }
43 const data = createActivityData(url, byActor, videoAbuse.toActivityPubObject(), audience) 44 const createActivity = buildCreateActivity(url, byActor, videoAbuse.toActivityPubObject(), audience)
44 45
45 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 46 return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
47}
48
49async function sendCreateCacheFile (byActor: ActorModel, fileRedundancy: VideoRedundancyModel) {
50 logger.info('Creating job to send file cache of %s.', fileRedundancy.url)
51
52 const redundancyObject = fileRedundancy.toActivityPubObject()
53
54 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(fileRedundancy.VideoFile.Video.id)
55 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, undefined)
56
57 const audience = getVideoAudience(video, actorsInvolvedInVideo)
58 const createActivity = buildCreateActivity(fileRedundancy.url, byActor, redundancyObject, audience)
59
60 return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
46} 61}
47 62
48async function sendCreateVideoComment (comment: VideoCommentModel, t: Transaction) { 63async function sendCreateVideoComment (comment: VideoCommentModel, t: Transaction) {
@@ -66,73 +81,73 @@ async function sendCreateVideoComment (comment: VideoCommentModel, t: Transactio
66 audience = getObjectFollowersAudience(actorsInvolvedInComment.concat(parentsCommentActors)) 81 audience = getObjectFollowersAudience(actorsInvolvedInComment.concat(parentsCommentActors))
67 } 82 }
68 83
69 const data = createActivityData(comment.url, byActor, commentObject, audience) 84 const createActivity = buildCreateActivity(comment.url, byActor, commentObject, audience)
70 85
71 // This was a reply, send it to the parent actors 86 // This was a reply, send it to the parent actors
72 const actorsException = [ byActor ] 87 const actorsException = [ byActor ]
73 await broadcastToActors(data, byActor, parentsCommentActors, actorsException) 88 await broadcastToActors(createActivity, byActor, parentsCommentActors, actorsException)
74 89
75 // Broadcast to our followers 90 // Broadcast to our followers
76 await broadcastToFollowers(data, byActor, [ byActor ], t) 91 await broadcastToFollowers(createActivity, byActor, [ byActor ], t)
77 92
78 // Send to actors involved in the comment 93 // Send to actors involved in the comment
79 if (isOrigin) return broadcastToFollowers(data, byActor, actorsInvolvedInComment, t, actorsException) 94 if (isOrigin) return broadcastToFollowers(createActivity, byActor, actorsInvolvedInComment, t, actorsException)
80 95
81 // Send to origin 96 // Send to origin
82 return unicastTo(data, byActor, comment.Video.VideoChannel.Account.Actor.sharedInboxUrl) 97 return unicastTo(createActivity, byActor, comment.Video.VideoChannel.Account.Actor.sharedInboxUrl)
83} 98}
84 99
85async function sendCreateView (byActor: ActorModel, video: VideoModel, t: Transaction) { 100async function sendCreateView (byActor: ActorModel, video: VideoModel, t: Transaction) {
86 logger.info('Creating job to send view of %s.', video.url) 101 logger.info('Creating job to send view of %s.', video.url)
87 102
88 const url = getVideoViewActivityPubUrl(byActor, video) 103 const url = getVideoViewActivityPubUrl(byActor, video)
89 const viewActivityData = createViewActivityData(byActor, video) 104 const viewActivity = buildViewActivity(byActor, video)
90 105
91 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) 106 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
92 107
93 // Send to origin 108 // Send to origin
94 if (video.isOwned() === false) { 109 if (video.isOwned() === false) {
95 const audience = getVideoAudience(video, actorsInvolvedInVideo) 110 const audience = getVideoAudience(video, actorsInvolvedInVideo)
96 const data = createActivityData(url, byActor, viewActivityData, audience) 111 const createActivity = buildCreateActivity(url, byActor, viewActivity, audience)
97 112
98 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 113 return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
99 } 114 }
100 115
101 // Send to followers 116 // Send to followers
102 const audience = getObjectFollowersAudience(actorsInvolvedInVideo) 117 const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
103 const data = createActivityData(url, byActor, viewActivityData, audience) 118 const createActivity = buildCreateActivity(url, byActor, viewActivity, audience)
104 119
105 // Use the server actor to send the view 120 // Use the server actor to send the view
106 const serverActor = await getServerActor() 121 const serverActor = await getServerActor()
107 const actorsException = [ byActor ] 122 const actorsException = [ byActor ]
108 return broadcastToFollowers(data, serverActor, actorsInvolvedInVideo, t, actorsException) 123 return broadcastToFollowers(createActivity, serverActor, actorsInvolvedInVideo, t, actorsException)
109} 124}
110 125
111async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { 126async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) {
112 logger.info('Creating job to dislike %s.', video.url) 127 logger.info('Creating job to dislike %s.', video.url)
113 128
114 const url = getVideoDislikeActivityPubUrl(byActor, video) 129 const url = getVideoDislikeActivityPubUrl(byActor, video)
115 const dislikeActivityData = createDislikeActivityData(byActor, video) 130 const dislikeActivity = buildDislikeActivity(byActor, video)
116 131
117 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) 132 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
118 133
119 // Send to origin 134 // Send to origin
120 if (video.isOwned() === false) { 135 if (video.isOwned() === false) {
121 const audience = getVideoAudience(video, actorsInvolvedInVideo) 136 const audience = getVideoAudience(video, actorsInvolvedInVideo)
122 const data = createActivityData(url, byActor, dislikeActivityData, audience) 137 const createActivity = buildCreateActivity(url, byActor, dislikeActivity, audience)
123 138
124 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 139 return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
125 } 140 }
126 141
127 // Send to followers 142 // Send to followers
128 const audience = getObjectFollowersAudience(actorsInvolvedInVideo) 143 const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
129 const data = createActivityData(url, byActor, dislikeActivityData, audience) 144 const createActivity = buildCreateActivity(url, byActor, dislikeActivity, audience)
130 145
131 const actorsException = [ byActor ] 146 const actorsException = [ byActor ]
132 return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, actorsException) 147 return broadcastToFollowers(createActivity, byActor, actorsInvolvedInVideo, t, actorsException)
133} 148}
134 149
135function createActivityData (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate { 150function buildCreateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate {
136 if (!audience) audience = getAudience(byActor) 151 if (!audience) audience = getAudience(byActor)
137 152
138 return audiencify( 153 return audiencify(
@@ -146,7 +161,7 @@ function createActivityData (url: string, byActor: ActorModel, object: any, audi
146 ) 161 )
147} 162}
148 163
149function createDislikeActivityData (byActor: ActorModel, video: VideoModel) { 164function buildDislikeActivity (byActor: ActorModel, video: VideoModel) {
150 return { 165 return {
151 type: 'Dislike', 166 type: 'Dislike',
152 actor: byActor.url, 167 actor: byActor.url,
@@ -154,7 +169,7 @@ function createDislikeActivityData (byActor: ActorModel, video: VideoModel) {
154 } 169 }
155} 170}
156 171
157function createViewActivityData (byActor: ActorModel, video: VideoModel) { 172function buildViewActivity (byActor: ActorModel, video: VideoModel) {
158 return { 173 return {
159 type: 'View', 174 type: 'View',
160 actor: byActor.url, 175 actor: byActor.url,
@@ -167,9 +182,10 @@ function createViewActivityData (byActor: ActorModel, video: VideoModel) {
167export { 182export {
168 sendCreateVideo, 183 sendCreateVideo,
169 sendVideoAbuse, 184 sendVideoAbuse,
170 createActivityData, 185 buildCreateActivity,
171 sendCreateView, 186 sendCreateView,
172 sendCreateDislike, 187 sendCreateDislike,
173 createDislikeActivityData, 188 buildDislikeActivity,
174 sendCreateVideoComment 189 sendCreateVideoComment,
190 sendCreateCacheFile
175} 191}
diff --git a/server/lib/activitypub/send/send-delete.ts b/server/lib/activitypub/send/send-delete.ts
index 3d1dfb699..479182543 100644
--- a/server/lib/activitypub/send/send-delete.ts
+++ b/server/lib/activitypub/send/send-delete.ts
@@ -15,24 +15,23 @@ async function sendDeleteVideo (video: VideoModel, t: Transaction) {
15 const url = getDeleteActivityPubUrl(video.url) 15 const url = getDeleteActivityPubUrl(video.url)
16 const byActor = video.VideoChannel.Account.Actor 16 const byActor = video.VideoChannel.Account.Actor
17 17
18 const data = deleteActivityData(url, video.url, byActor) 18 const activity = buildDeleteActivity(url, video.url, byActor)
19 19
20 const actorsInvolved = await VideoShareModel.loadActorsByShare(video.id, t) 20 const actorsInvolved = await getActorsInvolvedInVideo(video, t)
21 actorsInvolved.push(byActor)
22 21
23 return broadcastToFollowers(data, byActor, actorsInvolved, t) 22 return broadcastToFollowers(activity, byActor, actorsInvolved, t)
24} 23}
25 24
26async function sendDeleteActor (byActor: ActorModel, t: Transaction) { 25async function sendDeleteActor (byActor: ActorModel, t: Transaction) {
27 logger.info('Creating job to broadcast delete of actor %s.', byActor.url) 26 logger.info('Creating job to broadcast delete of actor %s.', byActor.url)
28 27
29 const url = getDeleteActivityPubUrl(byActor.url) 28 const url = getDeleteActivityPubUrl(byActor.url)
30 const data = deleteActivityData(url, byActor.url, byActor) 29 const activity = buildDeleteActivity(url, byActor.url, byActor)
31 30
32 const actorsInvolved = await VideoShareModel.loadActorsByVideoOwner(byActor.id, t) 31 const actorsInvolved = await VideoShareModel.loadActorsByVideoOwner(byActor.id, t)
33 actorsInvolved.push(byActor) 32 actorsInvolved.push(byActor)
34 33
35 return broadcastToFollowers(data, byActor, actorsInvolved, t) 34 return broadcastToFollowers(activity, byActor, actorsInvolved, t)
36} 35}
37 36
38async function sendDeleteVideoComment (videoComment: VideoCommentModel, t: Transaction) { 37async function sendDeleteVideoComment (videoComment: VideoCommentModel, t: Transaction) {
@@ -45,23 +44,23 @@ async function sendDeleteVideoComment (videoComment: VideoCommentModel, t: Trans
45 const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t) 44 const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t)
46 45
47 const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t) 46 const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t)
48 actorsInvolvedInComment.push(byActor) 47 actorsInvolvedInComment.push(byActor) // Add the actor that commented the video
49 48
50 const audience = getVideoCommentAudience(videoComment, threadParentComments, actorsInvolvedInComment, isVideoOrigin) 49 const audience = getVideoCommentAudience(videoComment, threadParentComments, actorsInvolvedInComment, isVideoOrigin)
51 const data = deleteActivityData(url, videoComment.url, byActor, audience) 50 const activity = buildDeleteActivity(url, videoComment.url, byActor, audience)
52 51
53 // This was a reply, send it to the parent actors 52 // This was a reply, send it to the parent actors
54 const actorsException = [ byActor ] 53 const actorsException = [ byActor ]
55 await broadcastToActors(data, byActor, threadParentComments.map(c => c.Account.Actor), actorsException) 54 await broadcastToActors(activity, byActor, threadParentComments.map(c => c.Account.Actor), actorsException)
56 55
57 // Broadcast to our followers 56 // Broadcast to our followers
58 await broadcastToFollowers(data, byActor, [ byActor ], t) 57 await broadcastToFollowers(activity, byActor, [ byActor ], t)
59 58
60 // Send to actors involved in the comment 59 // Send to actors involved in the comment
61 if (isVideoOrigin) return broadcastToFollowers(data, byActor, actorsInvolvedInComment, t, actorsException) 60 if (isVideoOrigin) return broadcastToFollowers(activity, byActor, actorsInvolvedInComment, t, actorsException)
62 61
63 // Send to origin 62 // Send to origin
64 return unicastTo(data, byActor, videoComment.Video.VideoChannel.Account.Actor.sharedInboxUrl) 63 return unicastTo(activity, byActor, videoComment.Video.VideoChannel.Account.Actor.sharedInboxUrl)
65} 64}
66 65
67// --------------------------------------------------------------------------- 66// ---------------------------------------------------------------------------
@@ -74,7 +73,7 @@ export {
74 73
75// --------------------------------------------------------------------------- 74// ---------------------------------------------------------------------------
76 75
77function deleteActivityData (url: string, object: string, byActor: ActorModel, audience?: ActivityAudience): ActivityDelete { 76function buildDeleteActivity (url: string, object: string, byActor: ActorModel, audience?: ActivityAudience): ActivityDelete {
78 const activity = { 77 const activity = {
79 type: 'Delete' as 'Delete', 78 type: 'Delete' as 'Delete',
80 id: url, 79 id: url,
diff --git a/server/lib/activitypub/send/send-follow.ts b/server/lib/activitypub/send/send-follow.ts
index 46d08c17b..170b46b48 100644
--- a/server/lib/activitypub/send/send-follow.ts
+++ b/server/lib/activitypub/send/send-follow.ts
@@ -15,12 +15,12 @@ function sendFollow (actorFollow: ActorFollowModel) {
15 logger.info('Creating job to send follow request to %s.', following.url) 15 logger.info('Creating job to send follow request to %s.', following.url)
16 16
17 const url = getActorFollowActivityPubUrl(actorFollow) 17 const url = getActorFollowActivityPubUrl(actorFollow)
18 const data = followActivityData(url, me, following) 18 const data = buildFollowActivity(url, me, following)
19 19
20 return unicastTo(data, me, following.inboxUrl) 20 return unicastTo(data, me, following.inboxUrl)
21} 21}
22 22
23function followActivityData (url: string, byActor: ActorModel, targetActor: ActorModel): ActivityFollow { 23function buildFollowActivity (url: string, byActor: ActorModel, targetActor: ActorModel): ActivityFollow {
24 return { 24 return {
25 type: 'Follow', 25 type: 'Follow',
26 id: url, 26 id: url,
@@ -33,5 +33,5 @@ function followActivityData (url: string, byActor: ActorModel, targetActor: Acto
33 33
34export { 34export {
35 sendFollow, 35 sendFollow,
36 followActivityData 36 buildFollowActivity
37} 37}
diff --git a/server/lib/activitypub/send/send-like.ts b/server/lib/activitypub/send/send-like.ts
index 83225f5df..a5408ac6a 100644
--- a/server/lib/activitypub/send/send-like.ts
+++ b/server/lib/activitypub/send/send-like.ts
@@ -17,20 +17,20 @@ async function sendLike (byActor: ActorModel, video: VideoModel, t: Transaction)
17 // Send to origin 17 // Send to origin
18 if (video.isOwned() === false) { 18 if (video.isOwned() === false) {
19 const audience = getVideoAudience(video, accountsInvolvedInVideo) 19 const audience = getVideoAudience(video, accountsInvolvedInVideo)
20 const data = likeActivityData(url, byActor, video, audience) 20 const data = buildLikeActivity(url, byActor, video, audience)
21 21
22 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 22 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
23 } 23 }
24 24
25 // Send to followers 25 // Send to followers
26 const audience = getObjectFollowersAudience(accountsInvolvedInVideo) 26 const audience = getObjectFollowersAudience(accountsInvolvedInVideo)
27 const data = likeActivityData(url, byActor, video, audience) 27 const activity = buildLikeActivity(url, byActor, video, audience)
28 28
29 const followersException = [ byActor ] 29 const followersException = [ byActor ]
30 return broadcastToFollowers(data, byActor, accountsInvolvedInVideo, t, followersException) 30 return broadcastToFollowers(activity, byActor, accountsInvolvedInVideo, t, followersException)
31} 31}
32 32
33function likeActivityData (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityLike { 33function buildLikeActivity (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityLike {
34 if (!audience) audience = getAudience(byActor) 34 if (!audience) audience = getAudience(byActor)
35 35
36 return audiencify( 36 return audiencify(
@@ -48,5 +48,5 @@ function likeActivityData (url: string, byActor: ActorModel, video: VideoModel,
48 48
49export { 49export {
50 sendLike, 50 sendLike,
51 likeActivityData 51 buildLikeActivity
52} 52}
diff --git a/server/lib/activitypub/send/send-undo.ts b/server/lib/activitypub/send/send-undo.ts
index 30d0fd98b..a50673c79 100644
--- a/server/lib/activitypub/send/send-undo.ts
+++ b/server/lib/activitypub/send/send-undo.ts
@@ -13,12 +13,13 @@ import { VideoModel } from '../../../models/video/video'
13import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' 13import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url'
14import { broadcastToFollowers, unicastTo } from './utils' 14import { broadcastToFollowers, unicastTo } from './utils'
15import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience' 15import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience'
16import { createActivityData, createDislikeActivityData } from './send-create' 16import { buildCreateActivity, buildDislikeActivity } from './send-create'
17import { followActivityData } from './send-follow' 17import { buildFollowActivity } from './send-follow'
18import { likeActivityData } from './send-like' 18import { buildLikeActivity } from './send-like'
19import { VideoShareModel } from '../../../models/video/video-share' 19import { VideoShareModel } from '../../../models/video/video-share'
20import { buildVideoAnnounce } from './send-announce' 20import { buildAnnounceWithVideoAudience } from './send-announce'
21import { logger } from '../../../helpers/logger' 21import { logger } from '../../../helpers/logger'
22import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
22 23
23async function sendUndoFollow (actorFollow: ActorFollowModel, t: Transaction) { 24async function sendUndoFollow (actorFollow: ActorFollowModel, t: Transaction) {
24 const me = actorFollow.ActorFollower 25 const me = actorFollow.ActorFollower
@@ -32,10 +33,10 @@ async function sendUndoFollow (actorFollow: ActorFollowModel, t: Transaction) {
32 const followUrl = getActorFollowActivityPubUrl(actorFollow) 33 const followUrl = getActorFollowActivityPubUrl(actorFollow)
33 const undoUrl = getUndoActivityPubUrl(followUrl) 34 const undoUrl = getUndoActivityPubUrl(followUrl)
34 35
35 const object = followActivityData(followUrl, me, following) 36 const followActivity = buildFollowActivity(followUrl, me, following)
36 const data = undoActivityData(undoUrl, me, object) 37 const undoActivity = undoActivityData(undoUrl, me, followActivity)
37 38
38 return unicastTo(data, me, following.inboxUrl) 39 return unicastTo(undoActivity, me, following.inboxUrl)
39} 40}
40 41
41async function sendUndoLike (byActor: ActorModel, video: VideoModel, t: Transaction) { 42async function sendUndoLike (byActor: ActorModel, video: VideoModel, t: Transaction) {
@@ -45,21 +46,21 @@ async function sendUndoLike (byActor: ActorModel, video: VideoModel, t: Transact
45 const undoUrl = getUndoActivityPubUrl(likeUrl) 46 const undoUrl = getUndoActivityPubUrl(likeUrl)
46 47
47 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) 48 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
48 const object = likeActivityData(likeUrl, byActor, video) 49 const likeActivity = buildLikeActivity(likeUrl, byActor, video)
49 50
50 // Send to origin 51 // Send to origin
51 if (video.isOwned() === false) { 52 if (video.isOwned() === false) {
52 const audience = getVideoAudience(video, actorsInvolvedInVideo) 53 const audience = getVideoAudience(video, actorsInvolvedInVideo)
53 const data = undoActivityData(undoUrl, byActor, object, audience) 54 const undoActivity = undoActivityData(undoUrl, byActor, likeActivity, audience)
54 55
55 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 56 return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
56 } 57 }
57 58
58 const audience = getObjectFollowersAudience(actorsInvolvedInVideo) 59 const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
59 const data = undoActivityData(undoUrl, byActor, object, audience) 60 const undoActivity = undoActivityData(undoUrl, byActor, likeActivity, audience)
60 61
61 const followersException = [ byActor ] 62 const followersException = [ byActor ]
62 return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException) 63 return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
63} 64}
64 65
65async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { 66async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Transaction) {
@@ -69,20 +70,20 @@ async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Trans
69 const undoUrl = getUndoActivityPubUrl(dislikeUrl) 70 const undoUrl = getUndoActivityPubUrl(dislikeUrl)
70 71
71 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) 72 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
72 const dislikeActivity = createDislikeActivityData(byActor, video) 73 const dislikeActivity = buildDislikeActivity(byActor, video)
73 const object = createActivityData(dislikeUrl, byActor, dislikeActivity) 74 const createDislikeActivity = buildCreateActivity(dislikeUrl, byActor, dislikeActivity)
74 75
75 if (video.isOwned() === false) { 76 if (video.isOwned() === false) {
76 const audience = getVideoAudience(video, actorsInvolvedInVideo) 77 const audience = getVideoAudience(video, actorsInvolvedInVideo)
77 const data = undoActivityData(undoUrl, byActor, object, audience) 78 const undoActivity = undoActivityData(undoUrl, byActor, createDislikeActivity, audience)
78 79
79 return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) 80 return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
80 } 81 }
81 82
82 const data = undoActivityData(undoUrl, byActor, object) 83 const undoActivity = undoActivityData(undoUrl, byActor, createDislikeActivity)
83 84
84 const followersException = [ byActor ] 85 const followersException = [ byActor ]
85 return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException) 86 return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
86} 87}
87 88
88async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) { 89async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
@@ -90,12 +91,27 @@ async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareMode
90 91
91 const undoUrl = getUndoActivityPubUrl(videoShare.url) 92 const undoUrl = getUndoActivityPubUrl(videoShare.url)
92 93
93 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) 94 const { activity: announceActivity, actorsInvolvedInVideo } = await buildAnnounceWithVideoAudience(byActor, videoShare, video, t)
94 const object = await buildVideoAnnounce(byActor, videoShare, video, t) 95 const undoActivity = undoActivityData(undoUrl, byActor, announceActivity)
95 const data = undoActivityData(undoUrl, byActor, object)
96 96
97 const followersException = [ byActor ] 97 const followersException = [ byActor ]
98 return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException) 98 return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
99}
100
101async function sendUndoCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel, t: Transaction) {
102 logger.info('Creating job to undo cache file %s.', redundancyModel.url)
103
104 const undoUrl = getUndoActivityPubUrl(redundancyModel.url)
105
106 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id)
107 const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
108
109 const audience = getVideoAudience(video, actorsInvolvedInVideo)
110 const createActivity = buildCreateActivity(redundancyModel.url, byActor, redundancyModel.toActivityPubObject())
111
112 const undoActivity = undoActivityData(undoUrl, byActor, createActivity, audience)
113
114 return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
99} 115}
100 116
101// --------------------------------------------------------------------------- 117// ---------------------------------------------------------------------------
@@ -104,7 +120,8 @@ export {
104 sendUndoFollow, 120 sendUndoFollow,
105 sendUndoLike, 121 sendUndoLike,
106 sendUndoDislike, 122 sendUndoDislike,
107 sendUndoAnnounce 123 sendUndoAnnounce,
124 sendUndoCacheFile
108} 125}
109 126
110// --------------------------------------------------------------------------- 127// ---------------------------------------------------------------------------
diff --git a/server/lib/activitypub/send/send-update.ts b/server/lib/activitypub/send/send-update.ts
index 6f1d80898..605473338 100644
--- a/server/lib/activitypub/send/send-update.ts
+++ b/server/lib/activitypub/send/send-update.ts
@@ -7,11 +7,11 @@ import { VideoModel } from '../../../models/video/video'
7import { VideoChannelModel } from '../../../models/video/video-channel' 7import { VideoChannelModel } from '../../../models/video/video-channel'
8import { VideoShareModel } from '../../../models/video/video-share' 8import { VideoShareModel } from '../../../models/video/video-share'
9import { getUpdateActivityPubUrl } from '../url' 9import { getUpdateActivityPubUrl } from '../url'
10import { broadcastToFollowers } from './utils' 10import { broadcastToFollowers, unicastTo } from './utils'
11import { audiencify, getAudience } from '../audience' 11import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience'
12import { logger } from '../../../helpers/logger' 12import { logger } from '../../../helpers/logger'
13import { videoFeedsValidator } from '../../../middlewares/validators'
14import { VideoCaptionModel } from '../../../models/video/video-caption' 13import { VideoCaptionModel } from '../../../models/video/video-caption'
14import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
15 15
16async function sendUpdateVideo (video: VideoModel, t: Transaction, overrodeByActor?: ActorModel) { 16async function sendUpdateVideo (video: VideoModel, t: Transaction, overrodeByActor?: ActorModel) {
17 logger.info('Creating job to update video %s.', video.url) 17 logger.info('Creating job to update video %s.', video.url)
@@ -26,12 +26,12 @@ async function sendUpdateVideo (video: VideoModel, t: Transaction, overrodeByAct
26 const videoObject = video.toActivityPubObject() 26 const videoObject = video.toActivityPubObject()
27 const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC) 27 const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)
28 28
29 const data = updateActivityData(url, byActor, videoObject, audience) 29 const updateActivity = buildUpdateActivity(url, byActor, videoObject, audience)
30 30
31 const actorsInvolved = await VideoShareModel.loadActorsByShare(video.id, t) 31 const actorsInvolved = await getActorsInvolvedInVideo(video, t)
32 actorsInvolved.push(byActor) 32 if (overrodeByActor) actorsInvolved.push(overrodeByActor)
33 33
34 return broadcastToFollowers(data, byActor, actorsInvolved, t) 34 return broadcastToFollowers(updateActivity, byActor, actorsInvolved, t)
35} 35}
36 36
37async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelModel, t: Transaction) { 37async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelModel, t: Transaction) {
@@ -42,7 +42,7 @@ async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelMod
42 const url = getUpdateActivityPubUrl(byActor.url, byActor.updatedAt.toISOString()) 42 const url = getUpdateActivityPubUrl(byActor.url, byActor.updatedAt.toISOString())
43 const accountOrChannelObject = accountOrChannel.toActivityPubObject() 43 const accountOrChannelObject = accountOrChannel.toActivityPubObject()
44 const audience = getAudience(byActor) 44 const audience = getAudience(byActor)
45 const data = updateActivityData(url, byActor, accountOrChannelObject, audience) 45 const updateActivity = buildUpdateActivity(url, byActor, accountOrChannelObject, audience)
46 46
47 let actorsInvolved: ActorModel[] 47 let actorsInvolved: ActorModel[]
48 if (accountOrChannel instanceof AccountModel) { 48 if (accountOrChannel instanceof AccountModel) {
@@ -55,19 +55,35 @@ async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelMod
55 55
56 actorsInvolved.push(byActor) 56 actorsInvolved.push(byActor)
57 57
58 return broadcastToFollowers(data, byActor, actorsInvolved, t) 58 return broadcastToFollowers(updateActivity, byActor, actorsInvolved, t)
59}
60
61async function sendUpdateCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel) {
62 logger.info('Creating job to update cache file %s.', redundancyModel.url)
63
64 const url = getUpdateActivityPubUrl(redundancyModel.url, redundancyModel.updatedAt.toISOString())
65 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id)
66
67 const redundancyObject = redundancyModel.toActivityPubObject()
68
69 const accountsInvolvedInVideo = await getActorsInvolvedInVideo(video, undefined)
70 const audience = getObjectFollowersAudience(accountsInvolvedInVideo)
71
72 const updateActivity = buildUpdateActivity(url, byActor, redundancyObject, audience)
73 return unicastTo(updateActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
59} 74}
60 75
61// --------------------------------------------------------------------------- 76// ---------------------------------------------------------------------------
62 77
63export { 78export {
64 sendUpdateActor, 79 sendUpdateActor,
65 sendUpdateVideo 80 sendUpdateVideo,
81 sendUpdateCacheFile
66} 82}
67 83
68// --------------------------------------------------------------------------- 84// ---------------------------------------------------------------------------
69 85
70function updateActivityData (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityUpdate { 86function buildUpdateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityUpdate {
71 if (!audience) audience = getAudience(byActor) 87 if (!audience) audience = getAudience(byActor)
72 88
73 return audiencify( 89 return audiencify(
diff --git a/server/lib/activitypub/send/utils.ts b/server/lib/activitypub/send/utils.ts
index da437292e..c20c15633 100644
--- a/server/lib/activitypub/send/utils.ts
+++ b/server/lib/activitypub/send/utils.ts
@@ -59,11 +59,11 @@ async function forwardActivity (
59async function broadcastToFollowers ( 59async function broadcastToFollowers (
60 data: any, 60 data: any,
61 byActor: ActorModel, 61 byActor: ActorModel,
62 toActorFollowers: ActorModel[], 62 toFollowersOf: ActorModel[],
63 t: Transaction, 63 t: Transaction,
64 actorsException: ActorModel[] = [] 64 actorsException: ActorModel[] = []
65) { 65) {
66 const uris = await computeFollowerUris(toActorFollowers, actorsException, t) 66 const uris = await computeFollowerUris(toFollowersOf, actorsException, t)
67 return broadcastTo(uris, data, byActor) 67 return broadcastTo(uris, data, byActor)
68} 68}
69 69
@@ -115,8 +115,8 @@ export {
115 115
116// --------------------------------------------------------------------------- 116// ---------------------------------------------------------------------------
117 117
118async function computeFollowerUris (toActorFollower: ActorModel[], actorsException: ActorModel[], t: Transaction) { 118async function computeFollowerUris (toFollowersOf: ActorModel[], actorsException: ActorModel[], t: Transaction) {
119 const toActorFollowerIds = toActorFollower.map(a => a.id) 119 const toActorFollowerIds = toFollowersOf.map(a => a.id)
120 120
121 const result = await ActorFollowModel.listAcceptedFollowerSharedInboxUrls(toActorFollowerIds, t) 121 const result = await ActorFollowModel.listAcceptedFollowerSharedInboxUrls(toActorFollowerIds, t)
122 const sharedInboxesException = await buildSharedInboxesException(actorsException) 122 const sharedInboxesException = await buildSharedInboxesException(actorsException)