import { MiddlewareHandler, Context } from "hono"; import { DataDriver } from "@rebasepro/types"; import { AccessTokenPayload } from "./jwt"; import { HonoEnv } from "../api/types"; import type { ApiKeyStore } from "./api-keys/api-key-store"; /** * Result from a custom auth validator. * - `false`/`null`/`undefined` = not authenticated * - `true` = authenticated as default user * - object with `userId` or `uid` = authenticated with user info */ export type AuthResult = boolean | null | undefined | { userId?: string; uid?: string; roles?: string[]; [key: string]: unknown; }; /** * Options for creating an auth middleware via createAuthMiddleware() */ export interface AuthMiddlewareOptions { /** DataDriver to scope via withAuth() for RLS */ driver: DataDriver; /** * Optional per-request driver resolver for multi-data-source backends. * Given the request context, returns the unscoped delegate to use (e.g. * Postgres vs Mongo, picked by the request's collection data source). * When omitted, `driver` is used for every request. */ resolveDriver?: (c: Context) => DataDriver; /** * If true, return 401 when no valid token is present. * * **Defaults to `true` (secure by default).** Set to `false` only for * intentionally public endpoints where access control is fully delegated * to Postgres Row-Level Security policies. */ requireAuth?: boolean; /** Optional custom validator (for non-JWT auth, e.g. external auth providers) */ validator?: (c: Context) => Promise; /** * A static secret key for server-to-server / script authentication. * * When a request sends `Authorization: Bearer ` and the key matches * this value, the request is granted admin-level access (uid: `service`, * roles: `["admin"]`) **without** JWT verification. The driver is scoped * via `withAuth()` with the service identity. * * This is the Rebase equivalent of a Service Account key. * Set via `REBASE_SERVICE_KEY` in `.env` and pass through the backend config. * * **Security:** The comparison uses constant-time equality to prevent * timing attacks. The key must be at least 32 characters. */ serviceKey?: string; /** * API key store for authenticating `rk_` prefixed tokens. * When set, tokens starting with `rk_` are validated against the * database instead of being treated as JWTs. */ apiKeyStore?: ApiKeyStore; } /** * Hono middleware that requires a valid JWT token via Authorization header. * Returns 401 if token is missing or invalid. * * **Security:** Tokens are only accepted via the `Authorization: Bearer` * header. Query-string tokens (`?token=`) are intentionally NOT accepted * here because URLs leak into access logs, proxies, Referer headers, and * browser history. Use {@link queryTokenAuth} on routes that legitimately * need query-string tokens (e.g. storage file serving for ``). */ export declare const requireAuth: MiddlewareHandler; /** * Factory that creates a requireAuth middleware with optional service key support. * * When `serviceKey` is provided, the middleware will check if the Bearer token * matches the service key using constant-time comparison. If it matches, the * request is authenticated as a service user with admin privileges. * * This allows admin routes (which use standalone requireAuth + requireAdmin) * to be accessed via service keys for scripts and server-to-server calls. */ export declare function createRequireAuth(options?: { serviceKey?: string; }): MiddlewareHandler; /** * Middleware that requires the user to have an admin or schema-admin role. * Must be used AFTER requireAuth or on a route where user is guaranteed. */ export declare const requireAdmin: MiddlewareHandler; /** * Middleware that optionally extracts user from JWT via Authorization header. * Does not return 401 if token is missing — allows anonymous access. * * Query-string tokens are NOT accepted here. Use {@link queryTokenAuth} * on routes that need them. */ export declare const optionalAuth: MiddlewareHandler; /** * Extract user from token - for WebSocket authentication */ export declare function extractUserFromToken(token: string): AccessTokenPayload | null; /** * Create a configurable auth middleware that handles: * 1. Token extraction (via custom validator or JWT Bearer token) * 2. RLS-scoped DataDriver via withAuth() * 3. Enforcement (401 when requireAuth is true and no user) * * **Secure by default:** `requireAuth` defaults to `true`. Anonymous * access is only allowed when the developer explicitly opts out by * setting `requireAuth: false`, indicating that Postgres RLS policies * fully control access. * * **Fail-closed:** The raw unscoped driver is never placed in the * request context. Every code path either scopes via `withAuth()` or * rejects the request. This prevents silent RLS bypass. * * This is the single source of truth for HTTP auth in Rebase. * Use this instead of manually parsing tokens in route handlers. */ export declare function createAuthMiddleware(options: AuthMiddlewareOptions): MiddlewareHandler; /** * Middleware that authenticates via a `?token=` query parameter. * * **Use sparingly.** Tokens in URLs leak into access logs, proxy logs, * Referer headers, and browser history. This middleware exists solely for * routes where the consumer cannot set HTTP headers — e.g. ``, * `` for file downloads, or similar browser-native requests. * * Apply it **before** `requireAuth` or `optionalAuth` on the specific * route that needs it. Those middlewares will see the user context this * middleware sets and skip their own 401 check. * * @example * ```ts * router.get("/file/*", queryTokenAuth, readAuthMiddleware, handler); * ``` */ export declare const queryTokenAuth: MiddlewareHandler; /** * Authorizes anonymous access to **public** storage objects (those under the * public prefix), which are served token-less via stable, permanent URLs. * * Runs on the storage `/file/*` and `/metadata/*` routes, *after* the token * middleware and *before* the read-auth gate. If the request is already * authenticated (Bearer or scoped token), it does nothing. Otherwise, when the * requested object path is public, it sets a minimal "public" principal so the * downstream `requireAuth` gate lets the read through. Private paths are left * untouched, so they still require a valid token. */ export declare const publicObjectAuth: MiddlewareHandler; /** * Middleware that authenticates file-serving routes using scoped download tokens. * It enforces that only scoped "file-read" tokens can access "/file/*" and "?token=" query params. * Full access JWTs are explicitly rejected on "/file/*" routes, and in the "?token=" query param. */ export declare const fileTokenAuth: MiddlewareHandler;