Skip to content

fix: close the Phase 1-4 audit defects - #10

Merged
AmrMsCLL merged 2 commits into
mainfrom
fix/audit-defects
Sep 26, 2026
Merged

AmrMsCLL merged 2 commits into
mainfrom
fix/audit-defects

Conversation

@AmrMsCLL

Copy link
Copy Markdown
Member

Fixes the defects found in the Phase 1–4 audit against the unified media tracker plan. No migrations; main (including #7, #8 and #9) is merged in.

Changes

Accounts and email

  • Password reset, password change and confirming an email change now cancel pending email changes and outstanding reset links. Before this, a pending email change survived a password reset and could still take over the account.
  • Requesting an email change warns the old address with a link to reset the password, which cancels the change.
  • SMTP errors are rethrown as MailDeliveryError with code, status and command but without the server response, so logs never contain addresses. Forgot-password and resend verification answer the same whether or not the email could be sent; registration and email change answer 503.

Release notifications

  • Only refused recipients (RCPT TO) and rejected messages count against a reader. Sender, DATA command and connection failures are outages that stop the run without blaming anyone.
  • A message rejected for one reader no longer stops digests for everyone after them.
  • A run sends only the releases it actually claimed (updateManyAndReturn), and only skips releases it evaluated.
  • Releases left sent for over an hour without a later digest (a crash mid-send) are queued again.
  • New release markers, the check time, inbox rows and digest events are written in one transaction; a release listed twice in one check is kept once.
  • When a title's preferred source is switched off, its notifications pause with a hint in the editor instead of silently following another source.
  • Unsubscribing from a deleted account returns normally instead of a 500.

Catalogue and library

  • Applying an import attaches matches to stored titles without overwriting them with partial search data (it used to blank synopses and statuses for everyone).
  • Saved titles that were never refreshed or are older than a week are refreshed from their source, 25 per scheduler run.
  • Season, episode, chapter and volume progress are no longer capped at stored totals.
  • Removing a game's last platform turns its release notifications off.
  • Two people adding the same new title at once no longer returns a 500.

Reviews, profiles and moderation

  • Review visibility is a "Private" switch that starts off, so ratings and reviews are public by default.
  • Private ratings stay off public profiles (ratings, activity, library badges and statistics); administrators still see them.
  • Open reports stay in the admin queue when the author clears the review text.

Imports

  • Match options carry the adult flag so covers are blurred on the review page.
  • An import cannot be deleted while it is being read, matched or applied.
  • Uploads go to their own temp directory, emptied at start-up.

Other

  • IGDB release dates repeated per region are merged.
  • Security headers: Strict-Transport-Security behind HTTPS, X-Content-Type-Options, X-Frame-Options and Referrer-Policy; X-Powered-By is off.

Test expectations changed

These tests encoded the old behaviour:

  • admin.spec.ts: the open-report query no longer filters on review text.
  • profiles.spec.ts: the activity rating query requires public visibility.
  • account.spec.ts: token cleanup covers pending email changes and reset links.
  • notifications.spec.ts: mocks follow the single transaction and the claim-and-return call; the skip query targets evaluated releases; the refused-reader case uses RCPT TO refusals, since errors raised before contacting the server now count as outages.

24 tests were added for the new behaviour.

Verification

  • npm run lint, npm test (242 server, 29 frontend) and npm run build pass on the merged branch.
  • Throwaway Compose stack: ready with no Prisma drift and the headers present. Through Mailpit, a pending email change was refused after a password reset, and the old address got its warning without the new address or a token. A private rating stayed off the public profile until made public. In the browser, chapter 8 saved on a title with 5 chapters and the review editor showed the Private switch.

- Password reset, password change and email confirmation cancel pending
  email changes and reset links; a requested email change warns the old
  address; account emails that fail are logged without the address and
  forgot-password answers the same either way.
- SMTP errors keep code, status and command but drop the server response.
- Digests count only refused recipients and rejected messages against a
  reader, treat sender and connection failures as outages, send only the
  releases a run claimed and requeue sends interrupted by a crash; new
  release markers, inbox rows and digest events are written together.
- Notifications pause instead of following another source when a title's
  preferred source is switched off; unsubscribing a deleted account works.
- Imports attach matches without overwriting stored titles, and saved
  titles are refreshed from their source weekly.
- Progress fields accept values past stored totals; removing a game's last
  platform turns its notifications off; a concurrent first add retries.
- Private ratings stay off public profiles; the review editor uses a
  Private switch that starts off.
- Open reports stay in the admin queue when review text is cleared.
- Import matches carry the adult flag, imports cannot be deleted while
  running and leftover uploads are removed at start-up.
- IGDB release dates repeated per region are merged.
- Security headers, including HSTS behind HTTPS; X-Powered-By is off.
@github-actions github-actions Bot added the size/xl Over 600 changed lines, excluding lockfiles label Sep 26, 2026
@AmrMsCLL
AmrMsCLL merged commit d48c726 into main Sep 26, 2026
6 checks passed
@AmrMsCLL
AmrMsCLL deleted the fix/audit-defects branch September 26, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl Over 600 changed lines, excluding lockfiles

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant