Releases: AdrianRossouw/foragerr
Release list
v0.9.23 - candidate covers via same-origin proxy
Candidate covers are back — proxied same-origin, CSP untouched.
Fixed
- The v0.9.17 self-contained Content-Security-Policy silently blocked
ComicVine candidate covers in the Add-series picker and Library-import
proposals (they were hotlinked to CV's CDN). Covers now render through a
new authenticated same-origin proxy (/api/v1/metadata/cover) that only
fetches allowlisted ComicVine media hosts — every redirect hop re-checked
against the allowlist — verifies responses are real images by magic bytes,
caps sizes, and bounds concurrency and caching. The CSP is unchanged.
(FRG-META-021)
v0.9.22 - erroneous tag (content = v0.9.21)
Erroneous tag: created against the v0.9.21 merge commit before the cover-proxy change merged - content is identical to v0.9.21. Pushed tags are immutable (FRG-PROC-013), so this tag stays; the cover-proxy release is v0.9.23.
v0.9.21 - first-run pull backfill
Fresh installs start with a month of pull history.
Added
- First-run pull backfill (
pull_backfill_weeks, default 4,0disables,
capped at 12): when the pull store is empty, the weekly refresh also
fetches the previous few release weeks, so a new install's Calendar shows
what came out recently instead of a bare screen. One-shot by construction
— once any week is stored, refreshes use the standard window. (FRG-PULL-010)
v0.9.20 - shipdate-derived pull weeks
Pull weeks now file under their shipdate's ISO week.
Fixed
- Stored pull weeks were keyed by the number requested from the source;
talkhard indexes weeks one lower than ISO (walksoftly happened to align),
so an entire week of releases filed under the previous week — the Calendar
showed "this week" empty while the comics sat one page back. Entries now
pool across fetched payloads and store under the ISO week of their own
release date, immune to any source's numbering convention; an empty
non-future payload is skipped rather than ever wiping a derived week.
(FRG-PULL-002, FRG-PULL-003)
v0.9.19 - pull source successor (talkhard)
The weekly pull source moved: walksoftly retired, talkhard succeeds it.
Fixed
- The default weekly-pull source (
pull_source_url) pointed at the retired
walksoftly.itsaninja.partyhost (dead with HTTP 523 since at least
2026-07-20; upstream retired it 2026-05 per the Mylar community fork). The
default now points at its successor,talkhard.notaninja.party, same API
contract. Existing installs that never overrode the setting pick the new
default up on upgrade; an explicitpull_source_urlin config.yaml is
honored unchanged. (FRG-PULL-002)
v0.9.18 - Humble CDN allowlist fix
Live-dogfood fix: Humble downloads refused their own CDN.
Fixed
- Humble Bundle downloads failed with "download URL is outside the provider
allowlist: cdn.humble.com": live Humble serves signed URLs from
cdn.humble.com as well as the dl.humble.com the research fixtures had
observed. The source-download allowlist now trusts the two Humble-operated
apex domains (dot-boundary subdomain matching, HTTPS-only and md5
verification unchanged). (FRG-SRC-006)
v0.9.17 - deployment-security hardening
Deployment-security hardening (m10-deployment-posture), the first M10 go-live
change: security headers everywhere, opt-in trusted-proxy support, minimal
unauthenticated disclosure, and the committed security posture record.
Added
- Opt-in trusted-proxy handling (
FORAGERR_TRUSTED_PROXIES/
trusted_proxies): behind a TLS-terminating proxy you run, session cookies
now carrySecureand rate-limiting/audit attribute requests to the real
client address. Forwarded headers from any unlisted peer are ignored, as
before; forwarded entries are validated as IP literals and fail closed.
(FRG-SEC-007) - Security response headers on every response —
X-Content-Type-Options: nosniff,Referrer-Policy: same-origin,X-Frame-Options: DENY, and a
per-surface Content-Security-Policy (deny-all on API/OPDS/health, self-only
on the web UI). No CORS surface exists, by tested position. (FRG-SEC-006) docs/security/posture.md— the deployment security posture record (TLS
delegation, at-rest storage classes and the full-database-encryption
rejection, DoS envelope, residual decisions) — and a manual
deployment-security page (TLS stories, full-disk-encryption
recommendation, container run flags, downgrade warning). (FRG-DEP-017)
Changed
GET /healthbody is now minimal (FRG-DEP-007, FRG-SEC-008): overall
status plus failing component names only — the database path, migration
revisions, scheduler task list, and error text no longer appear
unauthenticated. Status codes are unchanged (Docker HEALTHCHECK and
monitors keep working). Upgrade note: if you scraped/healthfor
component detail, authenticate and use
GET /api/v1/system/health/componentsinstead.- Unhandled server errors now always return a generic error envelope with the
traceback confined to the server log; theServerresponse header is
suppressed. (FRG-SEC-008)
Security
- Aged residuals decided: RISK-008 (DDL extraction) formally re-accepted as
dormant with a review trigger; FRG-DEP-012 diagnostic bundle re-accepted to
backlog; trusted-proxy misconfiguration recorded as RISK-052.
Requirements: FRG-SEC-006, FRG-SEC-007, FRG-SEC-008, FRG-DEP-007 (modified),
FRG-DEP-017.
v0.9.16 — per-issue OPDS covers
Each comic issue shows its own cover in OPDS readers (m9-opds-per-issue-cover),
the second fix from the on-device Panels test.
Fixed
- OPDS acquisition feeds gave every issue in a series the one cached ComicVine
volume cover, so all issues rendered identically in a reader and mismatched
each issue's actual first page. Each issue entry now advertises its own
first-page cover — distinct per issue and matching what it opens to — while
the single series cover moves to the shelf/nav entry, where one-per-series is
correct (FRG-OPDS-020). A file with no renderable first page falls back to
the series cover, never a broken link. Verified on a real reader.
No schema or configuration changes; no upgrade steps.
v0.9.15 — OPDS covers on the auth realm
Covers load in OPDS readers again (m9-opds-cover-realm) — found and fixed
during the on-device Panels test.
Fixed
- OPDS feeds advertised each series cover at
/api/v1/series/{id}/cover, a
route behind the web-UI/API-key perimeter rather than the OPDS Basic realm —
so a reader authenticated for the catalog was rejected (401) following the
cover link, and covers never appeared. Covers are now served at
/opds/series-cover/{id}on the OPDS realm, with HEAD parity; the feed
points there (FRG-OPDS-019). Verified end-to-end on a real reader.
No schema or configuration changes; no upgrade steps.
v0.9.14 — accessibility conformance + axe gate
Accessibility conformance, and the scanner that keeps it true
(m9-a11y-fixes, owner-approved same day).
Added
- Accessibility gate: the e2e harness now runs the axe-core WCAG 2.1 A/AA
ruleset across 14 core screens and fails on any serious or critical
violation (FRG-PROC-019). The harness is fully green — 36 scenarios, the
a11y tier included.
Fixed
- All four serious accessibility violations found by the post-cycle scan
(FRG-UI-038): the connection indicator is now screen-reader-perceivable;
muted text and danger-toned text meet the 4.5:1 contrast minimum everywhere
(new--color-danger-texttone); indexer/download-client cards no longer
nest interactive controls (the provider name is the keyboard edit control);
the Health components table is keyboard-scrollable. Verified: a full axe
sweep of all 21 screens reports zero violations. - The e2e harness's stale expectations (pre-existing red): renaming is pinned
on in the harness and expectations follow the current naming template;
the Sources spec no longer pins the pre-extension "Coming soon" chip.
No behavior changes; no upgrade steps.