You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #6 (deliberately deferred — see PR closing #6 for the analysis).
What
When a notify URL leaks (screenshot, casual share, agent dev-box compromise), the only recovery today is uninstalling and reinstalling the iOS app so APNs hands out a new device token and UpsertByDeviceToken issues a fresh subscriber row. That works but is heavy: ~2 minutes plus losing all local app state (host configs, shortcuts, theme).
Why
Quality-of-life recovery for a real-but-low-frequency scenario. Not a security blocker — the rate limit + body cap landed in #6 already cap the damage a leaked URL can cause (notification spam, no credential exposure).
Suggested fix
Server:
POST /rotate accepting {"deviceToken": "..."}. Find subscriber by device token; delete + insert with fresh ID; return {"id", "notifyURL"} with the new values. Return 404 if no existing subscriber (iOS falls back to /subscribe).
New Store.RotateByDeviceToken(ctx, deviceToken, newIDFn, now) (Subscriber, error) interface method + SQLite (DELETE + INSERT in a tx) + Firestore (Delete doc + Create new) implementations.
Follow-up to #6 (deliberately deferred — see PR closing #6 for the analysis).
What
When a notify URL leaks (screenshot, casual share, agent dev-box compromise), the only recovery today is uninstalling and reinstalling the iOS app so APNs hands out a new device token and
UpsertByDeviceTokenissues a fresh subscriber row. That works but is heavy: ~2 minutes plus losing all local app state (host configs, shortcuts, theme).Why
Quality-of-life recovery for a real-but-low-frequency scenario. Not a security blocker — the rate limit + body cap landed in #6 already cap the damage a leaked URL can cause (notification spam, no credential exposure).
Suggested fix
Server:
POST /rotateaccepting{"deviceToken": "..."}. Find subscriber by device token; delete + insert with fresh ID; return{"id", "notifyURL"}with the new values. Return 404 if no existing subscriber (iOS falls back to/subscribe).Store.RotateByDeviceToken(ctx, deviceToken, newIDFn, now) (Subscriber, error)interface method + SQLite (DELETE + INSERT in a tx) + Firestore (Delete doc + Create new) implementations.iOS:
PushService.rotateSubscription()posting to/rotateand replacing localPushSubscription.Tests
Acceptance
/rotateend-to-end test passes.