/** * Authentication management for web interface */ // Use relative path for API const AUTH_API_BASE = '/api'; const COOKIE_NAME = 'auth_token'; const COOKIE_MAX_AGE = 60 * 60 * 24 * 7; // 7 days /** * Set token in HTTP-only cookie (via server) * Since we can't set HttpOnly cookies from JavaScript, we store in localStorage * but also try to set a non-HttpOnly cookie for compatibility */ function setToken(token) { // Store in localStorage as primary (for backward compatibility) localStorage.setItem('auth_token', token); // Also try to set cookie (non-HttpOnly, but better than nothing) // Note: HttpOnly must be set by server, this is a fallback const expires = new Date(); expires.setTime(expires.getTime() + COOKIE_MAX_AGE * 1000); document.cookie = `${COOKIE_NAME}=${token};expires=${expires.toUTCString()};path=/;SameSite=Strict`; } /** * Get token from cookie first, then fallback to localStorage */ function getToken() { // Try cookie first const cookieToken = getTokenFromCookie(); if (cookieToken) { return cookieToken; } // Fallback to localStorage return localStorage.getItem('auth_token'); } /** * Get token from cookie */ function getTokenFromCookie() { const name = COOKIE_NAME + '='; const decodedCookie = decodeURIComponent(document.cookie); const cookieArray = decodedCookie.split(';'); for (let i = 0; i < cookieArray.length; i++) { let cookie = cookieArray[i]; while (cookie.charAt(0) === ' ') { cookie = cookie.substring(1); } if (cookie.indexOf(name) === 0) { return cookie.substring(name.length, cookie.length); } } return null; } /** * Remove token from cookie and localStorage */ function removeToken() { // Remove from localStorage localStorage.removeItem('auth_token'); localStorage.removeItem('user'); // Remove cookie document.cookie = `${COOKIE_NAME}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;`; } // Check if user is authenticated async function checkAuth() { const token = getToken(); const userStr = localStorage.getItem('user'); if (!token) { // Redirect to login page instead of just showing prompt redirectToLogin(); return false; } // Verify token with server try { const response = await fetch(`${AUTH_API_BASE}/auth/me`, { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); showUserInfo(data.user); showMainContent(); return true; } else { // Token invalid, remove it and redirect removeToken(); redirectToLogin(); return false; } } catch (error) { console.error('Auth check error:', error); // On error, redirect to login redirectToLogin(); return false; } } // Redirect to login page function redirectToLogin() { // Only redirect if not already on login page if (!window.location.pathname.includes('/login')) { window.location.href = '/login'; } } // Show user info when authenticated function showUserInfo(user) { const userInfo = document.getElementById('userInfo'); const loginPrompt = document.getElementById('loginPrompt'); const mainTabs = document.getElementById('mainTabs'); const currentUser = document.getElementById('currentUser'); if (userInfo) userInfo.style.display = 'flex'; if (loginPrompt) loginPrompt.style.display = 'none'; if (mainTabs) mainTabs.style.visibility = 'visible'; if (currentUser) currentUser.textContent = user.full_name || user.username; } // Show main content (only when authenticated) function showMainContent() { const mainContent = document.getElementById('main-content'); if (mainContent) mainContent.style.display = 'block'; } // Hide main content (when not authenticated) function hideMainContent() { const mainContent = document.getElementById('main-content'); if (mainContent) mainContent.style.display = 'none'; } // Show login prompt when not authenticated (not used anymore - we redirect instead) function showLoginPrompt() { const userInfo = document.getElementById('userInfo'); const loginPrompt = document.getElementById('loginPrompt'); const mainTabs = document.getElementById('mainTabs'); if (userInfo) userInfo.style.display = 'none'; if (loginPrompt) loginPrompt.style.display = 'block'; if (mainTabs) mainTabs.style.visibility = 'hidden'; // Hide main content hideMainContent(); } // Handle logout async function handleLogout() { if (!confirm('Êtes-vous sûr de vouloir vous déconnecter?')) { return; } // Remove token from localStorage and cookie removeToken(); // Call logout endpoint try { await fetch(`${AUTH_API_BASE}/auth/logout`, { method: 'POST' }); } catch (error) { console.error('Logout error:', error); } // Redirect to login page window.location.href = '/login'; } // Add authorization header to all fetch requests function addAuthHeader(options = {}) { const token = getToken(); if (token) { options.headers = options.headers || {}; options.headers['Authorization'] = `Bearer ${token}`; } return options; } // Wrapper for fetch with auth async function authFetch(url, options = {}) { options = addAuthHeader(options); return fetch(url, options); } // Make functions available globally window.checkAuth = checkAuth; window.showUserInfo = showUserInfo; window.showLoginPrompt = showLoginPrompt; window.handleLogout = handleLogout; window.authFetch = authFetch; window.addAuthHeader = addAuthHeader; window.getToken = getToken; window.setToken = setToken; window.removeToken = removeToken; // Check authentication on page load document.addEventListener('DOMContentLoaded', () => { checkAuth(); });