Repository navigation
Conversation
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
There was a problem hiding this comment.
Code Review
This pull request implements multi-factor authentication (MFA) using TOTP, integrating it into the sign-in, password recovery, and R3 approval flows. It also updates the configuration for Supabase Auth and adds comprehensive E2E tests. The review feedback highlights several areas for improvement, including adding defensive null checks to prevent runtime errors in the MFA components, refining state management in the authentication page to handle React's StrictMode correctly, and improving error handling for promise rejections in the password reset flow.
c7c1720 to
bd47b11
Compare
8bdf3da to
8c47535
Compare
bd47b11 to
32791d4
Compare
8c47535 to
382bcbf
Compare
32791d4 to
05a181f
Compare
382bcbf to
8c393bb
Compare
05a181f to
0dec20c
Compare
8c393bb to
b4ec0de
Compare
Security review (session)The Verdict: approve with nits. Nothing blocking. The findings below are fixed in this PR or moved to an issue. Fixed in
Follow-up issue (kernel, outside this PR)
Checked and fine
Re-validated locally: lint, typecheck, unit 106 passed (5 skipped), Generated by Claude Code |
0dec20c to
5fe9d6b
Compare
38c4cd6 to
f6f2cf2
Compare
f6f2cf2 to
9cc1ce8
Compare
|
Heads-up from #113: 🤖 Generated with Claude Code |
|
Done in It is not covered by e2e yet. Rotation is still R2 on Generated by Claude Code |
9cdb3ef to
8ae500e
Compare
0e17452 to
397f579
Compare
|
Rebased onto #91, which is now on
Local, on a fresh compose stack with Generated by Claude Code |
8ae500e to
919d0a4
Compare
397f579 to
ee6ba69
Compare
919d0a4 to
fccfbd9
Compare
ee6ba69 to
f1eed73
Compare
fccfbd9 to
9c327d6
Compare
f1eed73 to
1bd3941
Compare
9c327d6 to
1dca154
Compare
1bd3941 to
50bbbc8
Compare
…18) Adds the e2e workspace package and an e2e workflow that builds the image, starts docker compose on fresh volumes and runs Playwright through MVP exit criterion 1: sign up, create the first org, upload the sample e-invoice, wait for the proposal, approve it, check the vendor, document and entry lists and the Excel export, then read the vendor, purchase document, balanced journal entry and audit rows from the database as the superuser. The ci job installs the e2e package too, so pnpm typecheck covers it, and pnpm lint now includes e2e/. Plan T9 and exit criterion 4 updated. Closes #18 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013LrvuThKGaPX1uDwUiwmGQ
… browser language #206 (#47) picks the SPA language from the saved choice, then navigator.languages, and Playwright's Chromium reports en-US, so the Inbox test would see the English screens. Pinning the context locale to vi-VN keeps the test on the default locale. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013LrvuThKGaPX1uDwUiwmGQ
… step-up (#32) Rebased onto main with member invites, owner confirmations (#119), the sessions screen (#147, #178) and MFA_REQUIRED (#126), so the earlier commits of this PR are squashed into one. - auth-js uses PKCE. settleCallback() runs before the router: it explains failed links by known error codes only (a link's error_description is attacker-written), notes a link opened in another browser, sends recovery links to /reset-password, and removes the one-time code and error parameters from the URL and history. - /reset-password asks for the TOTP code first when the user has a factor; /mfa is the sign-in challenge, and every data route waits for aal2. MFA_REQUIRED from the kernel (#126) now sends the user to /mfa instead of showing an error; /mfa signs out through the shared sign-out that revokes the Crove session first (#178). - Settings: two-factor card (TOTP enroll, verify, disable). - Step-up (P11): approving, inviting, changing a role or removing a member (inside #119's confirmation) and rotating the inbound address show a prompt on STEP_UP_REQUIRED that names the pending action, asks for a fresh code or points to enabling two-factor, and repeats the refused request as sent (an approval prompted on one revision gets STALE_REVISION if someone saved another meanwhile). - Compose: GOTRUE_MAILER_URLPATHS_* include the /auth/v1 prefix (email links were broken on self-host), and AUTH_STEP_UP defaults to required. - e2e with email confirmation on (compose.e2e.yml, Mailpit, RFC 6238 TOTP, an inbound address for the rotation): confirmation and reused links, a forged link error, recovery, TOTP enrollment and the sign-in challenge, refresh and sign-out, the invite, owner confirmation, role change and removal step-up flows across two browsers, the rotation step-up, and the Inbox approval with its denied and aal2 audit rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013LrvuThKGaPX1uDwUiwmGQ
#217 limits email-sending auth requests to 5 per client address per hour and one per recipient a minute, in the proxy. The e2e tests sign up and recover from the runner's single address, often right after mailing the same recipient, so the stack raises both limits and Supabase Auth's deployment-wide budget, keeping the 10-client ratio the kernel enforces at start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013LrvuThKGaPX1uDwUiwmGQ
1dca154 to
06be6ec
Compare
50bbbc8 to
c74cf7a
Compare
|
Rebased on
Local, with #191 on top: lint, typecheck, docs check and unit tests (375) pass, and the full Playwright suite on the compose stack passes 10/10 (the 6 auth tests here, #91's Inbox test and #191's 3). Generated by Claude Code |
06be6ec to
e5b3440
Compare
Closes #32
Stacked on #91 (the Playwright harness this PR's tests run in), so the base is #91's branch and the diff shows only #32. Merge #91 first; GitHub then retargets this PR to
main. After member invites (#125, #132) and crove-extract landed, the PR was rebased and squashed into one commit. A second commit covers the inbound address rotation, which #142 made R3.Bug fixed on the way
The bundled Supabase Auth built email links as
http://localhost:8080/verify?.... TheGOTRUE_MAILER_URLPATHS_*defaults are resolved againstAPI_EXTERNAL_URL's origin and drop/auth/v1, and the SPA served those links as unknown routes. So sign-up confirmation and password recovery did not work on self-host onceAUTH_AUTOCONFIRM=false.docker-compose.ymlnow sets the four URL paths to/auth/v1/verify.What changes
SPA (
apps/app)settleCallback()runs once at startup, before the router reads the URL. It:error_descriptionis attacker-written text);/reset-password, even if Supabase Auth redirected elsewhere;/reset-password: new password screen. A user with a verified factor enters a code first, so a recovery link alone does not get past MFA./mfa: after a password sign-in, a user with a verified factor enters the code. Every data route redirects there until the session isaal2. This guard is in the SPA only; the kernel side is Kernel: refuse aal1 tokens from users who have a verified MFA factor #126.STEP_UP_REQUIRED: approving, inviting a member (feat: member invites with consent #125), changing a member's role or removing a member (feat(kernel): change member roles and remove members #115), and rotating the inbound address (R3 since fix(kernel): rate-limit inbound address rotation and require step-up #142). The prompt:STALE_REVISIONif someone saved another meanwhile;Compose:
AUTH_STEP_UPnow defaults torequired, as #90 planned once these screens existed.offis still accepted on a local URL only. A local user therefore has to enable two-factor before the first approval or membership change, and the app walks them through it.e2e: the stack runs with email confirmation on, set in
e2e/compose.e2e.yml. That file also raises the email rate limit for repeated local runs, and gives orgs an inbound address (INBOUND_DOMAIN; nothing delivers to it). Tests read links from Mailpit and compute TOTP codes (RFC 6238,e2e/lib/totp.ts).auth.spec.ts:aal1, with data routes blocked, thenaal2after the code;inbox.spec.ts: signs up through the confirmation email. Approving meets the step-up prompt (which names the approval), then the user enables two-factor and approves. The audit rows show the denied attempt (STEP_UP_REQUIRED,aal1) and the approval (aal2,mfaAtset).Docs: plan (login section, T2, step-up line, Decision 6 spike marked pass), the Vietnamese page, and the README configuration row.
Tests
mainat fix(finance): ledger checks see every line of the entry #140 (b21d931, includes fix(kernel): rate-limit inbound address rotation and require step-up #142) plus test: Playwright end-to-end test of the Inbox flow on docker compose #91: a freshdocker composestack withcompose.e2e.yml, with the kernel andcrove-extractimages built from this tree. All 7 Playwright tests pass in about 1.2 min; the TOTP tests wait for new 30 s windows so no code is reused.pnpm lint,pnpm typecheck, unit tests,pnpm docs:checkand the app build pass.aal2guard is Kernel: refuse aal1 tokens from users who have a verified MFA factor #126.Not in this PR
🤖 Generated with Claude Code
https://claude.ai/code/session_013LrvuThKGaPX1uDwUiwmGQ