@appwarden/middleware 3.4.2 → 3.5.0
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 +1 -1
- package/chunk-X7WZVYQS.js +6 -0
- package/{chunk-24CQJ54X.js → chunk-XFG6SUSV.js} +1 -1
- package/cloudflare/astro.d.ts +2 -16
- package/cloudflare/astro.js +4 -2
- package/cloudflare/nextjs.d.ts +1 -1
- package/cloudflare/nextjs.js +3 -1
- package/cloudflare/react-router.d.ts +1 -1
- package/cloudflare/react-router.js +4 -2
- package/cloudflare/tanstack-start.d.ts +32 -25
- package/cloudflare/tanstack-start.js +16 -9
- package/package.json +10 -3
- package/vercel.d.ts +1 -1
- package/vercel.js +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/appwarden/middleware)
|
|
5
5
|
[](https://www.npmjs.com/package/@appwarden/middleware)
|
|
6
6
|
[](https://docs.npmjs.com/generating-provenance-statements)
|
|
7
|
-

|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
|
|
10
10
|
## Core Features
|
|
@@ -3,7 +3,7 @@ var isResponseLike = (value) => {
|
|
|
3
3
|
if (!value || typeof value !== "object") return false;
|
|
4
4
|
const candidate = value;
|
|
5
5
|
const headers = candidate.headers;
|
|
6
|
-
return !!(headers && typeof headers === "object" && typeof headers.has === "function" && typeof headers.set === "function" && typeof headers.get === "function"
|
|
6
|
+
return !!(headers && typeof headers === "object" && typeof headers.has === "function" && typeof headers.set === "function" && typeof headers.get === "function");
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export {
|
package/cloudflare/astro.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Runtime } from '@astrojs/cloudflare';
|
|
2
|
-
import {
|
|
2
|
+
import { MiddlewareHandler } from 'astro';
|
|
3
3
|
import { U as UseCSPInput } from '../use-content-security-policy-DUYpyUPy.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
@@ -30,20 +30,6 @@ interface AstroAppwardenConfig {
|
|
|
30
30
|
* This allows dynamic configuration based on environment variables.
|
|
31
31
|
*/
|
|
32
32
|
type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroAppwardenConfig;
|
|
33
|
-
/**
|
|
34
|
-
* Astro middleware context type.
|
|
35
|
-
* Re-exported from Astro's official APIContext type for type compatibility.
|
|
36
|
-
*
|
|
37
|
-
* @deprecated Use `APIContext` from 'astro' directly. This alias is kept for backward compatibility.
|
|
38
|
-
*/
|
|
39
|
-
type AstroMiddlewareContext = APIContext;
|
|
40
|
-
/**
|
|
41
|
-
* Astro middleware function signature.
|
|
42
|
-
* This is an alias for Astro's official MiddlewareHandler type for type compatibility.
|
|
43
|
-
*
|
|
44
|
-
* @deprecated Use `MiddlewareHandler` from 'astro' directly. This alias is kept for backward compatibility.
|
|
45
|
-
*/
|
|
46
|
-
type AstroMiddlewareFunction = MiddlewareHandler;
|
|
47
33
|
/**
|
|
48
34
|
* Creates an Appwarden middleware function for Astro.
|
|
49
35
|
*
|
|
@@ -69,4 +55,4 @@ type AstroMiddlewareFunction = MiddlewareHandler;
|
|
|
69
55
|
*/
|
|
70
56
|
declare function createAppwardenMiddleware(configFn: AstroConfigFn): MiddlewareHandler;
|
|
71
57
|
|
|
72
|
-
export {
|
|
58
|
+
export { createAppwardenMiddleware };
|
package/cloudflare/astro.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isResponseLike
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XFG6SUSV.js";
|
|
4
4
|
import {
|
|
5
5
|
useContentSecurityPolicy
|
|
6
6
|
} from "../chunk-AXWJZE7U.js";
|
|
7
|
+
import {
|
|
8
|
+
getNowMs
|
|
9
|
+
} from "../chunk-X7WZVYQS.js";
|
|
7
10
|
import {
|
|
8
11
|
validateConfig
|
|
9
12
|
} from "../chunk-MNGMTDH3.js";
|
|
@@ -43,7 +46,6 @@ var AstroCloudflareConfigSchema = z.object({
|
|
|
43
46
|
});
|
|
44
47
|
|
|
45
48
|
// src/adapters/astro-cloudflare.ts
|
|
46
|
-
var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
47
49
|
function createAppwardenMiddleware(configFn) {
|
|
48
50
|
return async (context, next) => {
|
|
49
51
|
const startTime = getNowMs();
|
package/cloudflare/nextjs.d.ts
CHANGED
|
@@ -61,4 +61,4 @@ type NextJsMiddlewareFunction = (request: NextRequest, event?: NextFetchEvent) =
|
|
|
61
61
|
*/
|
|
62
62
|
declare function createAppwardenMiddleware(configFn: NextJsCloudflareConfigFn): NextJsMiddlewareFunction;
|
|
63
63
|
|
|
64
|
-
export {
|
|
64
|
+
export { createAppwardenMiddleware };
|
package/cloudflare/nextjs.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getNowMs
|
|
3
|
+
} from "../chunk-X7WZVYQS.js";
|
|
1
4
|
import {
|
|
2
5
|
validateConfig
|
|
3
6
|
} from "../chunk-MNGMTDH3.js";
|
|
@@ -52,7 +55,6 @@ var NextJsCloudflareConfigSchema = z.object({
|
|
|
52
55
|
});
|
|
53
56
|
|
|
54
57
|
// src/adapters/nextjs-cloudflare.ts
|
|
55
|
-
var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
56
58
|
function createAppwardenMiddleware(configFn) {
|
|
57
59
|
return async (request, _event) => {
|
|
58
60
|
const startTime = getNowMs();
|
|
@@ -76,4 +76,4 @@ type ReactRouterMiddlewareFunction = (args: ReactRouterMiddlewareArgs, next: ()
|
|
|
76
76
|
*/
|
|
77
77
|
declare function createAppwardenMiddleware(configFn: ReactRouterConfigFn): ReactRouterMiddlewareFunction;
|
|
78
78
|
|
|
79
|
-
export { type CloudflareContext,
|
|
79
|
+
export { type CloudflareContext, cloudflareContextSymbol, createAppwardenMiddleware };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isResponseLike
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XFG6SUSV.js";
|
|
4
4
|
import {
|
|
5
5
|
useContentSecurityPolicy
|
|
6
6
|
} from "../chunk-AXWJZE7U.js";
|
|
7
|
+
import {
|
|
8
|
+
getNowMs
|
|
9
|
+
} from "../chunk-X7WZVYQS.js";
|
|
7
10
|
import {
|
|
8
11
|
validateConfig
|
|
9
12
|
} from "../chunk-MNGMTDH3.js";
|
|
@@ -45,7 +48,6 @@ var ReactRouterCloudflareConfigSchema = z.object({
|
|
|
45
48
|
var cloudflareContextSymbol = /* @__PURE__ */ Symbol.for(
|
|
46
49
|
"@appwarden/middleware:cloudflare"
|
|
47
50
|
);
|
|
48
|
-
var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
49
51
|
function getCloudflareContext(context) {
|
|
50
52
|
if (context?.cloudflare) {
|
|
51
53
|
return context.cloudflare;
|
|
@@ -29,48 +29,55 @@ interface TanStackStartAppwardenConfig {
|
|
|
29
29
|
* This allows dynamic configuration based on environment variables.
|
|
30
30
|
*/
|
|
31
31
|
type TanStackStartConfigFn = (cloudflare: TanStackStartCloudflareContext) => TanStackStartAppwardenConfig;
|
|
32
|
+
/**
|
|
33
|
+
* The result returned by the `next()` function in TanStack Start request middleware.
|
|
34
|
+
*
|
|
35
|
+
* Mirrors the internal `RequestServerResult` interface from `@tanstack/start-client-core`
|
|
36
|
+
* without importing from an unstable internal package path.
|
|
37
|
+
*/
|
|
38
|
+
interface TanStackStartNextResult {
|
|
39
|
+
request: Request;
|
|
40
|
+
pathname: string;
|
|
41
|
+
context: Record<string, unknown>;
|
|
42
|
+
response: Response;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The `next()` function passed to TanStack Start request middleware.
|
|
46
|
+
*
|
|
47
|
+
* Mirrors the internal `RequestServerNextFn` signature.
|
|
48
|
+
*/
|
|
49
|
+
type TanStackStartNextFn = (options?: {
|
|
50
|
+
context?: Record<string, unknown>;
|
|
51
|
+
}) => Promise<TanStackStartNextResult>;
|
|
32
52
|
/**
|
|
33
53
|
* TanStack Start middleware server callback arguments.
|
|
34
|
-
*
|
|
54
|
+
*
|
|
55
|
+
* Mirrors the official TanStack Start `RequestServerOptions` interface, with
|
|
56
|
+
* an additional optional `cloudflare` context property for Cloudflare
|
|
57
|
+
* Workers deployments.
|
|
35
58
|
*/
|
|
36
59
|
interface TanStackStartMiddlewareArgs {
|
|
37
60
|
request: Request;
|
|
38
|
-
|
|
61
|
+
pathname: string;
|
|
39
62
|
context: {
|
|
40
63
|
cloudflare?: TanStackStartCloudflareContext;
|
|
41
64
|
[key: string]: unknown;
|
|
42
65
|
};
|
|
66
|
+
next: TanStackStartNextFn;
|
|
67
|
+
serverFnMeta?: unknown;
|
|
43
68
|
}
|
|
44
69
|
/**
|
|
45
70
|
* TanStack Start middleware function signature.
|
|
46
|
-
*
|
|
71
|
+
*
|
|
72
|
+
* Mirrors the official TanStack Start `RequestServerFn` type used for
|
|
73
|
+
* request middleware server functions.
|
|
47
74
|
*/
|
|
48
|
-
type TanStackStartMiddlewareFunction = (args: TanStackStartMiddlewareArgs) => Promise<
|
|
75
|
+
type TanStackStartMiddlewareFunction = (args: TanStackStartMiddlewareArgs) => Promise<TanStackStartNextResult | Response>;
|
|
49
76
|
/**
|
|
50
|
-
* Creates an Appwarden middleware function for TanStack Start.
|
|
51
|
-
*
|
|
52
|
-
* This middleware checks if the site is locked and throws a redirect to the lock page if so.
|
|
53
|
-
* It should be added to the `requestMiddleware` array in your `src/start.ts` file.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* // src/start.ts
|
|
58
|
-
* import { createStart } from "@tanstack/react-start"
|
|
59
|
-
* import { createAppwardenMiddleware } from "@appwarden/middleware/tanstack-start"
|
|
60
|
-
*
|
|
61
|
-
* const appwardenMiddleware = createAppwardenMiddleware(({ env }) => ({
|
|
62
|
-
* lockPageSlug: env.APPWARDEN_LOCK_PAGE_SLUG,
|
|
63
|
-
* appwardenApiToken: env.APPWARDEN_API_TOKEN,
|
|
64
|
-
* }))
|
|
65
|
-
*
|
|
66
|
-
* export const startInstance = createStart(() => ({
|
|
67
|
-
* requestMiddleware: [appwardenMiddleware],
|
|
68
|
-
* }))
|
|
69
|
-
* ```
|
|
70
77
|
*
|
|
71
78
|
* @param configFn - A function that receives the Cloudflare context and returns the config
|
|
72
79
|
* @returns A TanStack Start middleware function
|
|
73
80
|
*/
|
|
74
81
|
declare function createAppwardenMiddleware(configFn: TanStackStartConfigFn): TanStackStartMiddlewareFunction;
|
|
75
82
|
|
|
76
|
-
export { type
|
|
83
|
+
export { type TanStackStartCloudflareContext, createAppwardenMiddleware };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isResponseLike
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-XFG6SUSV.js";
|
|
4
4
|
import {
|
|
5
5
|
useContentSecurityPolicy
|
|
6
6
|
} from "../chunk-AXWJZE7U.js";
|
|
7
|
+
import {
|
|
8
|
+
getNowMs
|
|
9
|
+
} from "../chunk-X7WZVYQS.js";
|
|
7
10
|
import {
|
|
8
11
|
validateConfig
|
|
9
12
|
} from "../chunk-MNGMTDH3.js";
|
|
@@ -42,9 +45,8 @@ var TanStackStartCloudflareConfigSchema = z.object({
|
|
|
42
45
|
});
|
|
43
46
|
|
|
44
47
|
// src/adapters/tanstack-start-cloudflare.ts
|
|
45
|
-
var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
46
48
|
function createAppwardenMiddleware(configFn) {
|
|
47
|
-
|
|
49
|
+
const middleware = async (args) => {
|
|
48
50
|
const startTime = getNowMs();
|
|
49
51
|
const { request, next, context } = args;
|
|
50
52
|
try {
|
|
@@ -52,7 +54,7 @@ function createAppwardenMiddleware(configFn) {
|
|
|
52
54
|
if (!cloudflare) {
|
|
53
55
|
console.error(
|
|
54
56
|
printMessage(
|
|
55
|
-
"Cloudflare context not found. Ensure
|
|
57
|
+
"Cloudflare context not found in TanStack Start context. Ensure your Register type includes the cloudflare context, or pass it manually in the middleware wrapper."
|
|
56
58
|
)
|
|
57
59
|
);
|
|
58
60
|
return next();
|
|
@@ -79,7 +81,7 @@ function createAppwardenMiddleware(configFn) {
|
|
|
79
81
|
debugFn("Already on lock page - skipping");
|
|
80
82
|
return next();
|
|
81
83
|
}
|
|
82
|
-
const
|
|
84
|
+
const lockStatus = await checkLockStatus({
|
|
83
85
|
request,
|
|
84
86
|
appwardenApiToken: config.appwardenApiToken,
|
|
85
87
|
appwardenApiHostname: config.appwardenApiHostname,
|
|
@@ -87,13 +89,14 @@ function createAppwardenMiddleware(configFn) {
|
|
|
87
89
|
lockPageSlug: config.lockPageSlug,
|
|
88
90
|
waitUntil: (fn) => cloudflare.ctx.waitUntil(fn)
|
|
89
91
|
});
|
|
90
|
-
if (
|
|
92
|
+
if (lockStatus.isLocked) {
|
|
91
93
|
const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
|
|
92
94
|
debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
|
|
93
95
|
throw createRedirect(lockPageUrl);
|
|
94
96
|
}
|
|
95
97
|
debugFn("Website is unlocked");
|
|
96
|
-
const
|
|
98
|
+
const result = await next();
|
|
99
|
+
const { response } = result;
|
|
97
100
|
if (config.contentSecurityPolicy && isResponseLike(response)) {
|
|
98
101
|
debugFn("Applying CSP middleware");
|
|
99
102
|
const cspContext = {
|
|
@@ -111,11 +114,14 @@ function createAppwardenMiddleware(configFn) {
|
|
|
111
114
|
);
|
|
112
115
|
const elapsed2 = Math.round(getNowMs() - startTime);
|
|
113
116
|
debugFn(`Middleware executed in ${elapsed2}ms`);
|
|
114
|
-
return
|
|
117
|
+
return {
|
|
118
|
+
...result,
|
|
119
|
+
response: cspContext.response
|
|
120
|
+
};
|
|
115
121
|
}
|
|
116
122
|
const elapsed = Math.round(getNowMs() - startTime);
|
|
117
123
|
debugFn(`Middleware executed in ${elapsed}ms`);
|
|
118
|
-
return
|
|
124
|
+
return result;
|
|
119
125
|
} catch (error) {
|
|
120
126
|
if (isResponseLike(error)) {
|
|
121
127
|
throw error;
|
|
@@ -128,6 +134,7 @@ function createAppwardenMiddleware(configFn) {
|
|
|
128
134
|
return next();
|
|
129
135
|
}
|
|
130
136
|
};
|
|
137
|
+
return middleware;
|
|
131
138
|
}
|
|
132
139
|
export {
|
|
133
140
|
createAppwardenMiddleware
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appwarden/middleware",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Instantly shut off access your app deployed on Cloudflare or Vercel",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@astrojs/cloudflare": ">=11.0.0",
|
|
67
67
|
"@opennextjs/cloudflare": ">=1.16.6",
|
|
68
|
+
"@tanstack/start": "^1.120.20",
|
|
68
69
|
"@vercel/functions": ">=1.0.0",
|
|
69
70
|
"astro": ">=4.0.0",
|
|
70
71
|
"next": ">=14"
|
|
@@ -82,6 +83,9 @@
|
|
|
82
83
|
"@opennextjs/cloudflare": {
|
|
83
84
|
"optional": true
|
|
84
85
|
},
|
|
86
|
+
"@tanstack/start": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
85
89
|
"@vercel/functions": {
|
|
86
90
|
"optional": true
|
|
87
91
|
}
|
|
@@ -106,10 +110,13 @@
|
|
|
106
110
|
"wrangler@>=4.0.0 <4.59.1": ">=4.59.1",
|
|
107
111
|
"qs@>=6.7.0 <=6.14.1": ">=6.14.2",
|
|
108
112
|
"devalue@<=5.6.2": ">=5.6.3",
|
|
109
|
-
"minimatch@<10.2.1": ">=10.2.
|
|
113
|
+
"minimatch@<10.2.1": ">=10.2.3",
|
|
110
114
|
"tar@<7.5.8": ">=7.5.8",
|
|
111
115
|
"ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0",
|
|
112
|
-
"rollup@>=4.0.0 <4.59.0": ">=4.59.0"
|
|
116
|
+
"rollup@>=4.0.0 <4.59.0": ">=4.59.0",
|
|
117
|
+
"h3@<=1.15.4": ">=1.15.5",
|
|
118
|
+
"js-yaml@<3.14.2": ">=3.14.2",
|
|
119
|
+
"fast-xml-parser@<5.3.8": ">=5.3.8"
|
|
113
120
|
}
|
|
114
121
|
}
|
|
115
122
|
}
|
package/vercel.d.ts
CHANGED
|
@@ -749,4 +749,4 @@ type VercelAppwardenConfig = z.input<typeof AppwardenConfigSchema>;
|
|
|
749
749
|
type VercelMiddlewareFunction = (request: Request) => Promise<Response>;
|
|
750
750
|
declare function createAppwardenMiddleware(config: VercelAppwardenConfig): VercelMiddlewareFunction;
|
|
751
751
|
|
|
752
|
-
export {
|
|
752
|
+
export { type VercelMiddlewareFunction, createAppwardenMiddleware };
|