Commit graph

7451 commits

Author SHA1 Message Date
Copilot
2a816e10a7
[WIP] Fix open issues after research and analysis (#110)
* Initial plan

* feat(ci): Add secret scanning with secretlint to pre-commit hooks

- Install secretlint and @secretlint/secretlint-rule-preset-recommend
- Configure secretlint with .secretlintrc.json
- Add secretlint to lint-staged configuration
- Update CONTRIBUTING.md to document secret scanning
- Resolves #55

Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com>

* feat(privacy): Disable telemetry and analytics by default

- Set SentryEnabled to false by default in SentryTarget
- Update English localization to clarify error reporting is opt-in
- Update README with detailed privacy information
- Machine fingerprinting already removed (returns "anonymous")
- Piwik analytics already removed
- AnalyticsEnabled defaults to false in config

This ensures no telemetry is sent without explicit user consent.

Resolves #8

Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com>

* refactor: Address code review feedback for pre-commit and telemetry changes

- Optimize secretlint to only scan relevant file types (not all files)
- Add ignoreFiles configuration to secretlint to exclude build artifacts
- Clarify comment in SentryTarget about reconfiguration location

Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com>
2025-12-21 14:19:46 -06:00
dependabot[bot]
a69534b56c
Bump the nuget group with 1 update (#109)
Bumps System.Private.Uri from 4.3.0 to 4.3.2

---
updated-dependencies:
- dependency-name: System.Private.Uri
  dependency-version: 4.3.2
  dependency-type: direct:production
  dependency-group: nuget
- dependency-name: System.Private.Uri
  dependency-version: 4.3.2
  dependency-type: direct:production
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-21 14:06:05 -06:00
Cody Kickertz
1bf1de8618
refactor: reduce cognitive complexity in FileNameBuilder.GetLanguagesToken (#108)
Extract helper methods:
- NormalizeLanguageCode: handles ISO639B mapping and culture conversion
- ApplyLanguageFilter: handles include/exclude filter logic

Uses LINQ for cleaner initial token processing.

Closes #75

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 14:00:42 -06:00
Cody Kickertz
663cc841da
fix: add readonly modifier to static regex field (#106)
PerlRegexFactory: static Regex field should be readonly to
prevent accidental reassignment.

Closes #36

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 14:00:21 -06:00
Cody Kickertz
b124fd8fc0
refactor(api): use async/await in MovieController.AllMovie (#107)
Convert blocking GetAwaiter().GetResult() to proper await pattern
in the API controller method.

Partial fix for #32

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 14:00:03 -06:00
Cody Kickertz
87605c0214
fix(deps): remove obsolete System.Private.Uri package (#104)
Closes #28

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 13:59:36 -06:00
Cody Kickertz
80912b7d43
fix(security): prevent path traversal and command injection (#102)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 12:21:31 -06:00
Cody Kickertz
9d7b5b5298
fix: avoid redundant First() calls in BasicRepository (#101)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 12:00:29 -06:00
Cody Kickertz
2b0f9ad03a
fix: add null safety to QualityProfile First/Last methods (#100)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 12:00:19 -06:00
Cody Kickertz
b843e777de
fix: add empty catch comment and SingleOrDefault safety (#99)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:59:59 -06:00
Cody Kickertz
1a5ca83f4f
fix: resolve thread safety issues in ConfigService cache (#98)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:58:46 -06:00
Cody Kickertz
d8c69e87e2
fix(security): add regex timeouts for ReDoS prevention (#97)
Add TimeSpan.FromSeconds(1) timeout to remaining regex patterns:
- FileNameBuilder.cs: EditionOrdinalRegex, EditionUppercaseRegex
- Parser.cs: SlugSpaceRegex, SlugInvalidCharsRegex, SlugDuplicateDefaultRegex

Clears final 5 SonarCloud security hotspots for 100% review coverage

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:50:11 -06:00
Cody Kickertz
9bf299c196
fix: add empty checks before First() in MovieFileController (#96)
Add guard clauses to prevent InvalidOperationException when
movieFiles list is empty in bulk update/delete operations

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:44:49 -06:00
Cody Kickertz
0081ec2aa1
fix: use SingleOrDefault() with null check in UserService (#95)
Replace .Single() with .SingleOrDefault() when reading Config element
from XML to prevent InvalidOperationException on malformed config files

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:39:41 -06:00
Cody Kickertz
c249c20eb2
fix: add null/empty checks before First() in download clients (#94)
- FileStationProxy: throw if no file info returned from API
- NzbVortex: return outputPath if no files in response
- RTorrent: use FirstOrDefault() for validation errors

Prevents InvalidOperationException on empty collections

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:36:28 -06:00
Cody Kickertz
67a4720ed3
perf: fix remaining regex caching and add timeouts (#93)
- XbmcNfoDetector: convert instance regex to static readonly with timeout
- Parser: add RegexOptions.Compiled and timeout to ReportMovieTitleFolderRegex

Addresses Issue #36

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:15:46 -06:00
Cody Kickertz
739a672637
perf: replace List.Contains() with HashSet for O(1) lookups (#92)
- ReleaseSearchService: wrap wantedLanguages in HashSet<Language>
- FileNameBuilder: convert splitFilter array to HashSet<string>
- NewznabCategoryFieldOptionsConverter: use HashSet<int> for category filters

Addresses Issue #35

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 11:15:37 -06:00
Cody Kickertz
168ea24266
perf(backend): cache additional regex patterns (#89)
* perf(backend): cache regex patterns for better performance

- TransmissionBase: add static VersionRegex, share with Transmission
- SearchCriteriaBase: cache RepeatingPlusRegex
- SearchMovieComparer: cache QueryYearRegex
- XbmcMetadata: cache WatchedRegex

Avoids regex compilation on each method call.

Partially addresses #36

* fix(security): add regex timeout to prevent ReDoS vulnerabilities

All cached regex patterns now include TimeSpan.FromSeconds(1) timeout
to prevent potential denial of service from malicious input patterns.

---------

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-21 10:38:37 -06:00
Cody Kickertz
80c364110c
fix(ui): update user-facing links to Aletheia resources (#86)
- MoreInfo: point to Aletheia GitHub instead of Radarr resources
- UpdateChanges: link issue numbers to Aletheia repo
- Add "Upstream" translation key for Radarr reference link

Closes #53

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-19 20:00:39 -06:00
Cody Kickertz
c4dae9a279
fix: add null safety to LINQ First/Single calls (#83)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-19 19:35:45 -06:00
Cody Kickertz
934a18e9a5
perf: cache regex patterns in Parser.ToUrlSlug and FileNameBuilder.GetEditionToken (#82)
Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-19 19:35:29 -06:00
Cody Kickertz
f2fff6419d
refactor: notification provider deduplication + docs (#81)
* fix: SonarCloud null safety and struct comparison issues

- OsPath.cs: Remove ReferenceEquals checks on struct (always false)
- SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew

* fix: remaining React index-as-key issues and backend null safety

Frontend:
- Fix 8 remaining index-as-key violations using content-based keys
- ImportMovieSelectFolder.js: use errorMessage as key
- ImportMovieFooter.js: use errorMessage as key
- CustomFormat.js: use item.name as key
- AddSpecificationItem.js: use preset.name as key
- QualityProfileItems.js: use message as key
- QualityProfileFormatItems.js: use message as key

Backend (cherry-picked from batch-3):
- OsPath.cs: Remove ReferenceEquals on struct
- SkyHookProxy.cs: Add null-conditional for Credits

* refactor(notifications): consolidate GetPosterUrl to base class

* docs: add architectural decisions log

* fix(sonar): enable path traversal suppressions for media management app

---------

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-19 19:35:14 -06:00
admin
70cfd14971 fix: SonarCloud null safety and struct comparison issues
- OsPath.cs: Remove ReferenceEquals checks on struct (always false)
- SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew
2025-12-19 15:53:17 -06:00
admin
835ec47313 fix: SonarCloud bugs batch 2
- S2445: Make _connections readonly for thread-safe locking (MessageHub.cs)
- S6756: Use setState callbacks for 5 React components
- S1764: Remove duplicate expression in QualityProfileSelectInput.tsx
- S2583: Remove unreachable conditions in NotificationDefinition.cs
- S2259: Fix null reference in Pushcut.cs
2025-12-19 15:22:56 -06:00
admin
4cf5f1d576 Fix SonarCloud issues and add suppression config
Backend:
- Add regex timeout to prevent ReDoS (S6444):
  - SkyHookProxy.cs: ImdbUrlRegex, TmdbUrlRegex
  - PushsaferSettings.cs: HexColorRegex
  - Parser.cs: ImdbIdRegex

Frontend:
- Fix sorting without localeCompare (S2871):
  - MovieIndex.tsx, Collection.js, DiscoverMovie.js

Config:
- Add sonar-project.properties with documented false positive suppressions:
  - S8135: TMDB public API token (not a secret)
  - S6680: Directory depth iteration (naturally bounded)
  - S6674: NLog structured logging placeholder syntax
  - S4662: PostCSS mixin directives
  - S5145: Sanitized log data
2025-12-19 15:03:23 -06:00
Cody Kickertz
0366c8f258
Merge pull request #68 from cheir-mneme/fix/p4-backend
perf: backend optimizations for regex caching and O(n*m) patterns
2025-12-19 13:45:24 -06:00
admin
189039c875 fix(security): add path validation to OpenWriteStream and regex timeouts
- DiskProviderBase: Add Ensure.That path validation to OpenWriteStream
- CleanseLogMessage: Add 5-second timeout to all 22 regex patterns to prevent ReDoS
2025-12-19 13:22:25 -06:00
admin
dda89e2fda Optimize O(n*m) Contains patterns with HashSet
- MovieService.FindByTitle: Convert title lists to HashSets
- MoviesSearchService: Convert queue IDs to HashSet
2025-12-19 13:11:07 -06:00
admin
0e5abe56f0 Cache regex instances as static compiled fields
- SkyHookProxy: Cache IMDB/TMDB URL regexes
- PushsaferSettings: Cache hex color validation regex
- Parser: Cache IMDB ID validation regex
2025-12-19 13:08:40 -06:00
admin
019f0862b3 fix(security): address P3 vulnerabilities and add mitigations
Security fixes:
- XXE prevention: disable XmlResolver in UTorrentProxy.cs (#42)
- Path traversal: validate paths in LogFileController.cs (#44)
- Path traversal: validate paths in MediaCoverController.cs (#44)
- ReDoS mitigation: add 5s timeout to user regex patterns

Documentation:
- CORS: document security rationale in Startup.cs (#43)

Closes #42, #43, #44
Related: #59, #60, #61 (SonarCloud triage - GitHub alerts now at 0 open)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 12:12:54 -06:00
admin
a57775a9ee fix: thread-safe SHA1 hashing in HashConverter 2025-12-19 10:29:44 -06:00
admin
1fe49f6bf2 test: add IMDb list error message verification tests 2025-12-19 10:15:33 -06:00
admin
0dc6442986 Fix CancellationTokenSource resource leaks (BLOCKER severity)
- ManagedHttpDispatcher: Dispose quickFailCts and linkedTokenSource in finally block
- CommandExecutor: Dispose _cancellationTokenSource on shutdown
- Scheduler: Dispose _cancellationTokenSource on shutdown
- IntegrationTestBase: Store CTS as field and dispose in TearDown

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 09:35:35 -06:00
admin
e2b2227a17 Fix blocking semaphore in MediaCoverService
Convert _semaphore.Wait() to async pattern with WaitAsync()
to prevent thread blocking during image resizing operations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 09:26:41 -06:00
admin
f435f38a27 Fix remaining technical debt bugs
- Bug-001: Add null check for SingleOrDefault() in TorrentRssParser
- Bug-006: Replace generic Exception with PathCombinationException in OsPath
- Bug-006: Replace generic Exception with NotSupportedException in IMDbListRequestGenerator
2025-12-19 09:05:54 -06:00
admin
1190d218af Add log sanitization for CodeQL log forging alerts 2025-12-18 20:17:42 -06:00
admin
b1f50bae97 Fix deadlock risk in ReleasePushController with async SemaphoreSlim 2025-12-18 20:02:15 -06:00
admin
2b19ec07ff fix: resolve technical debt and npm vulnerabilities
NPM Security (0 vulnerabilities remaining):
- Add yarn resolutions for cross-spawn, brace-expansion, color-string, glob, postcss

Bug fixes:
- Bug-002: Use FirstOrDefault with null check (DownloadStationTaskProxyV2)
- Bug-007: Fix inverted exception logic for magnet fallback (TorrentClientBase)
- Bug-008: Fix stale closure using ref (MovieSearchInput)
- Bug-009: Fix Number.Number.parseInt typos across 50+ files
- Bug-010: Add regex timeout and Compiled flag (RegexReplace)
- Bug-011: Add null checks for XML queries (ConfigFileProvider)
- Bug-012: Remove empty touch handler (MovieDetails)
- Bug-013: Use Path.GetFileName for safer check (InstallUpdateService)
- Bug-014: Return Ok instead of Accepted for sync PUT (MovieController)
- Bug-016: Fix double bracket typo in log message (InstallUpdateService)
- Bug-017: Add console.warn to catch block (MovieTagInput)
- Bug-018: Remove stray debug console.log (SignalRConnector)
- Bug-019: Document disabled regex with ReDoS justification (Parser)
2025-12-18 19:54:02 -06:00
admin
5c51367bec fix(security): sanitize user-controlled strings in log statements
Add SanitizeForLog() extension method to prevent log forging attacks
by replacing control characters (newlines, etc.) with spaces. Applied
across 30 files that log user-controlled data like paths, titles,
URLs, and usernames.

Fixes CodeQL log-forging alerts.
2025-12-18 17:17:02 -06:00
admin
9c0e11b40b refactor: remove redundant boolean literals (S1125)
Replace == false with negation operator, remove == true comparisons
2025-12-18 16:31:05 -06:00
admin
021fd9b55e perf: use char overloads for StartsWith/EndsWith (S6610)
Use single character overloads instead of single-character string
overloads for better performance.
2025-12-18 16:17:37 -06:00
admin
6b67a1672c refactor: seal non-derived private classes (S3260)
63 private nested classes marked as sealed since they have no derived classes.
2025-12-18 16:05:31 -06:00
admin
b5bcb14d75 refactor: make methods static where instance data not used (S2325)
~243 methods converted to static where they don't access instance data.
Fixed call sites that needed to use type name instead of instance.
2025-12-18 16:02:13 -06:00
admin
aa748bfaa6 refactor: reduce LanguageParser cognitive complexity
Replace 40+ individual if statements with dictionary-based lookup.
Extract helper methods for keyword, case-sensitive regex, and
case-insensitive regex language detection. Original method reduced
from ~400 lines to ~17 lines while preserving all behavior.
2025-12-18 15:48:31 -06:00
admin
6a4fb133b5 refactor: reduce MyAnonamouseParser cognitive complexity
Extract helper methods for author parsing, title flags, and freeleech
detection to simplify the main ParseResponse loop.

Addresses #30
2025-12-18 15:43:56 -06:00
admin
9de2f9a168 refactor: replace ApplicationException with domain-specific exceptions
Create custom exception classes:
- InvalidDatabaseSchemaException for migration errors
- ServiceInstallationException for service install failures
- DataRetrievalException for repository query mismatches
- InvalidRequestException for HTTP request validation
- InvalidHeaderException for HTTP header validation

Resolves SonarCloud S3988 (ApplicationException usage).
2025-12-18 15:37:21 -06:00
admin
f7a196dec6 fix: add timeout to regex for DoS prevention 2025-12-18 15:02:41 -06:00
admin
fb6e131d68 fix: address code review findings
- Fix Torznab default definition protocol (Usenet -> Torrent)
- Add try-catch around JSON deserialization in MAM parser
- Add logging for author info parse failures
- Add null check for JSON response
2025-12-18 14:51:22 -06:00
admin
2045f39037 feat(ui): add media type badge to poster view 2025-12-18 14:42:42 -06:00
admin
bd6f7ece9c feat(indexer): enable book and audiobook support in Newznab/Torznab 2025-12-18 14:37:01 -06:00