@appwarden/middleware
Version:
Instantly disable all user interaction with your app deployed on Cloudflare or Vercel
415 lines (410 loc) • 26.6 kB
TypeScript
import { APIContext } from 'astro';
import { z } from 'zod';
/**
* Zod schema for Astro Cloudflare adapter configuration.
* Validates the config object returned by the configFn.
*/
declare const AstroCloudflareConfigSchema: z.ZodObject<{
/** The slug/path of the lock page to redirect to when the site is locked */
lockPageSlug: z.ZodEffects<z.ZodString, string, string>;
/** The Appwarden API token for authentication */
appwardenApiToken: z.ZodEffects<z.ZodEffects<z.ZodString, string, unknown>, string, unknown>;
/** Optional custom API hostname (defaults to https://api.appwarden.io) */
appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>>;
/** Enable debug logging */
debug: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>, boolean | "true" | "false", string | boolean | undefined>, boolean, string | boolean | undefined>>;
/** Optional Content Security Policy configuration */
contentSecurityPolicy: z.ZodOptional<z.ZodLazy<z.ZodObject<{
mode: z.ZodUnion<[z.ZodLiteral<"disabled">, z.ZodLiteral<"report-only">, z.ZodLiteral<"enforced">]>;
directives: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodObject<{
"default-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"script-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"style-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"img-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"connect-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"font-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"object-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"media-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"frame-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
sandbox: z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"report-uri": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"child-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"form-action": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"frame-ancestors": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"plugin-types": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"base-uri": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"report-to": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"worker-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"manifest-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"prefetch-src": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"navigate-to": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"require-sri-for": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"block-all-mixed-content": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"upgrade-insecure-requests": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"trusted-types": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
"require-trusted-types-for": z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodString, z.ZodBoolean]>>;
}, "strip", z.ZodTypeAny, {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
}, {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
}>]>, string | {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
}, string | {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
}>, {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
} | undefined, string | {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
}>;
}, "strip", z.ZodTypeAny, {
mode: "disabled" | "report-only" | "enforced";
directives?: {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
} | undefined;
}, {
mode: "disabled" | "report-only" | "enforced";
directives: string | {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
};
}>>>;
}, "strip", z.ZodTypeAny, {
debug: boolean;
lockPageSlug: string;
appwardenApiToken: string;
contentSecurityPolicy?: {
mode: "disabled" | "report-only" | "enforced";
directives?: {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
} | undefined;
} | undefined;
appwardenApiHostname?: string | undefined;
}, {
lockPageSlug: string;
debug?: string | boolean | undefined;
contentSecurityPolicy?: {
mode: "disabled" | "report-only" | "enforced";
directives: string | {
"default-src"?: string | boolean | string[] | undefined;
"script-src"?: string | boolean | string[] | undefined;
"style-src"?: string | boolean | string[] | undefined;
"img-src"?: string | boolean | string[] | undefined;
"connect-src"?: string | boolean | string[] | undefined;
"font-src"?: string | boolean | string[] | undefined;
"object-src"?: string | boolean | string[] | undefined;
"media-src"?: string | boolean | string[] | undefined;
"frame-src"?: string | boolean | string[] | undefined;
sandbox?: string | boolean | string[] | undefined;
"report-uri"?: string | boolean | string[] | undefined;
"child-src"?: string | boolean | string[] | undefined;
"form-action"?: string | boolean | string[] | undefined;
"frame-ancestors"?: string | boolean | string[] | undefined;
"plugin-types"?: string | boolean | string[] | undefined;
"base-uri"?: string | boolean | string[] | undefined;
"report-to"?: string | boolean | string[] | undefined;
"worker-src"?: string | boolean | string[] | undefined;
"manifest-src"?: string | boolean | string[] | undefined;
"prefetch-src"?: string | boolean | string[] | undefined;
"navigate-to"?: string | boolean | string[] | undefined;
"require-sri-for"?: string | boolean | string[] | undefined;
"block-all-mixed-content"?: string | boolean | string[] | undefined;
"upgrade-insecure-requests"?: string | boolean | string[] | undefined;
"trusted-types"?: string | boolean | string[] | undefined;
"require-trusted-types-for"?: string | boolean | string[] | undefined;
};
} | undefined;
appwardenApiToken?: unknown;
appwardenApiHostname?: string | undefined;
}>;
type AstroCloudflareConfig = z.infer<typeof AstroCloudflareConfigSchema>;
/**
* Input type for Astro Cloudflare adapter configuration.
* This is the pre-transformation type that accepts string | boolean for debug
* and string | object for CSP directives, allowing users to pass environment
* variables directly without manual transformation.
*/
type AstroCloudflareConfigInput = z.input<typeof AstroCloudflareConfigSchema>;
/**
* Build-time helper that merges generated config with call-site overrides.
*
* Call-site config has highest priority, followed by framework headers,
* then remote Appwarden configuration.
*/
declare function getAppwardenConfiguration(generatedConfig: Record<string, unknown>, config: Partial<AstroCloudflareConfigInput>): AstroCloudflareConfig;
/**
* Normalized Cloudflare runtime context exposed to Appwarden config functions.
*
* Astro v6 no longer exposes the old `locals.runtime` shape, so we compose the
* runtime from current Cloudflare primitives instead:
* - bindings from `cloudflare:workers`
* - cache storage from the global `caches`
* - execution context from `context.locals.cfContext`
*/
interface AstroCloudflareRuntime {
env: CloudflareEnv;
caches: CacheStorage;
ctx: ExecutionContext;
}
/**
* Configuration for the Appwarden middleware.
*
* This is an alias of the validated output type from
* AstroCloudflareConfigSchema, so it always stays in sync with the
* actual runtime config contract.
*/
type AstroAppwardenConfig = AstroCloudflareConfig;
/**
* Configuration function that receives the Cloudflare runtime and returns the config.
* This allows dynamic configuration based on environment variables.
* Accepts pre-transformation input types (e.g., string | boolean for debug, string | object for CSP directives).
*/
type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroCloudflareConfigInput | AstroCloudflareConfig;
/**
* Creates an Appwarden middleware function for Astro.
*
* This middleware checks if the site is locked and redirects to the lock page if so.
* It should be used with Astro's `sequence()` function or exported directly as `onRequest`.
*
* @example
* ```typescript
* // src/middleware.ts
* import { sequence } from "astro:middleware"
* import { createAppwardenMiddleware } from "@appwarden/middleware/cloudflare/astro"
*
* const appwarden = createAppwardenMiddleware(({ env }) => ({
* lockPageSlug: env.APPWARDEN_LOCK_PAGE_SLUG,
* appwardenApiToken: env.APPWARDEN_API_TOKEN,
* }))
*
* export const onRequest = sequence(appwarden)
* ```
*
* @param configFn - A function that receives the Cloudflare runtime and returns the config
* @returns An Astro middleware function
*/
declare function createAppwardenMiddleware(configFn: AstroConfigFn): (context: APIContext, next: () => Promise<Response>) => Promise<Response>;
export { type AstroAppwardenConfig, type AstroCloudflareConfig, type AstroCloudflareConfigInput, type AstroCloudflareRuntime, type AstroConfigFn, createAppwardenMiddleware, getAppwardenConfiguration };