Skip to content

Prowlarr Import, Auto Imports, QB Category Filtering, Hardlinking#341

Merged
therobbiedavis merged 53 commits intocanaryfrom
feature/prowlarr-integration
Feb 19, 2026
Merged

Prowlarr Import, Auto Imports, QB Category Filtering, Hardlinking#341
therobbiedavis merged 53 commits intocanaryfrom
feature/prowlarr-integration

Conversation

@therobbiedavis
Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis commented Feb 18, 2026

Added

  • Prowlarr-compatible API endpoints for indexer import, supporting varied payloads and deduplication.
  • Hardlinking with fallback to copying. (Closes [Feature Request] Hardlinking #211, Closes [Feature Request] Add support for hardlinking books #190)
  • Indexer import broadcasts updates and notifications, with persistent notifications via SignalR.
  • Calendar view for upcoming releases.
  • Custom paths. (Closes [Feature Request] Allow customization of book folder name #218, Closes [Feature Request] Update Audiobook Root Path #217)
  • Job reset logic and stability window handling for auto-import of completed downloads.
  • Enhanced Transmission/qBittorrent adapter authentication and session management.
  • Indexer search from the Audiobook Details view.
  • Download client test endpoints now use current form values.
  • Root folder system with full CRUD, selection, and migration from legacy output paths.
  • Loading indicators and improved UI feedback for all settings tabs.
  • General Settings API key input with better controls and accessibility.
  • Toast suppression (global and per-indexer) to reduce notification noise.
  • Database migrations for ExtractArchives, author ASINs, and quality profile minimum score.
  • Sidebar navigation and sub-navigation for grouping audiobooks by books, authors, or series.
  • AdvancedSearchModal with ASIN, author, title, and series search prefixes.
  • Download status indicators and animations for active downloads in the wanted view.
  • Pinia store improvements for accurate, reactive UI updates.
  • Quality profiles support a minimum score threshold.
  • Download clients can be enabled/disabled directly from the settings view.
  • Native browser lazy loading for all images, with fallback and placeholder system.
  • Author ASIN support for image lookup.
  • Unit/integration tests for new features and bugfixes.
  • Updated frontend and backend dependencies, regenerated lockfiles.

Fixed

Changed

  • Standardized and cleaned up console logging across the application.
  • Standardized and consolidated reusable styles.
  • Folders are now only created at time of import. (Fixes Newly added books cause directories to be eagerly created in root directory #302)
  • More informative logs for background services and download processing.
  • Custom filter modal UI/UX overhaul for clarity and accessibility.
  • Improved fallback and cache logic for author images.
  • Sort dropdown logic and per-group sort state.
  • General Settings API key input layout and controls.
  • All toasts are mirrored as persistent notifications via SignalR.
  • Updated README and in-code comments for new features and troubleshooting.
  • Reduced logging to a rolling 5 files (no max size yet). (Fixes Logs folder taking up tens of gigs #335, Fixes Current instance creates huge log file #283)

Removed

  • Duplicate/early broadcast and toast on the create path in the indexer import flow.
  • Redundant/no-op code (e.g., unnecessary string replacements).
  • Debug console.log statements from production code.

Replaces direct usage of modal body divs with the shared <ModalBody> component across all modal implementations for consistency and maintainability. Updates related imports and adjusts styles to rely on the shared modal stylesheet, removing redundant or conflicting custom modal styles. Also improves the custom path selection UX in EditAudiobookModal and RootFolderSelect, and adds a new test for custom path prefill.
Refactors the settings UI into modular section components (Authentication, File Management, Download, Features, External Requests, Search), adds new CSS for modular styling, and introduces extensive unit tests for each section. Updates test helpers and modal logic for improved reliability. Adds new dependencies for color utilities and CLI tools. Updates App.vue and related components to use CSS variables for branding. Includes a Cypress visual regression test and screenshot for General Settings.
Deleted PR_v0.2.46.md release notes and two temporary Node.js scripts (tmp_check.js, tmp_context.js) used for template and context inspection. Cleans up repository by removing files no longer needed.
Deleted docs/STRUCTURAL_IMPROVEMENTS.md, which contained high-level recommendations for improving code organization, maintainability, and testability in the project.
Restructure frontend UI: move domain-specific components into domain/, consolidate modal pieces under feedback/, and form inputs under form/; add new base UI primitives (ConfigCard, EmptyState, FormField, InfoCard, LoadingState, Pill, ProgressBar, StatusBadge, StatusCard and index). Introduce composables (useFormState, useLoadingState) and centralized design tokens/animations in styles (base.css extended, new animations.css, utilities and components CSS paths), and update main.css imports to the new styles layout. Update App.vue to use the new Pill component for counts and error badges, adjust router-link active class handling and font-weight tweaks, and import updated feedback/confirm components. Update test setup to stub feedback modal components and update many unit tests to match new component paths and APIs. Overall this standardizes UI primitives, cleans legacy badge styles, and updates tests/imports to the new structure.
Update Listenarr.Api.csproj to set Version and AssemblyVersion to 0.2.47. This increments the package and assembly version for the upcoming release.
Ensure test APIs use saved secrets when editing: include the existing client/indexer ID when testing and no password/API key was entered, so the server can merge stored credentials. Update DownloadClientFormModal to show a '(Saved password)' placeholder when editing and no password input. Clarify admin password help text and make its placeholder indicate it updates the password. UI/style tweaks: increase global button radius to 8px, adjust .btn padding, add cursor pointer and maintain button height, raise toast z-index, and add full-width primary button styles on the login view to improve touch/visual consistency.
Add comprehensive unit tests for search UI and formatting/helpers (SearchResultCard, SearchResultActions, SearchResultMetadata, formatting and helper utils) and a new useAdvancedSearch composable. Move/refactor search components into a dedicated search dir and add related assets/icons, styles, and types. Update settings and form components (remove/replace some legacy controls), adjust tests accordingly, and tweak main/styles. Backend/domain/infrastructure updates: add several EF migrations (quality profile custom group names, remove prefer-us flag, add published date to Audiobook), update domain models, controllers and services to match the schema changes, and adjust repository/configuration code for quality profiles.
UI & behavior: add Calendar nav link (with preload) and adjust router. Major refactor of audiobook modals (AddLibraryModal & AudiobookDetailsModal): normalize metadata source names, add Audimeta/Audible/OpenLibrary links, support publishedDate formatting, display series/genres/flags, relabel runtime, improve layout and responsive CSS, and move form bits into shared components. Data handling: sanitize seriesNumber and propagate publishedDate from audimeta mappings. Tests: update SearchResultCard/Actions specs to remove/adjust view-details expectations. Removals: delete ManualImportModal and several feedback/legacy view components. Backend: related updates to search/DTO/service code and quality profile config to support improved metadata handling.
Introduce separate folder, single-file and multi-file naming patterns across the app. Adds UI controls, previews and a pattern-help modal in File Management settings, updates FileManagementSection and SettingsView tests, and adapts ManualImport and AddLibrary flows to respect single vs multi-file naming (including custom root path handling). Includes a comprehensive Cypress E2E suite for pattern selection/validation and import/download scenarios. Backend changes add migrations and service/controller updates to persist/use the new settings, and new/updated API tests cover pattern selection and import integrations. Also includes minor UI/UX fixes and CSS simplifications and small robustness improvements in several components (type-safe event handling, drag reorder safety).
Introduce Hardlink/Copy as a supported file-handling mode across the app and add volume checking to warn about broken hardlinks. Frontend: add Hardlink/Copy option in ManualImportModal and FileManagementSection, update types (ManualImportRequest.inputMode), implement apiService.checkVolume, show a hardlink warning in MoveAudiobookModal with volume check logic and styles, adjust UI/search templates and tests, and add an E2E Cypress spec (hardlink-move-flow.cy.ts) plus test output. Backend: add /api/filesystem/check-volume and VolumeCheckResponse to FileSystemController. Remove legacy Audible/Playwright scraping and related controllers/services/typed clients and clean up DI registrations and csproj compile items. Also add new unit tests for hardlink/file-move flows. These changes enable safer moves by detecting cross-volume moves that would break hardlinks and adjust behavior/UI accordingly.
Introduce Prowlarr indexer import (API + controller) and frontend UI to import indexers from Prowlarr, including API client support and modal in Indexers settings. Add download history/error tracking models, migrations, services, state machine and related repository/service implementations and tests to improve completed-download processing and import blocking. Enhance search/manual-search UX: seeders/leechers columns, formatting tweaks, runtime conversion logic, improved ASIN validation, and integrate Manual Search modal into audiobook views. Use server-provided 'wanted' flag in library views/stores, simplify library sync to trust server data, and apply various styling and accessibility refinements across the frontend.
Implement Sonarr-style failed-download handling across backend and frontend. Backend: add ApplicationSettings support, propagate settings into download polling, detect failed states for qBittorrent/Transmission/SABnzbd/NZBGet, persist client-specific IDs, normalize client state mapping, and add HandleFailedDownloadAsync + GetClientItemId helper to mark failures, record history, remove from client, and optionally auto-search. Frontend: expose settings toggles (Enable Failed Download Handling, Auto-search on Failed Downloads) and update types; add API key visibility toggle to ApiKeyControl. Add EF migration to persist new settings and update model snapshot; set domain defaults for new configuration flags.
Centralize and float Entity Framework package versions by introducing an EFVersion property (set to 8.*) and replacing hardcoded 8.0.23 references. Updated Directory.Build.props, Listenarr.Api.csproj, Listenarr.Application.csproj and tests/Listenarr.Api.Tests.csproj to use $(EFVersion) for Microsoft.Data.Sqlite.Core, Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.Sqlite and Microsoft.EntityFrameworkCore.Design. This makes EF package versioning consistent and easier to update across projects.
Use null-coalescing assignment to initialize Download.Metadata and set a safe default for ClientState ("Unknown") in DownloadMonitorService to avoid null refs and simplify code. Add a ValueComparer for the Dictionary<string, object>? mapping in DownloadHistoryConfiguration (plus required using directives) so EF Core can detect changes, compute hashes and create snapshots correctly when storing metadata as TEXT.
Refine UI styling across InfoCard, StatusCard, and SystemView for a more consistent visual appearance. Changes include:
- Set card/section backgrounds to #232323
- Increase border-radius from 6px to 8px
- Add subtle box-shadow (0 6px 18px rgba(0,0,0,0.25)) to introduce depth
- Replace InfoCard hover background change with a slight translateY(-1px) lift
- Reduce SystemView padding from 2rem to 1rem
These updates provide visual polish and unify spacing/depth semantics across the affected components.
UI: Improve CustomSelect and FiltersDropdown visuals and behavior — add active states, responsive styles, sort/direction icons, indicators for selected items, keyboard/ARIA tweaks, and a reset action for filters. AudiobooksView: implement lazy author cover loading with IntersectionObserver, placeholder shimmer, load/error handlers, author cover overrides and loading flags, observe author cards only when needed, add a sticky legend for status colors, and multiple responsive toolbar/layout refinements; optimize image-wait logic to only consider visible images. API: MetadataController now uses IMemoryCache to cache author lookup results (including not-found markers and cached image paths) to reduce repeated lookups. Build: update EF package references in Listenarr.Infrastructure.csproj to use the $(EFVersion) property.
Reformat the audiobooks v-for wrapper for improved readability and update the scroll container height calculation from calc(100vh - 130px) to calc(100vh - 170px) to account for additional toolbar/header space. Minor non-functional markup formatting change and layout height adjustment in fe/src/views/library/AudiobooksView.vue.
Remove the inline totalHeight spacer style and tweak container paddings/heights to fix excess bottom gap and scrolling area. The scroll container height was changed from calc(100vh - 170px) to calc(100vh - 165px), bottom padding referencing --legend-height was removed, and the status legend bottom padding was reduced. Changes applied to fe/src/views/library/AudiobooksView.vue to tighten layout and improve visible content when scrolling.
Replace Sonarr/Lidarr/Lidarr-style naming from comments, changelog and tests and replace with neutral/standard wording. Update CHANGELOG entry to refer to "standard DTOs" and adjust comments across controllers, adapters, services, domain models, infrastructure and tests to remove product-specific references. These are documentation/comment/test wording changes only and do not alter runtime behavior.
Remove filesystem checks from AudiobookDtoFactory and treat presence of DB file records as authoritative for Wanted. Replace ExecuteDeleteAsync with ToListAsync + RemoveRange + SaveChangesAsync in DownloadHistoryService for in-memory DB compatibility and log/return the removed count. Update tests to match these behavior changes: pass ApplicationSettings where required in download monitor tests, create a default quality profile in the in-memory DB for scoring tests, and change the file mover hardlink test to expect a false result (no exception) when the source is missing.
Remove an old ManualImport_AppendsUniqueSuffix_WhenDestinationExists test and mark GetQueue_DoesNotPurge_WhenSabnzbdHistoryContainsMatch as skipped due to telemetry Increment() mock verification issues. Add FileUtils test GetUniqueDestinationPath_BatchImport_HandleMultipleCollisions_WithUsedSet to cover batch import collision handling when a used-destinations set is tracked, asserting proper suffixing (e.g. " (1)", " (2)") for successive collisions.
Re-enable GetQueue_DoesNotPurge_WhenSabnzbdHistoryContainsMatch test by removing the Skip attribute. Update the seeded Download so it represents an orphaned item: set Status to Queued and StartedAt to 10 minutes ago (meets orphan age threshold). Clarify test comment to explain why this download would be considered orphaned.
Register a test-friendly IFfmpegService in TestServiceFactory that provides a Moq-based mock returning a temporary mock ffprobe path for GetFfprobePathAsync and EnsureFfprobeInstalledAsync. This prevents real ffprobe extraction during tests, avoiding race conditions and file access issues in CI environments. Also adds a System.IO using required for Path.GetTempPath().
Allow tests to override the SQLite DB path via Listenarr:SqliteDbPath. Program.cs now uses the configuration value (resolving relative paths against ContentRootPath) and still ensures the DB directory exists for EF migrations.

Introduce ListenarrWebApplicationFactory for tests: sets the environment to Testing, injects an in-memory configuration with a unique temp DB path per test run and disables Playwright, and replaces IFfmpegService with a mock to avoid external ffprobe/ffmpeg dependencies.

Update existing integration tests to use ListenarrWebApplicationFactory instead of WebApplicationFactory<Program> so each test run uses isolated test DB and mocked services.
Change environment name checks from "Testing" to "Test" in Program.cs and the test web factory so the test host patches are applied when ASPNETCORE_ENVIRONMENT=Test (matches GitHub Actions). Ensures consistency between the test runner and application environment name.
Allow tests to control runtime behavior and fix MyAnonamouse test handling. Program.Testing now respects Listenarr:SqliteDbPath (absolute or relative) and injects Listenarr:DisableHostedServices=true for test runs. Program.cs registers hosted/background services only when Listenarr:DisableHostedServices is false. MyAnonamouseSearchProvider no longer rejects injected HttpClient based on BaseAddress.Host (preserving test handlers) and only adds the mam_id cookie when present. Tests updated to set the SQLite path and disable hosted services. These changes enable configurable test DB locations, prevent unwanted background services during tests, and ensure MyAnonamouse requests remain authenticated in tests.
When an attempted hardlink fails, try copying the file as a fallback. Added warning logs when hardlinking fails, updated info log to reflect hardlinked/copied outcome, set WasCopied on success, and throw an IOException if both hardlink and copy fail. Changes touch ImportSingleFile and ImportFilesFromDirectory.
Add detailed debug/info logs for manual import batches and per-item processing, including files-per-audiobook, import index/path/audiobook, unique destination resolution (and when it changes), and usedDestinations tracking. Replace unconditional File.Move/File.Copy with guarded operations using overwrite:false and wrap in try/catch to log and rethrow IOExceptions when a destination unexpectedly exists. These changes improve observability for debugging and reduce risk of accidental overwrites during batch imports.
After applying naming patterns in FileNamingService, normalize folderRelative path separators to the platform-specific Path.DirectorySeparatorChar. Adds a null/whitespace guard and replaces '/' and '\\' with Path.DirectorySeparatorChar in two locations to ensure consistent, OS-correct folder paths and avoid mixed separators.
Detect multi-file imports by checking diskNumber or chapterNumber and select settings.MultiFileNamingPattern instead of the default FileNamingPattern. Adds an isMultiFile flag and conditional filePattern selection so multi-file releases use the dedicated naming pattern.
Replace the locally-created HttpClient and HttpClientHandler (with CookieContainer and custom timeout) with the injected `http` client when calling qBittorrent endpoints. The login and subsequent version check now use the provided `http` instance, simplifying the code and avoiding creation/disposal of an extra HttpClient and handler.
Introduce QBittorrentHelpers to centralize category parameter building and logging; apply category filters across DownloadService and QbittorrentAdapter. Improve connection/test handling and user-facing messages for qBittorrent, NZBGet, SABnzbd and Transmission (better error mapping, timeouts, network/auth checks, and consistent "connected" responses). Update the download client modal to build a settings-shaped config for test connections and preserve existing passwords when editing. Adjust existing qBittorrent tests to expect the new messages and add unit tests for QBittorrentHelpers.
Prefer an IHttpClientFactory-created HttpClient so unit tests can inject DelegatingHandler mocks, while falling back to a locally-created HttpClient with a CookieContainer for real qBittorrent authentication flows. Ensure a 30s timeout for both factory and local clients, try to detect Set-Cookie headers from login responses, retry the version endpoint after authentication, and if the factory client appears stateless, attempt a final fallback local login using a cookie-enabled client. Add defensive disposal for locally created HttpClient and improve logging around header/cookie inspection and fallback attempts.
Update QbittorrentAdapter to return a clearer error string when the client receives a 403/401 response. The message now reads 'Forbidden: Authentication required.' instead of the generic 'Authentication Required.' to better reflect the forbidden status while keeping the existing credential-failure message unchanged.
Update package.json and regenerate package-lock.json files for frontend and discord-bot. Frontend deps bumped (vue and @vue/compiler-sfc to 3.5.27, @types/node, eslint-plugin-vue, vitest, added qs), many transitive dependency upgrades (Babel 7.28.x -> 7.29.x, esbuild 0.27.2 -> 0.27.3, csstools packages, @exodus/bytes, @hapi/tlds, etc.), and updated lock metadata (node engine hints and integrity hashes). This commit reflects dependency upgrades and lockfile refreshes across fe/, listenarr.api/tools/discord-bot/, and repo root.
Add logic to prefer serving a cached author image when an author ASIN is stored. ImagesController now looks up an author's ASIN via IAudiobookRepository and tries to use the local image cache before falling back to Audimeta or Audnexus lookups, with additional logging and error handling. Introduce GetAuthorAsinByNameAsync to the IAudiobookRepository and implement it in AudiobookRepository with name normalization and a DB scan for matching authors. Update tests to include a stubbed GetAuthorAsinByNameAsync implementation.
Inject IAudiobookRepository and use it in MetadataController to handle cases where an author cache entry is marked NotFound. Instead of immediately returning 404, the controller now attempts to resolve a stored author ASIN via _audiobookRepository.GetAuthorAsinByNameAsync, checks for a cached image via _imageCacheService.GetCachedImagePathAsync, and if found updates the cache entry (including CachedPath, Asin, Name, and NotFound=false) with a 12-hour sliding expiration and returns the author info. Exceptions during DB/image probing are logged as warnings and the original NotFound behavior is preserved if no result is found.
Add hover/press prefetching for lazy routes (import preloadRoute and attach mouse/touch handlers) to warm dynamic imports and reduce navigation latency. Adjust select and filters dropdown CSS to align dropdowns to the right, tweak label and sort-icon sizing, and remove duplicate/legacy rules. Audiobooks view: add series-collection class, unify hover overlays (remove legacy .series-hover-overlay), adjust overlay z-index/pointer-events and author placeholder sizing, and hide overlays for both author and series when details are enabled. Fix AddNewView runtime handling (use nullish coalescing for display and a safer type cast when assigning runtime). Extend SearchSortBy types with 'Leechers' and 'Score'. Also add PhGlobe import to IndexersTab.
Show loading UI across settings: add header spinners and loading-state placeholders to Download Clients, Indexers, Notifications, Quality Profiles, and Root Folders; introduce per-view loading flags and use LoadingState where appropriate. Add lightweight LoadingState and PhSpinner stubs to test setup and import LoadingState in components. Include unit tests for loading states in Indexers, Notifications, Quality Profiles, Root Folders, and Download Clients to verify spinner/placeholder behavior while async calls are pending. Also add small CSS for the inline spinner.
Update ImagesController_AuthorStoredAsinTests to mock the new repository method used by production code. Added a comment explaining legacy callers used GetAllAsync and added mock setup for GetAuthorAsinByNameAsync(identifier) so tests remain compatible after the repository API change.
Document additional frontend and backend improvements and test updates for 0.2.48. Adds Settings loading UI and LoadingState placeholders, route prefetching, author ASIN image lookup improvements, qBittorrent adapter robustness (IHttpClientFactory/cookie fallback and clearer auth messages), and a note about bumped dependencies and regenerated lockfiles. Clarifies download client Test button behavior (modal uses unsaved form values; settings card uses saved DB values) and records updated/mocked unit tests covering loading indicators, ImagesController author ASIN path, Prowlarr compatibility, toast suppression/deduping, and other API fixes.
Make DDL handling robust by comparing downloadClientId/Type case-insensitively across activity and queue code paths, and update related UI logic. Normalize runtime handling: treat inputs as minutes (provide helper normalization from seconds when needed) and update formatting to expect minutes; also adjust search/result templates to derive lengthMinutes/runtime safely. Add a small BrandLogo component and expose it from base exports, plus test stubs and safeguards (image src normalization and HTTP base URL) to stabilize tests that reference static assets. Miscellaneous fixes: improve FileManagement pattern padding and preview, avoid sending an id when testing download client connections, add thin wrapper components for ActivityView/ApiKeyControl, update several unit tests and test setup to reflect the changes, and tweak some UI classes and defaults (audiobooks grouping/sorting behavior and SettingsView min-height removal). These changes improve correctness, backwards compatibility with varied API shapes, and test reliability.
Add robustness to tests and fix filter behavior in AudiobooksView.

- AudiobooksView.vue: Simplify grouped-collection sorting and expand clearFilters to also reset toolbar sort, builtin filters, search (and persisted search in localStorage), and selected custom filter.
- Tests: Add a new spec to verify the "Clear Filters" button resets search, custom and builtin filters. Add a skipped placeholder debug spec. Update IndexersTab.spec to reset modules and use vi.doMock for a reliable mock lifecycle.
- Test setup (test-setup.ts): Improve test runtime stability for CI by logging initialization, mocking BrandLogo to avoid SFC compile/file:// resolution, adding a mock implementation and named export for apiService.checkVolume, normalizing document.baseURI, intercepting Element.setAttribute('src') to handle file:/// URLs, and patching fs APIs to safely handle file:///logo.svg and similar paths.
- vitest.config.ts: Add a vite alias for '@' -> ./src to ensure imports resolve correctly in the test environment.

These changes aim to reduce flaky test failures related to file:// URL resolution and component compilation during tests, and to ensure clearing filters fully restores the default view state.
Store sort key/order per grouping (books/authors/series) using a reactive sortState and computed sortKey/sortOrder instead of global refs. Simplify the sort active expression to compare against the default sort option. Initialize groupBy from route/localStorage and validate per-group sort values on group changes, falling back to sensible DEFAULT_SORTS. Update clearFilters to reset the current group's sort, clear author image caches and re-run lazy image observation. Minor UI tweak: replace min-height with a fixed calc height for empty-state containers in AudiobooksView and CollectionView.
Refactor the CustomFilterModal template and styles to improve layout, accessibility and per-field inputs. Rule rows are now card-styled with separate rule-fields and actions, conjunction selector moved before rules, group start/end toggles updated (aria-pressed, titles), and remove button given a title. Per-field value inputs were specialized: boolean, quality profile, language, numeric (publishYear/files), and filesize (numeric + unit select) handling updated to use getFileSizeDisplay and dedicated event handlers. Minor form improvements: added id/autocomplete for the label input, adjusted spacing, typography and responsive form control sizes, and cleaned up some modal-specific CSS. These changes aim to improve usability and visual clarity when editing custom filters.
Add identifier validation to prevent path traversal and overly long values, and log rejected identifiers. Enhance ImagesController to sanitize and validate returned relative image paths (using Path.GetFullPath and Path.GetRelativePath) and only serve files inside allowed directories (cache/images, config/cache/images, wwwroot). Attempt to move temp-cached images into library storage earlier (with guarded move attempts and validation of moved paths) and add additional logging around move attempts and path normalization. In LogRedaction, switch to Regex.Replace (with Regex.Escape) and skip empty secrets to perform robust, case-insensitive redaction; add the required using for Regex.
therobbiedavis and others added 2 commits February 19, 2026 18:29
Add defensive checks when resolving image locations: treat absolute (rooted) paths returned by image services as invalid, and reject files that are reparse points (symlinks). Also conservatively reject moved image paths if the target file does not exist. Log warnings and handle exceptions during attribute inspection, setting relativePath to null on failure to prevent serving or following unexpected/unsafe paths.
… of sensitive method

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@therobbiedavis therobbiedavis merged commit 33192b9 into canary Feb 19, 2026
7 checks passed
@therobbiedavis therobbiedavis deleted the feature/prowlarr-integration branch February 19, 2026 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment