Changeset d49b60b in Klonkt for src/config


Ignore:
Timestamp:
07/19/2026 02:52:55 AM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
dd568e7
Parents:
c867b7b
git-author:
Robin <roboburr@…> (07/19/2026 02:52:09 AM)
git-committer:
Robin <roboburr@…> (07/19/2026 02:52:55 AM)
Message:

Feature: OAuth 2.0 for ActivityPub C2S (phase 1 — auth handshake)

First half of AP Client-to-Server: the auth layer native/web clients (Shaer)
need before they can drive a Klonkt account. The AP spec's own C2S half is what
keeps this inside-spec instead of cloning Mastodon's REST API.

  • OAuthService: public-client OAuth (RFC 8252), PKCE S256 REQUIRED, no secrets. Dynamic registration (RFC 7591 subset) with strict redirect_uri validation (https / loopback http / reverse-DNS custom scheme). Single-use 10-min codes; tokens stored sha256-hashed; a token is scoped to one user + one site.
  • routes/oauth.js: /oauth/register, /oauth/authorize (session-authed consent screen picking the site), /oauth/token, and RFC 8414 server metadata at /.well-known/oauth-authorization-server. Redirect params are appended to the registered URI verbatim (no new URL() round-trip that would mangle a native custom scheme). Pre-redirect validation errors never bounce to an unvalidated URI (open-redirect guard).
  • Actor doc advertises oauthAuthorizationEndpoint/oauthTokenEndpoint/uploadMedia in endpoints{} — all AP-spec terms, added to the AS2 conformance allowlist — so clients discover paths instead of hardcoding them (Klonkt's /ap/users/:slug differs from the daemon's /actors/:name; discovery makes that irrelevant).
  • oauth_clients/oauth_codes/oauth_tokens tables (additive).
  • i18n NL/EN/DE for the consent screen.

7 new OAuth tests (PKCE round-trip, replay protection, wrong-verifier reject,
bearer resolution incl. revoke, redirect-uri validation); 73 green. Verified
the full HTTP flow end to end (register → consent → code → token → bearer) and
that the raw Location header preserves the native redirect URI exactly. Beads:
klonkt-demo-srr. Next: klonkt-demo-1w4 (POST outbox accepts the activities).

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/config/database.js

    rc867b7b rd49b60b  
    282282      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    283283    );
     284    -- ActivityPub C2S (client-to-server): OAuth 2.0 for native/web clients (Shaer).
     285    -- Public clients + PKCE (RFC 8252); tokens stored hashed; token is per user+site.
     286    CREATE TABLE IF NOT EXISTS oauth_clients (
     287      client_id TEXT PRIMARY KEY,
     288      client_name TEXT,
     289      redirect_uris TEXT NOT NULL,        -- JSON array
     290      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
     291    );
     292    CREATE TABLE IF NOT EXISTS oauth_codes (
     293      code TEXT PRIMARY KEY,
     294      client_id TEXT NOT NULL,
     295      user_id TEXT NOT NULL,
     296      site_slug TEXT NOT NULL,
     297      redirect_uri TEXT NOT NULL,
     298      code_challenge TEXT,                -- PKCE S256 (verplicht voor public clients)
     299      scope TEXT,
     300      expires_at DATETIME NOT NULL,
     301      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
     302    );
     303    CREATE TABLE IF NOT EXISTS oauth_tokens (
     304      token_hash TEXT PRIMARY KEY,        -- sha256(bearer); het token zelf slaan we nooit op
     305      client_id TEXT NOT NULL,
     306      user_id TEXT NOT NULL,
     307      site_slug TEXT NOT NULL,
     308      scope TEXT,
     309      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     310      last_used_at DATETIME
     311    );
    284312    CREATE TABLE IF NOT EXISTS ap_outbox (
    285313      id TEXT PRIMARY KEY,            -- note path segment (uuid) → /ap/notes/<id>
Note: See TracChangeset for help on using the changeset viewer.