Add actorController
This commit is contained in:
parent
4e6b9f4328
commit
819ae61bca
|
@ -2,6 +2,7 @@ import { type Context, cors, type Handler, Hono, type HonoEnv, logger, type Midd
|
||||||
import { type Event } from '@/event.ts';
|
import { type Event } from '@/event.ts';
|
||||||
import '@/loopback.ts';
|
import '@/loopback.ts';
|
||||||
|
|
||||||
|
import { actorController } from './controllers/activitypub/actor.ts';
|
||||||
import {
|
import {
|
||||||
accountController,
|
accountController,
|
||||||
accountLookupController,
|
accountLookupController,
|
||||||
|
@ -67,6 +68,8 @@ app.get('/.well-known/host-meta', hostMetaController);
|
||||||
app.get('/.well-known/nodeinfo', nodeInfoController);
|
app.get('/.well-known/nodeinfo', nodeInfoController);
|
||||||
app.get('/.well-known/nostr.json', nostrController);
|
app.get('/.well-known/nostr.json', nostrController);
|
||||||
|
|
||||||
|
app.get('/users/:username', actorController);
|
||||||
|
|
||||||
app.get('/nodeinfo/:version', nodeInfoSchemaController);
|
app.get('/nodeinfo/:version', nodeInfoSchemaController);
|
||||||
|
|
||||||
app.get('/api/v1/instance', instanceController);
|
app.get('/api/v1/instance', instanceController);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { getAuthor } from '@/client.ts';
|
||||||
|
import { db } from '@/db.ts';
|
||||||
|
import { toActor } from '@/transformers/nostr-to-activitypub.ts';
|
||||||
|
import { activityJson } from '@/utils.ts';
|
||||||
|
|
||||||
|
import type { AppController } from '@/app.ts';
|
||||||
|
|
||||||
|
const actorController: AppController = async (c) => {
|
||||||
|
const notFound = c.json({ error: 'Not found' }, 404);
|
||||||
|
|
||||||
|
const username = c.req.param('username');
|
||||||
|
const user = await db.users.findFirst({ where: { username } });
|
||||||
|
|
||||||
|
const event = await getAuthor(user.pubkey);
|
||||||
|
if (!event) return notFound;
|
||||||
|
|
||||||
|
const actor = await toActor(event);
|
||||||
|
if (!actor) return notFound;
|
||||||
|
|
||||||
|
return activityJson(c, actor);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { actorController };
|
|
@ -6,9 +6,13 @@ import type { Event } from '@/event.ts';
|
||||||
import type { Actor } from '@/schemas/activitypub.ts';
|
import type { Actor } from '@/schemas/activitypub.ts';
|
||||||
|
|
||||||
/** Nostr metadata event to ActivityPub actor. */
|
/** Nostr metadata event to ActivityPub actor. */
|
||||||
async function toActor(event: Event<0>, username: string): Promise<Actor> {
|
async function toActor(event: Event<0>): Promise<Actor | undefined> {
|
||||||
const content = parseMetaContent(event);
|
const content = parseMetaContent(event);
|
||||||
|
|
||||||
|
if (!content.nip05) return;
|
||||||
|
const [username, hostname] = content.nip05.split('@');
|
||||||
|
if (hostname !== Conf.url.hostname) return;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'Person',
|
type: 'Person',
|
||||||
id: Conf.local(`/users/${username}`),
|
id: Conf.local(`/users/${username}`),
|
||||||
|
|
21
src/utils.ts
21
src/utils.ts
|
@ -1,6 +1,6 @@
|
||||||
import { getAuthor } from '@/client.ts';
|
import { getAuthor } from '@/client.ts';
|
||||||
import { Conf } from '@/config.ts';
|
import { Conf } from '@/config.ts';
|
||||||
import { nip19, parseFormData, z } from '@/deps.ts';
|
import { type Context, nip19, parseFormData, z } from '@/deps.ts';
|
||||||
import { type Event } from '@/event.ts';
|
import { type Event } from '@/event.ts';
|
||||||
import { lookupNip05Cached } from '@/nip05.ts';
|
import { lookupNip05Cached } from '@/nip05.ts';
|
||||||
|
|
||||||
|
@ -124,7 +124,26 @@ async function sha256(message: string): Promise<string> {
|
||||||
return hashHex;
|
return hashHex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** JSON-LD context. */
|
||||||
|
type LDContext = (string | Record<string, string | Record<string, string>>)[];
|
||||||
|
|
||||||
|
/** Add a basic JSON-LD context to ActivityStreams object, if it doesn't already exist. */
|
||||||
|
function maybeAddContext<T>(object: T): T & { '@context': LDContext } {
|
||||||
|
return {
|
||||||
|
'@context': ['https://www.w3.org/ns/activitystreams'],
|
||||||
|
...object,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Like hono's `c.json()` except returns JSON-LD. */
|
||||||
|
function activityJson<T, P extends string>(c: Context<any, P>, object: T) {
|
||||||
|
const response = c.json(maybeAddContext(object));
|
||||||
|
response.headers.set('content-type', 'application/activity+json; charset=UTF-8');
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
activityJson,
|
||||||
bech32ToPubkey,
|
bech32ToPubkey,
|
||||||
buildLinkHeader,
|
buildLinkHeader,
|
||||||
eventAge,
|
eventAge,
|
||||||
|
|
Loading…
Reference in New Issue