Skip to content

Pass a sealed preview through to the phone (GRYT-1688) - #3

Merged
sivert-io merged 1 commit into
mainfrom
claude/GRYT-1688-encrypted-previews
Oct 7, 2026
Merged

sivert-io merged 1 commit into
mainfrom
claude/GRYT-1688-encrypted-previews

Conversation

@sivert-io

@sivert-io sivert-io commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

A push can now carry preview: who wrote, where, and the first line, sealed by the server to a key only the phone has. The relay checks that it's base64url of a sane length, and forwards it without opening it:

  • APNs: top-level p, plus mutable-content: 1 so iOS hands it to the app's notification extension before showing it
  • FCM: data.p. Android still shows the fixed text for now (GRYT-1698).

The relay's own text is still sent, so a phone that can't open the preview shows "New message" as before. A push without a preview is byte for byte what it was.

The server half is Gryt-chat/server#286 and the phone half is Gryt-chat/mobile#316.

What to look at: PREVIEW_SHAPE caps it at 2,048 characters, well under APNs' 4 KB with the rest of the payload. This is the first thing a server sends that ends up on screen, but it can't be read here, and the relay's text is unchanged.

Tests: a preview reaches the sender untouched, APNs gets mutable-content and p, and FCM gets data.p. A push without one is unchanged. Bad shapes get a 400 and send nothing.

🤖 Generated with Claude Code

A push can now carry `preview`: who wrote, where, and the first line, sealed by the server to a key only the phone has. The relay checks that it's base64url of a sane length, and forwards it without opening it:

- APNs: top-level `p`, plus `mutable-content: 1` so iOS hands it to the app's notification extension before showing it
- FCM: `data.p`. Android still shows the fixed text for now (GRYT-1698).

The relay's own text is still sent, so a phone that can't open the preview shows "New message" as before. A push without a preview is byte for byte what it was.

The server half is in Gryt-chat/server and the phone half in Gryt-chat/mobile (linked below).

What to look at: `PREVIEW_SHAPE` caps it at 2,048 characters, well under APNs' 4 KB with the rest of the payload. This is the first thing a server sends that ends up on screen, but it can't be read here, and the relay's text is unchanged.

Tests: a preview reaches the sender untouched, APNs gets `mutable-content` and `p`, and FCM gets `data.p`. A push without one is unchanged. Bad shapes get a 400 and send nothing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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