@beignet/core
Version:
Core framework primitives for Beignet
180 lines • 6.13 kB
TypeScript
/**
* Security hooks for @beignet/core/server
*/
import type { HttpContractConfig } from "../../contracts/index.js";
import { type TrustedProxyConfig } from "../trusted-proxy.js";
import type { HttpRequestLike, HttpResponseHeaders, ServerHook } from "../types.js";
/**
* Strict-Transport-Security configuration.
*
* HSTS is disabled by default because it should only be sent by HTTPS
* deployments that intentionally commit browsers to the configured host policy.
*/
export interface StrictTransportSecurityOptions {
/**
* HSTS max-age value in seconds.
*
* Defaults to one year when `strictTransportSecurity` is configured as an
* object.
*/
maxAgeSec?: number;
/**
* Include subdomains in the HSTS policy.
*/
includeSubDomains?: boolean;
/**
* Mark the policy as eligible for browser preload lists.
*/
preload?: boolean;
}
/**
* Response security headers applied by `createSecurityHeadersHooks(...)`.
*
* Headers are only added when the response does not already define the same
* header name. Route handlers can therefore opt into route-specific CSP or
* download headers without fighting the global hook.
*/
export interface SecurityHeadersOptions {
/**
* Content Security Policy value. Disabled by default because browser apps need
* an app-owned asset, image, frame, and script policy.
*/
contentSecurityPolicy?: string | false;
/**
* Cross-Origin-Opener-Policy value.
*
* Defaults to `"same-origin"`.
*/
crossOriginOpenerPolicy?: string | false;
/**
* Cross-Origin-Resource-Policy value.
*
* Defaults to `"same-origin"`.
*/
crossOriginResourcePolicy?: string | false;
/**
* Permissions-Policy value.
*
* Defaults to disabling camera, microphone, and geolocation.
*/
permissionsPolicy?: string | false;
/**
* Referrer-Policy value.
*
* Defaults to `"strict-origin-when-cross-origin"`.
*/
referrerPolicy?: string | false;
/**
* Strict-Transport-Security value. Pass a string for full control or an object
* for Beignet to format the header. Disabled by default.
*/
strictTransportSecurity?: StrictTransportSecurityOptions | string | false;
/**
* X-Content-Type-Options value.
*
* Defaults to `"nosniff"`.
*/
xContentTypeOptions?: "nosniff" | false;
/**
* X-Frame-Options value.
*
* Defaults to `"DENY"`. Use `contentSecurityPolicy` with `frame-ancestors`
* for more precise frame control.
*/
xFrameOptions?: "DENY" | "SAMEORIGIN" | false;
}
export type CsrfFailureReason = "missing_origin" | "untrusted_origin" | "missing_token" | "invalid_token";
/**
* Double-submit cookie token configuration for `createCsrfHooks(...)`.
*/
export interface CsrfTokenOptions {
/**
* Header that must carry the CSRF token.
*
* Defaults to `"x-csrf-token"`.
*/
headerName?: string;
/**
* Cookie that stores the expected CSRF token.
*
* Defaults to `"beignet.csrf"`.
*/
cookieName?: string;
}
/**
* Options for `createCsrfHooks(...)`.
*/
export interface CsrfHooksOptions {
/**
* Unsafe HTTP methods protected by the hook.
*
* Defaults to `POST`, `PUT`, `PATCH`, and `DELETE`.
*/
protectedMethods?: readonly string[];
/**
* Additional trusted origins allowed to send protected requests.
*
* The request URL's own origin is always trusted. Use this for sibling
* frontends such as `https://app.example.com` calling `https://api.example.com`.
*/
trustedOrigins?: readonly string[] | ((args: {
origin: string;
req: HttpRequestLike;
contract: HttpContractConfig;
}) => boolean);
/**
* Whether unsafe requests without `Origin` or `Referer` are allowed.
*
* Defaults to `true` so server-to-server calls, tests, and older same-origin
* clients keep working. Set to `false` for cookie-backed browser-only APIs.
*/
allowMissingOrigin?: boolean;
/**
* Optional double-submit cookie token check.
*
* When configured, protected requests must send the same token in the
* configured header and cookie.
*/
token?: false | CsrfTokenOptions;
/**
* Hook-local trusted-proxy policy used when comparing the request's external
* origin against `Origin` or `Referer`. This overrides the server-level
* policy.
*
* Configure this only when the app is always behind a platform or reverse
* proxy that strips or normalizes forwarding headers. Without this option,
* CSRF uses the `requestInfo` resolved by `createServer(...)`.
*/
trustedProxy?: TrustedProxyConfig;
/**
* App-owned escape hatch for routes that have another verifier, such as
* provider webhooks or auth callbacks.
*/
skip?: (args: {
req: HttpRequestLike;
contract: HttpContractConfig;
params: Record<string, string>;
}) => boolean | Promise<boolean>;
}
/**
* Apply Beignet's default security response headers to a mutable header record.
*
* Existing headers are preserved case-insensitively so route-owned responses can
* provide more specific policies.
*/
export declare function applySecurityHeaders(headers: HttpResponseHeaders, options?: SecurityHeadersOptions): void;
/**
* Create a server hook that adds common browser security headers to every
* response, including native streamed responses.
*/
export declare function createSecurityHeadersHooks<Ctx>(options?: SecurityHeadersOptions): ServerHook<Ctx>;
/**
* Create CSRF protection for unsafe HTTP methods.
*
* The default protects cookie-backed browser routes from cross-origin unsafe
* requests while still allowing server-to-server calls and tests that do not
* send browser origin headers. Set `allowMissingOrigin: false` and configure
* `token` for stricter browser-only APIs.
*/
export declare function createCsrfHooks<Ctx>(options?: CsrfHooksOptions): ServerHook<Ctx>;
//# sourceMappingURL=security.d.ts.map