Skip to content

fix: password reset flow#1566

Open
tyler-dane wants to merge 5 commits intomainfrom
feat/email-pw-reset
Open

fix: password reset flow#1566
tyler-dane wants to merge 5 commits intomainfrom
feat/email-pw-reset

Conversation

@tyler-dane
Copy link
Contributor

@tyler-dane tyler-dane commented Mar 24, 2026

Fix password reset email URL and simplify environment configuration

Problem

Password reset emails sent from staging and production contained http://localhost:9080 as the base URL, making the reset link unusable. The variable LOCAL_WEB_URL was hardcoded to localhost:9080 in all env files — including staging and production — because its name implied it was only for local use. The correct domain values existed in STAGING_WEB_URL and PROD_WEB_URL, but those were never wired into the backend schema or the reset link builder.

A secondary issue: the CLI had three separate URL env vars (LOCAL_WEB_URL, STAGING_WEB_URL, PROD_WEB_URL) that were mostly redundant with each other, adding cognitive overhead to env file setup.

Changes

Rename LOCAL_WEB_URLFRONTEND_URL and fix values per environment

  • FRONTEND_URL now holds the public-facing frontend URL for the current deployment — localhost:9080 for local, the real domain for staging/prod
  • Wired through the Zod backend schema (env.constants.ts) so ENV.FRONTEND_URL is always the correct domain
  • buildResetPasswordLink() now uses this correct value, so reset emails link to the right domain in every environment

Consolidate CLI URL configuration

  • Removed STAGING_WEB_URL and PROD_WEB_URL from all env files and CLI_ENV — they duplicated FRONTEND_URL's value
  • getCleanupUrl() now simply returns ${FRONTEND_URL}/cleanup — no NODE_ENV branching needed
  • getDomainAnswer() extracts the hostname from FRONTEND_URL when it's a real domain; falls back to an interactive prompt (with a tip to set FRONTEND_URL) when it's localhost
  • Net result: one URL variable to set, zero redundancy

Password reset UI flow

  • Enhanced AuthModal to handle the post-reset sign-up flow and show appropriate status messaging
  • Improved URL token handling in useAuthFormHandlers during the reset flow
  • Added loader logic in loaders.ts to detect and route reset password sessions

Delete user GCal access check

  • deleteCompassDataForMatchingUsers now checks for a Google refresh token before attempting GCal cleanup, avoiding spurious errors for password-only users

Test plan

  • Trigger a password reset in staging — confirm the email link points to https://backend.compasscalendar.app/day?auth=reset&token=...
  • Complete the reset flow end-to-end: receive email → click link → set new password → sign in
  • Run backend tests: pnpm test in packages/backend — Zod schema + supertokens middleware tests
  • Run web tests: pnpm test in packages/web — AuthModal tests
  • Run CLI locally: confirm delete command cleanup URL resolves correctly

Note

Medium Risk
Touches password reset and auth URL handling across web routing, modal state, and backend email link generation; misconfiguration of the renamed FRONTEND_URL env var or redirect/query handling could break reset links or login UX.

Overview
Fixes the password-reset flow end-to-end by preserving ?auth=reset&token=... through //day/day/:date redirects and by making the reset submit resilient to URL changes (token is re-injected before submit, then removed afterward).

Updates the auth modal to introduce a loginAfterReset view and show a success status message on the login form after a successful reset, with new/updated tests covering redirect preservation and view switching.

Renames backend/CLI configuration from LOCAL_WEB_URL to FRONTEND_URL for building reset-password links and local CLI cleanup URLs, updating env schema, examples, and docs accordingly.

Written by Cursor Bugbot for commit 3ecdcb7. This will update automatically on new commits. Configure here.

…ogle Calendar access check

- Updated the deleteCompassDataForMatchingUsers function to accept a second parameter, gcalAccess, indicating whether the user has Google Calendar access.
- This change allows for more granular control over the deletion process based on the user's Google Calendar connection status.
…et flow

- Introduced a new `RouteLocationMirror` component to synchronize URL state with the AuthModal.
- Added `renderWithDayRedirectRoute` function to facilitate testing of the AuthModal with day-based routing.
- Updated tests to verify that the reset password flow correctly preserves authentication parameters in the URL during redirects.
- Implemented `updateCurrentUrlSearchParams` function to streamline URL parameter updates in the authentication flow.
- Enhanced existing tests to ensure robust coverage of the new functionality and maintainability of the AuthModal component.
…aging

- Introduced a new status message in the LogInForm to inform users of successful password resets.
- Updated AuthModal logic to handle the new "loginAfterReset" view, improving user experience during the authentication process.
- Enhanced tests for LogInForm to verify the display of status messages, ensuring accurate feedback for users.
- Refactored related hooks and components to support the updated authentication flow and maintain clarity in the codebase.
@tyler-dane tyler-dane marked this pull request as ready for review March 24, 2026 03:20
…eset

- Added a test to verify that clicking "Sign up" after a successful password reset correctly transitions the user to the sign-up view.
- Updated error handling in the useZodForm hook to log errors in development mode, improving debugging capabilities during form submissions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant