Skip to content

fix(auth): multi-tab logout sync, distinct reset error codes, case discussion i18n parity#46

Merged
jamofer merged 1 commit into
masterfrom
fix/auth-session-edge-cases
May 24, 2026
Merged

fix(auth): multi-tab logout sync, distinct reset error codes, case discussion i18n parity#46
jamofer merged 1 commit into
masterfrom
fix/auth-session-edge-cases

Conversation

@jamofer

@jamofer jamofer commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

Three independent auth/i18n polish items that share the same surface (auth boundary + cases page in non-EN locales).

  • Multi-tab logout sync. Logging out in tab A used to leave tab B fully authenticated until its next request came back 401. Added useStorageAuthSync to hooks/useAuth.js — a one-effect hook that subscribes to the storage event on window, listens for the auth token being removed in another tab, and reacts by clearing the TanStack Query cache and redirecting to /login. Mounted once by AppLayout. Ignores unrelated keys and ignores events that set a new token (a login in another tab shouldn't bounce the current one).

  • Distinct reset password error codes. POST /auth/password-reset/confirm returned a single opaque "Invalid or expired token" for every failure mode, so users couldn't tell whether their link was wrong, already used, or just timed out. Refactored confirm_password_reset to return a PasswordResetOutcome enum (OK / UNKNOWN / USED / EXPIRED). The router maps each non-OK outcome to 400 with a structured detail = {code, message} payload. New i18n keys auth:reset.errors.reset_token_invalid|used|expired in all 5 locales (EN/ES/CA/GL/EU); ResetPasswordPage looks up the code via a small resetErrorMessage helper that falls back to the message or auth:reset.failure if anything's missing.

  • Cases discussion i18n parity (CA/GL/EU). The discussion block in cases.json for the three minority locales only had the 2 confirm-dialog keys; the 6 inline labels (empty, add, edit, delete, save, cancel) were missing, so users in Catalan/Galician/Basque saw raw discussion.add keys in the case comment thread. Backfilled all 6 with native translations to match the EN/ES baseline.

Tests:

  • Backend test_password_reset.py extended: three existing 400 cases now also assert the specific detail.code. 11/11 passing.
  • New useStorageAuthSync.test.jsx covers the three event branches — token removed, unrelated key, token replaced — confirming cache clear + redirect only on the real logout case.
  • ResetPasswordPage.test.jsx parametrized over the three error codes, asserts the localized message lands in the alert.
  • AppLayoutMobile.test.jsx mock for useAuth extended with a useStorageAuthSync stub so the layout still renders under test.

Frontend suite: 375 passing. Backend: 894.

@jamofer jamofer merged commit a8c22e0 into master May 24, 2026
5 checks passed
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