Changeset 61e3daf in Klonkt for src/config/database.js


Ignore:
Timestamp:
07/21/2026 12:38:08 AM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
928d1c7
Parents:
4a08bfc
git-author:
Robin <roboburr@…> (07/21/2026 12:38:07 AM)
git-committer:
Robin <roboburr@…> (07/21/2026 12:38:08 AM)
Message:

Feature: paid posts slice 1, owner Patreon config (encrypted)

The site owner can connect their OWN Patreon campaign for paid posts
(klonkt-demo-aki), premium-gated in Beheer. Client id/secret, campaign
id and the creator access/refresh token are stored ENCRYPTED at rest
(new CryptoBox AES-256-GCM helper, key from PAID_SECRET), so a database
dump leaks nothing usable; the token auto-refreshes. Separate from
Klonkt Premium's license flow, which is untouched. Degrades gracefully:
without PAID_SECRET the admin page refuses to save rather than storing
plaintext. Nothing patron-facing yet (posts.paid + unlock come in
slices 2 to 4), so no changelog entry.

CryptoBox also carries the cookie-less signed-blob helper (signBlob/
verifyBlob) that slices 3 and 4 reuse for the OAuth state and the
WebAuthn challenge.

Changed files:
src/config/database.js

  • paid_patreon table (site_id PK, secrets encrypted)

src/server.js

  • mount /admin/paid

src/views/pages/admin.ejs

  • "Betaalde posts" button in Beheer

New file:
src/services/CryptoBox.js

  • aes-256-gcm encrypt/decrypt + HMAC signBlob/verifyBlob

src/services/PaidPatreonService.js

  • owner config CRUD (encrypted), token refresh, creatorAccessToken

src/routes/admin-paid.js

  • premium-gated config form (GET/POST/disconnect)

src/views/pages/admin-paid.ejs

  • the form + status

test/paid-patreon.test.js

  • crypto roundtrip, no-plaintext-in-DB, refresh, blob signing

docs/paid-posts-design.md, docs/privacy-betaalde-posts.md

  • concurrency property documented

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/config/database.js

    r4a08bfc r61e3daf  
    310310      last_used_at DATETIME
    311311    );
     312    -- Paid posts (klonkt-demo-aki): the site owner's own Patreon campaign.
     313    -- Secrets are encrypted at rest (CryptoBox). Never reuses the instance-level
     314    -- patreon_* settings, which are Klonkt Premium's separate license flow.
     315    CREATE TABLE IF NOT EXISTS paid_patreon (
     316      site_id TEXT PRIMARY KEY,
     317      client_id TEXT,
     318      client_secret_enc TEXT,
     319      campaign_id TEXT,
     320      access_token_enc TEXT,
     321      refresh_token_enc TEXT,
     322      token_exp INTEGER,               -- unix seconds
     323      default_min_cents INTEGER DEFAULT 0,
     324      updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
     325    );
    312326    CREATE TABLE IF NOT EXISTS ap_outbox (
    313327      id TEXT PRIMARY KEY,            -- note path segment (uuid) → /ap/notes/<id>
Note: See TracChangeset for help on using the changeset viewer.