mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
29974d3ab9
Follow-up to #15719 addressing a Codex P2 review note. After #15719, legacy v1.0.7 clients that only send `deviceId` were silent-OKed unconditionally. But `publicProcedure` still receives `ctx.userId` from `createLambdaContext` — and in the *active* sign-out path (the user is still authenticated when logout fires) that userId is valid. Skipping the delete in that case orphans the existing `(userId, deviceId)` row, so `PushChannel.deliver` keeps fanning notifications out to a signed-out device. Expo's `DeviceNotRegistered` receipt only fires on uninstall, not on logout, so the cron worker doesn't catch this either. Fix: add a Path B fallback — when `ctx.userId` is available, run the original `(userId, deviceId)` delete. Path A (expoToken pair) still wins when present; Path C (silent OK) is now reserved for the case the original PR was actually targeting: a v1.0.7 client whose session is already gone, which is the source of the 401 storm. Path matrix: expoToken present → Path A: precise delete by (expoToken, deviceId) no expoToken, ctx.userId present → Path B: legacy (userId, deviceId) delete no expoToken, no session → Path C: silent OK, cron cleans up Tests added: - legacy + valid session → falls back to (userId, deviceId) - legacy + no session → silent OK - expoToken always takes precedence over userId fallback