arch-atlas

Forgot Password Notifier

forget_password/presentation/providers

domain

Overview

Three coordinated notifiers that drive the email-based reset flow: ForgotPasswordNotifier triggers the reset email, ResetPasswordOtpNotifier verifies the 6-digit code, UpdatePasswordNotifier sets the new password. Each owns its own state and is consumed by a dedicated screen.

User Flow

  1. ForgetPasswordScreen → sendResetEmail(email) POSTs /auth/customer/emailpass-verified/reset-password.
  2. 201 flips emailSent=true; user is navigated to ResetPasswordOtpScreen with the email in extra.
  3. ResetPasswordOtpScreen verifies the code, receives a short-lived reset token.
  4. ResetPasswordScreen submits new password + token; backend rotates credentials.
  5. User is bounced to LoginScreen with the new password.

Cases & Edge Cases

  • Backend returns the same 201 whether the email exists or not (enumeration-safe) — UI must not leak existence.
  • Reset token expires server-side; UI surfaces a generic 'Something went wrong' to avoid hinting at expiry.
  • If the user navigates back from the OTP screen, the email field must repopulate — state is held by Riverpod, not by route extra.

Code References

  • lib/src/features/shared/auth/forget_password/presentation/providers/forgot_password_notifier.dart:7
  • lib/src/features/shared/auth/forget_password/presentation/providers/reset_password_otp_notifier.dart
  • lib/src/features/shared/auth/forget_password/presentation/providers/update_password_notifier.dart

API Calls

  • POST/auth/customer/emailpass-verified/reset-passwordno status

    Trigger a password-reset email for the given address.

    Request
    { identifier: string /* email */ }
    Response
    201 (no body)
    lib/src/features/shared/auth/forget_password/presentation/forget_password.dart

    auth: none. Idempotent — same 201 whether the email exists or not (enumeration-safe).

  • POST/auth/reset-password/verifyno status

    Verify the OTP from the reset email and receive a short-lived reset token.

    Request
    { email: string, otp: string }
    Response
    { success: true, data: { token: string } }
    Errors
    • ·{ success: false, error: string } — verbatim error surface
    lib/src/features/shared/auth/forget_password/presentation/reset_password_otp_screen.dart

    auth: none. The returned token is the input to /auth/customer/emailpass-verified/update.

  • POST/auth/customer/emailpass-verified/updateno status

    Set a new password using the short-lived reset token.

    Request
    { email: string, password: string } + header `Authorization: Bearer <resetToken>`
    Response
    { success: true }
    lib/src/features/shared/auth/forget_password/presentation/reset_password_screen.dart

    auth: reset-token (NOT the customer bearer). UI surfaces generic 'Something went wrong' on expiry.

Notes

The seller role has no separate forgot-password flow — backend resets the customer credential and the seller token is invalidated implicitly on next dual-login.