@appwarden/middleware 1.5.1 → 2.0.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/vercel.js CHANGED
@@ -1,91 +1,30 @@
1
1
  import {
2
- getEdgeConfigId,
3
2
  isCacheUrl,
4
3
  isValidCacheUrl
5
4
  } from "./chunk-QEFORWCW.js";
5
+ import {
6
+ validateConfig
7
+ } from "./chunk-6PUA5YXP.js";
6
8
  import {
7
9
  LockValue,
8
- MemoryCache,
9
- getErrors
10
- } from "./chunk-L6RSRHOF.js";
10
+ MemoryCache
11
+ } from "./chunk-B5IE7V77.js";
11
12
  import {
12
13
  APPWARDEN_CACHE_KEY,
13
- APPWARDEN_TEST_ROUTE,
14
- APPWARDEN_USER_AGENT,
15
14
  debug,
16
15
  errors,
17
16
  globalErrors,
17
+ isHTMLRequest,
18
18
  printMessage
19
- } from "./chunk-FDIKUQ3E.js";
19
+ } from "./chunk-7UTT3M2S.js";
20
20
 
21
21
  // src/runners/appwarden-on-vercel.ts
22
+ import { waitUntil } from "@vercel/functions";
22
23
  import { NextResponse } from "next/server";
23
24
 
24
25
  // src/schemas/vercel.ts
25
26
  import { z } from "zod";
26
27
 
27
- // src/utils/vercel/delete-edge-value.ts
28
- var deleteEdgeValue = async ({
29
- keyName,
30
- provider,
31
- cacheUrl,
32
- vercelApiToken
33
- }) => {
34
- try {
35
- switch (provider) {
36
- case "edge-config": {
37
- const edgeConfigId = getEdgeConfigId(cacheUrl);
38
- if (!edgeConfigId) {
39
- throw new Error("Failed to parse `edgeConfigId`");
40
- }
41
- const res = await fetch(
42
- `https://api.vercel.com/v1/edge-config/${edgeConfigId}/items`,
43
- {
44
- method: "PATCH",
45
- headers: {
46
- Authorization: `Bearer ${vercelApiToken}`,
47
- "Content-Type": "application/json"
48
- },
49
- body: JSON.stringify({
50
- items: [
51
- {
52
- key: keyName,
53
- operation: "delete"
54
- }
55
- ]
56
- })
57
- }
58
- );
59
- if (res.status !== 200) {
60
- let response = void 0;
61
- try {
62
- response = await res.json();
63
- } catch (error) {
64
- }
65
- throw new Error(
66
- `api.vercel.com/v1/edge-config responded with ${res.status} - ${res.statusText}${response?.error?.message ? ` - ${response?.error?.message}` : ""}`
67
- );
68
- }
69
- break;
70
- }
71
- case "upstash": {
72
- const { hostname, password } = new URL(cacheUrl);
73
- const { Redis } = await import("@upstash/redis");
74
- const redis = new Redis({ url: `https://${hostname}`, token: password });
75
- await redis.del(keyName);
76
- break;
77
- }
78
- default:
79
- throw new Error(`Unsupported provider: ${provider}`);
80
- }
81
- } catch (e) {
82
- const message = "Failed to delete edge value";
83
- console.error(
84
- printMessage(e instanceof Error ? `${message} - ${e.message}` : message)
85
- );
86
- }
87
- };
88
-
89
28
  // src/utils/vercel/get-lock-value.ts
