@appwarden/middleware 3.4.0 → 3.4.2

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
@@ -4,7 +4,7 @@
4
4
  [![GitHub](https://img.shields.io/badge/GitHub-appwarden%2Fmiddleware-181717?logo=github&logoColor=white)](https://github.com/appwarden/middleware)
5
5
  [![npm version](https://img.shields.io/npm/v/@appwarden/middleware.svg)](https://www.npmjs.com/package/@appwarden/middleware)
6
6
  [![npm provenance](https://img.shields.io/badge/npm-provenance-green)](https://docs.npmjs.com/generating-provenance-statements)
7
- ![Test Coverage](https://img.shields.io/badge/coverage-92.46%25-brightgreen)
7
+ ![Test Coverage](https://img.shields.io/badge/coverage-91.49%25-brightgreen)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
9
 
10
10
  ## Core Features
@@ -0,0 +1,11 @@
1
+ // src/utils/is-response-like.ts
2
+ var isResponseLike = (value) => {
3
+ if (!value || typeof value !== "object") return false;
4
+ const candidate = value;
5
+ const headers = candidate.headers;
6
+ return !!(headers && typeof headers === "object" && typeof headers.has === "function" && typeof headers.set === "function" && typeof headers.get === "function" && "body" in candidate);
7
+ };
8
+
9
+ export {
10
+ isResponseLike
11
+ };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-HCGLR3Z3.js";
5
5
  import {
6
6
  makeCSPHeader
7
- } from "./chunk-G4RRFNHY.js";
7
+ } from "./chunk-GK6JL5NZ.js";
8
8
 
9
9
  // src/middlewares/use-content-security-policy.ts
10
10
  var AppendAttribute = (attribute, nonce) => ({
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-HCGLR3Z3.js";
4
4
  import {
5
5
  printMessage
6
- } from "./chunk-G4RRFNHY.js";
6
+ } from "./chunk-GK6JL5NZ.js";
7
7
 
8
8
  // src/utils/build-lock-page-url.ts
9
9
  function normalizeLockPageSlug(lockPageSlug) {
@@ -40,7 +40,7 @@ var createRedirect = (url) => {
40
40
  // src/utils/debug.ts
41
41
  var debug = (isDebug) => (...msg) => {
42
42
  if (!isDebug) return;
43
- const formatted = msg.map((m) => {
43
+ const parts = msg.map((m) => {
44
44
  let content;
45
45
  if (m instanceof Error) {
46
46
  content = m.stack ?? m.message;
@@ -57,9 +57,10 @@ var debug = (isDebug) => (...msg) => {
57
57
  } else {
58
58
  content = String(m);
59
59
  }
60
- return printMessage(content);
60
+ return content;
61
61
  });
62
- console.log(...formatted);
62
+ const message = parts.join(" ");
63
+ console.log(printMessage(message));
63
64
  };
64
65
 
65
66
  // src/utils/memory-cache.ts
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MemoryCache,
3
3
  debug
4
- } from "./chunk-QVRWMYGL.js";
4
+ } from "./chunk-EPJ4ZVO6.js";
5
5
  import {
6
6
  APPWARDEN_CACHE_KEY,
7
7
  APPWARDEN_TEST_ROUTE
@@ -11,7 +11,7 @@ import {
11
11
  getLockValue,
12
12
  store,
13
13
  syncEdgeValue
14
- } from "./chunk-G4RRFNHY.js";
14
+ } from "./chunk-GK6JL5NZ.js";
15
15
 
16
16
  // src/core/check-lock-status.ts
17
17
  var createContext = async (config) => {
@@ -42,9 +42,6 @@ var createContext = async (config) => {
42
42
  };
43
43
  var resolveLockStatus = async (context) => {
44
44
  const { lockValue, shouldDeleteEdgeValue } = await getLockValue(context);
45
- if (lockValue) {
46
- context.debug("Lock value resolved from cache");
47
- }
48
45
  if (shouldDeleteEdgeValue) {
49
46
  context.debug("Deleting corrupted cache value");
50
47
  await deleteEdgeValue(context);
@@ -61,15 +58,21 @@ var resolveLockStatus = async (context) => {
61
58
  var checkLockStatus = async (config) => {
62
59
  const context = await createContext(config);
63
60
  let { isLocked, isTestLock, lockValue, wasDeleted } = await resolveLockStatus(context);
64
- if (MemoryCache.isExpired(lockValue) || wasDeleted) {
61
+ const isExpired = MemoryCache.isExpired(lockValue);
62
+ if (!isExpired && !wasDeleted && lockValue) {
63
+ context.debug("Lock value resolved from cache");
64
+ }
65
+ if (isExpired || wasDeleted) {
65
66
  if (!lockValue || wasDeleted || lockValue.isLocked) {
66
67
  context.debug(
67
- "Cache expired/missing/corrupted or site is locked - syncing with API synchronously"
68
+ "No fresh cached lock status available - syncing with API synchronously"
68
69
  );
69
70
  await syncEdgeValue(context);
70
71
  ({ isLocked, isTestLock } = await resolveLockStatus(context));
71
72
  } else {
72
- context.debug("Cache expired but site unlocked - syncing in background");
73
+ context.debug(
74
+ "Cached lock status expired but last known state unlocked - syncing with API in background"
75
+ );
73
76
  config.waitUntil(syncEdgeValue(context));
74
77
  }
75
78
  }
@@ -11,12 +11,7 @@ var store = {
11
11
  };
12
12
  var getCacheValue = async (context, cacheKey) => {
13
13
  const match = await context.cache.match(cacheKey);
14
- if (!match) {
15
- context.debug(`[${cacheKey.pathname}] Cache MISS!`);
16
- return void 0;
17
- }
18
- context.debug(`[${cacheKey.pathname}] Cache MATCH!`);
19
- return match;
14
+ return match ?? void 0;
20
15
  };
21
16
  var updateCacheValue = async (context, cacheKey, value, ttl) => {
22
17
  context.debug(
@@ -262,7 +257,7 @@ var APIError = class extends Error {
262
257
  var DEFAULT_API_HOSTNAME = "https://api.appwarden.io";
263
258
  var syncEdgeValue = async (context) => {
264
259
  const apiHostname = context.appwardenApiHostname ?? DEFAULT_API_HOSTNAME;
265
- context.debug(`Fetching lock value from API: ${apiHostname}`);
260
+ context.debug(`GET ${apiHostname}`);
266
261
  try {
267
262
  const response = await fetch(new URL("/v1/status/check", apiHostname), {
268
263
  method: "POST",
@@ -289,10 +284,7 @@ var syncEdgeValue = async (context) => {
289
284
  const parsedValue = LockValue.omit({ lastCheck: true }).parse(
290
285
  result.content
291
286
  );
292
- context.debug(
293
- `API call to ${apiHostname} succeeded`,
294
- `Lock status: ${parsedValue.isLocked ? "LOCKED" : "UNLOCKED"}`
295
- );
287
+ context.debug(`GET ${apiHostname} succeeded`);
296
288
  await context.edgeCache.updateValue({
297
289
  ...parsedValue,
298
290
  lastCheck: Date.now()
@@ -302,7 +294,7 @@ var syncEdgeValue = async (context) => {
302
294
  }
303
295
  }
304
296
  } catch (e) {
305
- const message = `API call to ${apiHostname} failed`;
297
+ const message = `GET ${apiHostname} failed`;
306
298
  console.error(
307
299
  printMessage(
308
300
  e instanceof APIError ? e.message : e instanceof Error ? `${message}: ${e.message}` : message
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getErrors,
3
3
  printMessage
4
- } from "./chunk-G4RRFNHY.js";
4
+ } from "./chunk-GK6JL5NZ.js";
5
5
 
6
6
  // src/utils/validate-config.ts
7
7
  function validateConfig(config, schema) {
@@ -1,19 +1,22 @@
1
+ import {
2
+ isResponseLike
3
+ } from "../chunk-24CQJ54X.js";
1
4
  import {
2
5
  useContentSecurityPolicy
3
- } from "../chunk-YBWFEBZC.js";
6
+ } from "../chunk-AXWJZE7U.js";
4
7
  import {
5
8
  validateConfig
6
- } from "../chunk-U3T4R5KZ.js";
9
+ } from "../chunk-MNGMTDH3.js";
7
10
  import {
8
11
  checkLockStatus
9
- } from "../chunk-3MKVGKH7.js";
12
+ } from "../chunk-G5FWKV2Q.js";
10
13
  import {
11
14
  TEMPORARY_REDIRECT_STATUS,
12
15
  buildLockPageUrl,
13
16
  createRedirect,
14
17
  debug,
15
18
  isOnLockPage
16
- } from "../chunk-QVRWMYGL.js";
19
+ } from "../chunk-EPJ4ZVO6.js";
17
20
  import {
18
21
  UseCSPInputSchema,
19
22
  isHTMLRequest
@@ -22,7 +25,7 @@ import {
22
25
  AppwardenApiTokenSchema,
23
26
  BooleanSchema,
24
27
  printMessage
25
- } from "../chunk-G4RRFNHY.js";
28
+ } from "../chunk-GK6JL5NZ.js";
26
29
 
27
30
  // src/schemas/astro-cloudflare.ts
28
31
  import { z } from "zod";
@@ -85,7 +88,7 @@ function createAppwardenMiddleware(configFn) {
85
88
  });
86
89
  if (result.isLocked) {
87
90
  const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
88
- debugFn(`Site is locked - redirecting to ${lockPageUrl.pathname}`);
91
+ debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
89
92
  if (context.redirect) {
90
93
  return context.redirect(
91
94
  lockPageUrl.toString(),
@@ -94,9 +97,9 @@ function createAppwardenMiddleware(configFn) {
94
97
  }
95
98
  return createRedirect(lockPageUrl);
96
99
  }
97
- debugFn("Site is unlocked to origin");
100
+ debugFn("Website is unlocked");
98
101
  const response = await next();
99
- if (config.contentSecurityPolicy) {
102
+ if (config.contentSecurityPolicy && isResponseLike(response)) {
100
103
  debugFn("Applying CSP middleware");
101
104
  const cspContext = {
102
105
  request,
@@ -119,7 +122,7 @@ function createAppwardenMiddleware(configFn) {
119
122
  debugFn(`Middleware executed in ${elapsed}ms`);
120
123
  return response;
121
124
  } catch (error) {
122
- if (error instanceof Response) {
125
+ if (isResponseLike(error)) {
123
126
  throw error;
124
127
  }
125
128
  console.error(
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  validateConfig
3
- } from "../chunk-U3T4R5KZ.js";
3
+ } from "../chunk-MNGMTDH3.js";
4
4
  import {
5
5
  checkLockStatus
6
- } from "../chunk-3MKVGKH7.js";
6
+ } from "../chunk-G5FWKV2Q.js";
7
7
  import {
8
8
  TEMPORARY_REDIRECT_STATUS,
9
9
  buildLockPageUrl,
10
10
  debug,
11
11
  isOnLockPage
12
- } from "../chunk-QVRWMYGL.js";
12
+ } from "../chunk-EPJ4ZVO6.js";
13
13
  import {
14
14
  UseCSPInputSchema,
15
15
  isHTMLRequest
@@ -18,7 +18,7 @@ import {
18
18
  AppwardenApiTokenSchema,
19
19
  BooleanSchema,
20
20
  printMessage
21
- } from "../chunk-G4RRFNHY.js";
21
+ } from "../chunk-GK6JL5NZ.js";
22
22
 
23
23
  // src/adapters/nextjs-cloudflare.ts
24
24
  import {
@@ -88,7 +88,7 @@ function createAppwardenMiddleware(configFn) {
88
88
  });
89
89
  if (result.isLocked) {
90
90
  const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
91
- debugFn(`Site is locked - redirecting to ${lockPageUrl.pathname}`);
91
+ debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
92
92
  return NextResponse.redirect(lockPageUrl, TEMPORARY_REDIRECT_STATUS);
93
93
  }
94
94
  debugFn("Site is unlocked");
@@ -96,7 +96,7 @@ function createAppwardenMiddleware(configFn) {
96
96
  debugFn(
97
97
  `Applying CSP headers in ${config.contentSecurityPolicy.mode} mode`
98
98
  );
99
- const { makeCSPHeader } = await import("../cloudflare-36BOGAYU.js");
99
+ const { makeCSPHeader } = await import("../cloudflare-K5EFFMNI.js");
100
100
  const [headerName, headerValue] = makeCSPHeader(
101
101
  "",
102
102
  config.contentSecurityPolicy.directives,
@@ -1,18 +1,21 @@
1
+ import {
2
+ isResponseLike
3
+ } from "../chunk-24CQJ54X.js";
1
4
  import {
2
5
  useContentSecurityPolicy
3
- } from "../chunk-YBWFEBZC.js";
6
+ } from "../chunk-AXWJZE7U.js";
4
7
  import {
5
8
  validateConfig
6
- } from "../chunk-U3T4R5KZ.js";
9
+ } from "../chunk-MNGMTDH3.js";
7
10
  import {
8
11
  checkLockStatus
9
- } from "../chunk-3MKVGKH7.js";
12
+ } from "../chunk-G5FWKV2Q.js";
10
13
  import {
11
14
  buildLockPageUrl,
12
15
  createRedirect,
13
16
  debug,
14
17
  isOnLockPage
15
- } from "../chunk-QVRWMYGL.js";
18
+ } from "../chunk-EPJ4ZVO6.js";
16
19
  import {
17
20
  UseCSPInputSchema,
18
21
  isHTMLRequest
@@ -21,7 +24,7 @@ import {
21
24
  AppwardenApiTokenSchema,
22
25
  BooleanSchema,
23
26
  printMessage
24
- } from "../chunk-G4RRFNHY.js";
27
+ } from "../chunk-GK6JL5NZ.js";
25
28
 
26
29
  // src/schemas/react-router-cloudflare.ts
27
30
  import { z } from "zod";
@@ -101,12 +104,12 @@ function createAppwardenMiddleware(configFn) {
101
104
  });
102
105
  if (result.isLocked) {
103
106
  const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
104
- debugFn(`Site is locked - redirecting to ${lockPageUrl.pathname}`);
107
+ debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
105
108
  throw createRedirect(lockPageUrl);
106
109
  }
107
- debugFn("Site is unlocked to origin");
110
+ debugFn("Website is unlocked");
108
111
  const response = await next();
109
- if (config.contentSecurityPolicy && response instanceof Response) {
112
+ if (config.contentSecurityPolicy && isResponseLike(response)) {
110
113
  debugFn("Applying CSP middleware");
111
114
  const cspContext = {
112
115
  request,
@@ -129,7 +132,7 @@ function createAppwardenMiddleware(configFn) {
129
132
  debugFn(`Middleware executed in ${elapsed}ms`);
130
133
  return response;
131
134
  } catch (error) {
132
- if (error instanceof Response) {
135
+ if (isResponseLike(error)) {
133
136
  throw error;
134
137
  }
135
138
  console.error(
@@ -1,18 +1,21 @@
1
+ import {
2
+ isResponseLike
3
+ } from "../chunk-24CQJ54X.js";
1
4
  import {
2
5
  useContentSecurityPolicy
3
- } from "../chunk-YBWFEBZC.js";
6
+ } from "../chunk-AXWJZE7U.js";
4
7
  import {
5
8
  validateConfig
6
- } from "../chunk-U3T4R5KZ.js";
9
+ } from "../chunk-MNGMTDH3.js";
7
10
  import {
8
11
  checkLockStatus
9
- } from "../chunk-3MKVGKH7.js";
12
+ } from "../chunk-G5FWKV2Q.js";
10
13
  import {
11
14
  buildLockPageUrl,
12
15
  createRedirect,
13
16
  debug,
14
17
  isOnLockPage
15
- } from "../chunk-QVRWMYGL.js";
18
+ } from "../chunk-EPJ4ZVO6.js";
16
19
  import {
17
20
  UseCSPInputSchema,
18
21
  isHTMLRequest
@@ -21,7 +24,7 @@ import {
21
24
  AppwardenApiTokenSchema,
22
25
  BooleanSchema,
23
26
  printMessage
24
- } from "../chunk-G4RRFNHY.js";
27
+ } from "../chunk-GK6JL5NZ.js";
25
28
 
26
29
  // src/schemas/tanstack-start-cloudflare.ts
27
30
  import { z } from "zod";
@@ -86,12 +89,12 @@ function createAppwardenMiddleware(configFn) {
86
89
  });
87
90
  if (result.isLocked) {
88
91
  const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
89
- debugFn(`Site is locked - redirecting to ${lockPageUrl.pathname}`);
92
+ debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
90
93
  throw createRedirect(lockPageUrl);
91
94
  }
92
- debugFn("Site is unlocked to origin");
95
+ debugFn("Website is unlocked");
93
96
  const response = await next();
94
- if (config.contentSecurityPolicy && response instanceof Response) {
97
+ if (config.contentSecurityPolicy && isResponseLike(response)) {
95
98
  debugFn("Applying CSP middleware");
96
99
  const cspContext = {
97
100
  request,
@@ -114,7 +117,7 @@ function createAppwardenMiddleware(configFn) {
114
117
  debugFn(`Middleware executed in ${elapsed}ms`);
115
118
  return response;
116
119
  } catch (error) {
117
- if (error instanceof Response) {
120
+ if (isResponseLike(error)) {
118
121
  throw error;
119
122
  }
120
123
  console.error(
@@ -11,7 +11,7 @@ import {
11
11
  makeCSPHeader,
12
12
  store,
13
13
  syncEdgeValue
14
- } from "./chunk-G4RRFNHY.js";
14
+ } from "./chunk-GK6JL5NZ.js";
15
15
  export {
16
16
  CSP_KEYWORDS,
17
17
  autoQuoteCSPDirectiveArray,
package/cloudflare.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  useContentSecurityPolicy
3
- } from "./chunk-YBWFEBZC.js";
3
+ } from "./chunk-AXWJZE7U.js";
4
4
  import {
5
5
  checkLockStatus
6
- } from "./chunk-3MKVGKH7.js";
6
+ } from "./chunk-G5FWKV2Q.js";
7
7
  import {
8
8
  buildLockPageUrl,
9
9
  createRedirect,
10
10
  debug,
11
11
  isOnLockPage
12
- } from "./chunk-QVRWMYGL.js";
12
+ } from "./chunk-EPJ4ZVO6.js";
13
13
  import {
14
14
  APPWARDEN_CACHE_KEY,
15
15
  UseCSPInputSchema,
@@ -22,7 +22,7 @@ import {
22
22
  insertErrorLogs,
23
23
  printMessage,
24
24
  store
25
- } from "./chunk-G4RRFNHY.js";
25
+ } from "./chunk-GK6JL5NZ.js";
26
26
 
27
27
  // src/runners/appwarden-on-cloudflare.ts
28
28
  import { ZodError } from "zod";
package/index.js CHANGED
@@ -5,14 +5,14 @@ import {
5
5
  } from "./chunk-QEFORWCW.js";
6
6
  import {
7
7
  useContentSecurityPolicy
8
- } from "./chunk-YBWFEBZC.js";
8
+ } from "./chunk-AXWJZE7U.js";
9
9
  import {
10
10
  APPWARDEN_CACHE_KEY,
11
11
  CSPDirectivesSchema,
12
12
  CSPModeSchema,
13
13
  LOCKDOWN_TEST_EXPIRY_MS
14
14
  } from "./chunk-HCGLR3Z3.js";
15
- import "./chunk-G4RRFNHY.js";
15
+ import "./chunk-GK6JL5NZ.js";
16
16
  export {
17
17
  APPWARDEN_CACHE_KEY,
18
18
  CSPDirectivesSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appwarden/middleware",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "Instantly shut off access your app deployed on Cloudflare or Vercel",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -108,7 +108,8 @@
108
108
  "devalue@<=5.6.2": ">=5.6.3",
109
109
  "minimatch@<10.2.1": ">=10.2.1",
110
110
  "tar@<7.5.8": ">=7.5.8",
111
- "ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0"
111
+ "ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0",
112
+ "rollup@>=4.0.0 <4.59.0": ">=4.59.0"
112
113
  }
113
114
  }
114
115
  }
package/vercel.js CHANGED
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-QEFORWCW.js";
5
5
  import {
6
6
  validateConfig
7
- } from "./chunk-U3T4R5KZ.js";
7
+ } from "./chunk-MNGMTDH3.js";
8
8
  import {
9
9
  MemoryCache,
10
10
  TEMPORARY_REDIRECT_STATUS,
11
11
  buildLockPageUrl,
12
12
  debug,
13
13
  isOnLockPage
14
- } from "./chunk-QVRWMYGL.js";
14
+ } from "./chunk-EPJ4ZVO6.js";
15
15
  import {
16
16
  APPWARDEN_CACHE_KEY,
17
17
  CSPDirectivesSchema,
@@ -24,7 +24,7 @@ import {
24
24
  LockValue,
25
25
  makeCSPHeader,
26
26
  printMessage
27
- } from "./chunk-G4RRFNHY.js";
27
+ } from "./chunk-GK6JL5NZ.js";
28
28
 
29
29
  // src/runners/appwarden-on-vercel.ts
30
30
  import { waitUntil } from "@vercel/functions";
@@ -296,7 +296,9 @@ function createAppwardenMiddleware(config) {
296
296
  provider
297
297
  })).lockValue;
298
298
  if (lockValue?.isLocked) {
299
- debugFn("Site is locked - redirecting to lock page");
299
+ debugFn(
300
+ `Website is locked - redirecting to ${parsedConfig.lockPageSlug}`
301
+ );
300
302
  const lockPageUrl = buildLockPageUrl(
301
303
  parsedConfig.lockPageSlug,
302
304
  request.url