diff --git a/src/activitypub/helpers.js b/src/activitypub/helpers.js index cc4892acb6..ce1d7e6e2d 100644 --- a/src/activitypub/helpers.js +++ b/src/activitypub/helpers.js @@ -198,6 +198,9 @@ Helpers.resolveLocalId = async (input) => { case 'message': return { type: 'message', id: value, ...activityData }; + + case 'actor': + return { type: 'application', id: null }; } return { type: null, id: null, ...activityData }; diff --git a/src/activitypub/inbox.js b/src/activitypub/inbox.js index cd13982b8c..faab5c0674 100644 --- a/src/activitypub/inbox.js +++ b/src/activitypub/inbox.js @@ -367,9 +367,12 @@ inbox.announce = async (req) => { inbox.follow = async (req) => { const { actor, object, id: followId } = req.body; + // Sanity checks const { type, id } = await helpers.resolveLocalId(object.id); - if (!['category', 'user'].includes(type)) { + if (type === 'application') { + return activitypub.relays.handshake(req.body); + } else if (!['category', 'user'].includes(type)) { throw new Error('[[error:activitypub.invalid-id]]'); } @@ -454,7 +457,9 @@ inbox.accept = async (req) => { const { type } = object; const { type: localType, id } = await helpers.resolveLocalId(object.actor); - if (!['user', 'category'].includes(localType)) { + if (object.id === `${nconf.get('url')}/actor`) { + return activitypub.relays.handshake(req.body); + } else if (!['user', 'category'].includes(localType)) { throw new Error('[[error:invalid-data]]'); } diff --git a/src/activitypub/relays.js b/src/activitypub/relays.js index b222f0b5b7..aa6000f154 100644 --- a/src/activitypub/relays.js +++ b/src/activitypub/relays.js @@ -90,6 +90,32 @@ Relays.remove = async (url) => { ]); }; -Relays.handshake = async (activity) => { - console.log(activity); +Relays.handshake = async (object) => { + const now = new Date(); + const { type, actor } = object; + + // Confirm relay was added + const exists = await db.isSortedSetMember('relays:createtime', actor); + if (!exists) { + throw new Error('[[error:api.400]]'); + } + + if (type === 'Follow') { + await db.sortedSetIncrBy('relays:state', 1, actor); + await activitypub.send('uid', 0, actor, { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://pleroma.example/schemas/litepub-0.1.jsonld', + ], + id: `${nconf.get('url')}/actor#activity/accept/${encodeURIComponent(actor)}/${now.getTime()}`, + type: 'Accept', + to: [actor], + published: now.toISOString(), + object, + }); + } else if (type === 'Accept') { + await db.sortedSetIncrBy('relays:state', 1, actor); + } else { + throw new Error('[[error:api.400]]'); + } }; \ No newline at end of file