@appwarden/middleware 3.1.1 → 3.2.1

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
@@ -1,6 +1,6 @@
1
1
  # @appwarden/middleware
2
2
 
3
- ![Test Coverage](https://img.shields.io/badge/coverage-95.44%25-brightgreen)
3
+ ![Test Coverage](https://img.shields.io/badge/coverage-95.58%25-brightgreen)
4
4
  [![npm version](https://img.shields.io/npm/v/@appwarden/middleware.svg)](https://www.npmjs.com/package/@appwarden/middleware)
5
5
  [![npm provenance](https://img.shields.io/badge/npm-provenance-green)](https://docs.npmjs.com/generating-provenance-statements)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
@@ -2,7 +2,7 @@ import {
2
2
  debug,
3
3
  isHTMLResponse,
4
4
  printMessage
5
- } from "./chunk-7UTT3M2S.js";
5
+ } from "./chunk-L5EQIJZB.js";
6
6
 
7
7
  // src/schemas/use-content-security-policy.ts
8
8
  import { z as z2 } from "zod";
@@ -75,6 +75,47 @@ var UseCSPInputSchema = z2.object({
75
75
  { path: ["directives"], message: "DirectivesRequired" /* DirectivesRequired */ }
76
76
  );
77
77
 
78
+ // src/utils/cloudflare/csp-keywords.ts
79
+ var CSP_KEYWORDS = [
80
+ "self",
81
+ "none",
82
+ "unsafe-inline",
83
+ "unsafe-eval",
84
+ "unsafe-hashes",
85
+ "strict-dynamic",
86
+ "report-sample",
87
+ "unsafe-allow-redirects",
88
+ "wasm-unsafe-eval",
89
+ "trusted-types-eval",
90
+ "report-sha256",
91
+ "report-sha384",
92
+ "report-sha512",
93
+ "unsafe-webtransport-hashes"
94
+ ];
95
+ var CSP_KEYWORDS_SET = new Set(CSP_KEYWORDS);
96
+ var isCSPKeyword = (value) => {
97
+ return CSP_KEYWORDS_SET.has(value.toLowerCase());
98
+ };
99
+ var isQuoted = (value) => {
100
+ return value.startsWith("'") && value.endsWith("'");
101
+ };
102
+ var autoQuoteCSPKeyword = (value) => {
103
+ const trimmed = value.trim();
104
+ if (isQuoted(trimmed)) {
105
+ return trimmed;
106
+ }
107
+ if (isCSPKeyword(trimmed)) {
108
+ return `'${trimmed}'`;
109
+ }
110
+ return trimmed;
111
+ };
112
+ var autoQuoteCSPDirectiveValue = (value) => {
113
+ return value.trim().split(/\s+/).filter(Boolean).map(autoQuoteCSPKeyword).join(" ");
114
+ };
115
+ var autoQuoteCSPDirectiveArray = (values) => {
116
+ return values.map(autoQuoteCSPKeyword);
117
+ };
118
+
78
119
  // src/utils/cloudflare/make-csp-header.ts
79
120
  var addNonce = (value, cspNonce) => value.replace("{{nonce}}", `'nonce-${cspNonce}'`);
80
121
  var makeCSPHeader = (cspNonce, directives, mode) => {
@@ -85,14 +126,19 @@ var makeCSPHeader = (cspNonce, directives, mode) => {
85
126
  throw new Error(`${originalName} is specified more than once`);
86
127
  }
87
128
  namesSeen.add(name);
129
+ let directiveValue;
88
130
  if (Array.isArray(value)) {
89
- value = addNonce(value.join(" "), cspNonce);
131
+ directiveValue = autoQuoteCSPDirectiveArray(value).join(" ");
90
132
  } else if (value === true) {
91
- value = "";
133
+ directiveValue = "";
134
+ } else if (typeof value === "string") {
135
+ directiveValue = autoQuoteCSPDirectiveValue(value);
136
+ } else {
137
+ return;
92
138
  }
93
- if (value) {
94
- result.push(`${name} ${addNonce(value, cspNonce)}`);
95
- } else if (value !== false) {
139
+ if (directiveValue) {
140
+ result.push(`${name} ${addNonce(directiveValue, cspNonce)}`);
141
+ } else {
96
142
  result.push(name);
97
143
  }
98
144
  });
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getErrors
3
- } from "./chunk-OPZQCRC4.js";
3
+ } from "./chunk-ZX5QO4Y2.js";
4
4
  import {
5
5
  printMessage
6
- } from "./chunk-7UTT3M2S.js";
6
+ } from "./chunk-L5EQIJZB.js";
7
7
 
8
8
  // src/utils/validate-config.ts
9
9
  function validateConfig(config, schema) {
@@ -8,7 +8,24 @@ var APPWARDEN_CACHE_KEY = "appwarden-lock";
8
8
  // src/utils/debug.ts
9
9
  var debug = (...msg) => {
10
10
  if (true) {
11
- console.log(...msg);
11
+ const formatted = msg.map((m) => {
12
+ if (typeof m === "object" && m !== null) {
13
+ if (m instanceof Error) {
14
+ return m.stack ?? m.message;
15
+ }
16
+ try {
17
+ return JSON.stringify(m);
18
+ } catch {
19
+ try {
20
+ return String(m);
21
+ } catch {
22
+ return "[Unserializable value]";
23
+ }
24
+ }
25
+ }
26
+ return m;
27
+ });
28
+ console.log(...formatted);
12
29
  }
13
30
  };
14
31
 
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  LockValue,
3
3
  MemoryCache
4
- } from "./chunk-OPZQCRC4.js";
4
+ } from "./chunk-ZX5QO4Y2.js";
5
5
  import {
6
6
  APPWARDEN_CACHE_KEY,
7
7
  APPWARDEN_TEST_ROUTE,
8
8
  debug,
9
9
  printMessage
10
- } from "./chunk-7UTT3M2S.js";
10
+ } from "./chunk-L5EQIJZB.js";
11
11
 
12
12
  // src/utils/cloudflare/cloudflare-cache.ts
13
13
  var store = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LOCKDOWN_TEST_EXPIRY_MS
3
- } from "./chunk-7UTT3M2S.js";
3
+ } from "./chunk-L5EQIJZB.js";
4
4
 
