feat(login): handle the emailed sign-in approval code #458
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/MAPPS-397-spa-login-approval-code"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
With LOGIN_APPROVAL_ENABLED on, mokosh-server's suspicious-login gate (PMS-658) emails a single-use six-digit code and answers the login with empty tokens,
user: Noneandapproval_required: true(crates/mokosh-types/src/auth.rs,src/modules/auth/service.rs). The SPA's standalone form never declared that field, so serde dropped it, the response fell into theresp.usermatch, and the user got "Sign-in succeeded but no account was returned. Try again." Retrying issued a fresh code and repeated forever: a permanent lockout with a message that never mentions the email.LoginRespnow decodesapproval_requiredbehind a serde default (older servers omit it) andLoginBodycarriesapproval_code, serialized only when present. A newapproval_requiredarm sits ahead of both themfa_requiredarm and theresp.usermatch, reveals an "Approval code" input, and prompts "Enter the code we emailed you to approve this sign-in."; the next submit re-POSTs the same login with the code. Once the challenge is showing, a 401 means the emailed code was wrong or expired rather than a bad password (the server returnsUnauthorizedfromverify_login_approval), so it maps to "That code is not valid, check the email or try signing in again."The recurrence gate the issue asks for is a compile-time one rather than the literal type swap.
mokosh_types::auth::LoginResponsederives onlySerializeandLoginRequestonlyDeserialize, verified against mokosh-server main at 38c8945, so neither can be used on the client side of the wire yet; the swap also needs the SPA's hand-copiedCurrentUserreplaced, which MAPPS-383 left out of scope. Instead two#[cfg(test)]functions destructure both shared types exhaustively and map every field ontoLoginResp/LoginBody. Droppingapproval_requiredfrom the pattern fails the build with E0027, so a field added server-side cannot go unread. AddingSerialize/Deserializeupstream and finishing the swap wants its own issue; this run is not permitted to file one in YouTrack.Gate green via
just pre-commit: fmt --check, clippy --all-targets -D warnings, cargo check --target wasm32-unknown-unknown, cargo test --lib (244 passed, 0 failed; was 240).#MAPPS-397