Two WebAuthn client/route hardening fixes:
- GET /login/webauthn/begin wrote a challenge to the session on a safe method
(login-flow DoS / CSRF surface). Make it POST with CSRF, matching the
registration-begin endpoint; update webauthn.js and tests accordingly.
- webauthn.js rendered dynamic error text (err.message, server error fields)
via innerHTML — an XSS-prone sink. Add showAlert() that sets textContent;
route all dynamic error messages through it. The trusted server-rendered
credentials partial is still injected as markup.
Refs: porchlight-cog, porchlight-t7y
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>