Skip to content

Commit

Permalink
fix: Only show private replies to authenticated users
Browse files Browse the repository at this point in the history
  • Loading branch information
Mauve Signweaver committed Jun 6, 2024
1 parent a494be8 commit 85bedac
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
11 changes: 9 additions & 2 deletions src/server/api/inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,15 @@ export const inboxRoutes = (cfg: APIConfig, store: Store, apsystem: ActivityPubS
}, async (request, reply) => {
const { actor, inReplyTo } = request.params

// No need for verification?
const collection = await apsystem.repliesCollection(actor, decodeURIComponent(inReplyTo))
let to: string | undefined

// Only try to set `to` if it's a signed request
if (request.headers.signature !== undefined) {
const submittedActorMention = await apsystem.verifySignedRequest(request, actor)
to = await apsystem.mentionToActor(submittedActorMention)
}

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

return await reply.send(collection)
})
Expand Down
4 changes: 2 additions & 2 deletions src/server/apsystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,8 @@ export default class ActivityPubSystem {
await this.sendTo(followerURL, fromActor, response)
}

async repliesCollection (fromActor: string, inReplyTo: string): Promise<APCollection> {
const items = await this.store.forActor(fromActor).inboxObjects.list({ inReplyTo })
async repliesCollection (fromActor: string, inReplyTo: string, to?: string): Promise<APCollection> {
const items = await this.store.forActor(fromActor).inboxObjects.list({ inReplyTo, to })
const id = this.makeURL(`/v1/${fromActor}/inbox/replies/${encodeURIComponent(inReplyTo)}`)

return {
Expand Down
20 changes: 19 additions & 1 deletion src/server/store/ObjectStore.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint @typescript-eslint/no-non-null-assertion: 0 */
import test from 'ava'
import { APObjectStore } from './ObjectStore'
import { APObjectStore, PUBLIC_TO_URL } from './ObjectStore'
import { MemoryLevel } from 'memory-level'
import { APNote } from 'activitypub-types'

Expand All @@ -13,6 +13,7 @@ const note: APNote = {
'@context': 'https://www.w3.org/ns/activitystreams',
type: 'Note',
id: 'https://example.com/note1',
to: [PUBLIC_TO_URL],
published: new Date().toISOString(),
attributedTo: 'https://example.com/user1',
content: 'Hello world'
Expand Down Expand Up @@ -43,3 +44,20 @@ test('APObjectStore - list from indexes', async t => {
const fromA = await store.list({ attributedTo: a.attributedTo })
t.deepEqual(fromA, [b, a], 'Got just notes by a')
})

test('APObjectStore - filter private objects', async t => {
const store = newStore()
const exampleTo = 'https://example.com'

const a = { ...note, to: [exampleTo] }

await store.add(a)

const publicList = await store.list()

t.deepEqual(publicList, [], 'Private note was not listed')

const privateList = await store.list({ to: exampleTo })

t.deepEqual(privateList, [a], 'Private posts are listable')
})
21 changes: 19 additions & 2 deletions src/server/store/ObjectStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { AbstractLevel } from 'abstract-level'
import { APObject } from 'activitypub-types'
import createError from 'http-errors'

export const PUBLIC_TO_URL = 'https://www.w3.org/ns/activitystreams#Public'

export interface ListParameters {
inReplyTo?: string
attributedTo?: string
to?: string
skip?: number
limit?: number
}
Expand Down Expand Up @@ -89,7 +92,7 @@ export class APObjectStore {
}
}

async list ({ skip = 0, limit = Infinity, attributedTo, inReplyTo }: ListParameters = {}): Promise<APObject[]> {
async list ({ skip = 0, limit = Infinity, attributedTo, inReplyTo, to }: ListParameters = {}): Promise<APObject[]> {
const items: APObject[] = []

let iterator = null
Expand All @@ -108,7 +111,21 @@ export class APObjectStore {
skip--
continue
}
items.push(await this.get(url))
const object = await this.get(url)

if (Array.isArray(object.to)) {
if (!object.to.includes(PUBLIC_TO_URL)) {
if ((to === undefined) || !object.to.includes(to)) {
continue
}
}
} else if (typeof object.to === 'string') {
if (object.to !== PUBLIC_TO_URL) {
if (object.to !== to) continue
}
}
// TODO: Should we handle `to` being an object?
items.push(object)
}

return items
Expand Down

0 comments on commit 85bedac

Please sign in to comment.