@pramen/cms 0.0.60 → 0.0.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -204,9 +204,13 @@ const handlers = { ...createCmsHandlers(cms) };
204
204
  const routes = [...cmsRoutes({ handlers: cms })];
205
205
  ```
206
206
 
207
- That identity must also be granted by your ACL. Preview is **DO-only**: redemption reaches
208
- the Durable Object, so `signPagePreview` refuses on the D1 store rather than mint a link
209
- that could never be redeemed.
207
+ That identity must also be granted by your ACL. Preview works on **both stores**. It used to
208
+ be DO-only redemption goes through `ctx.callPrivileged`, which only forwarded to the
209
+ Durable Object, so minting on D1 would have handed out a link that 404s forever and
210
+ `signPagePreview` refused instead. `callPrivileged` now dispatches locally in the Worker on
211
+ the D1 store, so the refusal is gone. A browser redeeming a link sends no `x-pramen-store`
212
+ header, so a deployment serving the CMS from D1 needs `PRAMEN_STORE=d1` for the redeem route
213
+ to land on the right store (an embedded topology sets it anyway).
210
214
 
211
215
  The grant is scoped to **one page** and carries its own expiry (default 1 hour, clamped to
212
216
  30 days), so a leaked link is not "see all drafts" and stops working on its own. Signing
package/dist/index.d.ts CHANGED
@@ -2837,7 +2837,7 @@ export declare function createCollectionHandlers(collections: readonly Collectio
2837
2837
  revisionId: string;
2838
2838
  }, Record<string, unknown>>;
2839
2839
  /** Mint a signed link that shows ONE row's unpublished state, to whoever holds it.
2840
- * Mirrors `signPagePreview` — same secret, same TTL clamp, same D1 refusal, and the
2840
+ * Mirrors `signPagePreview` — same secret, same TTL clamp, works on both stores, and the
2841
2841
  * same rule that the row is read through the ACL FIRST: minting a link is granting
2842
2842
  * access to the row, so a caller who cannot read it must not be able to mint one. */
2843
2843
  signCollectionPreview: import("@pramen/server").Handler<{
package/dist/index.js CHANGED
@@ -3799,10 +3799,11 @@ export function createCmsHandlers(opts = {}) {
3799
3799
  const secret = previewSecret(ctx.env);
3800
3800
  if (!secret)
3801
3801
  throw previewUnconfigured(); // fail closed — never mint a forgeable link
3802
- // The redeem route always reaches a Durable Object (callPrivileged -> PRAMEN.get); it
3803
- // has no notion of `x-pramen-store`. Minting on the D1 store therefore produces a
3804
- // link that 404s forever while the editor reports success refuse instead of
3805
- // handing out a token that cannot work.
3802
+ // This used to refuse on the D1 store: redemption goes through `ctx.callPrivileged`,
3803
+ // which only forwarded to a DO, so a link minted on D1 would have 404'd forever while
3804
+ // the editor reported success. `callPrivileged` now dispatches locally in the Worker
3805
+ // on D1, so both stores mint. The redeem route is a BROWSER request carrying no
3806
+ // `x-pramen-store`, so a D1 deployment still needs `PRAMEN_STORE=d1` to route it.
3806
3807
  const db = cdb(ctx);
3807
3808
  // Read the page through the ACL first: minting a link is granting access to it, so a
3808
3809
  // caller who cannot read the page must not be able to mint a link that can.
@@ -4919,7 +4920,7 @@ export function createCollectionHandlers(collections, opts = {}) {
4919
4920
  }),
4920
4921
  // ---- preview ------------------------------------------------------------
4921
4922
  /** Mint a signed link that shows ONE row's unpublished state, to whoever holds it.
4922
- * Mirrors `signPagePreview` — same secret, same TTL clamp, same D1 refusal, and the
4923
+ * Mirrors `signPagePreview` — same secret, same TTL clamp, works on both stores, and the
4923
4924
  * same rule that the row is read through the ACL FIRST: minting a link is granting
4924
4925
  * access to the row, so a caller who cannot read it must not be able to mint one. */
4925
4926
  signCollectionPreview: query(async (ctx, input) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pramen/cms",
3
- "version": "0.0.60",
3
+ "version": "0.0.61",
4
4
  "description": "Optional block/page builder for pramen — Drupal-Paragraphs-style typed blocks in named regions, reusable blocks, scheduled publishing, built entirely from pramen primitives.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,7 +41,7 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@pramen/server": "0.0.60"
44
+ "@pramen/server": "0.0.61"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": ">=18"
package/src/index.ts CHANGED
@@ -4330,11 +4330,11 @@ export function createCmsHandlers(opts: CmsHandlerOpts = {}) {
4330
4330
  signPagePreview: query(async (ctx, input: { pageId: string; expiresIn?: number }) => {
4331
4331
  const secret = previewSecret(ctx.env);
4332
4332
  if (!secret) throw previewUnconfigured(); // fail closed — never mint a forgeable link
4333
- // The redeem route always reaches a Durable Object (callPrivileged -> PRAMEN.get); it
4334
- // has no notion of `x-pramen-store`. Minting on the D1 store therefore produces a
4335
- // link that 404s forever while the editor reports success refuse instead of
4336
- // handing out a token that cannot work.
4337
-
4333
+ // This used to refuse on the D1 store: redemption goes through `ctx.callPrivileged`,
4334
+ // which only forwarded to a DO, so a link minted on D1 would have 404'd forever while
4335
+ // the editor reported success. `callPrivileged` now dispatches locally in the Worker
4336
+ // on D1, so both stores mint. The redeem route is a BROWSER request carrying no
4337
+ // `x-pramen-store`, so a D1 deployment still needs `PRAMEN_STORE=d1` to route it.
4338
4338
  const db = cdb(ctx);
4339
4339
  // Read the page through the ACL first: minting a link is granting access to it, so a
4340
4340
  // caller who cannot read the page must not be able to mint a link that can.
@@ -5626,7 +5626,7 @@ export function createCollectionHandlers(collections: readonly CollectionDef[],
5626
5626
  // ---- preview ------------------------------------------------------------
5627
5627
 
5628
5628
  /** Mint a signed link that shows ONE row's unpublished state, to whoever holds it.
5629
- * Mirrors `signPagePreview` — same secret, same TTL clamp, same D1 refusal, and the
5629
+ * Mirrors `signPagePreview` — same secret, same TTL clamp, works on both stores, and the
5630
5630
  * same rule that the row is read through the ACL FIRST: minting a link is granting
5631
5631
  * access to the row, so a caller who cannot read it must not be able to mint one. */
5632
5632
  signCollectionPreview: query(async (ctx, input: { collection: string; id: string; expiresIn?: number }) => {