Changeset 6bd25d1 in Klonkt


Ignore:
Timestamp:
06/24/2026 10:27:56 AM (3 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
5bf63b7
Parents:
69815b2
Message:

feat(activitypub): phase 1 — discoverable/fetchable actor (WebFinger, Actor, Outbox, Notes)

First step of real ActivityPub federation: per-site RSA keys, WebFinger,
a content-negotiated Actor document (AP-JSON for servers, redirect to the HTML
profile for browsers), Outbox (Create/Note) and Note objects under /ap/*.
Inbox is a 202 stub for now; Follow/Accept + HTTP-signature verify + delivery
to followers land in the next step (tested live against Mastodon).

Co-Authored-By: Claude <noreply@…>

Location:
src
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/config/database.js

    r69815b2 r6bd25d1  
    295295    CREATE INDEX IF NOT EXISTS idx_post_likes_post ON post_likes(post_id);
    296296  `);
     297
     298  // ── ActivityPub (fediverse bridge) ──────────────────────────
     299  // RSA keypair per actor (Mastodon-compatible HTTP Signatures; separate from
     300  // the Cirkels Ed25519 keys). ap_followers = remote AP actors following us.
     301  db.exec(`
     302    CREATE TABLE IF NOT EXISTS ap_keys (
     303      slug TEXT PRIMARY KEY,
     304      public_pem TEXT NOT NULL,
     305      private_pem TEXT NOT NULL,
     306      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
     307    );
     308    CREATE TABLE IF NOT EXISTS ap_followers (
     309      id INTEGER PRIMARY KEY AUTOINCREMENT,
     310      slug TEXT NOT NULL,
     311      actor_uri TEXT NOT NULL,
     312      inbox TEXT,
     313      shared_inbox TEXT,
     314      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     315      UNIQUE(slug, actor_uri)
     316    );
     317    CREATE INDEX IF NOT EXISTS idx_ap_followers_slug ON ap_followers(slug);
     318  `);
    297319}
    298320
  • src/server.js

    r69815b2 r6bd25d1  
    6464import changelogRoutes from './routes/changelog.js';
    6565import ogRoutes from './routes/og.js';
     66import apRoutes from './routes/activitypub.js';
    6667
    6768// SESSION_SECRET: use the env var if set. Otherwise auto-generate a strong one
     
    223224app.use(federationRoutes);
    224225
     226// ActivityPub: WebFinger + /ap/* (site-agnostic, resolves the site by slug).
     227app.use(apRoutes);
     228
    225229// Themed OG cards (/og/:slug.png) — resolve the site by slug themselves, so they
    226230// run before resolveSite and need no site context.
Note: See TracChangeset for help on using the changeset viewer.