Changeset 834bcc3 in Klonkt for src/services/PatreonService.js


Ignore:
Timestamp:
06/23/2026 06:14:27 PM (3 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
d774679
Parents:
bb42dfb
Message:

i18n: translate Dutch code comments to English across src/

Comments in routes/services/views/config/middleware/assets translated to
English for the public repo. A few dev-facing throw/console message strings
were Englished too. No user-facing UI strings or i18n dictionary values changed
(src/services/i18n.js untouched). Logic unchanged.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/PatreonService.js

    rbb42dfb r834bcc3  
    1 // Patreon-entitlement (premium-laag).
     1// Patreon entitlement (premium layer).
    22//
    3 // Model (Klonkt, 2026-06): de app + alle updates zijn gratis. Een paar premium-
    4 // modules (Hub-modus, Statistieken, Fan-login) zitten achter een $10-lifetime
    5 // Patreon-supporter-status. De centrale license-server (license.klonkt.com)
    6 // checkt Patreon en tekent een Ed25519-JWT "entitlement-token". DEZE instance
    7 // verifieert dat token OFFLINE met de publieke sleutel van de server — een
    8 // gekraakte/geforkte self-host kan dus geen geldig token verzinnen (alleen de
    9 // license-server kan tekenen). Dat is het echte slot; de feature-flags zelf zijn
    10 // op self-host wel te patchen (bewust geaccepteerd: $10 < moeite om te kraken).
     3// Model (Klonkt, 2026-06): the app + all updates are free. A few premium
     4// modules (Hub mode, Statistics, Fan login) are gated behind a $10 lifetime
     5// Patreon supporter status. The central license server (license.klonkt.com)
     6// checks Patreon and signs an Ed25519 JWT "entitlement token". THIS instance
     7// verifies that token OFFLINE using the server's public key — a cracked/forked
     8// self-host cannot forge a valid token (only the license server can sign).
     9// That is the real lock; feature flags themselves can be patched on self-host
     10// (deliberately accepted: $10 < effort to crack).
    1111//
    12 // Premium staat STANDAARD UIT (KLONKT_PREMIUM_ENABLED != 'on'): dan is er geen
    13 // premium-UI en wordt er niets gegate. De self-hoster zet 'm aan zodra Patreon
    14 // geregeld is.
     12// Premium is OFF by default (KLONKT_PREMIUM_ENABLED != 'on'): no premium UI
     13// is shown and nothing is gated. Self-hosters enable it once Patreon is set up.
    1514
    1615import crypto from 'node:crypto';
     
    2524export function licenseBase() { return LICENSE_URL; }
    2625
    27 // --- Publieke sleutel van de license-server cachen (voor offline verificatie) ---
     26// --- Cache the license-server public key (for offline verification) ---
    2827let _pubKey = null;
    2928async function licensePublicKey() {
    3029  if (_pubKey) return _pubKey;
    3130  const res = await fetch(`${LICENSE_URL}/pubkey`);
    32   if (!res.ok) throw new Error('pubkey fetch faalde: ' + res.status);
     31  if (!res.ok) throw new Error('pubkey fetch failed: ' + res.status);
    3332  const pem = await res.text();
    3433  _pubKey = crypto.createPublicKey(pem); // SPKI-PEM -> Ed25519 public key
     
    4039}
    4140
    42 // Verifieer een entitlement-token (EdDSA-JWT van de license-server). Gooit bij
    43 // ongeldige handtekening/issuer/verlooptijd. Geeft de claims terug.
     41// Verify an entitlement token (EdDSA JWT from the license server). Throws on
     42// invalid signature, issuer, or expiry. Returns the claims on success.
    4443export async function verifyEntitlementToken(token) {
    4544  const parts = String(token || '').split('.');
     
    4746  const [h, p, s] = parts;
    4847  const header = JSON.parse(b64urlToBuf(h).toString('utf8'));
    49   if (header.alg !== 'EdDSA') throw new Error('onverwacht alg');
     48  if (header.alg !== 'EdDSA') throw new Error('unexpected alg');
    5049  const key = await licensePublicKey();
    5150  const ok = crypto.verify(null, Buffer.from(`${h}.${p}`), key, b64urlToBuf(s));
    52   if (!ok) throw new Error('ongeldige handtekening');
     51  if (!ok) throw new Error('invalid signature');
    5352  const payload = JSON.parse(b64urlToBuf(p).toString('utf8'));
    54   if (payload.iss !== ISSUER) throw new Error('onverwachte issuer');
    55   if (payload.exp && payload.exp * 1000 < Date.now()) throw new Error('verlopen token');
     53  if (payload.iss !== ISSUER) throw new Error('unexpected issuer');
     54  if (payload.exp && payload.exp * 1000 < Date.now()) throw new Error('expired token');
    5655  return payload; // { sub, entitled, plan, lifetime_support_cents, exp, ... }
    5756}
     
    7170}
    7271
    73 // Is deze instance premium? Premium-laag aan + een geldig, niet-verlopen,
    74 // entitled opgeslagen token. Patreon-lifetime daalt nooit, dus opnieuw koppelen
    75 // na verloop slaagt altijd.
     72// Is this instance premium? Premium layer enabled + a valid, non-expired,
     73// entitled stored token. Patreon lifetime never decreases, so re-linking
     74// after expiry always succeeds.
    7675export function isPremium() {
    7776  if (!premiumEnabled()) return false;
     
    8281}
    8382
    84 // Is een premium-feature beschikbaar? True als de premium-laag UIT staat (dan is
    85 // niets gegate — huidige gedrag), of AAN én deze instance is entitled. False alleen
    86 // als premium aan staat maar er geen geldige Patreon-koppeling is (= betaalmuur).
     83// Is a premium feature available? True if the premium layer is OFF (nothing is
     84// gated — current behavior), or ON and this instance is entitled. False only
     85// if premium is on but there is no valid Patreon connection (= paywall).
    8786export function premiumUnlocked() {
    8887  return !premiumEnabled() || isPremium();
Note: See TracChangeset for help on using the changeset viewer.