rhythmjs

Search documentation

Search guides, the tutorial and every package.

On this page

@rhythmjs/security/authentication#

TypeScript
function attachUser<TUser>(resolve: (ctx) => TUser | null | undefined | Promise<...>): DeriveMiddleware<RhythmHttpContext, UserContext<TUser>>
function requireAuthentication<TUser>(options?: RequireAuthenticationOptions): DeriveMiddleware<..., { user: TUser }>
function redirectIfAuthenticated(to: string): Middleware<RhythmHttpContext & UserContext>
function isAuthenticated<TUser>(ctx: UserContext<TUser>): ctx is ... & { user: TUser }
function getBearerToken(request: Request): string | null
function getBasicCredentials(request: Request): BasicCredentials | null
attachUser(resolve)#
Runs the resolver per request and sets ctx.user to its result or null. Throws a TypeError at setup when the resolver is not a function.
requireAuthenticationOptions#
redirectTo (redirect instead of failing), status (default 401), message, and challenge (sets WWW-Authenticate).
getBasicCredentials(request)#
Decodes a Basic authorization header into { username, password } (BasicCredentials), or null when absent or malformed.

@rhythmjs/security/authorization#

TypeScript
function authorize<TContext>(check: (ctx: TContext) => boolean | Promise<boolean>, options?: AuthorizeOptions): Middleware<TContext>
function requireRoles<TUser>(required: readonly string[], options?: RequireRolesOptions<TUser>): Middleware<...>
function requirePermissions<TUser>(required: readonly string[], options?: RequirePermissionsOptions<TUser>): Middleware<...>
authorize(check, options?)#
Answers options.status (default 403) with options.message when the predicate refuses; otherwise continues.
requireRoles / requirePermissions#
Read user.roles / user.permissions unless a custom extractor is given; match is "any" (default) or "all". A null user answers 401; an insufficient one 403.

@rhythmjs/security/rate-limit#

TypeScript
function rateLimit(options?: RateLimitOptions): Middleware<RhythmHttpContext>
function rateLimitWs(options?: RateLimitOptions): RateLimitWsMiddleware
function memoryRateLimitStore(): RateLimitStore
RateLimitOptions#
limit (default 100), windowMs (default 60 000), store (RateLimitStore: increment(key, windowMs) returning RateLimitInfo, plus reset), keyOf(request), skip(request), headers (emit RateLimit-*; default true), message, and trustProxy (default false; true or a hop count enables X-Forwarded-For keying).
Default key#
With trustProxy set, the X-Forwarded-For entry that many hops from the right (the trusted proxy's append), truncated to 64 characters; else request.ip when your Bun.serve fetch exposes it (via server.requestIP()), else the literal key "global". X-Forwarded-For is never consulted without trustProxy, since the client controls it.
On refusal#
Status 429 with Retry-After (seconds to reset) and the JSON body { "success": false, "status": 429, "message": ... }. rateLimitWs is a ws-shaped middleware ((ctx, next)) that sets the same 429 Response on ctx.response instead, for RhythmWs.use().

@rhythmjs/security/cors#

TypeScript
function cors(options?: CorsOptions): Middleware<RhythmHttpContext>

Returns middleware that sets Access-Control-* headers on every response. A preflight OPTIONS request is answered with 204 No Content directly; downstream middleware never runs for it.

origin?: string | string[] | ((origin: string) => string | null)#
Default "*". A non-wildcard string or array is echoed back only when the request origin matches; a function returns the origin to allow or null. Whenever origin is not "*", Vary: Origin is appended to the response.
allowMethods?: string[]#
Default GET,HEAD,PUT,POST,DELETE,PATCH,QUERY. Sent as Access-Control-Allow-Methods on preflight responses.
allowHeaders?: string[]#
Default: reflect the preflight's Access-Control-Request-Headers. When headers are sent, Vary: Access-Control-Request-Headers is appended to the preflight response.
exposeHeaders?: string[]#
Default none. Sent as Access-Control-Expose-Headers when non-empty.
maxAge?: number#
Default unset. Sent as Access-Control-Max-Age on preflight responses when provided.
credentials?: boolean#
Default unset. When true, sets Access-Control-Allow-Credentials: true.

The CorsOptions interface is also exported from the subpath.

@rhythmjs/security/csrf#

TypeScript
function csrf(options?: CsrfOptions): Middleware<RhythmHttpContext>

Returns middleware that rejects a request with 403 and the JSON body { "success": false, "status": 403, "message": "Forbidden" } when all three conditions hold: the method is not GET or HEAD, the content type is a form type (application/x-www-form-urlencoded, multipart/form-data, or text/plain), and the Origin header is missing or not allowed. Every other request passes through.

origin?: string | string[] | ((origin: string) => boolean)#
Default: allow only the request URL's own origin. A string allows one origin, an array allows each listed origin, and a predicate returns whether the given origin is allowed.

The CsrfOptions interface is also exported from the subpath.

@rhythmjs/security/secure-headers#

TypeScript
function secureHeaders(options?: SecureHeadersOptions): Middleware<RhythmHttpContext>

Returns middleware that awaits next() and then sets the resolved headers on the response, so they apply after the handlers run. Every SecureHeadersOptions key accepts a string to override the header value or false to drop the header. The defaults are:

crossOriginOpenerPolicy#
Cross-Origin-Opener-Policy: same-origin
crossOriginResourcePolicy#
Cross-Origin-Resource-Policy: same-origin
referrerPolicy#
Referrer-Policy: no-referrer
strictTransportSecurity#
Strict-Transport-Security: max-age=15552000; includeSubDomains
xContentTypeOptions#
X-Content-Type-Options: nosniff
xDnsPrefetchControl#
X-DNS-Prefetch-Control: off
xDownloadOptions#
X-Download-Options: noopen
xFrameOptions#
X-Frame-Options: SAMEORIGIN
xPermittedCrossDomainPolicies#
X-Permitted-Cross-Domain-Policies: none
xXssProtection#
X-XSS-Protection: 0

contentSecurityPolicy (Content-Security-Policy) and crossOriginEmbedderPolicy (Cross-Origin-Embedder-Policy) default to off and are sent only when configured with a string value.

The SecureHeadersOptions interface is also exported from the subpath.