feat: add email auth captcha support for release 6.6.0 - #13686
sidmorizon wants to merge 4 commits into
Conversation
f904cb0 to
94ab043
Compare
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
|
@codex security review |
|
Claude review session: https://claude.ai/code/session_01UT1zjgexj75CURCMAhuLVi |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 94ab043914
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Cursor review failed. Remote error: |
|
Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings. |
|
Cursor review failed. Remote error: |
|
Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings. |
| platformEnv.isWeb && | ||
| rootNavigationRef.current | ||
| ?.getRootState() | ||
| ?.routes.some((route) => route.name === ERootRoutes.Onboarding) |
There was a problem hiding this comment.
🟡 P2: Stale onboarding route blocks recovery
Severity: non-severe
When WalletClear leaves an inactive Onboarding entry in the root stack, this guard skips toOnBoardingPage. The user remains on Main without a wallet.
Targets
release/v6.6.0, based directly on release commit352c5ebfd7a6a00e19bedfd9a9b8d7c8a3ca2e4f. Contains the email OTP CAPTCHA integration, environment-aware Supabase configuration, server-configured OTP lengths, and a developer-only CAPTCHA/password login test mode. No additionalxcommits are included.Email OTP sign-in and resend can obtain a Turnstile token before calling Supabase. The shared flow validates challenge messages, consumes tokens once, cancels stale requests, and replaces blocked or stalled CAPTCHA frames with a loading state and an actionable error. Once the hosted page reports readiness, it owns challenge retries. Normal email sign-in now enables CAPTCHA in both production and test environments. The persisted OneKey test-node setting selects the shared Supabase URL, publishable key and hosted CAPTCHA page; the test environment uses Test2. Client initialization waits for those settings, and session reads/writes use separate project storage keys. Keyless OAuth retains its existing configuration.
With developer mode enabled, the real OneKey ID dialog includes hidden controls for switching between production, Test1 and Test2 Supabase projects, selecting the CAPTCHA page, and simulating clients without CAPTCHA support. Both the title gesture and debug client/overrides require developer mode; turning it off stops applying an already-open panel’s configuration. Each preset selects its matching URL and publishable key; keys are not displayed. The test client preserves PKCE and keeps its session in memory without signing in to OneKey ID. Supabase rejection toasts follow the v6.5.0 behavior, and code entry accepts non-empty numeric OTPs without a fixed length or truncation; Supabase validates the configured length. Native inputs retain the number-pad keyboard.
The developer panel also provides a Password login switch. This mode accepts an unmodified password of arbitrary characters and length in a masked field with the default mobile keyboard, without automatically sending OTP. Next acquires a fresh CAPTCHA token and calls
signInWithPasswordwith the selected email, password and token. Retries use new tokens; configuration changes cancel pending challenges and clear the password. Password testing always uses an in-memory client, including the Production preset, and reports success only after receiving a session and verifying its user throughgetUser. It never commits a OneKey ID session.CAPTCHA status stays in its own area; Resend retains its original Processing, countdown, and Resend labels. Code entry and Next are disabled while the initial CAPTCHA/send is pending and after recognized failures, including CAPTCHA rejection, network failures, and timeouts. Successful sends enable entry; unrecognized errors allow submission. A failed resend preserves the ability to submit a previously requested code. Failure classification uses structured metadata and the existing recognized Supabase cooldown-message fallback without changing toast messages. Message-only cooldowns (including zero seconds) keep initial code entry disabled; a failed resend still allows a previously issued code.
Desktop loads CAPTCHA as an Electron webview guest instead of an iframe under the file renderer. An OTA-delivered guest preload exposes the hosted page's existing ReactNativeWebView messaging interface and forwards validated results through sendToHost. The renderer validates the guest, channel, current document, origin, request ID, and payload. CAPTCHA pages receive no wallet provider. The preload is composed before bundle metadata generation and loaded through the existing shell's integrity-checked API, without changing Electron main or main-window preload code. Hosting does not need file:// or null allowances, and web security remains enabled.
Additional changes from integration testing:
Validation
Latest combined changes: all 129 tests across nine affected suites pass, covering environment selection/hydration, session isolation and storage, password/CAPTCHA ordering, exact password forwarding, server rejection, invalid sessions, fresh-token retries, cancellation, developer gating and existing OTP behavior. PR-profile local lint, formatting, TypeScript and repository checks pass.
Real Web dialog: Password login and Client CAPTCHA can be enabled together, the password field is masked with no length cap, and Next becomes enabled after input without automatically sending OTP. Live password authentication awaits validation with an existing account; automated tests mock the authentication endpoint.
Review-fix regression tests reproduced 10 failures before the fix. All 98 tests across the six affected auth/debug suites pass after the fix, covering developer-mode gating in development/release builds, disabling an active debug configuration, raw/wrapped message-only cooldowns, unknown-error permissiveness, and failed resends.
Before these review fixes, on the release/v6.6.0 baseline with its locked dependency versions, all 164 tests in the 12 changed test files passed, covering CAPTCHA frames/lifecycle, guest preload, OTP dialogs, debug presets and onboarding. Coverage includes malformed/stale messages, ordinary DApp preload preservation, preload acquisition failure, DNS/TLS/offline signals, HTTP errors, process termination, startup timeouts and repeated retries without sending OTP.
yarn agent:check --profile commitpassed, including lint and TypeScript.Desktop renderer builds succeeded; generated static/preload.js is present in OTA metadata with a matching SHA-512 digest.
Unmodified app.asar from the locally installed OneKey 2.app reporting version 6.6.0, run with matching Electron 43.1.1 and an isolated profile (not a Git tag checkout/build; the installer commit/tag has not been verified): the file renderer opens the real login dialog with web security enabled. A stopped local CAPTCHA endpoint returns ERR_CONNECTION_REFUSED; initial load and Retry show the network hint and enabled Retry while code entry and Next stay disabled.
In the same file renderer, the hosted Test CAPTCHA visibly reached Success. The real dialog displayed Sent to and its resend countdown; logs recorded HTTP 200 from /auth/v1/otp, followed by /auth/v1/verify and /auth/v1/user after the user entered the emailed code and confirmed success. The QA and installed 6.6.0 app.asar hashes match.
Earlier real Web checks covered loading/error/Retry, missing-token rejection with the original server toast, offline failure and OTP input gating. iOS/Android accepted OTP requests after real CAPTCHA; extension and debug preset switching were also verified.
The replacement Turnstile sitekey from https://github.com/OneKeyHQ/app-webview-pages/pull/70 passed a real CAPTCHA in the desktop dialog using a local build of that page and Test2. Supabase accepted the OTP request, rejected a missing-token control with HTTP 400, and verified the user-provided 10-digit code through the SDK with a returned session and successful getUser. Hosted deployment of the new sitekey was not exercised.
Rebuilt desktop file renderer: after successful CAPTCHA and OTP sending, the real dialog preserved 10-digit and 21-digit numeric input (including leading zeros) with Next enabled. Clearing the field disabled Next. Fake test input was not submitted.
Follow-up before rollout
Production CAPTCHA is enabled by this change. Before rollout, verify that the production hosted page and its sitekey match the production Supabase secret and are reachable on all targets; the new combined production configuration has not been live-verified here. Testing with the original shell code does not substitute for signed OTA installation, and Windows has not been exercised. OTA must ship the renderer, composed static preload and matching metadata together. Hosted CAPTCHA deployments must keep compatible CSP and bridge origin allowlists for Web and extension; desktop requires no opaque-origin exception.