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 '@/loopback.ts';
|
||||
|
||||
import { actorController } from './controllers/activitypub/actor.ts';
|
||||
import {
|
||||
accountController,
|
||||
accountLookupController,
|
||||
|
@ -67,6 +68,8 @@ app.get('/.well-known/host-meta', hostMetaController);
|
|||
app.get('/.well-known/nodeinfo', nodeInfoController);
|
||||
app.get('/.well-known/nostr.json', nostrController);
|
||||
|
||||
app.get('/users/:username', actorController);
|
||||
|
||||
app.get('/nodeinfo/:version', nodeInfoSchemaController);
|
||||
|
||||
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';
|
||||
|
||||
/** 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);
|
||||
|
||||
if (!content.nip05) return;
|
||||
const [username, hostname] = content.nip05.split('@');
|
||||
if (hostname !== Conf.url.hostname) return;
|
||||
|
||||
return {
|
||||
type: 'Person',
|
||||
id: Conf.local(`/users/${username}`),
|
||||
|
|
21
src/utils.ts
21
src/utils.ts
|
@ -1,6 +1,6 @@
|
|||
import { getAuthor } from '@/client.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 { lookupNip05Cached } from '@/nip05.ts';
|
||||
|
||||
|
@ -124,7 +124,26 @@ async function sha256(message: string): Promise<string> {
|
|||
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 {
|
||||
activityJson,
|
||||
bech32ToPubkey,
|
||||
buildLinkHeader,
|
||||
eventAge,
|
||||
|
|
Loading…
Reference in New Issue