5
5
  // src/utils/build-lock-page-url.ts
6
6
  function normalizeLockPageSlug(lockPageSlug) {
@@ -23,6 +23,17 @@ function isOnLockPage(lockPageSlug, requestUrl) {
23
23
  return normalizedPathname === normalizedSlug;
24
24
  }
25
25
 
26
+ // src/utils/create-redirect.ts
27
+ var TEMPORARY_REDIRECT_STATUS = 302;
28
+ var createRedirect = (url) => {
29
+ return new Response(null, {
30
+ status: TEMPORARY_REDIRECT_STATUS,
31
+ headers: {
32
+ Location: url.toString()
33
+ }
34
+ });
35
+ };
36
+
26
37
  // src/utils/memory-cache.ts
27
38
  var MemoryCache = class {
28
39
  cache = /* @__PURE__ */ new Map();
@@ -125,6 +136,8 @@ var LockValue = z.object({
125
136
  export {
126
137
  buildLockPageUrl,
127
138
  isOnLockPage,
139
+ TEMPORARY_REDIRECT_STATUS,
140
+ createRedirect,
128
141
  getErrors,
129
142
  MemoryCache,
130
143
  BooleanSchema,
@@ -1,23 +1,21 @@
1
- import {
2
- TEMPORARY_REDIRECT_STATUS,
3
- createRedirect
4
- } from "../chunk-6M7BE3AW.js";
5
1
  import {
6
2
  validateConfig
7
- } from "../chunk-RDASXYYU.js";
3
+ } from "../chunk-COV6SHCD.js";
8
4
  import {
9
5
  checkLockStatus
10
- } from "../chunk-RB2LXM55.js";
6
+ } from "../chunk-MDODCAA3.js";
11
7
  import {
12
8
  AppwardenApiTokenSchema,
13
9
  BooleanSchema,
10
+ TEMPORARY_REDIRECT_STATUS,
14
11
  buildLockPageUrl,
12
+ createRedirect,
15
13
  isOnLockPage
16
- } from "../chunk-OPZQCRC4.js";
14
+ } from "../chunk-ZX5QO4Y2.js";
17
15
  import {
18
16
  isHTMLRequest,
19
17
  printMessage
20
- } from "../chunk-7UTT3M2S.js";
18
+ } from "../chunk-L5EQIJZB.js";
21
19
 
22
20
  // src/schemas/astro-cloudflare.ts
23
21
  import { z } from "zod";
@@ -1,22 +1,20 @@
1
- import {
2
- TEMPORARY_REDIRECT_STATUS
3
- } from "../chunk-6M7BE3AW.js";
4
1
  import {
5
2
  validateConfig
6
- } from "../chunk-RDASXYYU.js";
3
+ } from "../chunk-COV6SHCD.js";
7
4
  import {
8
5
  checkLockStatus
9
- } from "../chunk-RB2LXM55.js";
6
+ } from "../chunk-MDODCAA3.js";
10
7
  import {
11
8
  AppwardenApiTokenSchema,
12
9
  BooleanSchema,
10
+ TEMPORARY_REDIRECT_STATUS,
13
11
  buildLockPageUrl,
14
12
  isOnLockPage
15
- } from "../chunk-OPZQCRC4.js";
13
+ } from "../chunk-ZX5QO4Y2.js";
16
14
  import {
17
15
  isHTMLRequest,
18
16
  printMessage
19
- } from "../chunk-7UTT3M2S.js";
17
+ } from "../chunk-L5EQIJZB.js";
20
18
 
