- Refactor auth init: initialize MSAL before React mounts so MsalProvider
handles handleRedirectPromise exactly once (no double-calls, no stale locks)
- Simplify AuthGuard to pure AuthenticatedTemplate/UnauthenticatedTemplate
- Remove trailing slash from redirect URI to match Azure AD registration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Clear stale interaction.status key from localStorage before MSAL
initializes. A failed or interrupted loginRedirect leaves this lock
set, blocking all subsequent auth calls with interaction_in_progress.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Purge stale msal.* keys from sessionStorage before MSAL initializes.
When cache location was switched from sessionStorage to localStorage,
leftover MSAL entries caused Storage.key(i) to return null during
createKeyMaps iteration, crashing isCredentialKey with TypeError.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch MSAL cache to localStorage + cookie fallback to fix AADSTS90014 (PKCE state lost on redirect)
- Fix base path and redirect URI to use correct case: lusa-Back-Planner
- Add deploy.sh for server-side build and deploy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MSAL SPA redirect flow with Azure AD authentication
- AuthGuard wrapper with auto-redirect for unauthenticated users
- Navbar shows logged-in user name and sign out button
- Vite base path set to /lusa-back-planner/ for subdirectory hosting
- Apache config for SPA fallback routing
- Environment variables for Azure AD tenant/client/redirect
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>