Bug: opening calendar in a new browser tab forced a re-login every time,
even when the user was authenticated in another tab.
Root cause: tokenSet/userData/redirectState were stored in sessionStorage,
which is per-tab by design. New tab → empty sessionStorage → app
redirects to OIDC. With Dex's password-DB connector (no IdP-side session
cookie), Dex re-prompts for credentials.
Mail (tmail-flutter) has the same OIDC flow but persists tokens in
IndexedDB (Hive box `tokenoidccache`) which IS shared across tabs —
hence mail SSO worked but calendar didn't.
Fix: replace sessionStorage with localStorage for the auth-related keys
(tokenSet, userData, redirectState). localStorage is shared across tabs
of the same origin. Other sessionStorage usages (e.g. eventUpdateModalReopen)
are unchanged — they are genuinely per-tab.
Files touched:
- src/features/User/useInitializeApp.ts (load + setup redirect state)
- src/features/User/LoginCallback.tsx (save tokens after callback,
read pending redirectState, removeItem on completion)
- src/utils/apiUtils.ts (write redirectState during 401-driven SSO redirect)
- src/components/Calendar/hooks/useUtilMenus.ts (logout cleanup)
Verified: open clean tab → login alice → open another tab on
calendar.workavia.local → loaded silently with avatar visible, no
login form prompted.
On hard reload, useCalendarLoader dispatches getCalendarDetailAsync(calId)
for selected calendars (cached in localStorage) BEFORE getCalendarsListAsync
has fulfilled. The detail thunk sees an empty state.calendars.list and
rejects with "Calendar X not found in store". The reject handler then sets
state.calendars.error, and HandleLogin redirects to /error.
Result: ~50% of reloads land on /error.
Treat this specific race-condition error like AbortError: ignore it. The
detail fetch is naturally re-issued by useCalendarLoader once the list is
loaded, so no functional regression.
- src/static/header-logo.svg: rebuild with SVG <text> "Workavia" (black) +
"Calendar" (orange gradient), keeping the original calendar icon
Style matches Workavia Mail logo (brand name in black, app suffix in color)
- src/static/twake-workplace.svg: simplify to centered "Workavia" text
- Loading.tsx alt: "twake workplace" -> "Workavia"