Fix setup/loading flow and WebSocket connection
1. Setup redirect flow (setup -> loading -> login): - Add /loading to exempt paths - Redirect setup to login after completion - Redirect loading to login when initialization complete 2. Close pages after completion: - Block access to /setup after setup is done - Block access to /loading after initialization complete - Proper redirect handling prevents re-access 3. Fix WebSocket 403 error: - Change /ws/progress to /ws/connect (correct endpoint) - Add /ws/connect to exempt paths - Subscribe to 'system' room for progress updates - Fix message data handling format
This commit is contained in:
@@ -32,9 +32,11 @@ class SetupRedirectMiddleware(BaseHTTPMiddleware):
|
|||||||
# Paths that should always be accessible, even without setup
|
# Paths that should always be accessible, even without setup
|
||||||
EXEMPT_PATHS = {
|
EXEMPT_PATHS = {
|
||||||
"/setup", # Setup page itself
|
"/setup", # Setup page itself
|
||||||
|
"/loading", # Loading page (initialization progress)
|
||||||
"/login", # Login page (needs to be accessible after setup)
|
"/login", # Login page (needs to be accessible after setup)
|
||||||
"/queue", # Queue page (for initial load)
|
"/queue", # Queue page (for initial load)
|
||||||
"/api/auth/", # All auth endpoints (setup, login, logout, register)
|
"/api/auth/", # All auth endpoints (setup, login, logout, register)
|
||||||
|
"/ws/connect", # WebSocket connection (needed for loading page)
|
||||||
"/api/queue/", # Queue API endpoints
|
"/api/queue/", # Queue API endpoints
|
||||||
"/api/downloads/", # Download API endpoints
|
"/api/downloads/", # Download API endpoints
|
||||||
"/api/config/", # Config API (needed for setup and management)
|
"/api/config/", # Config API (needed for setup and management)
|
||||||
@@ -115,6 +117,29 @@ class SetupRedirectMiddleware(BaseHTTPMiddleware):
|
|||||||
"""
|
"""
|
||||||
path = request.url.path
|
path = request.url.path
|
||||||
|
|
||||||
|
# Check if trying to access setup or loading page after completion
|
||||||
|
if path in ("/setup", "/loading"):
|
||||||
|
if not self._needs_setup():
|
||||||
|
# Setup is complete, check loading status
|
||||||
|
if path == "/setup":
|
||||||
|
# Redirect to loading if initialization is in progress
|
||||||
|
# Otherwise redirect to login
|
||||||
|
return RedirectResponse(url="/login", status_code=302)
|
||||||
|
elif path == "/loading":
|
||||||
|
# Check if initialization is complete
|
||||||
|
try:
|
||||||
|
from src.server.database.connection import get_db_session
|
||||||
|
from src.server.database.system_settings_service import SystemSettingsService
|
||||||
|
|
||||||
|
async with get_db_session() as db:
|
||||||
|
is_complete = await SystemSettingsService.is_initial_scan_completed(db)
|
||||||
|
if is_complete:
|
||||||
|
# Initialization complete, redirect to login
|
||||||
|
return RedirectResponse(url="/login", status_code=302)
|
||||||
|
except Exception:
|
||||||
|
# If we can't check, allow access to loading page
|
||||||
|
pass
|
||||||
|
|
||||||
# Skip setup check for exempt paths
|
# Skip setup check for exempt paths
|
||||||
if self._is_path_exempt(path):
|
if self._is_path_exempt(path):
|
||||||
return await call_next(request)
|
return await call_next(request)
|
||||||
|
|||||||
@@ -294,13 +294,19 @@
|
|||||||
|
|
||||||
function connectWebSocket() {
|
function connectWebSocket() {
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
const wsUrl = `${protocol}//${window.location.host}/ws/progress`;
|
const wsUrl = `${protocol}//${window.location.host}/ws/connect`;
|
||||||
|
|
||||||
ws = new WebSocket(wsUrl);
|
ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log('WebSocket connected');
|
console.log('WebSocket connected');
|
||||||
updateConnectionStatus(true);
|
updateConnectionStatus(true);
|
||||||
|
|
||||||
|
// Subscribe to system room for progress updates
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
action: 'join',
|
||||||
|
room: 'system'
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
@@ -340,8 +346,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleProgressUpdate(data) {
|
function handleProgressUpdate(message) {
|
||||||
const { type, status, title, message, percent, current, total, metadata } = data;
|
// Handle WebSocket message format: { type: string, data: {...} }
|
||||||
|
const data = message.data || message;
|
||||||
|
const { type, status, title, message: msg, percent, current, total, metadata } = data;
|
||||||
|
|
||||||
// Determine step ID based on type and metadata
|
// Determine step ID based on type and metadata
|
||||||
let stepId = metadata?.step_id || type;
|
let stepId = metadata?.step_id || type;
|
||||||
@@ -351,7 +359,7 @@
|
|||||||
createStep(stepId, title || stepTitles[stepId] || stepId);
|
createStep(stepId, title || stepTitles[stepId] || stepId);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStep(stepId, status, message, percent, current, total);
|
updateStep(stepId, status, msg, percent, current, total);
|
||||||
|
|
||||||
// Check for completion
|
// Check for completion
|
||||||
if (metadata?.initialization_complete) {
|
if (metadata?.initialization_complete) {
|
||||||
@@ -360,7 +368,7 @@
|
|||||||
|
|
||||||
// Handle errors
|
// Handle errors
|
||||||
if (status === 'failed') {
|
if (status === 'failed') {
|
||||||
showError(message || 'An error occurred during initialization');
|
showError(msg || 'An error occurred during initialization');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +482,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function continueToApp() {
|
function continueToApp() {
|
||||||
window.location.href = '/';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start WebSocket connection when page loads
|
// Start WebSocket connection when page loads
|
||||||
|
|||||||
Reference in New Issue
Block a user