fix(web): deleting an account revokes its Linear grant at Vercel Connect

Merged
DA
7d ago
+109-23

What

Privacy gap 1 from the PRIVACY.md audit (#2287), approved by Dean: deleting an account didn't revoke the account's Linear grant at Vercel Connect. Only Disconnect did.

  • The revoke Disconnect makes is now one shared effect, revokeLinearGrant in hosted/linear-connect.ts. It asks Connect only where the deployment names a connector, and logs a failure by Connect's word, code and status (LinearConnectFailure.message), never Connect's sentence.
  • POST /api/account/delete calls it after the user row (with linear_connection and everything else under it) is deleted, in the same order as Disconnect, which deletes the row and then revokes. A revoke that fails is logged and the account is deleted all the same.
  • Sweep retry: not built. Once the user row is gone, nothing in the database names the account, so a retry would need a new pending-revocation table that outlives the user, plus a migration and a sweep step. That isn't the "simple" case the task allowed for. The policy says plainly what happens if Connect can't be reached.
  • PRIVACY.md: both sentences saying deletion doesn't revoke the grant now say it does, and what happens if Connect is down.

Tests (tests/account-app.test.ts, golden exchanges over a scripted Vercel Connect)

  • delete-success and delete-analytics-failure now end with the account's grant revoked.
  • New delete-linear-revoke-failure: Connect refuses the revoke, and the account is still deleted with a 200 {deleted:true} (golden recorded with LUKE_UPDATE_FIXTURES=1; the new file is just that answer).
  • delete-store-unavailable revokes nothing, so the grant stands for the retry.
  • Fails on main's account-app.ts (revoked: []). account-plan-template.test.ts now provides a LinearConnect that refuses to be asked, since the group requires the service.

Checks

./scripts/check.sh: everything passes except one vitest worker that was SIGKILLed for memory while I ran three checks in parallel on this VM. That file (voice-service-exchange.test.ts) passes on its own. Server-only, no Mac UI, so verify.sh doesn't apply and was not run (Linux VM; CI builds nothing for the Mac).

šŸ¤– Generated with Claude Code


Devin Review