diff --git a/backend/src/activitypub/actors/index.ts b/backend/src/activitypub/actors/index.ts index 2ec74ef..3f5a04d 100644 --- a/backend/src/activitypub/actors/index.ts +++ b/backend/src/activitypub/actors/index.ts @@ -11,22 +11,6 @@ export function actorURL(domain: string, id: string): URL { return new URL(`/ap/users/${id}`, 'https://' + domain) } -function inboxURL(id: URL): URL { - return new URL(id + '/inbox') -} - -function outboxURL(id: URL): URL { - return new URL(id + '/outbox') -} - -function followingURL(id: URL): URL { - return new URL(id + '/following') -} - -export function followersURL(id: URL): URL { - return new URL(id + '/followers') -} - // https://www.w3.org/TR/activitystreams-vocabulary/#actor-types export interface Actor extends APObject { inbox: URL @@ -143,8 +127,14 @@ type PersonProperties = { icon?: { url: string } image?: { url: string } preferredUsername?: string + + inbox?: string + outbox?: string + following?: string + followers?: string } +// Create a local user export async function createPerson( domain: string, db: D1Database, @@ -178,6 +168,23 @@ export async function createPerson( } const id = actorURL(domain, properties.preferredUsername).toString() + + if (properties.inbox === undefined) { + properties.inbox = id + '/inbox' + } + + if (properties.outbox === undefined) { + properties.outbox = id + '/outbox' + } + + if (properties.following === undefined) { + properties.following = id + '/following' + } + + if (properties.followers === undefined) { + properties.followers = id + '/followers' + } + const row = await db .prepare( ` @@ -256,6 +263,10 @@ export function personFromRow(row: any): Person { domain = new URL(row.original_actor_id).hostname } + if (properties.inbox === undefined) { + console.warn('malformed Actor: missing inbox') + } + return { // Hidden values [emailSymbol]: row.email, @@ -270,11 +281,7 @@ export function personFromRow(row: any): Person { type: PERSON, id, published: new Date(row.cdate).toISOString(), - inbox: inboxURL(row.id), - outbox: outboxURL(row.id), - following: followingURL(row.id), - followers: followersURL(row.id), url: new URL('@' + preferredUsername, 'https://' + domain), - } as Person + } as unknown as Person } diff --git a/backend/src/activitypub/objects/note.ts b/backend/src/activitypub/objects/note.ts index 1986bbc..0fc92b0 100644 --- a/backend/src/activitypub/objects/note.ts +++ b/backend/src/activitypub/objects/note.ts @@ -2,7 +2,6 @@ import type { Actor } from 'wildebeest/backend/src/activitypub/actors' import type { Link } from 'wildebeest/backend/src/activitypub/objects/link' -import { followersURL } from 'wildebeest/backend/src/activitypub/actors' import { PUBLIC_GROUP } from 'wildebeest/backend/src/activitypub/activities' import * as objects from '.' @@ -36,7 +35,7 @@ export async function createPublicNote( attributedTo: actorId, content, to: [PUBLIC_GROUP], - cc: [followersURL(actorId)], + cc: [actor.followers.toString()], // FIXME: stub values replies: null, diff --git a/backend/test/activitypub.spec.ts b/backend/test/activitypub.spec.ts index 47a460c..6a46173 100644 --- a/backend/test/activitypub.spec.ts +++ b/backend/test/activitypub.spec.ts @@ -31,7 +31,13 @@ describe('ActivityPub', () => { test('fetch user by id', async () => { const db = await makeDB() - const properties = { summary: 'test summary' } + const properties = { + summary: 'test summary', + inbox: 'https://example.com/inbox', + outbox: 'https://example.com/outbox', + following: 'https://example.com/following', + followers: 'https://example.com/followers', + } const pubKey = '-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApnI8FHJQXqqAdM87YwVseRUqbNLiw8nQ0zHBUyLylzaORhI4LfW4ozguiw8cWYgMbCufXMoITVmdyeTMGbQ3Q1sfQEcEjOZZXEeCCocmnYjK6MFSspjFyNw6GP0a5A/tt1tAcSlgALv8sg1RqMhSE5Kv+6lSblAYXcIzff7T2jh9EASnimaoAAJMaRH37+HqSNrouCxEArcOFhmFETadXsv+bHZMozEFmwYSTugadr4WD3tZd+ONNeimX7XZ3+QinMzFGOW19ioVHyjt3yCDU1cPvZIDR17dyEjByNvx/4N4Zly7puwBn6Ixy/GkIh5BWtL5VOFDJm/S+zcf1G1WsOAXMwKL4Nc5UWKfTB7Wd6voId7vF7nI1QYcOnoyh0GqXWhTPMQrzie4nVnUrBedxW0s/0vRXeR63vTnh5JrTVu06JGiU2pq2kvwqoui5VU6rtdImITybJ8xRkAQ2jo4FbbkS6t49PORIuivxjS9wPl7vWYazZtDVa5g/5eL7PnxOG3HsdIJWbGEh1CsG83TU9burHIepxXuQ+JqaSiKdCVc8CUiO++acUqKp7lmbYR9E/wRmvxXDFkxCZzA0UL2mRoLLLOe4aHvRSTsqiHC5Wwxyew5bb+eseJz3wovid9ZSt/tfeMAkCDmaCxEK+LGEbJ9Ik8ihis8Esm21N0A54sCAwEAAQ==-----END PUBLIC KEY-----' await db