Changeset 1b4d5dd in Klonkt


Ignore:
Timestamp:
06/16/2026 06:23:28 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
f63cbc2
Parents:
a9e23f6
Message:

Patreon premium gate (Phase 1): entitlement verification + Connect Patreon + isPremium

Klonkt-side of the Patreon model. The license server signs an Ed25519 JWT
entitlement token; this instance verifies it OFFLINE with Node-crypto
against /pubkey (no jose dependency). PatreonService: verify/store/isPremium.
Routes /admin/patreon/connect|callback|disconnect. Premium card in
Admin → Settings.

Premium is OFF BY DEFAULT (env KLONKT_PREMIUM_ENABLED != on) → no premium
UI, nothing gated. Inert deployment until the self-hoster enables it and
connects Patreon. Gating Hub/Statistics/Fan login follows in Phases 2-4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@…>

Location:
src
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/middleware/render.js

    ra9e23f6 r1b4d5dd  
    1818import { isViewer } from './auth.js';
    1919import { getSetting } from '../services/SettingsService.js';
     20import { isPremium as isPremiumInstance, premiumEnabled } from '../services/PatreonService.js';
    2021import { PLATFORMS as PLATFORMS_CATALOG } from '../services/PlatformIcons.js';
    2122
     
    7778    isViewer: _isViewer,
    7879    canMutate: !_isViewer,
     80    isPremium: isPremiumInstance(),
     81    premiumEnabled: premiumEnabled(),
    7982    siteOwnerAvatar,
    8083    site: _site,
  • src/routes/admin-settings.js

    ra9e23f6 r1b4d5dd  
    2222import { requireGod } from '../middleware/auth.js';
    2323import { getTenancy, setTenancy, getSetting, setSetting } from '../services/SettingsService.js';
     24import { entitlementStatus } from '../services/PatreonService.js';
    2425
    2526const router = express.Router();
     
    7475    hubHeroImage: getSetting('hub_hero_image') || '',
    7576    hubHeroOverlay: clampOverlay(getSetting('hub_hero_overlay')),
     77    premium: entitlementStatus(),
    7678    success: req.query.success || null,
    7779    error: req.query.error || null,
  • src/server.js

    ra9e23f6 r1b4d5dd  
    4848import adminCircleRoutes from './routes/admin-circle.js';
    4949import adminUpdatesRoutes from './routes/admin-updates.js';
     50import adminPatreonRoutes from './routes/admin-patreon.js';
    5051import circleRoutes from './routes/circle.js';
    5152
     
    239240app.use('/admin/circle', adminCircleRoutes);
    240241app.use('/admin/updates', adminUpdatesRoutes);
     242app.use('/admin/patreon', adminPatreonRoutes);
    241243app.use('/admin', adminRoutes);
    242244app.use('/prutter', prutterRoutes);
  • src/views/pages/admin-settings.ejs

    ra9e23f6 r1b4d5dd  
    44
    55  <% if (success) { %><div class="alert alert-success"><%= success %></div><% } %>
     6  <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
    67
    78  <section class="set-card">
     
    3738    </form>
    3839  </section>
     40
     41  <%# Premium (Patreon) — alleen zichtbaar als de self-hoster de premium-laag aanzet
     42      (env KLONKT_PREMIUM_ENABLED=on). Standaard onzichtbaar; niets gegate. %>
     43  <% if (premium && premium.enabled) { %>
     44  <section class="set-card" style="margin-top:1rem">
     45    <h2>Premium (Patreon)</h2>
     46    <p class="set-help">Ontgrendel de premium-modules (Hub-modus, Statistieken, Fan-login)
     47      met je <strong>$10-lifetime</strong> Patreon-steun. De app en alle updates blijven gratis.</p>
     48    <% if (premium.premium) { %>
     49      <p class="set-help"><strong>✓ Premium actief.</strong>
     50        <% if (premium.supportCents) { %>Lifetime-steun: $<%= (premium.supportCents/100).toFixed(2) %>.<% } %></p>
     51      <a href="/admin/patreon/disconnect" class="btn">Patreon ontkoppelen</a>
     52    <% } else if (premium.connected) { %>
     53      <p class="set-help">Patreon gekoppeld, maar nog geen $10 lifetime<% if (premium.supportCents) { %>
     54        (nu $<%= (premium.supportCents/100).toFixed(2) %>)<% } %>. Steun de campagne en koppel opnieuw.</p>
     55      <a href="/admin/patreon/connect" class="btn btn-primary">Opnieuw koppelen</a>
     56    <% } else { %>
     57      <p class="set-help">Nog niet gekoppeld.</p>
     58      <a href="/admin/patreon/connect" class="btn btn-primary">Koppel Patreon</a>
     59    <% } %>
     60  </section>
     61  <% } %>
    3962
    4063  <% if (tenancy === 'hub') { %>
Note: See TracChangeset for help on using the changeset viewer.