21
19
  // src/adapters/nextjs-cloudflare.ts
22
20
  import {
@@ -1,22 +1,20 @@
1
- import {
2
- createRedirect
3
- } from "../chunk-6M7BE3AW.js";
4
1
  import {
5
2
  validateConfig
6
- } from "../chunk-RDASXYYU.js";
3
+ } from "../chunk-COV6SHCD.js";
7
4
  import {
8
5
  checkLockStatus
9
- } from "../chunk-RB2LXM55.js";
6
+ } from "../chunk-MDODCAA3.js";
10
7
  import {
11
8
  AppwardenApiTokenSchema,
12
9
  BooleanSchema,
13
10
  buildLockPageUrl,
11
+ createRedirect,
14
12
  isOnLockPage
15
- } from "../chunk-OPZQCRC4.js";
13
+ } from "../chunk-ZX5QO4Y2.js";
16
14
  import {
17
15
  isHTMLRequest,
18
16
  printMessage
19
- } from "../chunk-7UTT3M2S.js";
17
+ } from "../chunk-L5EQIJZB.js";
20
18
 
21
19
  // src/schemas/react-router-cloudflare.ts
22
20
  import { z } from "zod";
@@ -1,22 +1,20 @@
1
- import {
2
- createRedirect
3
- } from "../chunk-6M7BE3AW.js";
4
1
  import {
5
2
  validateConfig
6
- } from "../chunk-RDASXYYU.js";
3
+ } from "../chunk-COV6SHCD.js";
7
4
  import {
8
5
  checkLockStatus
9
- } from "../chunk-RB2LXM55.js";
6
+ } from "../chunk-MDODCAA3.js";
10
7
  import {
11
8
  AppwardenApiTokenSchema,
12
9
  BooleanSchema,
13
10
  buildLockPageUrl,
11
+ createRedirect,
14
12
  isOnLockPage
15
- } from "../chunk-OPZQCRC4.js";
13
+ } from "../chunk-ZX5QO4Y2.js";
16
14
  import {
17
15
  isHTMLRequest,
18
16
  printMessage
19
- } from "../chunk-7UTT3M2S.js";
17
+ } from "../chunk-L5EQIJZB.js";
20
18
 
21
19
  // src/schemas/tanstack-start-cloudflare.ts
22
20
  import { z } from "zod";
package/cloudflare.js CHANGED
@@ -1,22 +1,24 @@
1
1
  import {
2
2
  useContentSecurityPolicy
3
- } from "./chunk-MOTPEQEU.js";
3
+ } from "./chunk-A5XGYLYS.js";
4
4
  import {
5
5
  checkLockStatus,
6
6
  getLockValue,
7
7
  store
8
- } from "./chunk-RB2LXM55.js";
8
+ } from "./chunk-MDODCAA3.js";
9
9
  import {
10
10
  AppwardenApiTokenSchema,
11
11
  BooleanSchema,
12
+ buildLockPageUrl,
13
+ createRedirect,
12
14
  getErrors,
13
15
  isOnLockPage
14
- } from "./chunk-OPZQCRC4.js";
16
+ } from "./chunk-ZX5QO4Y2.js";
15
17
  import {
16
18
  APPWARDEN_CACHE_KEY,
17
19
  isHTMLRequest,
18
20
  printMessage
19
- } from "./chunk-7UTT3M2S.js";
21
+ } from "./chunk-L5EQIJZB.js";
20
22
 
21
23
  // src/runners/appwarden-on-cloudflare.ts
22
24
  import { ZodError } from "zod";
