@appwarden/middleware 3.8.0 → 3.9.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 +60 -57
- package/{chunk-G5FWKV2Q.js → chunk-MYIKUPTR.js} +3 -3
- package/{chunk-GK6JL5NZ.js → chunk-QGXPAVOA.js} +3 -5
- package/{chunk-HCGLR3Z3.js → chunk-UIIYORBW.js} +3 -9
- package/{chunk-52NBQDQT.js → chunk-VSCXTBP6.js} +2 -2
- package/{chunk-EPJ4ZVO6.js → chunk-Z7FIMIZS.js} +2 -2
- package/cloudflare/astro.d.ts +359 -16
- package/cloudflare/astro.js +22 -16
- package/cloudflare/nextjs.d.ts +419 -16
- package/cloudflare/nextjs.js +19 -15
- package/cloudflare/react-router.d.ts +23 -92
- package/cloudflare/react-router.js +12 -17
- package/cloudflare/tanstack-start.d.ts +45 -94
- package/cloudflare/tanstack-start.js +37 -21
- package/{cloudflare-K5EFFMNI.js → cloudflare-PE3JKP3X.js} +1 -1
- package/cloudflare.d.ts +17 -77
- package/cloudflare.js +6 -40
- package/index.d.ts +1 -5
- package/index.js +3 -3
- package/package.json +7 -4
- package/{use-content-security-policy-DUYpyUPy.d.ts → use-content-security-policy-jlU0Hjj8.d.ts} +24 -71
- package/vercel.d.ts +26 -86
- package/vercel.js +25 -15
- package/chunk-MNGMTDH3.js +0 -25
- package/use-content-security-policy-Dvc-oObb.d.ts +0 -17
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
|
-

|
|
7
|
+

