6.8 KiB
Setup Wizard
Status: ✅ Implemented
9-step wizard for first-time configuration with connection testing, validation, database persistence, BookDate AI setup, and automated initial job execution.
Features
- 9 steps with progress indicator
- Connection testing for Plex, Prowlarr, qBittorrent
- Path validation with write permission checking
- Automated initial jobs (Audible refresh, Plex scan)
- Auto-enabling of scheduled jobs
- Dark mode support
Steps
- Welcome - Intro screen
- Admin Account - Create admin user
- Plex - Server URL, OAuth, library selection
- Prowlarr - URL, API key, indexer selection with priorities (1-25), seeding time, RSS monitoring
- Download Client - qBittorrent/Transmission config
- Paths - Download + media directories with validation
- BookDate - AI-powered recommendations config (OpenAI/Claude, optional)
- Review - Summary of all configs
- Finalize - Run initial Audible refresh + Plex scan, enable scheduled jobs
API Endpoints
POST /api/setup/test-plex
- Tests Plex connection, returns libraries if successful
POST /api/setup/test-prowlarr
- Tests connection, returns indexer details (id, name, protocol)
- User selects indexers and assigns priorities
POST /api/setup/test-download-client
- Tests qBittorrent/Transmission, returns client version
POST /api/setup/complete
- Saves all config to database
- Creates admin user account
- Enables auto jobs (Plex scan, Audible refresh)
- Marks setup as complete
- Returns JWT tokens for auto-login
State Interface
interface SetupState {
currentStep: number;
plexUrl: string;
plexToken: string;
plexLibraryId: string;
prowlarrUrl: string;
prowlarrApiKey: string;
prowlarrIndexers: Array<{id: number, name: string, priority: number, seedingTimeMinutes: number, rssEnabled: boolean}>;
downloadClient: 'qbittorrent' | 'transmission';
downloadClientUrl: string;
downloadClientUsername: string;
downloadClientPassword: string;
downloadDir: string;
mediaDir: string;
validated: {plex: boolean, prowlarr: boolean, downloadClient: boolean, paths: boolean};
}
Validation
Plex: Valid URL, non-empty token, connection succeeds, library available Prowlarr: Valid URL, non-empty API key, connection succeeds, ≥1 indexer selected with priority 1-25, seedingTimeMinutes ≥0, rssEnabled boolean (RSS timing defaults to 15min, configurable in scheduled jobs) Download Client: Valid URL, credentials required, connection succeeds Paths: Absolute paths, writable
OIDC-Only Setup Flow
When using OIDC authentication without creating a local admin:
- Setup wizard completes without creating admin user
- FinalizeStep detects no access token (OIDC-only mode)
- Shows message: jobs will run on first login
- User completes setup → redirected to /login
- User logs in via OIDC → first user becomes admin
- Initial jobs (Audible refresh + Library scan) trigger automatically in background
- User redirected to /setup/initializing page → shows real-time job progress
- Jobs complete → user clicks "Go to Homepage" → fully initialized app
User Experience:
- FinalizeStep: Clear instructions about first login
- First OIDC login: Automatic redirect to initializing page
- Initializing page: Real-time job status with progress indicators
- Subsequent logins: Normal login flow (no initializing page)
Implementation:
setup/page.tsx: PasseshasAdminTokensprop to FinalizeStep, clears localStorage to remove stale tokensFinalizeStep.tsx: Uses prop (not localStorage) to detect mode, shows appropriate UIOIDCAuthProvider.ts:- Triggers initial jobs on first user creation
- Returns
isFirstLogin: trueflag in AuthResult
api/auth/oidc/callback/route.ts:- Checks
isFirstLoginflag - Redirects to
/setup/initializingfor first login - Normal redirect for subsequent logins
- Checks
setup/initializing/page.tsx:- Reads auth data from URL hash
- Polls job status every 2s
- Shows real-time progress
- Auto-enables "Go to Homepage" when complete
system.initial_jobs_runconfig flag prevents duplicate runs
Fixed Issues ✅
1. Plex Server Info Parsing
- Issue: "Connected to undefined undefined"
- Cause: XML parsing not extracting
MediaContainer.$attributes - Fix: Proper XML attribute parsing with fallbacks
2. Auth Requirement
- Issue: Setup completion endpoint required auth before user login
- Fix: Removed auth requirement from
/api/setup/complete
3. Plex Token Hint
- Issue: Incorrect path shown for finding token
- Fix: Link to official Plex documentation
4. Prowlarr Indexer Selection
- Feature: Added UI for selecting indexers with priorities (1-25)
- Auto-selects all with default priority 10
- Saves to database as JSON
5. Initial Job Execution
- Feature: Added FinalizeStep (step 9)
- Normal mode (with admin): Runs jobs during setup
- OIDC-only mode: Jobs run on first OIDC login
- Polls job status every 2s until actual completion
- Shows real-time execution status (pending → running → completed/failed)
- Prevents navigation until all jobs complete
- Uses
/api/admin/job-status/:idendpoint for status polling
6. OIDC-Only Setup Support
- Issue: Initial jobs failed with "Authentication required" or "Failed to fetch job configuration"
- Root causes:
- No admin user created during setup (OIDC-only), no auth token available
- Stale tokens in localStorage from previous tests caused false-positive detection
- Fix: Proper architectural solution
- Setup wizard passes
hasAdminTokensprop to FinalizeStep (explicit mode detection) - Setup wizard clears localStorage before storing new tokens (removes stale data)
- FinalizeStep uses prop instead of checking localStorage (avoids stale token issues)
- OIDC-only mode redirects to /login after setup completion
- Setup wizard passes
- Jobs automatically trigger on first OIDC login (first user becomes admin)
- Background execution doesn't block authentication flow
7. Initializing Page Job Detection
- Issue: "Job did not start" error on initializing page while jobs running
- Root cause:
lastRunJobIdfield missing from ScheduledJob schematriggerJobNow()returned Bull job ID but never stored it- Initializing page couldn't find running jobs
- Fix: Database schema update + scheduler service update
- Added
lastRunJobIdfield to ScheduledJob model - Updated
triggerJobNow()to store Bull job ID in database - Migration:
20251221072639_add_last_run_job_id_to_scheduled_jobs
- Added
- Initializing page now successfully finds and polls running jobs
Related Files
/src/app/setup/- Wizard components/src/app/setup/initializing/- First login initialization page (OIDC-only)/src/app/api/setup/- API routes/src/lib/services/auth/OIDCAuthProvider.ts- OIDC auth + first login detection/src/lib/services/auth/IAuthProvider.ts- Auth interfaces (includes isFirstLogin flag)