fix(studio): await MFA factor deletions before responding - #48942
fix(studio): await MFA factor deletions before responding#48942SEPURI-SAI-KRISHNA wants to merge 1 commit into
Conversation
|
@SEPURI-SAI-KRISHNA is attempting to deploy a commit to the Supabase Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks for contributing to Supabase! ❤️ Our team will review your PR. A few tips for a smoother review process:
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe DELETE handler now awaits all MFA factor deletions, returns deletion errors, and reports success only after completion. Tests cover success, failures, empty factor lists, listing errors, asynchronous completion, and method validation. ChangesMFA factor deletion
Estimated code review effort: 3 (Moderate) | ~15–30 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
I have read the CONTRIBUTING.md file.
YES
What kind of change does this PR introduce?
Bug fix.
What is the current behavior?
On self-hosted Studio, Authentication → Users → (user) → Remove MFA factors can report success without having removed anything.
apps/studio/pages/api/platform/auth/[ref]/users/[id]/factors.tsdeletes the factors with an unawaitedforEach(async …):forEachdoes not await its callback, so the handler falls straight through to the200while thedeleteFactorcalls are still in flight. Two consequences:200has already been sent by the time a factor'serroris inspected, souseUserDeleteMFAFactorsMutationalways lands inonSuccessandUserOverview.tsxshows "Successfully deleted the user's factors" — even when every deletion failed and the user is still fully enrolled. For an admin unenrolling a locked-out or compromised user's MFA, that is a misleading confirmation of a security-relevant action.return res.status(400).json(...)inside the callback runs after the response was already sent, so the 400 payload is appended to the 200 payload. The body becomes two concatenated JSON documents ({"data":null,"error":null}{"error":{"message":"…"}}), and the write-after-end raisesERR_HTTP_HEADERS_SENTin the server logs.This is reachable only on self-hosted deployments —
pages/api/platform/**are the self-hosted shims, sinceAPI_URLonly falls back to/apiwhenIS_PLATFORMis false.The second failing test below is what surfaced the body corruption: it fails with
SyntaxError: Unexpected non-whitespace character after JSON at position 26, position 26 being the exact length of the already-sent200body.What is the new behavior?
The handler now awaits all deletions before responding, and returns a
400carrying the first deletion error:.mapstarts them all concurrently), so a single bad factor doesn't leave the rest enrolled.400shape matches the sibling self-hosted auth routes (users/[id]/index.ts).factor: any—listFactorsalready types the factors, which also lowers the@typescript-eslint/no-explicit-anyratchet count by one.Adds
apps/studio/tests/pages/api/platform/auth/[ref]/users/[id]/factors.test.ts(7 tests), following the existingtests/pages/api/**+node-mocks-httppattern. Two of them fail against the old handler:deleteFactoron a deferred promise and asserts the response is still open.Additional context
Checks run locally:
pnpm --filter studio exec vitest run tests/pages/api→ 37 passed (5 files)pnpm --filter studio run typecheck→ cleanpnpm --filter studio run lint:ratchet→ "Nice! Some rules improved."npx prettier --checkon both changed files → cleanNo API contract change: success and failure response shapes are unchanged, only when they are sent and whether failures are reported.
Summary by CodeRabbit
Bug Fixes
Tests