Previously, when a user changed the download_dir setting after initial
setup, the qBittorrent category "readmeabook" would retain the old save
path. This could cause torrents to download to the wrong location,
depending on qBittorrent's Automatic Torrent Management (ATM) settings.
Root cause:
- ensureCategory() only created the category if it didn't exist
- createCategory API is idempotent but doesn't update existing categories
- If download_dir changed from /downloads to /downloads/RMAB, category
would still have savePath=/downloads
qBittorrent behavior:
- If ATM enabled: category savePath overrides per-torrent savepath
- If ATM disabled: per-torrent savepath takes precedence
Fix:
- ensureCategory() now calls both createCategory AND editCategory
- createCategory: ensures category exists (idempotent)
- editCategory: updates save path to match current download_dir config
- This guarantees category path is always synced with database config
Benefits:
- Users can change download_dir setting and it takes effect immediately
- Works regardless of ATM settings in qBittorrent
- No manual qBittorrent category management needed
Updated documentation/phase3/qbittorrent.md to explain category
management and save path synchronization.
Previously, files were always being copied to /media/audiobooks regardless
of the configured media directory in settings. This was caused by:
1. FileOrganizer singleton reading from MEDIA_DIR env var (never set)
instead of database config 'media_dir'
2. Hardcoded /media/audiobooks fallback being used when env var not found
3. Three locations passing hardcoded paths to addOrganizeJob (unused)
Changes:
- Modified getFileOrganizer() to read media_dir from database config
- Made targetPath parameter optional in addOrganizeJob (not used by processor)
- Removed hardcoded /media/audiobooks paths from all addOrganizeJob calls
- Updated organize-files processor to await getFileOrganizer()
- Updated documentation to reflect configuration behavior
Files now correctly copy to the directory configured in setup wizard or
settings page, with /media/audiobooks only as fallback if not configured.
Fixes: User-reported issue where configured media directory was ignored
**Problem:** Prowlarr searches were querying ALL indexers instead of only
the ones enabled in user settings, causing torrents to be selected from
disabled/untrusted indexers.
**Root Cause:** The prowlarr.search() method didn't filter by indexer IDs,
and callers weren't passing enabled indexer IDs to the search.
**Changes:**
1. Added indexerIds parameter to SearchFilters interface
2. Updated prowlarr.service.ts search() to filter by indexerIds
3. Updated search-indexers.processor.ts to fetch and pass enabled indexer IDs
4. Updated interactive-search route to fetch and pass enabled indexer IDs
5. Added validation: search fails if no indexers are configured/enabled
6. Updated documentation to reflect indexer filtering behavior
**Impact:**
- Manual search: Only searches enabled indexers
- Interactive search: Only searches enabled indexers
- RSS monitoring: Already correctly filtered (no changes needed)
**Testing:** TypeScript type checking passed with no errors
Added /cache, /redis, and /pgdata to .gitignore to prevent committing local data directories. Updated the admin settings API to also mask values for keys containing 'secret' in addition to other sensitive keys.
Allow first user to bypass admin approval requirement when using
'admin_approval' access control method. The first user is auto-approved
and becomes admin, avoiding the situation where there's no admin to
approve the first user.
**Before:** First user gets stuck in pending_approval state
**After:** First user bypasses approval and becomes admin automatically
Subsequent users still require admin approval as expected.
Extract error messages from URL query parameters and display them
in the existing error box on the login page, then clean up the URL.
This fixes the UX issue where OIDC access denied errors were only
visible in the URL bar as query parameters.
Implements full OIDC configuration UI and backend support for access control and admin permissions.
**Access Control Features:**
- Open access (anyone can log in)
- Group/claim based access (require specific group membership)
- Allowed list (whitelist specific emails/usernames)
- Admin approval (manual approval required for new users)
**Admin Role Mapping:**
- Automatic admin role assignment based on OIDC claims
- Configurable claim name and value (default: groups claim)
- First user always becomes admin
- Dynamic role updates on each login
**Setup Wizard:**
- Updated OIDCConfigStep with comprehensive OIDC settings
- Access control method selector with conditional fields
- Admin role mapping configuration with examples
- Improved UX with clear sections and helpful descriptions
**Admin Settings:**
- Expanded OIDC section with all new configuration options
- Proper JSON array handling for allowed emails/usernames
- Visual organization matching setup wizard
**Backend:**
- Updated setup complete API to persist new OIDC fields
- Updated OIDC settings API for all new configuration
- Updated settings GET endpoint to return new fields with defaults
- Proper comma-separated to JSON array conversion
**Documentation:**
- Comprehensive OIDC section in auth.md
- Configuration examples and use cases
- Clear distinction between access control and admin roles
- Default values documented
All changes tested and ready for production use.