|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
|
|
10
10
|
## Core Features
|
|
@@ -39,11 +39,13 @@ The path or route (for example, `/maintenance`) to redirect users to when the do
|
|
|
39
39
|
This should be a working page on your site, such as a maintenance or status page, that
|
|
40
40
|
explains why the website is temporarily unavailable.
|
|
41
41
|
|
|
42
|
-
### `contentSecurityPolicy`
|
|
42
|
+
### `contentSecurityPolicy` (optional)
|
|
43
43
|
|
|
44
|
-
Controls the [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) headers that Appwarden adds.
|
|
44
|
+
Controls the [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) headers that Appwarden adds. This configuration is optional—if not provided, no CSP header will be applied.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
When provided, both `mode` and `directives` are required:
|
|
47
|
+
|
|
48
|
+
- `mode` controls how the CSP is applied:
|
|
47
49
|
- `"disabled"` – no CSP header is sent.
|
|
48
50
|
- `"report-only"` – sends the `Content-Security-Policy-Report-Only` header so violations are
|
|
49
51
|
reported (for example in the browser console) but not blocked.
|
|
@@ -52,7 +54,7 @@ Controls the [Content Security Policy](https://developer.mozilla.org/en-US/docs/
|
|
|
52
54
|
When developing or iterating on your CSP, we recommend starting with `"report-only"` so you can
|
|
53
55
|
identify and fix violations before switching to `"enforced"`.
|
|
54
56
|
|
|
55
|
-
- `directives`
|
|
57
|
+
- `directives` is an object whose keys are CSP directive names and whose values are
|
|
56
58
|
arrays of allowed sources. For example:
|
|
57
59
|
|
|
58
60
|
```ts
|
|
@@ -60,6 +62,7 @@ Controls the [Content Security Policy](https://developer.mozilla.org/en-US/docs/
|
|
|
60
62
|
mode: "enforced",
|
|
61
63
|
directives: {
|
|
62
64
|
"script-src": ["'self'", "{{nonce}}"],
|
|
65
|
+
"style-src": ["'self'", "{{nonce}}"],
|
|
63
66
|
},
|
|
64
67
|
}
|
|
65
68
|
```
|
|
@@ -108,7 +111,7 @@ The **Universal Middleware** (`@appwarden/middleware/cloudflare`) is the recomme
|
|
|
108
111
|
import { createAppwardenMiddleware } from "@appwarden/middleware/cloudflare"
|
|
109
112
|
|
|
110
113
|
const appwardenHandler = createAppwardenMiddleware((cloudflare) => ({
|
|
111
|
-
debug: cloudflare.env.DEBUG
|
|
114
|
+
debug: cloudflare.env.DEBUG,
|
|
112
115
|
lockPageSlug: cloudflare.env.LOCK_PAGE_SLUG,
|
|
113
116
|
appwardenApiToken: cloudflare.env.APPWARDEN_API_TOKEN,
|
|
114
117
|
contentSecurityPolicy: {
|
|
@@ -142,12 +145,12 @@ import { createAppwardenMiddleware } from "@appwarden/middleware/cloudflare/astr
|
|
|
142
145
|
const appwarden = createAppwardenMiddleware((cloudflare) => ({
|
|
143
146
|
lockPageSlug: cloudflare.env.APPWARDEN_LOCK_PAGE_SLUG,
|
|
144
147
|
appwardenApiToken: cloudflare.env.APPWARDEN_API_TOKEN,
|
|
145
|
-
debug: cloudflare.env.
|
|
148
|
+
debug: cloudflare.env.DEBUG,
|
|
146
149
|
contentSecurityPolicy: {
|
|
147
|
-
|
|
150
|
+
// See Configuration > contentSecurityPolicy section for details
|
|
151
|
+
mode: "report-only",
|
|
148
152
|
directives: {
|
|
149
|
-
"
|
|
150
|
-
"style-src": ["'self'", "{{nonce}}"],
|
|
153
|
+
"default-src": ["'self'"],
|
|
151
154
|
},
|
|
152
155
|
},
|
|
153
156
|
}))
|
|
@@ -159,55 +162,59 @@ See the [Astro + Cloudflare guide](https://appwarden.io/docs/guides/astro-cloudf
|
|
|
159
162
|
|
|
160
163
|
##### React Router on Cloudflare
|
|
161
164
|
|
|
165
|
+
- Set `future.v8_middleware: true` in your `react-router.config.ts` file
|
|
166
|
+
|
|
162
167
|
```ts
|
|
163
168
|
// app/root.tsx
|
|
169
|
+
import { env } from "cloudflare:workers"
|
|
164
170
|
import { createAppwardenMiddleware } from "@appwarden/middleware/cloudflare/react-router"
|
|
165
171
|
|
|
166
|
-
export const
|
|
167
|
-
createAppwardenMiddleware((
|
|
172
|
+
export const middleware = [
|
|
173
|
+
createAppwardenMiddleware(() => ({
|
|
168
174
|
lockPageSlug: env.APPWARDEN_LOCK_PAGE_SLUG,
|
|
169
175
|
appwardenApiToken: env.APPWARDEN_API_TOKEN,
|
|
170
176
|
// "debug" can be a string or boolean; the schema will normalize it
|
|
171
|
-
debug: env.
|
|
177
|
+
debug: env.DEBUG,
|
|
172
178
|
// "directives" can be a JSON string or an object; the schema will parse it
|
|
173
179
|
contentSecurityPolicy: {
|
|
174
|
-
|
|
175
|
-
|
|
180
|
+
// See Configuration > contentSecurityPolicy section for details
|
|
181
|
+
mode: "report-only",
|
|
182
|
+
directives: {
|
|
183
|
+
"default-src": ["'self'"],
|
|
184
|
+
},
|
|
176
185
|
},
|
|
177
186
|
})),
|
|
178
187
|
]
|
|
179
188
|
```
|
|
180
189
|
|
|
181
|
-
See the [React Router + Cloudflare guide](https://appwarden.io/docs/guides/react-router-cloudflare) for
|
|
190
|
+
See the [React Router + Cloudflare guide](https://appwarden.io/docs/guides/react-router-cloudflare) for more details.
|
|
182
191
|
|
|
183
192
|
##### TanStack Start on Cloudflare
|
|
184
193
|
|
|
185
194
|
```ts
|
|
186
195
|
// start.ts
|
|
187
196
|
import { createMiddleware } from "@tanstack/start"
|
|
188
|
-
import { env
|
|
197
|
+
import { env } from "cloudflare:workers"
|
|
189
198
|
import { createAppwardenMiddleware } from "@appwarden/middleware/cloudflare/tanstack-start"
|
|
190
199
|
|
|
191
|
-
const appwardenMiddleware =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
const appwardenMiddleware = createMiddleware().server(
|
|
201
|
+
createAppwardenMiddleware(() => ({
|
|
202
|
+
lockPageSlug: env.APPWARDEN_LOCK_PAGE_SLUG,
|
|
203
|
+
appwardenApiToken: env.APPWARDEN_API_TOKEN,
|
|
204
|
+
debug: env.DEBUG, // Accepts string or boolean
|
|
205
|
+
contentSecurityPolicy: {
|
|
206
|
+
// See Configuration > contentSecurityPolicy section for details
|
|
207
|
+
mode: "report-only",
|
|
208
|
+
directives: {
|
|
209
|
+
"default-src": ["'self'"],
|
|
210
|
+
},
|
|
200
211
|
},
|
|
201
|
-
},
|
|
202
|
-
|
|
212
|
+
})),
|
|
213
|
+
)
|
|
203
214
|
|
|
204
|
-
export
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
next,
|
|
208
|
-
context: { env, waitUntil },
|
|
209
|
-
})
|
|
210
|
-
})
|
|
215
|
+
export const startInstance = createStart(() => ({
|
|
216
|
+
requestMiddleware: [appwardenMiddleware],
|
|
217
|
+
}))
|
|
211
218
|
```
|
|
212
219
|
|
|
213
220
|
See the [TanStack Start + Cloudflare guide](https://appwarden.io/docs/guides/tanstack-start-cloudflare) for more details.
|
|
@@ -225,13 +232,13 @@ export const config = {
|
|
|
225
232
|
export default createAppwardenMiddleware((cloudflare) => ({
|
|
226
233
|
lockPageSlug: cloudflare.env.APPWARDEN_LOCK_PAGE_SLUG,
|
|
227
234
|
appwardenApiToken: cloudflare.env.APPWARDEN_API_TOKEN,
|
|
228
|
-
debug: cloudflare.env.
|
|
235
|
+
debug: cloudflare.env.DEBUG,
|
|
229
236
|
// Headers-only CSP (no HTML rewriting, no nonce support; do not use `{{nonce}}` here)
|
|
230
237
|
contentSecurityPolicy: {
|
|
231
|
-
|
|
238
|
+
// See Configuration > contentSecurityPolicy section for details
|
|
239
|
+
mode: "enforced",
|
|
232
240
|
directives: {
|
|
233
|
-
"
|
|
234
|
-
"style-src": ["'self'", "'unsafe-inline'"],
|
|
241
|
+
"default-src": ["'self'"],
|
|
235
242
|
},
|
|
236
243
|
},
|
|
237
244
|
}))
|
|
@@ -246,25 +253,22 @@ To use Appwarden as Vercel Edge Middleware, use the `@appwarden/middleware/verce
|
|
|
246
253
|
```ts
|
|
247
254
|
// middleware.ts (Next.js app on Vercel)
|
|
248
255
|
import { createAppwardenMiddleware } from "@appwarden/middleware/vercel"
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"script-src": ["'self'"],
|
|
263
|
-
"style-src": ["'self'", "'unsafe-inline'"],
|
|
264
|
-
},
|
|
256
|
+
|
|
257
|
+
const appwardenMiddleware = createAppwardenMiddleware({
|
|
258
|
+
// Edge Config or Upstash KV URL
|
|
259
|
+
cacheUrl: process.env.APPWARDEN_CACHE_URL!,
|
|
260
|
+
// Required when using Vercel Edge Config
|
|
261
|
+
vercelApiToken: process.env.APPWARDEN_VERCEL_API_TOKEN!,
|
|
262
|
+
appwardenApiToken: process.env.APPWARDEN_API_TOKEN!,
|
|
263
|
+
lockPageSlug: "/maintenance",
|
|
264
|
+
contentSecurityPolicy: {
|
|
265
|
+
// See Configuration > contentSecurityPolicy section for details
|
|
266
|
+
mode: "report-only",
|
|
267
|
+
directives: {
|
|
268
|
+
"default-src": ["'self'"],
|
|
265
269
|
},
|
|
266
270
|
},
|
|
267
|
-
)
|
|
271
|
+
})
|
|
268
272
|
|
|
269
273
|
export default appwardenMiddleware
|
|
270
274
|
```
|
|
@@ -293,7 +297,6 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
293
297
|
- `fix: resolve issue with X`
|
|
294
298
|
- `docs: update README`
|
|
295
299
|
- `chore: update dependencies`
|
|
296
|
-
- `refactor: improve code structure`
|
|
297
300
|
- `test: add tests for feature X`
|
|
298
301
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
299
302
|
5. Open a Pull Request
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemoryCache,
|
|
3
3
|
debug
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Z7FIMIZS.js";
|
|
5
5
|
import {
|
|
6
6
|
APPWARDEN_CACHE_KEY,
|
|
7
7
|
APPWARDEN_TEST_ROUTE
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UIIYORBW.js";
|
|
9
9
|
import {
|
|
10
10
|
deleteEdgeValue,
|
|
11
11
|
getLockValue,
|
|
12
12
|
store,
|
|
13
13
|
syncEdgeValue
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-QGXPAVOA.js";
|
|
15
15
|
|
|
16
16
|
// src/core/check-lock-status.ts
|
|
17
17
|
var createContext = async (config) => {
|
|
@@ -116,8 +116,7 @@ var AppwardenApiTokenSchema = z.string().refine((val) => !!val, { message: "appw
|
|
|
116
116
|
var LockValue = z.object({
|
|
117
117
|
isLocked: z.number(),
|
|
118
118
|
isLockedTest: z.number(),
|
|
119
|
-
lastCheck: z.number()
|
|
120
|
-
code: z.string()
|
|
119
|
+
lastCheck: z.number()
|
|
121
120
|
});
|
|
122
121
|
|
|
123
122
|
// src/utils/errors.ts
|
|
@@ -160,8 +159,7 @@ var getLockValue = async (context) => {
|
|
|
160
159
|
let cacheResponse, lockValue = {
|
|
161
160
|
isLocked: 0,
|
|
162
161
|
isLockedTest: 0,
|
|
163
|
-
lastCheck: Date.now()
|
|
164
|
-
code: ""
|
|
162
|
+
lastCheck: Date.now()
|
|
165
163
|
};
|
|
166
164
|
switch (context.provider) {
|
|
167
165
|
case "cloudflare-cache": {
|
|
@@ -259,7 +257,7 @@ var syncEdgeValue = async (context) => {
|
|
|
259
257
|
const apiHostname = context.appwardenApiHostname ?? DEFAULT_API_HOSTNAME;
|
|
260
258
|
context.debug(`GET ${apiHostname}`);
|
|
261
259
|
try {
|
|
262
|
-
const response = await fetch(new URL("/v1/status
|
|
260
|
+
const response = await fetch(new URL("/v1/appwarden/status", apiHostname), {
|
|
263
261
|
method: "POST",
|
|
264
262
|
headers: { "content-type": "application/json" },
|
|
265
263
|
body: JSON.stringify({
|
|
@@ -57,10 +57,10 @@ var CSPModeSchema = z2.union([
|
|
|
57
57
|
z2.literal("disabled"),
|
|
58
58
|
z2.literal("report-only"),
|
|
59
59
|
z2.literal("enforced")
|
|
60
|
-
])
|
|
60
|
+
]);
|
|
61
61
|
var UseCSPInputSchema = z2.object({
|
|
62
62
|
mode: CSPModeSchema,
|
|
63
|
-
directives: CSPDirectivesSchema.
|
|
63
|
+
directives: CSPDirectivesSchema.refine(
|
|
64
64
|
(val) => {
|
|
65
65
|
try {
|
|
66
66
|
if (typeof val === "string") {
|
|
@@ -75,13 +75,7 @@ var UseCSPInputSchema = z2.object({
|
|
|
75
75
|
).transform(
|
|
76
76
|
(val) => typeof val === "string" ? JSON.parse(val) : val
|
|
77
77
|
)
|
|
78
|
-
})
|
|
79
|
-
(values) => (
|
|
80
|
-
// validate that directives are provided when the mode is "report-only" or "enforced"
|
|
81
|
-
["report-only", "enforced"].includes(values.mode) ? !!values.directives : true
|
|
82
|
-
),
|
|
83
|
-
{ path: ["directives"], message: "DirectivesRequired" /* DirectivesRequired */ }
|
|
84
|
-
);
|
|
78
|
+
});
|
|
85
79
|
|
|
86
80
|
export {
|
|
87
81
|
LOCKDOWN_TEST_EXPIRY_MS,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
UseCSPInputSchema,
|
|
3
3
|
isHTMLResponse
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UIIYORBW.js";
|
|
5
5
|
import {
|
|
6
6
|
makeCSPHeader
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QGXPAVOA.js";
|
|
8
8
|
|
|
9
9
|
// src/middlewares/use-content-security-policy.ts
|
|
10
10
|
var AppendAttribute = (attribute, nonce) => ({
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LOCKDOWN_TEST_EXPIRY_MS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UIIYORBW.js";
|
|
4
4
|
import {
|
|
5
5
|
printMessage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QGXPAVOA.js";
|
|
7
7
|
|
|
8
8
|
// src/utils/build-lock-page-url.ts
|
|
9
9
|
function normalizeLockPageSlug(lockPageSlug) {
|