Corrects a design error in the previous commit. I had exposed register-begin as
a listener operation and gated it on a session cookie, but the approved flow has
no session at that point: the whole point is that a valid TOTP code is what
authorises registration, and the session is only issued once the new credential
has been verified.
Two consequences, both bad:
- There is no session cookie to check, so the gate could never have worked. It
would have been dead code that looked like a security control.
- More seriously, a listener-side register-begin would hand out a challenge
without proving anything. Anyone could obtain ceremony options and attempt
registration. The cookie check was not a weak control; the operation itself
was the hole.
Registration is now started by LoginManager, after it has verified both the code
and the nonce, and its options are returned with the login response. That is the
flow in the plan, and it keeps nonce validation in the one place that already
enforces it. The capability for register-finish is the single-use ceremonyId,
which is server-issued and bound to the identity that passed the check.
The listener now serves three operations, and a test pins that register-begin is
not one of them.
Also adds Payload::$register so the checkbox intent survives from the form to
LoginManager, and moves the ceremony marker constant to AppConstants since both
LoginManager and the listener now produce marked responses.