Liking cljdoc? Tell your friends :D

dev.arkaitz.web-base.gate

The gate on private pages (SPEC §5, §9). The base knows that a request may carry a subject and nothing about what a subject is: the host hands it a function from request to subject-or-nil, and per route a predicate over the request. What the base owns is the translation of a refusal into the right outcome for the kind of request — a 303 for a navigation, so a refused POST is never re-posted to the login page; an HX-Redirect for an htmx swap so the login page never lands inside a div; and a 403 error datum when there is a subject and the predicate still says no. No 401: a proper one needs WWW-Authenticate, and only whoever authenticates knows the scheme.

The gate on private pages (SPEC §5, §9). The base knows that a request may
carry a subject and nothing about what a subject is: the host hands it a
function from request to subject-or-nil, and per route a predicate over the
request. What the base owns is the translation of a refusal into the right
outcome for the kind of request — a `303` for a navigation, so a refused
POST is never re-posted to the login page; an `HX-Redirect` for an htmx swap
so the login page never lands inside a `div`; and a 403 error datum when
there is a subject and the predicate still says no. No `401`: a proper one
needs `WWW-Authenticate`, and only whoever authenticates knows the scheme.
raw docstring

middlewareclj

(middleware {:keys [login-path] :as opts})

reitit middleware compiled per route, over the route's data as reitit merged it from its parents — so a gate on a parent guards every child, a child's own gate replaces it, and a child's nil leaves the parent's in place. It vanishes from routes whose merged data has no :wb/gate (absent or nil), and fails at router construction when the gate is present but not callable — false would otherwise open a route without a symptom — or when no :login-path is configured, which would otherwise be a 500 on the first refused request. reitit hands the compile step the route data, not the path, so the errors name the config key.

reitit middleware compiled per route, over the route's data as reitit merged it
from its parents — so a gate on a parent guards every child, a child's own gate
replaces it, and a child's nil leaves the parent's in place. It vanishes from routes
whose merged data has no `:wb/gate` (absent or nil), and fails at router construction when the gate
is present but not callable — `false` would otherwise open a route without
a symptom — or when no `:login-path` is configured, which would otherwise
be a 500 on the first refused request. reitit hands the compile step the
route data, not the path, so the errors name the config key.
sourceraw docstring

refusal-headersclj

A refusal depends on the session and on the kind of request: never cached, and varying on the htmx headers like every response whose shape does. Public for testing/gate-refusal?, which recognises a refusal by them.

A refusal depends on the session and on the kind of request: never cached,
and varying on the htmx headers like every response whose shape does. Public for
`testing/gate-refusal?`, which recognises a refusal by them.
sourceraw docstring

subject-present?clj

(subject-present? request)

The stock predicate: there is a subject. Presence is all the base ever checks; it never looks inside, so false is a subject like any other.

The stock predicate: there is a subject. Presence is all the base ever
checks; it never looks inside, so `false` is a subject like any other.
sourceraw docstring

wrap-subjectclj

(wrap-subject handler subject-fn)

Puts (subject-fn request) on every request as :wb/subject, gated route or not — a public page's layout also paints the identity corner.

Eager on purpose (decided 2026-09-27 by a five-lens panel, measured): with auth-base the call is one indexed read of the revocation generation per signed-in request, 9.7 µs on SQLite, after the session read the store already made; it is wasted only on responses that paint no identity, and it is where revocation takes effect. A lazy value was rejected — a delay is truthy, so subject-present? would admit anyone — and so were a per-route opt-out (the default 404 has no route) and a cached generation (revocation within N seconds instead of at the next request). A route that needs no subject at all belongs in :sessionless.

Puts `(subject-fn request)` on every request as `:wb/subject`, gated route
or not — a public page's layout also paints the identity corner.

Eager on purpose (decided 2026-09-27 by a five-lens panel, measured): with
auth-base the call is one indexed read of the revocation generation per signed-in
request, 9.7 µs on SQLite, after the session read the store already made; it is
wasted only on responses that paint no identity, and it is where revocation takes
effect. A lazy value was rejected — a `delay` is truthy, so `subject-present?` would
admit anyone — and so were a per-route opt-out (the default 404 has no route) and a
cached generation (revocation within N seconds instead of at the next request). A
route that needs no subject at all belongs in `:sessionless`.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close