Skip to content

Push registration: a deleted account's request still on its way stores nothing - #5219

Merged
djizus merged 1 commit into
nextfrom
fix/push-registration-after-deletion
Nov 10, 2026
Merged

djizus merged 1 commit into
nextfrom
fix/push-registration-after-deletion

Conversation

@djizus

@djizus djizus commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #5215 (merged at cae140de75a): a push registration already in flight could recreate push data after the account was deleted.

The problem

A subscribe request that passed its session check before the player deleted their account could still write the phone's registration afterwards. Account deletion removes every push registration in its transaction (account-deletion.ts), but the store's insert checked only the device cap and the id's revocation. The anonymised user row stays, so the foreign key allowed it. The deleted account then had an APNs token or a browser endpoint again, and gameAlertDevices listed it. The sign-out on the registering page cannot be the guard: the account may be deleted from another device.

The fix

push-subscription-store.ts: the registration's one INSERT … SELECT … WHERE also requires that the owner has no row in account_deletions. That table is written in the deletion's own transaction. So whichever lands first wins: a deletion first means the insert writes nothing and returns deleted (the route answers 409 subscription_deleted); a registration first means the deletion's transaction removes it. No pre-insert check, client step or new state.

Tests

  • account-deletion.test.ts, once per transport (APNs, Web Push): the real Worker signs the account in, the store's registration is held just before its insert, the account is deleted through DELETE /api/account with its emailed code, and the insert is released. It returns deleted; no row, game-alert or chat-alert recipient is left. The same email then signs in to a new account, which registers the same phone. Both cases fail on next (455085973c6) (expected 'registered' to be 'deleted').
  • The held-insert helper moved from push-subscription-store.test.ts to held-push-registrations.ts so both suites use one.
  • pnpm --dir apps/realms test (350), realms typecheck, format:check, knip and words:check pass.

src/pwa/notifications.md notes the refusal beside the revocation rule.

…s nothing

The registration insert refuses an owner in account_deletions in the same statement as its cap and revocation checks, so a subscribe authorized before the deletion cannot write the phone back after it, whichever device deleted the account. The deletion suite holds an APNs and a Web Push registration at its insert across a real deletion, and the next account then registers the same phone.
@vercel

vercel Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated
eternum Ignored Ignored Nov 10, 2026 9:32am UTC
eternum-docs Ignored Ignored Nov 10, 2026 9:32am UTC
eternum-mobile Ignored Ignored Nov 10, 2026 9:32am UTC

Request Review

@djizus
djizus marked this pull request as ready for review November 10, 2026 09:47
@djizus
djizus merged commit 78a86c5 into next Nov 10, 2026
20 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