Name the account a forwarded push was sent to #2

Merged
vinz merged 1 commit from feature/push-recipient-account into main 2026-09-14 20:08:11 +02:00
Owner

Forwards the subscription's account as a top-level account key in the APNs payload, so a device signed in to several accounts can tell which one a tapped push belongs to before it navigates.

Three edits: store.Record gains Account, store.Get selects and scans it, and the forwarded payload carries it when non-empty. Plus README documentation and two store tests.

Verified on the relay box before merge:

  • go build / go vet / go test ./... green in the golang:1.26-bookworm container (no Go toolchain on the VPS).
  • Migration is safe: store.Open has called ensureColumn(db, "account", "TEXT NOT NULL DEFAULT ''") since account scoping landed, so the new SELECT cannot fail on an older database. The live database already has the column.
  • Payload shape confirmed: account serialises as a top-level key alongside aps, matching the README example. An empty account produces a byte-identical payload to today, so pre-account subscriptions are unaffected.
  • All 29 live subscriptions carry a non-empty account (19 distinct), all in the documented <id>@<host> shape.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LLcABfRAqD95tvasuTibbn

Forwards the subscription's `account` as a top-level `account` key in the APNs payload, so a device signed in to several accounts can tell which one a tapped push belongs to before it navigates. Three edits: `store.Record` gains `Account`, `store.Get` selects and scans it, and the forwarded payload carries it when non-empty. Plus README documentation and two store tests. Verified on the relay box before merge: - `go build` / `go vet` / `go test ./...` green in the `golang:1.26-bookworm` container (no Go toolchain on the VPS). - Migration is safe: `store.Open` has called `ensureColumn(db, "account", "TEXT NOT NULL DEFAULT ''")` since account scoping landed, so the new SELECT cannot fail on an older database. The live database already has the column. - Payload shape confirmed: `account` serialises as a **top-level** key alongside `aps`, matching the README example. An empty account produces a byte-identical payload to today, so pre-account subscriptions are unaffected. - All 29 live subscriptions carry a non-empty account (19 distinct), all in the documented `<id>@<host>` shape. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LLcABfRAqD95tvasuTibbn
status_id and account_id both describe the other party — whoever liked,
followed or wrote. Neither says which account was notified, and a device
signed in to several holds one subscription per account, so a tapped push
left the app guessing: it opened under whatever account was active, asked
that account's server for an id belonging to another, and either showed a
dead error screen or — when the id resolved there too, which is the ordinary
case on a single instance — a plausible and entirely wrong profile, with no
error to give it away.

The answer was already in the database. Every subscription is created with an
opaque account value, and has been since subscriptions were scoped per
account to stop a device's accounts evicting one another; it simply was never
read back out. Get now returns it and the forwarded payload carries it as
`account`, so the app can compare before it navigates.

Omitted when empty rather than sent blank: a subscription from a client
predating account scoping then produces the same bytes it does today.
vinz merged commit 1e5f9702e0 into main 2026-09-14 20:08:11 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
vinz/scatto-push-relay!2
No description provided.