The two ceremonies and the recovery route, five actions, as JSON.
The controller mints a challenge in one request and verifies it in the next, so the challenge
waits in the session between them. It deletes the challenge the first time something attempts
a verification, whether that attempt succeeded or not. A challenge is single-use, and nothing
in Ithibati.Identity.Passkeys can hold that property: the challenge lives wherever the caller
put it, and a replayed assertion looks the same as a first one there. This controller is the
caller, so this is where it happens.
The two ceremonies keep their challenges in separate places. Wax checks the type the client
wrote into the client data, not the type of the challenge it verifies against. One shared slot
would therefore let a challenge taken from the ungated sign-in endpoint be spent on a
registration, and Ithibati.Web.Handler.registration_subject/2 is the only place an instance
can refuse someone.
What follows a verification belongs to the application. See Ithibati.Web.Handler.