@becklyn/deployment-protection 0.4.2 → 0.4.3

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
@@ -240,7 +240,7 @@ When platform Deployment Protection is disabled, **this package** enforces the b
240
240
  6. Valid session or bypass cookie → allow
241
241
  7. Else → HTML login page (password and/or Sign in with Vercel)
242
242
 
243
- Session cookie: `__becklyn_dp_session` (HMAC-SHA256, 14 days by default).
243
+ Session cookie: `__becklyn_dp_session` (HMAC-SHA256, 14 days by default). On HTTPS it is `HttpOnly; Secure; SameSite=None` so a logged-in session is sent when the preview is embedded in a third-party iframe (e.g. Contentful live preview). On HTTP (localhost) it stays `SameSite=Lax` because browsers reject `SameSite=None` without `Secure`.
244
244
 
245
245
  ## Disable without code changes
246
246
 
@@ -283,6 +283,8 @@ Recommended matcher (must be pasted as a string literal in your middleware/proxy
283
283
  - Do not put the raw handoff secret in query strings — only signatures/tokens.
284
284
  - Turn off paid Vercel Password Protection / seat-heavy sharing once this is live; keep `VERCEL_AUTOMATION_BYPASS_SECRET` configured for tooling.
285
285
  - Middleware is a convenience edge check — do not treat it as the only control for highly sensitive data.
286
+ - `__becklyn_dp_session` is `SameSite=None` on HTTPS so third-party iframes can send it. That cookie only decides whether the preview may load; apps must still CSRF-protect their own state-changing endpoints. OAuth state/PKCE cookies stay `SameSite=Lax`.
287
+ - Safari (and some Chrome third-party-cookie settings) may still block unpartitioned third-party cookies even with `SameSite=None`.
286
288
 
287
289
  ## License
288
290
 
@@ -3,7 +3,7 @@ export declare function createSessionToken(secret: string, method: AuthMethod, s
3
3
  export declare function verifySessionToken(secret: string, token: string | undefined | null): Promise<SessionPayload | null>;
4
4
  export declare function sessionCookieOptions(maxAge: number, secure: boolean): {
5
5
  httpOnly: boolean;
6
- sameSite: "lax";
6
+ sameSite: "none" | "lax";
7
7
  secure: boolean;
8
8
  path: string;
9
9
  maxAge: number;
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAyB1D,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4BhC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;;;;;EAQnE"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAyB1D,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4BhC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;cAKrB,MAAM,GAAG,KAAK;;;;EAK5D"}
@@ -56,7 +56,9 @@ async function verifySessionToken(secret, token) {
56
56
  function sessionCookieOptions(maxAge, secure) {
57
57
  return {
58
58
  httpOnly: true,
59
- sameSite: "lax",
59
+ // SameSite=None; Secure is required for third-party iframes (e.g. Contentful).
60
+ // Browsers reject SameSite=None without Secure, so HTTP (localhost) stays Lax.
61
+ sameSite: (secure ? "none" : "lax"),
60
62
  secure,
61
63
  path: "/",
62
64
  maxAge,
@@ -1 +1 @@
1
- {"version":3,"file":"vercel-oauth.d.ts","sourceRoot":"","sources":["../../src/vercel-oauth.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAgBD,wBAAsB,4BAA4B,CAC9C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAsCnB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYtF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBxE;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB7E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkB3E;AAED,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACL,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GACF,IAAI,CAwBN"}
1
+ {"version":3,"file":"vercel-oauth.d.ts","sourceRoot":"","sources":["../../src/vercel-oauth.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAgBD,wBAAsB,4BAA4B,CAC9C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAsCnB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYtF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBxE;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB7E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkB3E;AAQD,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACL,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GACF,IAAI,CAsBN"}
@@ -151,6 +151,11 @@ function clearOAuthCookies(response, secure) {
151
151
  appendSetCookie(response, name, "", expired);
152
152
  }
153
153
  }
154
+ const SAME_SITE_LABEL = {
155
+ lax: "Lax",
156
+ strict: "Strict",
157
+ none: "None",
158
+ };
154
159
  function appendSetCookie(response, name, value, options) {
155
160
  const parts = [`${name}=${encodeURIComponent(value)}`];
156
161
  if (options.maxAge !== undefined) {
@@ -164,7 +169,7 @@ function appendSetCookie(response, name, value, options) {
164
169
  parts.push("Secure");
165
170
  }
166
171
  if (options.sameSite) {
167
- parts.push(`SameSite=${options.sameSite === "none" ? "None" : options.sameSite[0].toUpperCase()}${options.sameSite.slice(1)}`);
172
+ parts.push(`SameSite=${SAME_SITE_LABEL[options.sameSite]}`);
168
173
  }
169
174
  response.headers.append("Set-Cookie", parts.join("; "));
170
175
  }
package/dist/edge.mjs CHANGED
@@ -534,7 +534,9 @@ async function verifySessionToken(secret, token) {
534
534
  function sessionCookieOptions(maxAge, secure) {
535
535
  return {
536
536
  httpOnly: true,
537
- sameSite: "lax",
537
+ // SameSite=None; Secure is required for third-party iframes (e.g. Contentful).
538
+ // Browsers reject SameSite=None without Secure, so HTTP (localhost) stays Lax.
539
+ sameSite: secure ? "none" : "lax",
538
540
  secure,
539
541
  path: "/",
540
542
  maxAge
@@ -682,6 +684,11 @@ function clearOAuthCookies(response, secure) {
682
684
  appendSetCookie(response, name, "", expired);
683
685
  }
684
686
  }
687
+ var SAME_SITE_LABEL = {
688
+ lax: "Lax",
689
+ strict: "Strict",
690
+ none: "None"
691
+ };
685
692
  function appendSetCookie(response, name, value, options) {
686
693
  const parts = [`${name}=${encodeURIComponent(value)}`];
687
694
  if (options.maxAge !== void 0) {
@@ -695,9 +702,7 @@ function appendSetCookie(response, name, value, options) {
695
702
  parts.push("Secure");
696
703
  }
697
704
  if (options.sameSite) {
698
- parts.push(
699
- `SameSite=${options.sameSite === "none" ? "None" : options.sameSite[0].toUpperCase()}${options.sameSite.slice(1)}`
700
- );
705
+ parts.push(`SameSite=${SAME_SITE_LABEL[options.sameSite]}`);
701
706
  }
702
707
  response.headers.append("Set-Cookie", parts.join("; "));
703
708
  }
@@ -3,7 +3,7 @@ export declare function createSessionToken(secret: string, method: AuthMethod, s
3
3
  export declare function verifySessionToken(secret: string, token: string | undefined | null): Promise<SessionPayload | null>;
4
4
  export declare function sessionCookieOptions(maxAge: number, secure: boolean): {
5
5
  httpOnly: boolean;
6
- sameSite: "lax";
6
+ sameSite: "none" | "lax";
7
7
  secure: boolean;
8
8
  path: string;
9
9
  maxAge: number;
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAyB1D,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4BhC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;;;;;EAQnE"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAyB1D,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4BhC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;;cAKrB,MAAM,GAAG,KAAK;;;;EAK5D"}
@@ -51,7 +51,9 @@ export async function verifySessionToken(secret, token) {
51
51
  export function sessionCookieOptions(maxAge, secure) {
52
52
  return {
53
53
  httpOnly: true,
54
- sameSite: "lax",
54
+ // SameSite=None; Secure is required for third-party iframes (e.g. Contentful).
55
+ // Browsers reject SameSite=None without Secure, so HTTP (localhost) stays Lax.
56
+ sameSite: (secure ? "none" : "lax"),
55
57
  secure,
56
58
  path: "/",
57
59
  maxAge,
@@ -1 +1 @@
1
- {"version":3,"file":"vercel-oauth.d.ts","sourceRoot":"","sources":["../../src/vercel-oauth.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAgBD,wBAAsB,4BAA4B,CAC9C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAsCnB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYtF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBxE;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB7E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkB3E;AAED,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACL,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GACF,IAAI,CAwBN"}
1
+ {"version":3,"file":"vercel-oauth.d.ts","sourceRoot":"","sources":["../../src/vercel-oauth.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAgBD,wBAAsB,4BAA4B,CAC9C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAsCnB;AAED,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYtF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBxE;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB7E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkB3E;AAQD,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACL,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GACF,IAAI,CAsBN"}
@@ -141,6 +141,11 @@ export function clearOAuthCookies(response, secure) {
141
141
  appendSetCookie(response, name, "", expired);
142
142
  }
143
143
  }
144
+ const SAME_SITE_LABEL = {
145
+ lax: "Lax",
146
+ strict: "Strict",
147
+ none: "None",
148
+ };
144
149
  export function appendSetCookie(response, name, value, options) {
145
150
  const parts = [`${name}=${encodeURIComponent(value)}`];
146
151
  if (options.maxAge !== undefined) {
@@ -154,7 +159,7 @@ export function appendSetCookie(response, name, value, options) {
154
159
  parts.push("Secure");
155
160
  }
156
161
  if (options.sameSite) {
157
- parts.push(`SameSite=${options.sameSite === "none" ? "None" : options.sameSite[0].toUpperCase()}${options.sameSite.slice(1)}`);
162
+ parts.push(`SameSite=${SAME_SITE_LABEL[options.sameSite]}`);
158
163
  }
159
164
  response.headers.append("Set-Cookie", parts.join("; "));
160
165
  }
@@ -534,7 +534,9 @@ async function verifySessionToken(secret, token) {
534
534
  function sessionCookieOptions(maxAge, secure) {
535
535
  return {
536
536
  httpOnly: true,
537
- sameSite: "lax",
537
+ // SameSite=None; Secure is required for third-party iframes (e.g. Contentful).
538
+ // Browsers reject SameSite=None without Secure, so HTTP (localhost) stays Lax.
539
+ sameSite: secure ? "none" : "lax",
538
540
  secure,
539
541
  path: "/",
540
542
  maxAge
@@ -682,6 +684,11 @@ function clearOAuthCookies(response, secure) {
682
684
  appendSetCookie(response, name, "", expired);
683
685
  }
684
686
  }
687
+ var SAME_SITE_LABEL = {
688
+ lax: "Lax",
689
+ strict: "Strict",
690
+ none: "None"
691
+ };
685
692
  function appendSetCookie(response, name, value, options) {
686
693
  const parts = [`${name}=${encodeURIComponent(value)}`];
687
694
  if (options.maxAge !== void 0) {
@@ -695,9 +702,7 @@ function appendSetCookie(response, name, value, options) {
695
702
  parts.push("Secure");
696
703
  }
697
704
  if (options.sameSite) {
698
- parts.push(
699
- `SameSite=${options.sameSite === "none" ? "None" : options.sameSite[0].toUpperCase()}${options.sameSite.slice(1)}`
700
- );
705
+ parts.push(`SameSite=${SAME_SITE_LABEL[options.sameSite]}`);
701
706
  }
702
707
  response.headers.append("Set-Cookie", parts.join("; "));
703
708
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@becklyn/deployment-protection",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "license": "MIT",
5
5
  "description": "Simple shared username/password + Sign in with Vercel gate for Next.js and Storybook deployments",
6
6
  "homepage": "https://github.com/Becklyn-Studios/ts-libs/tree/main/packages/deployment-protection",