Skip to content

Commit

Permalink
Merge branch 'main' of ssh://github.com/hyphacoop/social.distributed.…
Browse files Browse the repository at this point in the history
…press into auto-accept-remote-deletes
  • Loading branch information
fauno committed Oct 28, 2024
2 parents bd7489c + 5bdf50b commit 33e870a
Show file tree
Hide file tree
Showing 8 changed files with 543 additions and 126 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "distributed-press-social",
"version": "1.4.1",
"version": "1.5.0",
"description": "API for the Distributed Press Social Inbox",
"main": "dist/index.js",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion src/server/api/followers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const followerRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityP

const collection = await apsystem.followersCollection(actor, !allowed)

return await reply.send(collection)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(collection)
})

// Remove a follower (notifying their server), use URL encoded URL of follower Actor
Expand Down
10 changes: 5 additions & 5 deletions src/server/api/inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS
id: `${cfg.publicURL}${request.url}`,
first: `${cfg.publicURL}/v1/${actor}/inbox?limit=100`
}
return await reply.send(inbox)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(inbox)
}
skip ??= 0

Expand All @@ -68,7 +68,7 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS
next,
orderedItems
}
return await reply.send(orderedCollectionPage)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(orderedCollectionPage)
})

// This is what instances will POST to in order to notify of follows/replies/etc
Expand Down Expand Up @@ -145,7 +145,7 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS

const collection = await apsystem.repliesCollection(actor, replyURL, to)

return await reply.send(collection)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(collection)
})

// TODO: Paging?
Expand Down Expand Up @@ -179,7 +179,7 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS

const collection = await apsystem.likesCollection(actor, objectURL, !allowed)

return await reply.send(collection)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(collection)
})

// TODO: Paging?
Expand Down Expand Up @@ -213,7 +213,7 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS

const collection = await apsystem.sharesCollection(actor, objectURL, !allowed)

return await reply.send(collection)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(collection)
})
// Deny a follow request/boost/etc
// The ID is the URL encoded id from the inbox activity
Expand Down
2 changes: 1 addition & 1 deletion src/server/api/outbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ export const outboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPub

const activity = await apsystem.getOutboxItem(actor, id)

return await reply.send(activity)
return await reply.headers({ 'Content-Type': 'application/activity+json' }).send(activity)
})
}
81 changes: 79 additions & 2 deletions src/server/apsystem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { MockFetch } from './fixtures/mockFetch.js'
import { generateKeypair } from 'http-signed-fetch'

// Helper function to create a new Store instance
function newStore (): Store {
function newStore(): Store {
return new Store(new MemoryLevel({ valueEncoding: 'json' }))
}

Expand All @@ -34,7 +34,7 @@ const mockFetch: FetchLike = async (input: RequestInfo | URL, init?: RequestInit
}
const mockHooks = new HookSystem(mockStore, mockFetch)

function noop (): void {
function noop(): void {
}
const mockLog = {
info: noop,
Expand Down Expand Up @@ -484,6 +484,83 @@ test('ActivityPubSystem - Interacted store', async t => {
}
})

test('ActivityPubSystem - Backfill Inbox', async t => {
const store = newStore()
const mockFetch = new MockFetch()
const hookSystem = new HookSystem(store, mockFetch.fetch as FetchLike)
const aps = new ActivityPubSystem(
'http://localhost',
store,
mockModCheck,
hookSystem,
mockLog,
mockFetch.fetch as FetchLike
)

const object = 'https://example.com/note1'
const authorMention = '@[email protected]'

const authorUrl = mockFetch.mockActor(authorMention)
// required for signed fetch
await store.forActor(authorMention).setInfo({
keypair: { ...generateKeypair() },
actorUrl: authorUrl,
publicKeyId: 'testAccount#main-key'
})

const note = {
'@context': 'https://www.w3.org/ns/activitystreams',
type: 'Note',
published: new Date().toISOString(),
content: 'Hello world',
to: [
'https://example.com/author/followers'
],
cc: [
'https://www.w3.org/ns/activitystreams#Public'
],
id: object,
attributedTo: authorUrl
}

const activity = {
'@context': 'https://www.w3.org/ns/activitystreams',
type: 'Create',
published: new Date().toISOString(),
actor: authorUrl,
object: note,
id: 'https://example.com/activity1'
}

mockFetch.mockOutbox(authorMention, [activity])

const followerMention = '@[email protected]'
const followerURL = mockFetch.mockActor(followerMention)
const followRequest: APActivity = {
id: 'https://example.com/follow',
type: 'Follow',
actor: followerURL,
object: authorUrl
}
mockFetch.addAPObject(followRequest)

const followerInbox = `${followerURL}inbox`

// mock the inbox
mockFetch.set(followerInbox, '')

await store.forActor(authorMention).inbox.add(followRequest)

await aps.acceptFollow(authorMention, followRequest)

t.assert(mockFetch.history.includes(followerInbox), 'data sent to inbox')

// mock follower actor
// make fake follow request in store
// accept follow
// expect requests for the outbox and notes, expect request in inbox
})

test('ActivityPubSystem - Handle Delete activity', async t => {
const store = newStore()
const mockFetch = new MockFetch()
Expand Down
Loading

0 comments on commit 33e870a

Please sign in to comment.