Skip to content

IAM - Password reset

Purpose

A person who cannot sign in requests a one-time email link and sets a new password without knowing the current one. Platform SMTP delivers the message. Success ends every session for that user.

Users and permissions

Any visitor on the tenant app may request a reset for an email address. Only an active workspace user who owns that email receives a link. Operators and admin-portal accounts are out of scope.

Requirements

ID Priority Requirement
RST-01 Must POST /api/auth/forgot-password with a valid email always returns 200 and the same generic message whether or not the account exists, so the response does not reveal registration.
RST-02 Must When the email matches an active user, the API stores a single-use hashed token that expires in 15 minutes, invalidates any earlier unused tokens for that user, and asks the mail binder to send the password-reset template with a link to /reset-password?token=….
RST-03 Must When the email is unknown, the user is locked, or SMTP is not configured, no usable token is left for the client and the response stays the generic success message.
RST-04 Must POST /api/auth/reset-password with a valid unused unexpired token and a password that passes the registration strength rule replaces the hash, deletes every session for that user, marks the token used, and returns 200.
RST-05 Must An expired, used, or unknown token is rejected with 400 and the password is unchanged.
RST-06 Must A new password that fails the registration strength rule is rejected with 400 before the hash is replaced.
RST-07 Must Sign-in shows a Forgot password link to /forgot-password. That page asks for email, posts forgot-password, and shows the generic confirmation.
RST-08 Must /reset-password?token=… asks for the new password twice, posts reset-password, and on success sends the person to sign-in with a success notice.
RST-09 Should When the two new-password fields differ, the reset form shows a mismatch message and does not call the API.

Screens

  • Sign-in: "Forgot password?" links to /forgot-password.
  • Forgot password (/forgot-password): email field, submit, link back to sign-in. After submit, show that if an account exists, instructions were sent.
  • Reset password (/reset-password): new password, confirm password, submit. Token comes from the query string. Success navigates to /sign-in with notice Password reset successfully. Please sign in.

Business rules

  • Token is 32 random bytes, stored only as SHA-256 (base64url). The raw token appears only in the email link.
  • TTL is 15 minutes from creation. One successful use consumes the token.
  • Password strength matches registration: at least 8 characters, with a letter, a number, and an uppercase letter.
  • Mail is sent through the apps/api binder and SmtpSettingsService using renderPasswordResetEmail. IAM does not import api-system.
  • Reset link base URL is WEB_APP_ORIGIN (default http://localhost:4200).
  • Locked users do not receive a reset email.

Acceptance criteria

  • RST-01: Given any well-formed email, when forgot-password is posted, then the response is 200 with the generic message.
  • RST-02: Given an active user and a working mail binder, when forgot-password is posted for that email, then a hashed token exists, earlier unused tokens for that user are gone, and the binder receives the reset URL.
  • RST-03: Given an unknown email, when forgot-password is posted, then no token is created and the response is still the generic success.
  • RST-04: Given a valid token, when reset-password is posted with a valid new password, then the hash matches the new password, all sessions for that user are deleted, and the token cannot be reused.
  • RST-05: Given an expired or used token, when reset-password is posted, then the response is 400 and the password is unchanged.
  • RST-06: Given a valid token, when the new password is too weak, then the response is 400 and the hash is unchanged.
  • RST-07: Given the sign-in screen, when the person opens Forgot password and submits an email, then forgot-password is called and the confirmation is shown.
  • RST-08: Given a reset link with a token, when the person submits matching valid passwords, then they land on sign-in with the success notice.
  • RST-09: Given the reset form, when the two password fields differ, then a mismatch message is shown and no API call is made.

Not yet implemented

Out of scope

  • Operator / admin-portal password reset.
  • An admin setting another user's password.
  • Rate limiting beyond single-use short-lived tokens.

Open questions

  • None.