Skip to content

!fix: password reset flow#1566

Merged
tyler-dane merged 16 commits intomainfrom
feat/email-pw-reset
Mar 26, 2026
Merged

!fix: password reset flow#1566
tyler-dane merged 16 commits intomainfrom
feat/email-pw-reset

Conversation

@tyler-dane
Copy link
Copy Markdown
Contributor

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

!Breaking change: Renames an environment value

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
Medium risk because it renames a required backend/CLI env var (LOCAL_WEB_URLFRONTEND_URL) and refactors SuperTokens override handlers plus web router/auth modal logic, which could break auth flows or deployments if misconfigured.

Overview
Fixes password reset links and simplifies URL env configuration by replacing LOCAL_WEB_URL (and CLI STAGING_WEB_URL/PROD_WEB_URL) with a single FRONTEND_URL used by the backend env schema, SuperTokens reset-email rewriting, and CLI domain/cleanup URL resolution.

Refactors backend SuperTokens overrides into supertokens.middleware.handlers.ts, centralizes “tag new user” email-list behavior in EmailService.tagNewUserIfEnabled, and adjusts tests accordingly (including avoiding a race in SyncDriver.createSync).

Hardens the web password reset UX: loader redirects now preserve ?auth=... query params, reset tokens are managed via URL-safe helpers, the modal adds a loginAfterReset state with a success message, and new tests cover redirects and view switching.

Minor cleanups: remove a noisy console.warn in core event mapping, stabilize RRULE tests, update CLI delete to skip Google watch cleanup when no refresh token exists, and reorganize/add internal docs plus ignore .claude/.

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

@tyler-dane tyler-dane marked this pull request as ready for review March 24, 2026 03:20
…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.
…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.
@tyler-dane tyler-dane force-pushed the feat/email-pw-reset branch from 3ecdcb7 to a735f6c Compare March 26, 2026 16:17
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue. You can view the agent here.

Comment thread packages/scripts/src/common/cli.utils.ts Outdated
@tyler-dane tyler-dane changed the title fix: password reset flow !fix: password reset flow Mar 26, 2026
- Added section on Google Series Splits to recurring events handling documentation to clarify handling of incremental sync payloads.
- Deleted outdated recurring events overview and sync documentation to streamline content and avoid redundancy.
- Updated frontend data flow documentation to consolidate information and clarify event flow.
- Revised principles documentation to align with repo guidance.
@tyler-dane tyler-dane merged commit 9b3c6fd into main Mar 26, 2026
9 checks passed
@tyler-dane tyler-dane deleted the feat/email-pw-reset branch March 26, 2026 18:56
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