feat: Add optional web interface authentication with session management
Local Docker Build (Dev) / build-dev (pull_request) Successful in 3s
Local Docker Build (Dev) / build-dev (pull_request) Successful in 3s
Authentication Features: - Optional HTTP Basic Auth with session cookies for web interface protection - Configurable username/password with session timeout (default: 1 hour) - Selective route protection (web interface protected, webhooks/APIs remain public) - Authentication status display with logout functionality in web UI - Session cleanup and graceful logout with browser re-authentication prompt Configuration: - WEB_AUTH_ENABLED in .env (default: false - no breaking changes) - WEB_AUTH_USERNAME/WEB_AUTH_PASSWORD in .env.secrets - WEB_AUTH_SESSION_TIMEOUT configurable (5min-24h range) Development Tools: - Added debug_tv.py for TV series/episode debugging (series, season, episode levels) - Comprehensive episode data inspection with validation and sources breakdown - Complements existing debug_movie.py for complete media debugging coverage Technical Implementation: - SimpleAuthMiddleware with FastAPI integration - Session management with automatic cleanup - Authentication status API endpoints - Responsive CSS styling for auth UI elements - JavaScript functions for auth checking and logout
This commit is contained in:
@@ -10,6 +10,7 @@ let dashboardData = null;
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initializeTabs();
|
||||
initializeEventListeners();
|
||||
checkAuthStatus(); // Check authentication status on page load
|
||||
loadDashboard();
|
||||
loadSeriesSources();
|
||||
});
|
||||
@@ -1375,4 +1376,62 @@ function updateEpisodeModalCounts() {
|
||||
${videoCountText}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================
|
||||
// Authentication Functions
|
||||
// ===========================
|
||||
|
||||
async function checkAuthStatus() {
|
||||
try {
|
||||
const response = await fetch('/api/auth/status');
|
||||
const authStatus = await response.json();
|
||||
|
||||
const authStatusDiv = document.getElementById('auth-status');
|
||||
const authUsernameSpan = document.getElementById('auth-username');
|
||||
|
||||
if (authStatus.auth_enabled && authStatus.authenticated) {
|
||||
// Show authentication status with username
|
||||
authUsernameSpan.textContent = authStatus.username;
|
||||
authStatusDiv.style.display = 'flex';
|
||||
} else if (authStatus.auth_enabled && !authStatus.authenticated) {
|
||||
// This shouldn't happen if middleware is working, but handle it
|
||||
console.warn('Auth enabled but not authenticated - middleware may be misconfigured');
|
||||
} else {
|
||||
// Authentication disabled - hide auth status
|
||||
authStatusDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to check authentication status:', error);
|
||||
// Hide auth status on error
|
||||
document.getElementById('auth-status').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
if (!confirm('Are you sure you want to logout?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/auth/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
showToast('✅ Logged out successfully', 'success');
|
||||
// Reload page to trigger authentication prompt
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1500);
|
||||
} else {
|
||||
showToast('❌ Logout failed', 'error');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Logout failed:', error);
|
||||
showToast('❌ Logout error', 'error');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user