Files
ohm_streaming/static/js/auth.js
T
root d4d8d8a3b6
CI / Test (Python 3.11) (push) Has been cancelled
CI / Test (Python 3.12) (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Type Check (push) Has been cancelled
CI / Summary (push) Has been cancelled
refactor: migrate main.py to modular routers and add project roadmap
- Migrated monolithic main.py to feature-scoped routers in app/routers/
- Added GEMINI.md for project context and AI instructional guidelines
- Updated README.md with a comprehensive modernization plan (SQL migration, robust scraping DSL, frontend modernization)
- Improved authentication with cookie support and modular JS
- Updated test suite and documentation
2026-03-24 10:12:04 +00:00

209 lines
5.9 KiB
JavaScript

/**
* 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();
});