Skip to content

chore: sync develop with main - #516

Merged
chodeus merged 6 commits into
developfrom
main
Aug 13, 2026
Merged

chore: sync develop with main#516
chodeus merged 6 commits into
developfrom
main

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

@coderabbitai ignore

develop has drifted behind main (releases, fixes, dependency bumps). Do not merge this PR — it reports the drift, it does not fix it.

develop requires branches be up to date, and head:main can never satisfy that without pulling develop's extension files into main, which the branch invariant forbids. Squash or rebase would also leave main unreachable from develop, so this workflow would just open another PR next push.

Sync locally instead:

git checkout develop && git merge origin/main && git push

Then verify git diff main develop is added extension files plus deploy/docker/Dockerfile only. GitHub marks this PR merged on its own once develop contains main's tip. Opened by the sync-develop workflow.

renovate Bot and others added 6 commits August 13, 2026 07:02
* chore(deps): update dependency vitest to v4

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* test: restore v3 mock-clearing semantics under vitest 4

vitest 4's restoreMocks only touches spies; mockReset alongside it clears
vi.fn() call history per test (and restores creation implementations), which
the module-scope mocks relied on. Comments naming the old mechanism updated.

---------

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: chodeus <dhoges90@icloud.com>
…red revokes, response docs (#515)

fix(frontend): follow-up micro-batch — abortable browsePosters, safe downloads, honest response docs

browsePosters forwards caller options to apiCore.get (unblocks abort on the
develop effects); one downloadBlob owner defers revokeObjectURL past WebKit's
click handling for all four download sites (anchor cleanup moved into
finally); the refresh endpoints document their 400/413 contracts.
…ility pass (#517)

* fix(ui): login toggle overlap root cause + one mobile pass

touch-expand's position:relative was beating absolute at equal specificity by
source order — now :where()-wrapped in the utilities layer so it can never
outrank an author position; the login toggle becomes a real 44px target with
a matching input reserve, and SearchInterface's clear button had the same
defect shape. Mobile pass at ~360-390px: 12 pages fixed (wraps, overflow
containers, the max-w-500 spacing-scale trap resolving to 2000px, 44px small
buttons via touch-expand); ~30 sub-44px hand-rolled controls deferred as
their own batch.

* fix(ui): review findings — nullish byte counts, review gate leads its row

?? preserves a legitimate 0-byte count at both size_bytes sites; the wrapped
setup footer puts the review gate first and hides empty spacers.
…ls the truth (#518)

* fix(api): cap every JSON body read; renovate gate tells the truth

All 22 raw request.json() sites route through the 1MiB streaming reader (one
413 BODY_TOO_LARGE owner); an empty body can no longer blank a module config
to defaults, disable a module, or silently re-save config; bodyless
provision/remove behaves as the documented {} all-instances form. renovate's
python<3.14 gate keeps its constraint for the real reason (CI and the image
run 3.13) with the exit condition documented — no dependency blocks 3.14.

* fix(frontend): invalidate poster list caches after a GDrive local delete

deleteGdriveLocal removes rows server-side; the cached /posters/list,
/posters/search and /posters/browse entries (all query variants — substring
match) now clear on success.

* fix(frontend): clear the real GDrive search cache prefix

/posters/search was a guessed path; the GDrive search caches under
/posters/sources/gdrive/search. Regression test pins all three cleared
prefixes and that unrelated entries survive.
…anning 297) (#520)

fix(api): poster preview authorizes the resolved path (CodeQL 297)

The absolute branch validated the raw path and served the resolved one, so a
symlink inside an allowed root served whatever it pointed at; the relative
branch's root gets the same resolved re-confinement. Regression test proves a
root-escaping symlink is refused.
* feat(logging): one designed redaction layer for all log output

log_redaction.py owns the taxonomy (URL userinfo, bearer headers, known-key
values with 4-char diagnostic prefixes, self-identifying token shapes) keyed
on SENSITIVE_FIELD_NAMES; it attaches once per Logger, redacts lazy args,
exc_info and stack_info, fails closed to a [redaction-error] line, and
subsumes the old SmartRedactionFilter with its coverage carried. Log files
write utf-8 explicitly (the mask char is non-ASCII).

* fix(logging): review round — env-independent e2e test, module-scope redact, case-safe assertion

The e2e test clears LOG_FILE so ambient environments can't redirect the log;
redact imports at module scope (cycle-free — log_redaction defers its config
import); the taxonomy subset assertion lowercases both sides to match the
IGNORECASE rules.
@chodeus
chodeus merged commit 6a42c71 into develop Aug 13, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant