Skip to content

AUTH-MAIL-002 — Make account-email delivery states honest and recoverable #120

Description

@daliu

Officer impact: Members receive clear, accurate instructions when verification or password-recovery email is sent, delayed, or unavailable. Officers can point members to a safe recovery path without requesting passwords, codes, screenshots, or private links.

Officer documentation: Update docs/officers/EVENTS_SHOP_MEMBERS.md and docs/officers/EMERGENCY_AND_RECOVERY.md with the member-facing recovery wording, stop conditions, proof, undo, and escalation. Mark the revised behavior NOT AVAILABLE YET until the website publication is verified.

Deployment evidence: None at issue creation. Closure requires deterministic frontend tests, no-network provider mocks/emulators, merged source, website publication, runmprc.com verification, and a staged Auth-flow walkthrough using synthetic accounts. It does not require or authorize real email delivery from production.

Problem

Account registration currently catches a Firebase verification-email error, writes only a console warning, and can still tell the member to check the inbox. That makes account created and verification message sent look like the same successful state.

The resend path has no visible cooldown. Raw or inconsistent provider errors can confuse members, while detailed password-reset errors can reveal whether an account exists.

Atomic outcome

Represent identity and email-delivery outcomes separately and provide one simple recovery path:

  • Account created.
  • Verification message accepted for sending.
  • Delivery request failed or is temporarily unavailable.
  • Resend is available after a visible cooldown.
  • Already verified, link expired/used, and wrong-account states have plain next steps.

The UI may suggest checking Spam and marking the approved sender as not spam, but must explain that this does not fix delivery for everyone.

Security and usability invariants

  • Never claim a message was sent after the Firebase call failed.
  • Password reset and public recovery responses remain generic and do not confirm whether an email/account exists.
  • Do not display raw Firebase error codes, stack traces, email addresses, action links, or tokens.
  • Do not log names, emails, request bodies, action links, or raw provider errors.
  • Resend has a client-visible cooldown and must also tolerate provider throttling; it is not an authorization control.
  • A retry cannot create another account, change membership, grant access, or lose the task the member was trying to complete.
  • Controls and copy use large, clear actions and ordinary language suitable for elderly/nontechnical members.
  • All tests use mocks/emulators and synthetic data; no production inbox or action link is used.

Acceptance criteria

  • Registration distinguishes account created from verification request accepted and verification request failed.
  • A failed verification request shows a generic recovery action and never says to check the inbox as if success were proven.
  • Resend shows a visible countdown, blocks accidental repeat clicks, and recovers after success, failure, refresh, and sign-in changes.
  • Password-reset UI returns the same public result for existing, missing, malformed, throttled, and provider-failure cases where enumeration resistance requires it.
  • Verification success, already verified, expired/used link, wrong account, offline, and provider-unavailable states have one clear next action.
  • Spam guidance names the currently configured sender generically and can be updated after AUTH-MAIL-001 without a code fork.
  • Screen-reader labels, focus movement, keyboard flow, readable control sizes, and loading/disabled states are tested.
  • Unit/integration tests prove success, send failure, resend cooldown, retry, navigation preservation, and generic-error behavior without any network call.
  • No logs, analytics, screenshots, fixtures, or errors contain an email address, action URL, code, or token.
  • Officer guidance states what can be checked, what must never be requested from a member, and when to escalate.

Dependencies and coordination

The implementation becomes claimable after #103 and the required no-network test boundary are merged. Provider configuration may proceed separately under #119.

Explicitly out of scope

  • Custom sender-domain DNS, SMTP/provider delivery, template administration, Google sign-in, membership approval, dues, discounts, or role grants.
  • Reading a member mailbox, sending production test mail, or collecting message headers/action links in public systems.

Claim protocol

Creation is not a claim. Before editing, confirm dependencies, assign the issue, post CLAIMED by <canonical agent> at <UTC>; branch <branch>, and re-read all comments. Keep this as one tested UI/recovery outcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authAuthentication and authorizationarea:firebaseFirebase services and dataarea:webWeb application and hostingbugSomething isn't workingpriority:P1High-priority follow-upsize:SSmall focused issuestatus:blocked-ownerRequires an owner or external decisiontype:reliabilityReliability and recoverytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions