2.4 KiB
middleware/require-auth
Purpose
requireAuth() is the canonical Hono middleware factory for gating a
route or sub-route on an authenticated principal. It reads
c.get("user") and, if the value is null (or absent), throws
AuthError(AUTH_UNAUTHENTICATED) carrying context.statusCode: 401
so the @suaveplan/api error-handler middleware translates it to an
HTTP 401 response.
Features
- Depends only on the typed
c.get("user")slot installed bysessionMiddleware— no dynamic service lookup, no per-request Better-Auth call. - Single failure mode:
AUTH_UNAUTHENTICATEDwithstatusCode: 401attached to the error context. - Idempotent — applying the middleware twice in the same chain costs one type narrow + one truthy check.
Usage: Basic
import { requireAuth } from "@suaveplan/api-plugin-auth/middleware/require-auth";
app.use("/private/*", requireAuth());
app.get("/private/me", (c) => c.json(c.get("user")));
Usage: Advanced
Compose requireAuth with requireRole and requireEmailVerified to
build a sliding scale of access controls. Each middleware throws its
own typed AuthError, so the error handler can emit specific OpenAPI
4xx responses per stage:
import {
requireAuth,
requireRole,
requireEmailVerified,
} from "@suaveplan/api-plugin-auth/middleware";
app.use("/admin/*", requireAuth(), requireRole("admin"));
app.use("/billing/*", requireAuth(), requireEmailVerified());
API Reference
function requireAuth(): MiddlewareHandler
Returns a Hono middleware handler. Throws
AuthError(AUTH_UNAUTHENTICATED, "Authentication required", { context: { statusCode: 401 } }) when c.get("user") is null or
undefined. Calls next() otherwise.
Implementation Notes
- The check uses
=== null || === undefinedrather than a truthy check so a fully-populatedPrincipalwith falsy values (e.g.email: ""after the principal mapping normalised it out) still passes.Principalobjects are never falsy. - Throwing — not returning a 401 response directly — keeps the error
shape consistent with
requireRoleandrequireEmailVerified; all three flow through the@suaveplan/apierror-handler, which both serialises the error envelope and emits the OTel span event. - The
statusCode: 401field is read by the error-handler middleware installed by@suaveplan/api; the auth plugin does not own status mapping itself.