aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/activitypub')
-rw-r--r--server/lib/activitypub/process-accept.ts6
-rw-r--r--server/lib/activitypub/process-add.ts2
-rw-r--r--server/lib/activitypub/process-follow.ts39
-rw-r--r--server/lib/activitypub/send-request.ts46
4 files changed, 79 insertions, 14 deletions
diff --git a/server/lib/activitypub/process-accept.ts b/server/lib/activitypub/process-accept.ts
index 37e42bd3a..9e0cd4032 100644
--- a/server/lib/activitypub/process-accept.ts
+++ b/server/lib/activitypub/process-accept.ts
@@ -7,7 +7,7 @@ async function processAcceptActivity (activity: ActivityAccept, inboxAccount?: A
7 7
8 const targetAccount = await db.Account.loadByUrl(activity.actor) 8 const targetAccount = await db.Account.loadByUrl(activity.actor)
9 9
10 return processFollow(inboxAccount, targetAccount) 10 return processAccept(inboxAccount, targetAccount)
11} 11}
12 12
13// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
@@ -18,10 +18,10 @@ export {
18 18
19// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
20 20
21async function processFollow (account: AccountInstance, targetAccount: AccountInstance) { 21async function processAccept (account: AccountInstance, targetAccount: AccountInstance) {
22 const follow = await db.AccountFollow.loadByAccountAndTarget(account.id, targetAccount.id) 22 const follow = await db.AccountFollow.loadByAccountAndTarget(account.id, targetAccount.id)
23 if (!follow) throw new Error('Cannot find associated follow.') 23 if (!follow) throw new Error('Cannot find associated follow.')
24 24
25 follow.set('state', 'accepted') 25 follow.set('state', 'accepted')
26 return follow.save() 26 await follow.save()
27} 27}
diff --git a/server/lib/activitypub/process-add.ts b/server/lib/activitypub/process-add.ts
index 40541aca3..024dee559 100644
--- a/server/lib/activitypub/process-add.ts
+++ b/server/lib/activitypub/process-add.ts
@@ -29,7 +29,7 @@ export {
29 29
30function processAddVideo (account: AccountInstance, videoChannelUrl: string, video: VideoTorrentObject) { 30function processAddVideo (account: AccountInstance, videoChannelUrl: string, video: VideoTorrentObject) {
31 const options = { 31 const options = {
32 arguments: [ account, videoChannelUrl ,video ], 32 arguments: [ account, videoChannelUrl, video ],
33 errorMessage: 'Cannot insert the remote video with many retries.' 33 errorMessage: 'Cannot insert the remote video with many retries.'
34 } 34 }
35 35
diff --git a/server/lib/activitypub/process-follow.ts b/server/lib/activitypub/process-follow.ts
index a04fc7994..ee5d97a0b 100644
--- a/server/lib/activitypub/process-follow.ts
+++ b/server/lib/activitypub/process-follow.ts
@@ -1,7 +1,9 @@
1import { ActivityFollow } from '../../../shared/models/activitypub/activity' 1import { ActivityFollow } from '../../../shared/models/activitypub/activity'
2import { getOrCreateAccount } from '../../helpers' 2import { getOrCreateAccount, retryTransactionWrapper } from '../../helpers'
3import { database as db } from '../../initializers' 3import { database as db } from '../../initializers'
4import { AccountInstance } from '../../models/account/account-interface' 4import { AccountInstance } from '../../models/account/account-interface'
5import { sendAccept } from './send-request'
6import { logger } from '../../helpers/logger'
5 7
6async function processFollowActivity (activity: ActivityFollow) { 8async function processFollowActivity (activity: ActivityFollow) {
7 const activityObject = activity.object 9 const activityObject = activity.object
@@ -18,15 +20,34 @@ export {
18 20
19// --------------------------------------------------------------------------- 21// ---------------------------------------------------------------------------
20 22
21async function processFollow (account: AccountInstance, targetAccountURL: string) { 23function processFollow (account: AccountInstance, targetAccountURL: string) {
22 const targetAccount = await db.Account.loadByUrl(targetAccountURL) 24 const options = {
25 arguments: [ account, targetAccountURL ],
26 errorMessage: 'Cannot follow with many retries.'
27 }
23 28
24 if (targetAccount === undefined) throw new Error('Unknown account') 29 return retryTransactionWrapper(follow, options)
25 if (targetAccount.isOwned() === false) throw new Error('This is not a local account.') 30}
31
32async function follow (account: AccountInstance, targetAccountURL: string) {
33 await db.sequelize.transaction(async t => {
34 const targetAccount = await db.Account.loadByUrl(targetAccountURL, t)
35
36 if (targetAccount === undefined) throw new Error('Unknown account')
37 if (targetAccount.isOwned() === false) throw new Error('This is not a local account.')
26 38
27 return db.AccountFollow.create({ 39 const sequelizeOptions = {
28 accountId: account.id, 40 transaction: t
29 targetAccountId: targetAccount.id, 41 }
30 state: 'accepted' 42 await db.AccountFollow.create({
43 accountId: account.id,
44 targetAccountId: targetAccount.id,
45 state: 'accepted'
46 }, sequelizeOptions)
47
48 // Target sends to account he accepted the follow request
49 return sendAccept(targetAccount, account, t)
31 }) 50 })
51
52 logger.info('Account uuid %s is followed by account %s.', account.url, targetAccountURL)
32} 53}
diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts
index ce9a96f14..e6ef5f37a 100644
--- a/server/lib/activitypub/send-request.ts
+++ b/server/lib/activitypub/send-request.ts
@@ -56,6 +56,18 @@ function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction)
56 return broadcastToFollowers(data, account, t) 56 return broadcastToFollowers(data, account, t)
57} 57}
58 58
59function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) {
60 const data = acceptActivityData(fromAccount)
61
62 return unicastTo(data, toAccount, t)
63}
64
65function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) {
66 const data = followActivityData(toAccount.url, fromAccount)
67
68 return unicastTo(data, toAccount, t)
69}
70
59// --------------------------------------------------------------------------- 71// ---------------------------------------------------------------------------
60 72
61export { 73export {
@@ -65,7 +77,9 @@ export {
65 sendAddVideo, 77 sendAddVideo,
66 sendUpdateVideo, 78 sendUpdateVideo,
67 sendDeleteVideo, 79 sendDeleteVideo,
68 sendDeleteAccount 80 sendDeleteAccount,
81 sendAccept,
82 sendFollow
69} 83}
70 84
71// --------------------------------------------------------------------------- 85// ---------------------------------------------------------------------------
@@ -81,6 +95,15 @@ async function broadcastToFollowers (data: any, fromAccount: AccountInstance, t:
81 return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload) 95 return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload)
82} 96}
83 97
98async 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
84function buildSignedActivity (byAccount: AccountInstance, data: Object) { 107function buildSignedActivity (byAccount: AccountInstance, data: Object) {
85 const activity = activityPubContextify(data) 108 const activity = activityPubContextify(data)
86 109
@@ -142,3 +165,24 @@ async function addActivityData (url: string, byAccount: AccountInstance, target:
142 165
143 return buildSignedActivity(byAccount, base) 166 return buildSignedActivity(byAccount, base)
144} 167}
168
169async 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
180async 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}