fix(auth): name the state and the address behind a refused sign-in (E9.5 S4)
"Your account is awaiting admin approval." was true and useless. It never said WHICH mailbox the account was on, and on 2026-09-03 that silence hid a Gmail alias mismatch for a day: a registration as np.temu@gmail.com met a Google claim of nptemu@gmail.com, and every screen in the funnel agreed to say nothing about it. Every refusal password-login can answer with now uses the codebase's structured {code, reason} detail, built in one helper. The three that arrive AFTER the password is proven carry the address on the account plus both gate flags; the two that answer before it (invalid, rate_limited) carry nothing, so a wrong password and an unknown account stay byte-identical. The frontend renders the first three as a named screen in place of the form — there is nothing to retype once the password is correct — with an icon, the two-gate checklist, the address in monospace, and a resend CTA where one helps. Reporting each gate from its own flag is the payoff of S1: approved-but-unverified is a real state now, and a screen that assumed a sequence would send that user off to wait for an admin who has already decided. The Google access-request notice names the address too, and says so when the request was already on file under ANOTHER spelling of the same mailbox — the honest version of "we didn't open a second one", stated only when it applies. It moved from the query string to the fragment: the notice now carries an address, and a query string lands in every reverse-proxy access log. Same reasoning that put the verify/reset tokens there, and the same owner already clears it. urlencode, not an f-string, because URLSearchParams reads a bare + in a fragment as a space and would mangle exactly the +tag addresses this epic exists to protect. upsert_pending_invite returns the row it settled on beside the is-new flag, since the row's stored address is what the notice has to name and what mail will go to. Deviation from the PendingScreen mockup, deliberately: no "Sign out" button and no separate "Not your address?" link. The mockup drew the panel in the app shell; the accepted decision (a) keeps the pending user session-less, so there is no session to end, and the address is named directly above a "Back to sign in" that answers the same question. UAT on localdev, both languages: all three refusals with the typed spelling deliberately differing from the stored one (the panel named the stored one), the resend CTA carrying the typed address into the resend form, and both access-request banners with a +tag address surviving the fragment round trip. Throwaway accounts and the language switch reverted.
This commit is contained in:
@@ -93,6 +93,41 @@
|
||||
"resendDone": "If that email has an unverified account, we've sent a new verification link. Check your inbox.",
|
||||
"oauthCancelled": "Google sign-in was cancelled. You can try again or use email and password.",
|
||||
"accessRequested": "Thanks — we recorded your request. An admin will review it.",
|
||||
"accessRequestedFor": "We've recorded your access request for:",
|
||||
"accessRequestedReview": "An admin will review it, and we'll email you either way.",
|
||||
"accessLinked": "You already had a request on file for this mailbox, under a different spelling:",
|
||||
"accessLinkedTail": "Google returns one fixed spelling of a Gmail address, so we linked this sign-in to that request instead of opening a second one. Any mail goes to the address above.",
|
||||
"blocked": {
|
||||
"addressLabel": "Address on file",
|
||||
"operator": "If you think this is a mistake, contact the operator at {{contact}}.",
|
||||
"gate": {
|
||||
"emailDone": "Email address confirmed",
|
||||
"emailPending": "Email address — not confirmed yet",
|
||||
"approvalDone": "Admin approval — granted",
|
||||
"approvalPending": "Admin approval — pending"
|
||||
},
|
||||
"email_unverified": {
|
||||
"title": "Confirm your email address",
|
||||
"body": "Your password is correct — we just can't let you in until the address on this account is confirmed. Open the link we emailed you, or ask for a new one.",
|
||||
"short": "Confirm your email address first — check your inbox."
|
||||
},
|
||||
"pending_approval": {
|
||||
"title": "Waiting for approval",
|
||||
"body": "Your password is correct and your address is confirmed. An admin still has to let you in — we'll email you as soon as they decide.",
|
||||
"short": "Your account is waiting for admin approval."
|
||||
},
|
||||
"suspended": {
|
||||
"title": "Account suspended",
|
||||
"body": "This account has been suspended, so it can't sign in by any method.",
|
||||
"short": "This account has been suspended."
|
||||
},
|
||||
"invalid": {
|
||||
"short": "Invalid email or password."
|
||||
},
|
||||
"rate_limited": {
|
||||
"short": "Too many attempts. Try again shortly."
|
||||
}
|
||||
},
|
||||
"accessDenied": "That account isn't approved for this instance yet — register below or ask the admin for access.",
|
||||
"suspended": "This account has been suspended and can't sign in. If you think this is a mistake, contact the operator (check your email for details).",
|
||||
"deleted": "Your account and all its data were permanently deleted. We've emailed you a confirmation."
|
||||
|
||||
@@ -93,6 +93,41 @@
|
||||
"resendDone": "Ha ehhez az e-mailhez tartozik megerősítetlen fiók, elküldtünk egy új megerősítő linket. Nézd meg a postafiókod.",
|
||||
"oauthCancelled": "A Google-belépés megszakadt. Próbáld újra, vagy lépj be e-maillel és jelszóval.",
|
||||
"accessRequested": "Köszönjük — rögzítettük a kérésed. Egy admin felülvizsgálja.",
|
||||
"accessRequestedFor": "Rögzítettük a hozzáférési kérelmedet erre a címre:",
|
||||
"accessRequestedReview": "Egy admin átnézi, és e-mailben szólunk a döntésről.",
|
||||
"accessLinked": "Ehhez a postafiókhoz már volt kérelmed, csak más írásmóddal:",
|
||||
"accessLinkedTail": "A Google egy rögzített írásmódot ad vissza a Gmail-címekből, ezért ezt a belépést a meglévő kérelemhez kötöttük, nem indítottunk újat. A levelek a fenti címre mennek.",
|
||||
"blocked": {
|
||||
"addressLabel": "Rögzített cím",
|
||||
"operator": "Ha tévedésnek gondolod, keresd az üzemeltetőt: {{contact}}.",
|
||||
"gate": {
|
||||
"emailDone": "E-mail-cím megerősítve",
|
||||
"emailPending": "E-mail-cím — még nincs megerősítve",
|
||||
"approvalDone": "Admin jóváhagyás — megvan",
|
||||
"approvalPending": "Admin jóváhagyás — folyamatban"
|
||||
},
|
||||
"email_unverified": {
|
||||
"title": "Erősítsd meg az e-mail-címed",
|
||||
"body": "A jelszavad jó — csak addig nem engedhetünk be, amíg a fiókon lévő cím nincs megerősítve. Nyisd meg a kiküldött linket, vagy kérj újat.",
|
||||
"short": "Előbb erősítsd meg az e-mail-címed — nézd meg a postafiókod."
|
||||
},
|
||||
"pending_approval": {
|
||||
"title": "Jóváhagyásra vár",
|
||||
"body": "A jelszavad jó, a címed megerősítve. Már csak arra várunk, hogy egy admin beengedjen — szólunk e-mailben, amint döntött.",
|
||||
"short": "A fiókod admin jóváhagyásra vár."
|
||||
},
|
||||
"suspended": {
|
||||
"title": "Felfüggesztett fiók",
|
||||
"body": "Ez a fiók fel van függesztve, így semmilyen módon nem tud belépni.",
|
||||
"short": "Ez a fiók fel van függesztve."
|
||||
},
|
||||
"invalid": {
|
||||
"short": "Hibás e-mail-cím vagy jelszó."
|
||||
},
|
||||
"rate_limited": {
|
||||
"short": "Túl sok próbálkozás. Próbáld újra kicsit később."
|
||||
}
|
||||
},
|
||||
"accessDenied": "Ez a fiók még nincs jóváhagyva ehhez a példányhoz — regisztrálj lent, vagy kérj hozzáférést az admintól.",
|
||||
"suspended": "Ez a fiók fel van függesztve, nem tud belépni. Ha tévedésnek gondolod, keresd az üzemeltetőt (a részletek az e-mailedben).",
|
||||
"deleted": "A fiókod és minden adata véglegesen törölve lett. A megerősítést e-mailben is elküldtük."
|
||||
|
||||
Reference in New Issue
Block a user