90
29
  var getLockValue = async (context) => {
91
30
  try {
@@ -191,26 +130,6 @@ var syncEdgeValue = async (context) => {
191
130
  }
192
131
  };
193
132
 
194
- // src/utils/handle-vercel-request.ts
195
- var handleVercelRequest = async (context, options) => {
196
- let cachedLockValue = context.memoryCache.get(context.keyName);
197
- const shouldRecheck = MemoryCache.isExpired(cachedLockValue);
198
- if (shouldRecheck) {
199
- const { lockValue, shouldDeleteEdgeValue } = await getLockValue(context);
200
- if (lockValue) {
201
- context.memoryCache.put(context.keyName, lockValue);
202
- }
203
- if (shouldDeleteEdgeValue) {
204
- await deleteEdgeValue(context);
205
- }
206
- cachedLockValue = lockValue;
207
- }
208
- if (cachedLockValue?.isLocked || context.requestUrl.pathname === APPWARDEN_TEST_ROUTE && !MemoryCache.isTestExpired(cachedLockValue)) {
209
- options.onLocked();
210
- }
211
- return cachedLockValue;
212
- };
213
-
214
133
  // src/schemas/vercel.ts
215
134
  var BaseNextJsConfigSchema = z.object({
216
135
  cacheUrl: z.string(),
@@ -267,75 +186,67 @@ var AppwardenConfigSchema = BaseNextJsConfigSchema.refine(
267
186
 
268
187
  // src/runners/appwarden-on-vercel.ts
269
188
  debug("Instantiating isolate");
270
- var renderLockPage = (context) => {
271
- context.req.nextUrl.pathname = context.lockPageSlug;
272
- return NextResponse.rewrite(context.req.nextUrl, {
273
- headers: {
274
- // no browser caching, otherwise we need to hard refresh to disable lock screen
275
- "Cache-Control": "no-store"
276
- }
277
- });
278
- };
279
189
  var memoryCache = new MemoryCache({ maxSize: 1 });
280
- var appwardenOnVercel = (input) => async (req, event) => {
281
- event.passThroughOnException();
282
- const parsedConfig = AppwardenConfigSchema.safeParse(input);
283
- if (!parsedConfig.success) {
284
- for (const error of getErrors(parsedConfig.error)) {
285
- console.error(printMessage(error));
286
- }
287
- return NextResponse.next();
288
- }
190
+ function safeWaitUntil(promise) {
289
191
  try {
290
- const requestUrl = new URL(req.url);
291
- const isHTMLRequest = req.headers.get("accept")?.includes("text/html");
292
- const isMonitoringRequest = req.headers.get("User-Agent") === APPWARDEN_USER_AGENT;
293
- debug({
294
- isHTMLRequest,
295
- url: requestUrl.pathname
296
- });
297
- if (isHTMLRequest && !isMonitoringRequest) {
298
- let appwardenResponse = void 0;
299
- const context = {
300
- req,
301
- event,
302
- requestUrl,
303
- memoryCache,
304
- waitUntil: (fn) => event.waitUntil(fn),
305
- keyName: APPWARDEN_CACHE_KEY,
306
- provider: isCacheUrl.edgeConfig(parsedConfig.data.cacheUrl) ? "edge-config" : "upstash",
307
- ...parsedConfig.data
308
- };
309
- const cacheValue = await handleVercelRequest(context, {
310
- onLocked: () => {
311
- appwardenResponse = renderLockPage(context);
312
- }
313
- });
192
+ waitUntil(promise);
193
+ } catch {
194
+ promise.catch(console.error);
195
+ }
196
+ }
197
+ function createAppwardenMiddleware(config) {
198
+ return async (request) => {
199
+ if (validateConfig(config, AppwardenConfigSchema)) {
200
+ return NextResponse.next();
201
+ }
202
+ const parsedConfig = AppwardenConfigSchema.parse(config);
203
+ try {
204
+ const requestUrl = new URL(request.url);
205
+ const isHTML = isHTMLRequest(request);
206
+ debug({ isHTMLRequest: isHTML, url: requestUrl.pathname });
207
+ if (!isHTML) {
208
+ return NextResponse.next();
209
+ }
210
+ if (!parsedConfig.lockPageSlug) {
211
+ return NextResponse.next();
212
+ }
213
+ const provider = isCacheUrl.edgeConfig(parsedConfig.cacheUrl) ? "edge-config" : "upstash";
214
+ const cacheValue = memoryCache.get(APPWARDEN_CACHE_KEY);
314
215
  const shouldRecheck = MemoryCache.isExpired(cacheValue);
315
216
  if (!cacheValue || shouldRecheck) {
316
- event.waitUntil(syncEdgeValue(context));
217
+ safeWaitUntil(
218
+ syncEdgeValue({
219
+ requestUrl,
220
+ cacheUrl: parsedConfig.cacheUrl,
221
+ appwardenApiToken: parsedConfig.appwardenApiToken,
222
+ vercelApiToken: parsedConfig.vercelApiToken
223
+ })
224
+ );
317
225
  }
318
- if (appwardenResponse) {
319
- return appwardenResponse;
226
+ const lockValue = cacheValue ?? (await getLockValue({
227
+ cacheUrl: parsedConfig.cacheUrl,
228
+ keyName: APPWARDEN_CACHE_KEY,
229
+ provider
230
+ })).lockValue;
231
+ if (lockValue?.isLocked) {
232
+ const lockPageUrl = new URL(parsedConfig.lockPageSlug, request.url);
233
+ return Response.redirect(lockPageUrl.toString(), 302);
320
234
  }
321
- }
322
- } catch (e) {
323
- const message = "Appwarden encountered an unknown error. Please contact Appwarden support at https://appwarden.io/join-community.";
324
- if (e instanceof Error) {
325
- if (!globalErrors.includes(e.message)) {
326
- console.error(printMessage(`${message} - ${e.message}`));
235
+ return NextResponse.next();
236
+ } catch (e) {
237
+ const message = "Appwarden encountered an unknown error. Please contact Appwarden support at https://appwarden.io/join-community.";
238
+ if (e instanceof Error) {
239
+ if (!globalErrors.includes(e.message)) {
240
+ console.error(printMessage(`${message} - ${e.message}`));
241
+ }
242
+ } else {
243
+ console.error(printMessage(message));
327
244
  }
328
- } else {
329
- console.error(printMessage(message));
245
+ return NextResponse.next();
330
246
  }
331
- throw e;
332
- }
333
- return NextResponse.next();
334
- };
335
-
336
- // src/bundles/vercel.ts
337
- var withAppwarden = appwardenOnVercel;
247
+ };
248
+ }
338
249
  export {
339
- BaseNextJsConfigSchema,
340
- withAppwarden
250
+ AppwardenConfigSchema,
251
+ createAppwardenMiddleware
341
252
  };
@@ -1,100 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- declare const ContentSecurityPolicySchema: z.ZodObject<{
4
- "default-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
5
- "script-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
6
- "style-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
7
- "img-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
8
- "connect-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
9
- "font-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
10
- "object-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
11
- "media-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
12
- "frame-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
13
- sandbox: z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
14
- "report-uri": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
15
- "child-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
16
- "form-action": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
17
- "frame-ancestors": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
18
- "plugin-types": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
19
- "base-uri": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
20
- "report-to": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
21
- "worker-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
22
- "manifest-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
23
- "prefetch-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
24
- "navigate-to": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
25
- "require-sri-for": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
26
- "block-all-mixed-content": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
27
- "upgrade-insecure-requests": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
28
- "trusted-types": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
29
- "require-trusted-types-for": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
30
- }, "strip", z.ZodTypeAny, {
31
- "default-src"?: string | boolean | string[] | undefined;
32
- "script-src"?: string | boolean | string[] | undefined;
33
- "style-src"?: string | boolean | string[] | undefined;
34
- "img-src"?: string | boolean | string[] | undefined;
35
- "connect-src"?: string | boolean | string[] | undefined;
36
- "font-src"?: string | boolean | string[] | undefined;
37
- "object-src"?: string | boolean | string[] | undefined;
38
- "media-src"?: string | boolean | string[] | undefined;
39
- "frame-src"?: string | boolean | string[] | undefined;
40
- sandbox?: string | boolean | string[] | undefined;
41
- "report-uri"?: string | boolean | string[] | undefined;
42
- "child-src"?: string | boolean | string[] | undefined;
43
- "form-action"?: string | boolean | string[] | undefined;
44
- "frame-ancestors"?: string | boolean | string[] | undefined;
45
- "plugin-types"?: string | boolean | string[] | undefined;
46
- "base-uri"?: string | boolean | string[] | undefined;
47
- "report-to"?: string | boolean | string[] | undefined;
48
- "worker-src"?: string | boolean | string[] | undefined;
49
- "manifest-src"?: string | boolean | string[] | undefined;
50
- "prefetch-src"?: string | boolean | string[] | undefined;
51
- "navigate-to"?: string | boolean | string[] | undefined;
52
- "require-sri-for"?: string | boolean | string[] | undefined;
53
- "block-all-mixed-content"?: string | boolean | string[] | undefined;
54
- "upgrade-insecure-requests"?: string | boolean | string[] | undefined;
55
- "trusted-types"?: string | boolean | string[] | undefined;
56
- "require-trusted-types-for"?: string | boolean | string[] | undefined;
57
- }, {
58
- "default-src"?: string | boolean | string[] | undefined;
59
- "script-src"?: string | boolean | string[] | undefined;
60
- "style-src"?: string | boolean | string[] | undefined;
61
- "img-src"?: string | boolean | string[] | undefined;
62
- "connect-src"?: string | boolean | string[] | undefined;
63
- "font-src"?: string | boolean | string[] | undefined;
64
- "object-src"?: string | boolean | string[] | undefined;
65
- "media-src"?: string | boolean | string[] | undefined;
66
- "frame-src"?: string | boolean | string[] | undefined;
67
- sandbox?: string | boolean | string[] | undefined;
68
- "report-uri"?: string | boolean | string[] | undefined;
69
- "child-src"?: string | boolean | string[] | undefined;
70
- "form-action"?: string | boolean | string[] | undefined;
71
- "frame-ancestors"?: string | boolean | string[] | undefined;
72
- "plugin-types"?: string | boolean | string[] | undefined;
73
- "base-uri"?: string | boolean | string[] | undefined;
74
- "report-to"?: string | boolean | string[] | undefined;
75
- "worker-src"?: string | boolean | string[] | undefined;
76
- "manifest-src"?: string | boolean | string[] | undefined;
77
- "prefetch-src"?: string | boolean | string[] | undefined;
78
- "navigate-to"?: string | boolean | string[] | undefined;
79
- "require-sri-for"?: string | boolean | string[] | undefined;
80
- "block-all-mixed-content"?: string | boolean | string[] | undefined;
81
- "upgrade-insecure-requests"?: string | boolean | string[] | undefined;
82
- "trusted-types"?: string | boolean | string[] | undefined;
83
- "require-trusted-types-for"?: string | boolean | string[] | undefined;
84
- }>;
85
- type ContentSecurityPolicyType = z.infer<typeof ContentSecurityPolicySchema>;
86
-
87
- declare global {
88
- interface CloudflareEnv extends Bindings {
89
- }
90
- }
91
- type Bindings = {
92
- DEBUG: string | boolean;
93
- LOCK_PAGE_SLUG: string;
94
- CSP_MODE: "disabled" | "report-only" | "enforced";
95
- CSP_DIRECTIVES: string | ContentSecurityPolicyType;
96
- APPWARDEN_API_TOKEN: string;
97
- APPWARDEN_API_HOSTNAME?: string;
98
- };
99
-
100
- export type { Bindings as B };