import { type Scope, type User } from 'harper'; import type { Middleware } from './http.ts'; /** * Harper's canonical "is this a super_user" check. Matches how Harper itself gates privileged paths * (e.g. impersonation, token minting): the resolved user carries `role.permission.super_user === true`. */ export declare function isSuperUser(user: User | undefined): boolean; /** * A Connect middleware that restricts the chain behind it (the Vite dev server) to Harper `super_user`s, * authenticated via HTTP Basic auth. It runs the check itself against Harper's APIs: * * - A super_user Harper already resolved (`req.user`, bridged onto the node request by `registerHttp` — * e.g. an authenticated admin) passes straight through. * - A loopback peer under `authorizeLocal` (the default in `harper dev`) also passes, authorized here the * same way the HMR WebSocket gate does it (`isUpgradeAuthorized`): Harper applies `authorizeLocal` to * MQTT (and its Bun HTTP inject path) but NOT the Node HTTP middleware layer this runs in, so `req.user` * is unset for a plain loopback `harper dev` request — we trust the real socket peer ourselves rather * than relying on Harper to pre-set it. So local development passes straight through with no prompt. * - Otherwise we validate an `Authorization: Basic` header directly with `server.authenticateUser` and, on * failure, reply `401` with a `WWW-Authenticate: Basic` header so a browser prompts for credentials. * * NOTE: this guards the HTTP surface — the Vite dev server's asset, module-transform and `/@fs/` * (arbitrary file read) endpoints, which is the dangerous part. Vite's HMR *WebSocket* runs on its own * port and is not routed through here; keep it bound to localhost (or otherwise unexposed) in any * non-local deployment. */ export declare function superUserAuth(scope: Scope, realm: string): Middleware; /** * Whether a WebSocket upgrade request may reach the Vite dev server — i.e. whether it represents a Harper * `super_user`. * * The HMR WebSocket is served on Harper's own port (see `setupDevelopment`), so the same super_user gate as * the HTTP surface should apply. But Harper runs its auth layer on the HTTP request chain, NOT the upgrade * chain — `req.user` is unset here — so we authorize the raw upgrade ourselves, from the three signals a real * client carries on a same-origin upgrade, cheapest first: * * 1. A loopback peer under `authorizeLocal` — mirrors how Harper trusts localhost for the HTTP surface, so * plain `harper dev` works with no prompt (the upgrade carries neither a Basic header nor a cookie, and * `authorizeLocal` sets no cookie). We trust the real socket peer, not a spoofable `X-Forwarded-For`. * 2. An `Authorization: Basic` header, validated exactly like the HTTP gate. Browsers seldom attach this to * a WebSocket handshake, but CLI clients (and some browsers) do. * 3. The `hdb-session` cookie Harper sets after any successful login (sessions are on by default). Cookies * ARE reliably sent on a same-origin upgrade, so this is the path that carries a logged-in admin's * identity from the page to a remotely-exposed HMR socket. * * Best-effort and fails closed: a missing global, store, or lookup error yields `false` (the upgrade is then * refused), never an unauthenticated pass. */ export declare function isUpgradeAuthorized(scope: Scope, req: any): Promise;