diff --git a/Docs/NAVIGATION.md b/Docs/NAVIGATION.md index a5b36fd..5de14a1 100644 --- a/Docs/NAVIGATION.md +++ b/Docs/NAVIGATION.md @@ -108,6 +108,7 @@ The middleware checks the current state and redirects accordingly: | Flag | Purpose | |------|---------| | `setup_complete` | Initial configuration was saved | +| `loading_started` | Loading phase has been initiated (redirected to /loading) | | `unresolved_completed` | User clicked "Done" on unresolved page | | `loading_complete` | Series scan + initial loading finished | | `nfo_scan_complete` | Final NFO scan finished | diff --git a/Docs/key b/Docs/key index 7a20a0d..02edff4 100644 --- a/Docs/key +++ b/Docs/key @@ -1,3 +1,7 @@ API key : 299ae8f630a31bda814263c551361448 9bc3e547caff878615cbdba2cc421d37 +/setup + + +SeriesApp initialized for directory: \ No newline at end of file diff --git a/src/server/api/auth.py b/src/server/api/auth.py index 31d7f1c..ade72b5 100644 --- a/src/server/api/auth.py +++ b/src/server/api/auth.py @@ -117,6 +117,10 @@ async def setup_auth(req: SetupRequest): # Store master password hash in config's other field config.other['master_password_hash'] = password_hash + # Mark that loading has been initiated (used by middleware to prevent + # premature redirect to /login after setup) + config.other['loading_started'] = True + # Store anime directory in config's other field if provided anime_directory = None if req.anime_directory: diff --git a/src/server/middleware/setup_redirect.py b/src/server/middleware/setup_redirect.py index 51dab03..45e570c 100644 --- a/src/server/middleware/setup_redirect.py +++ b/src/server/middleware/setup_redirect.py @@ -118,6 +118,20 @@ class SetupRedirectMiddleware(BaseHTTPMiddleware): return bool(other.get('unresolved_completed', False)) except Exception: return False + + def _is_loading_complete(self) -> bool: + """Check if initial loading has completed. + + Returns: + True if loading is complete, False otherwise + """ + try: + config_service = get_config_service() + config = config_service.load_config() + other = config.other or {} + return bool(other.get('loading_complete', False)) + except Exception: + return False async def dispatch( self, request: Request, call_next: Callable @@ -149,14 +163,17 @@ class SetupRedirectMiddleware(BaseHTTPMiddleware): # Handle phase query parameter phase = query_params.get("phase") if phase == "initial": - # phase=initial should not be accessed after setup is complete - # Redirect to login - return RedirectResponse(url="/login", status_code=302) + # Only redirect if loading has actually completed + # If loading_started=True but loading_complete=False, user should stay + # on loading page to see progress + if self._is_loading_complete(): + return RedirectResponse(url="/login", status_code=302) + # Otherwise, allow access to loading page (loading in progress) elif not phase: - # No phase specified and setup is complete - # Redirect to login since user should be further in the flow - return RedirectResponse(url="/login", status_code=302) - # phase=nfo is allowed - it triggers the NFO scan phase + # No phase specified and loading is complete + if self._is_loading_complete(): + return RedirectResponse(url="/login", status_code=302) + # phase=nfo is always allowed - it triggers the NFO scan phase # Skip setup check for exempt paths if self._is_path_exempt(path): diff --git a/src/server/services/initialization_service.py b/src/server/services/initialization_service.py index 225c4d5..5bb1fd8 100644 --- a/src/server/services/initialization_service.py +++ b/src/server/services/initialization_service.py @@ -383,6 +383,16 @@ async def perform_initial_setup(progress_service=None): # Mark the initial scan as completed await _mark_initial_scan_completed() + # Mark loading as complete in config (used by middleware to allow redirect to /login) + try: + from src.server.services.config_service import get_config_service + config_svc = get_config_service() + init_config = config_svc.load_config() + init_config.other['loading_complete'] = True + config_svc.save_config(init_config, create_backup=False) + except Exception as e: + logger.warning("Failed to save loading_complete flag: %s", e) + # Load series into memory from database await _load_series_into_memory(progress_service)