@@ -80,14 +82,6 @@ var usePipeline = (...initMiddlewares) => {
80
82
  };
81
83
  };
82
84
 
83
- // src/utils/render-lock-page.ts
84
- var renderLockPage = (context) => fetch(new URL(context.lockPageSlug, context.requestUrl.origin), {
85
- headers: {
86
- // no browser caching, otherwise we need to hard refresh to disable lock screen
87
- "Cache-Control": "no-store"
88
- }
89
- });
90
-
91
85
  // src/utils/cloudflare/insert-errors-logs.ts
92
86
  var insertErrorLogs = async (context, error) => {
93
87
  const errors = getErrors(error);
@@ -161,10 +155,8 @@ var useAppwarden = (input) => async (context, next) => {
161
155
  waitUntil: (fn) => context.waitUntil(fn)
162
156
  });
163
157
  if (result.isLocked) {
164
- context.response = await renderLockPage({
165
- lockPageSlug,
166
- requestUrl
167
- });
158
+ const lockPageUrl = buildLockPageUrl(lockPageSlug, request.url);
159
+ context.response = createRedirect(lockPageUrl);
168
160
  shouldCallNext = false;
169
161
  return;
170
162
  }
package/index.js CHANGED
@@ -7,11 +7,11 @@ import {
7
7
  CSPDirectivesSchema,
8
8
  CSPModeSchema,
9
9
  useContentSecurityPolicy
10
- } from "./chunk-MOTPEQEU.js";
10
+ } from "./chunk-A5XGYLYS.js";
11
11
  import {
12
12
  APPWARDEN_CACHE_KEY,
13
13
  LOCKDOWN_TEST_EXPIRY_MS
14
- } from "./chunk-7UTT3M2S.js";
14
+ } from "./chunk-L5EQIJZB.js";
15
15
  export {
16
16
  APPWARDEN_CACHE_KEY,
17
17
  CSPDirectivesSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appwarden/middleware",
3
- "version": "3.1.1",
3
+ "version": "3.2.1",
4
4
  "description": "Instantly shut off access your app deployed on Cloudflare or Vercel",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/vercel.js CHANGED
@@ -4,12 +4,14 @@ import {
4
4
  } from "./chunk-QEFORWCW.js";
5
5
  import {
6
6
  validateConfig
7
- } from "./chunk-RDASXYYU.js";
7
+ } from "./chunk-COV6SHCD.js";
8
8
  import {
9
9
  LockValue,
10
10
  MemoryCache,
11
+ TEMPORARY_REDIRECT_STATUS,
12
+ buildLockPageUrl,
11
13
  isOnLockPage
12
- } from "./chunk-OPZQCRC4.js";
14
+ } from "./chunk-ZX5QO4Y2.js";
13
15
  import {
14
16
  APPWARDEN_CACHE_KEY,
15
17
  debug,
@@ -17,7 +19,7 @@ import {
17
19
  globalErrors,
18
20
  isHTMLRequest,
19
21
  printMessage
20
- } from "./chunk-7UTT3M2S.js";
22
+ } from "./chunk-L5EQIJZB.js";
21
23
 
22
24
  // src/runners/appwarden-on-vercel.ts
23
25
  import { waitUntil } from "@vercel/functions";
@@ -233,8 +235,14 @@ function createAppwardenMiddleware(config) {
233
235
  provider
234
236
  })).lockValue;
235
237
  if (lockValue?.isLocked) {
236
- const lockPageUrl = new URL(parsedConfig.lockPageSlug, request.url);
237
- return Response.redirect(lockPageUrl.toString(), 302);
238
+ const lockPageUrl = buildLockPageUrl(
239
+ parsedConfig.lockPageSlug,
240
+ request.url
241
+ );
242
+ return Response.redirect(
243
+ lockPageUrl.toString(),
244
+ TEMPORARY_REDIRECT_STATUS
245
+ );
238
246
  }
239
247
  return NextResponse.next();
240
248
  } catch (e) {
package/chunk-6M7BE3AW.js DELETED
@@ -1,15 +0,0 @@
1
- // src/utils/create-redirect.ts
2
- var TEMPORARY_REDIRECT_STATUS = 302;
3
- var createRedirect = (url) => {
4
- return new Response(null, {
5
- status: TEMPORARY_REDIRECT_STATUS,
6
- headers: {
7
- Location: url.toString()
8
- }
9
- });
10
- };
11
-
12
- export {
13
- TEMPORARY_REDIRECT_STATUS,
14
- createRedirect
15
- };