Add MANAGE_PEERTUBE_FOLLOW right
[oweals/peertube.git] / server / lib / activitypub / send-request.ts
1 import * as Sequelize from 'sequelize'
2
3 import { database as db } from '../../initializers'
4 import {
5   AccountInstance,
6   VideoInstance,
7   VideoChannelInstance
8 } from '../../models'
9 import { httpRequestJobScheduler } from '../jobs'
10 import { signObject, activityPubContextify } from '../../helpers'
11 import { Activity } from '../../../shared'
12
13 function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) {
14   const videoChannelObject = videoChannel.toActivityPubObject()
15   const data = createActivityData(videoChannel.url, videoChannel.Account, videoChannelObject)
16
17   return broadcastToFollowers(data, videoChannel.Account, t)
18 }
19
20 function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) {
21   const videoChannelObject = videoChannel.toActivityPubObject()
22   const data = updateActivityData(videoChannel.url, videoChannel.Account, videoChannelObject)
23
24   return broadcastToFollowers(data, videoChannel.Account, t)
25 }
26
27 function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) {
28   const data = deleteActivityData(videoChannel.url, videoChannel.Account)
29
30   return broadcastToFollowers(data, videoChannel.Account, t)
31 }
32
33 function sendAddVideo (video: VideoInstance, t: Sequelize.Transaction) {
34   const videoObject = video.toActivityPubObject()
35   const data = addActivityData(video.url, video.VideoChannel.Account, video.VideoChannel.url, videoObject)
36
37   return broadcastToFollowers(data, video.VideoChannel.Account, t)
38 }
39
40 function sendUpdateVideo (video: VideoInstance, t: Sequelize.Transaction) {
41   const videoObject = video.toActivityPubObject()
42   const data = updateActivityData(video.url, video.VideoChannel.Account, videoObject)
43
44   return broadcastToFollowers(data, video.VideoChannel.Account, t)
45 }
46
47 function sendDeleteVideo (video: VideoInstance, t: Sequelize.Transaction) {
48   const data = deleteActivityData(video.url, video.VideoChannel.Account)
49
50   return broadcastToFollowers(data, video.VideoChannel.Account, t)
51 }
52
53 function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction) {
54   const data = deleteActivityData(account.url, account)
55
56   return broadcastToFollowers(data, account, t)
57 }
58
59 function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) {
60   const data = acceptActivityData(fromAccount)
61
62   return unicastTo(data, toAccount, t)
63 }
64
65 function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) {
66   const data = followActivityData(toAccount.url, fromAccount)
67
68   return unicastTo(data, toAccount, t)
69 }
70
71 // ---------------------------------------------------------------------------
72
73 export {
74   sendCreateVideoChannel,
75   sendUpdateVideoChannel,
76   sendDeleteVideoChannel,
77   sendAddVideo,
78   sendUpdateVideo,
79   sendDeleteVideo,
80   sendDeleteAccount,
81   sendAccept,
82   sendFollow
83 }
84
85 // ---------------------------------------------------------------------------
86
87 async function broadcastToFollowers (data: any, fromAccount: AccountInstance, t: Sequelize.Transaction) {
88   const result = await db.Account.listAcceptedFollowerUrlsForApi(fromAccount.id, 0)
89
90   const jobPayload = {
91     uris: result.data,
92     body: data
93   }
94
95   return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload)
96 }
97
98 async function unicastTo (data: any, toAccount: AccountInstance, t: Sequelize.Transaction) {
99   const jobPayload = {
100     uris: [ toAccount.url ],
101     body: data
102   }
103
104   return httpRequestJobScheduler.createJob(t, 'httpRequestUnicastHandler', jobPayload)
105 }
106
107 function buildSignedActivity (byAccount: AccountInstance, data: Object) {
108   const activity = activityPubContextify(data)
109
110   return signObject(byAccount, activity) as Promise<Activity>
111 }
112
113 async function getPublicActivityTo (account: AccountInstance) {
114   const inboxUrls = await account.getFollowerSharedInboxUrls()
115
116   return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public')
117 }
118
119 async function createActivityData (url: string, byAccount: AccountInstance, object: any) {
120   const to = await getPublicActivityTo(byAccount)
121   const base = {
122     type: 'Create',
123     id: url,
124     actor: byAccount.url,
125     to,
126     object
127   }
128
129   return buildSignedActivity(byAccount, base)
130 }
131
132 async function updateActivityData (url: string, byAccount: AccountInstance, object: any) {
133   const to = await getPublicActivityTo(byAccount)
134   const base = {
135     type: 'Update',
136     id: url,
137     actor: byAccount.url,
138     to,
139     object
140   }
141
142   return buildSignedActivity(byAccount, base)
143 }
144
145 async function deleteActivityData (url: string, byAccount: AccountInstance) {
146   const base = {
147     type: 'Delete',
148     id: url,
149     actor: byAccount.url
150   }
151
152   return buildSignedActivity(byAccount, base)
153 }
154
155 async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any) {
156   const to = await getPublicActivityTo(byAccount)
157   const base = {
158     type: 'Add',
159     id: url,
160     actor: byAccount.url,
161     to,
162     object,
163     target
164   }
165
166   return buildSignedActivity(byAccount, base)
167 }
168
169 async function followActivityData (url: string, byAccount: AccountInstance) {
170   const base = {
171     type: 'Follow',
172     id: byAccount.url,
173     actor: byAccount.url,
174     object: url
175   }
176
177   return buildSignedActivity(byAccount, base)
178 }
179
180 async function acceptActivityData (byAccount: AccountInstance) {
181   const base = {
182     type: 'Accept',
183     id: byAccount.url,
184     actor: byAccount.url
185   }
186
187   return buildSignedActivity(byAccount, base)
188 }