Changeset 072a242 in Klonkt for src/routes
- Timestamp:
- 07/21/2026 03:26:24 AM (7 weeks ago)
- Branches:
- main
- Children:
- b9beb16
- Parents:
- dede82e
- git-author:
- Robin <roboburr@…> (07/21/2026 03:26:22 AM)
- git-committer:
- Robin <roboburr@…> (07/21/2026 03:26:24 AM)
- Location:
- src/routes
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/routes/paid.js
rdede82e r072a242 15 15 import PaidPatreon from '../services/PaidPatreonService.js'; 16 16 import Passkey from '../services/PasskeyService.js'; 17 import { renderPostBodyHtml } from './posts.js';18 17 19 18 const router = express.Router(); … … 128 127 const post = db.prepare("SELECT * FROM posts WHERE site_id = ? AND slug = ? AND status = 'published'").get(r.site.id, String(payload.post || '')); 129 128 if (!post || !post.paid) return res.status(404).json({ error: 'gone' }); 130 res.json({ ok: true, title: post.title || '', html: renderPostBodyHtml(r.site, post, req) }); 129 // Hand back a short-lived, single-post unlock capability. The client reloads 130 // the real post page with it (?u=), so the post renders through its normal 131 // template: correct layout, scoped styles, working audio. Not a cookie and 132 // not stored: a 120s signed blob that lives only in that one URL. 133 const token = signBlob({ purpose: 'unlocked', siteId: r.site.id, post: post.slug }, 120); 134 res.json({ ok: true, redirect: `${res.locals.siteUrlBase || ''}/${encodeURIComponent(post.slug)}?u=${encodeURIComponent(token)}` }); 131 135 }); 132 136 -
src/routes/posts.js
rdede82e r072a242 22 22 import { premiumUnlocked } from '../services/PatreonService.js'; 23 23 import { defaultMinCents as paidDefaultMinCents, patreonUrl as paidPatronUrl } from '../services/PaidPatreonService.js'; 24 import { verifyBlob } from '../services/CryptoBox.js'; 24 25 import MusicMeta from '../services/MusicMeta.js'; 25 26 … … 1238 1239 // never see the unlock button). 1239 1240 const canEditThis = req.session?.user && PermissionsService.canEditPost(req.session.user, post, site); 1240 if (post.paid && !canEditThis) { 1241 // A fresh unlock capability (?u=) from /paid/unlock lets a just-verified 1242 // supporter render the FULL post through this normal template (correct layout, 1243 // scoped styles, working audio). Short-lived signed blob, single post, not a 1244 // cookie and not stored. 1245 const _u = req.query.u ? verifyBlob(String(req.query.u)) : null; 1246 const _unlocked = _u && _u.purpose === 'unlocked' && _u.siteId === site.id && String(_u.post) === String(post.slug); 1247 if (post.paid && !canEditThis && !_unlocked) { 1241 1248 const { newerPost, olderPost } = postNeighbors(site, post, res.locals.tenancy === 'hub'); 1242 1249 return renderPage(req, res, 'pages/paid-gate', {
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)