kopia lustrzana https://github.com/cloudflare/wildebeest
MOW-128: collect and expose peers
rodzic
48ab322250
commit
39e76bfb48
|
@ -1,6 +1,7 @@
|
||||||
import { defaultImages } from 'wildebeest/config/accounts'
|
import { defaultImages } from 'wildebeest/config/accounts'
|
||||||
import { generateUserKey } from 'wildebeest/backend/src/utils/key-ops'
|
import { generateUserKey } from 'wildebeest/backend/src/utils/key-ops'
|
||||||
import { type APObject, sanitizeContent, sanitizeName } from '../objects'
|
import { type APObject, sanitizeContent, sanitizeName } from '../objects'
|
||||||
|
import { addPeer } from 'wildebeest/backend/src/activitypub/peers'
|
||||||
|
|
||||||
const PERSON = 'Person'
|
const PERSON = 'Person'
|
||||||
const isTesting = typeof jest !== 'undefined'
|
const isTesting = typeof jest !== 'undefined'
|
||||||
|
@ -112,6 +113,12 @@ export async function getAndCache(url: URL, db: D1Database): Promise<Actor> {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new Error('SQL error: ' + error)
|
throw new Error('SQL error: ' + error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add peer
|
||||||
|
{
|
||||||
|
const domain = actor.id.host
|
||||||
|
await addPeer(db, domain)
|
||||||
|
}
|
||||||
return actor
|
return actor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { UUID } from 'wildebeest/backend/src/types'
|
import type { UUID } from 'wildebeest/backend/src/types'
|
||||||
|
import { addPeer } from 'wildebeest/backend/src/activitypub/peers'
|
||||||
|
|
||||||
export const originalActorIdSymbol = Symbol()
|
export const originalActorIdSymbol = Symbol()
|
||||||
export const originalObjectIdSymbol = Symbol()
|
export const originalObjectIdSymbol = Symbol()
|
||||||
|
@ -118,6 +119,12 @@ export async function cacheObject(
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
|
|
||||||
|
// Add peer
|
||||||
|
{
|
||||||
|
const domain = originalObjectId.host
|
||||||
|
await addPeer(db, domain)
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const properties = JSON.parse(row.properties)
|
const properties = JSON.parse(row.properties)
|
||||||
const object = {
|
const object = {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { getResultsField } from 'wildebeest/backend/src/mastodon/utils'
|
||||||
|
|
||||||
|
export async function getPeers(db: D1Database): Promise<Array<String>> {
|
||||||
|
const query = `SELECT domain FROM peers `
|
||||||
|
const statement = db.prepare(query)
|
||||||
|
|
||||||
|
return getResultsField(statement, 'domain')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addPeer(db: D1Database, domain: string): Promise<void> {
|
||||||
|
const query = `
|
||||||
|
INSERT OR IGNORE INTO peers (domain)
|
||||||
|
VALUES (?)
|
||||||
|
`
|
||||||
|
|
||||||
|
const out = await db.prepare(query).bind(domain).run()
|
||||||
|
if (!out.success) {
|
||||||
|
throw new Error('SQL error: ' + out.error)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import { makeDB, isUrlValid } from './utils'
|
||||||
import { MessageType } from 'wildebeest/backend/src/types/queue'
|
import { MessageType } from 'wildebeest/backend/src/types/queue'
|
||||||
import type { JWK } from 'wildebeest/backend/src/webpush/jwk'
|
import type { JWK } from 'wildebeest/backend/src/webpush/jwk'
|
||||||
import { createPerson } from 'wildebeest/backend/src/activitypub/actors'
|
import { createPerson } from 'wildebeest/backend/src/activitypub/actors'
|
||||||
|
import * as actors from 'wildebeest/backend/src/activitypub/actors'
|
||||||
import { createPrivateNote, createPublicNote } from 'wildebeest/backend/src/activitypub/objects/note'
|
import { createPrivateNote, createPublicNote } from 'wildebeest/backend/src/activitypub/objects/note'
|
||||||
import { addObjectInOutbox } from 'wildebeest/backend/src/activitypub/actors/outbox'
|
import { addObjectInOutbox } from 'wildebeest/backend/src/activitypub/actors/outbox'
|
||||||
import { strict as assert } from 'node:assert/strict'
|
import { strict as assert } from 'node:assert/strict'
|
||||||
|
@ -128,6 +129,38 @@ describe('ActivityPub', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Actors', () => {
|
||||||
|
test('getAndCache adds peer', async () => {
|
||||||
|
const actorId = new URL('https://example.com/user/foo')
|
||||||
|
|
||||||
|
globalThis.fetch = async (input: RequestInfo) => {
|
||||||
|
if (input.toString() === actorId.toString()) {
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
id: actorId,
|
||||||
|
type: 'Person',
|
||||||
|
preferredUsername: 'sven',
|
||||||
|
name: 'sven ssss',
|
||||||
|
|
||||||
|
icon: { url: 'icon.jpg' },
|
||||||
|
image: { url: 'image.jpg' },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`unexpected request to "${input}"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = await makeDB()
|
||||||
|
|
||||||
|
await actors.getAndCache(actorId, db)
|
||||||
|
|
||||||
|
const { results } = (await db.prepare('SELECT domain from peers').all()) as any
|
||||||
|
assert.equal(results.length, 1)
|
||||||
|
assert.equal(results[0].domain, 'example.com')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('Objects', () => {
|
describe('Objects', () => {
|
||||||
test('cacheObject deduplicates object', async () => {
|
test('cacheObject deduplicates object', async () => {
|
||||||
const db = await makeDB()
|
const db = await makeDB()
|
||||||
|
@ -159,6 +192,19 @@ describe('ActivityPub', () => {
|
||||||
assert.equal(result.count, 1)
|
assert.equal(result.count, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('cacheObject adds peer', async () => {
|
||||||
|
const db = await makeDB()
|
||||||
|
const properties = { type: 'Note', a: 1, b: 2 }
|
||||||
|
const actor = await createPerson(domain, db, userKEK, 'a@cloudflare.com')
|
||||||
|
const originalObjectId = new URL('https://example.com/object1')
|
||||||
|
|
||||||
|
await cacheObject(domain, db, properties, actor.id, originalObjectId, false)
|
||||||
|
|
||||||
|
const { results } = (await db.prepare('SELECT domain from peers').all()) as any
|
||||||
|
assert.equal(results.length, 1)
|
||||||
|
assert.equal(results[0].domain, 'example.com')
|
||||||
|
})
|
||||||
|
|
||||||
test('serve unknown object', async () => {
|
test('serve unknown object', async () => {
|
||||||
const db = await makeDB()
|
const db = await makeDB()
|
||||||
const res = await ap_objects.handleRequest(domain, db, 'unknown id')
|
const res = await ap_objects.handleRequest(domain, db, 'unknown id')
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { addPeer } from 'wildebeest/backend/src/activitypub/peers'
|
||||||
|
import { strict as assert } from 'node:assert/strict'
|
||||||
|
import * as peers from 'wildebeest/functions/api/v1/instance/peers'
|
||||||
|
import { makeDB } from '../utils'
|
||||||
|
|
||||||
|
describe('Mastodon APIs', () => {
|
||||||
|
describe('instance', () => {
|
||||||
|
test('returns peers', async () => {
|
||||||
|
const db = await makeDB()
|
||||||
|
await addPeer(db, 'a')
|
||||||
|
await addPeer(db, 'b')
|
||||||
|
|
||||||
|
const res = await peers.handleRequest(db)
|
||||||
|
assert.equal(res.status, 200)
|
||||||
|
|
||||||
|
const data = await res.json<Array<string>>()
|
||||||
|
assert.equal(data.length, 2)
|
||||||
|
assert.equal(data[0], 'a')
|
||||||
|
assert.equal(data[1], 'b')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { cors } from 'wildebeest/backend/src/utils/cors'
|
||||||
|
import type { Env } from 'wildebeest/backend/src/types/env'
|
||||||
|
import { getPeers } from 'wildebeest/backend/src/activitypub/peers'
|
||||||
|
|
||||||
|
export const onRequest: PagesFunction<Env, any> = async ({ env }) => {
|
||||||
|
return handleRequest(env.DATABASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handleRequest(db: D1Database): Promise<Response> {
|
||||||
|
const headers = {
|
||||||
|
...cors(),
|
||||||
|
'content-type': 'application/json; charset=utf-8',
|
||||||
|
}
|
||||||
|
const peers = await getPeers(db)
|
||||||
|
return new Response(JSON.stringify(peers), { headers })
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- Migration number: 0003 2023-02-02T15:03:27.478Z
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS peers (
|
||||||
|
domain TEXT NOT NULL
|
||||||
|
);
|
Ładowanie…
Reference in New Issue