qualora / static /js /auth-init.js
Pratham Amritkar
final
d833ce9
Raw
History Blame Contribute Delete
4.52 kB
/**
* auth-init.js β€” Enterprise Authentication Initialization
* * Runs on page load to establish UI auth state and protect routes.
* Strictly aligned with HTTP-Only Cookie architecture.
*/
(function initAuthState() {
'use strict';
const currentPath = window.location.pathname;
// ── 1. Check if user just logged in ──────────────────────────────────────
const justLoggedIn = sessionStorage.getItem('just_logged_in');
if (justLoggedIn) sessionStorage.removeItem('just_logged_in');
// ── 2. Sync User Metadata ────────────────────────────────────────────────
// We treat the 'user' object in localStorage as our UI "Auth Hint".
// The actual security is handled by the invisible HTTP-Only access_token cookie.
// Cookie Sync: Check for the 'qualora_logged_in' mirror cookie.
// This allows JS to see if the server thinks we are authenticated (breaks 302 loops).
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
return null;
}
const isLoggedIn = getCookie('qualora_logged_in') === 'true';
let userJSON = localStorage.getItem('user');
// Fallback to session if local is empty (e.g., privacy mode)
if (!userJSON) {
userJSON = sessionStorage.getItem('user');
if (userJSON) localStorage.setItem('user', userJSON);
}
let user = null;
if (userJSON) {
try {
// If the mirror cookie is missing, the server session is gone.
// We MUST purge the local 'Auth Hint' to prevent redirect loops.
if (!isLoggedIn && !justLoggedIn) {
localStorage.removeItem('user');
sessionStorage.removeItem('user');
userJSON = null;
} else {
user = JSON.parse(userJSON);
// Validation: Ensure it's a real user object
if (!user || (!user.email && !user._id)) {
user = null;
localStorage.removeItem('user');
}
}
} catch (e) {
console.warn('[Qualora] Failed to parse user metadata:', e.message);
localStorage.removeItem('user');
}
}
// ── 3. Route Guarding ────────────────────────────────────────────────────
// List of routes that require an authenticated session
const protectedRoutes = ['/dashboard', '/audit', '/admin', '/knowledge-base', '/agents'];
const isProtectedRoute = protectedRoutes.some(route => currentPath.startsWith(route));
if (isProtectedRoute && !user) {
// Race condition check: If we just logged in, allow temporary pass-through
if (justLoggedIn) {
user = { _id: 'loading', email: 'loading...', temp: true };
} else {
console.warn('[Qualora] Unauthorized access attempt. Redirecting to landing.');
window.location.href = '/';
return;
}
}
// ── 4. Landing Page Logic ────────────────────────────────────────────────
// If authenticated and sitting on landing page, move to dashboard
if ((currentPath === '/' || currentPath === '/index.html') && user && !user.temp) {
window.location.href = '/dashboard';
return;
}
// ── 5. Establish Global Auth Context ─────────────────────────────────────
// NOTE: 'token' is now null because it is hidden in an HTTP-Only cookie.
window.__authState = {
isAuthenticated: !!user && !user.temp,
user: user,
cookieManaged: true, // Internal flag for fetch-wrapper
lastChecked: new Date().toISOString()
};
// Notify other modules (like nav-controllers) that auth state is ready
document.dispatchEvent(new CustomEvent('authStateReady', {
detail: window.__authState
}));
console.log(`[Qualora] Auth initialized. Mode: ${user ? 'Authenticated' : 'Guest'}`);
})();