Skip to content

feat: add email auth captcha support for release 6.6.0 - #13686

Open
sidmorizon wants to merge 4 commits into
release/v6.6.0from
codex/email-otp-captcha-test
Open

sidmorizon wants to merge 4 commits into
release/v6.6.0from
codex/email-otp-captcha-test

Conversation

@sidmorizon

@sidmorizon sidmorizon commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Targets release/v6.6.0, based directly on release commit 352c5ebfd7a6a00e19bedfd9a9b8d7c8a3ca2e4f. Contains the email OTP CAPTCHA integration, environment-aware Supabase configuration, server-configured OTP lengths, and a developer-only CAPTCHA/password login test mode. No additional x commits 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 signInWithPassword with 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 through getUser. 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:

  • Allow Turnstile's required native frame navigation and retain Electron development origin checks to avoid Chromium renderer failures.
  • Avoid opening onboarding twice after a Web refresh restores its route.
  • Centralize extension IDs, origins, and store URLs, and migrate existing store-link consumers.
  • Add a local CAPTCHA fixture, an isolated Auth Gallery flow, and setup/verification documentation.

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 commit passed, 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.

@sidmorizon
sidmorizon changed the base branch from x to release/v6.6.0 September 22, 2026 07:40
@sidmorizon
sidmorizon force-pushed the codex/email-otp-captcha-test branch from f904cb0 to 94ab043 Compare September 22, 2026 07:40
@sidmorizon sidmorizon changed the title feat: add email otp captcha flow and debug controls feat: add email otp captcha support for release 6.6.0 Sep 22, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Native Changes Detected

This PR contains changes that cannot be shipped via bundle update and requires a full App Shell release.

Electron Main Process (1 files)

  • apps/desktop/app/app.ts

Extension Manifest

  • apps/ext/src/manifest/shared.js

Action required:

  • Add the no-release label if this PR should not be included in bundle releases
  • Coordinate with the release team for App Shell release scheduling

AI review prompt:

  • Review this range for bundle-release safety; do not remove the warning unless the detected native/App Shell boundary is wrong.
  • Label impact as main UI JS runtime, background JS runtime, both, or native shell only.
  • Production main/background JS runtimes have isolated JS heaps; native resources may be shared in the same process, so call out both sides explicitly.
  • For DB schema/migration hits, verify Realm and IndexedDB stay in sync and rollback is not expected through bundle-only release.
  • Preserve hardware-wallet isolation, extension CSP, transaction verification, and native security checks.

Auto-detected by native change check

@sidmorizon
sidmorizon marked this pull request as ready for review September 22, 2026 08:34
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-09-22T08:42:48.903797Z 94ab043 Manual request
🔒 Security Review Completed 2026-09-22T08:46:21.105897Z 94ab043 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@codex review

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@codex security review

@sidmorizon

Copy link
Copy Markdown
Contributor Author

@sidmorizon

Copy link
Copy Markdown
Contributor Author

Claude review session: https://claude.ai/code/session_01UT1zjgexj75CURCMAhuLVi

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

@sidmorizon

Copy link
Copy Markdown
Contributor Author

View Devin Review ↗️

Comment thread packages/kit/src/components/OneKeyAuth/supabase/requestEmailOtp.ts
@sidmorizon

Copy link
Copy Markdown
Contributor Author

Cursor review failed.

Remote error: cursor_not_found: HTTP 404 Not Found: AI Model Not Found: Model name is not valid: "grok-4.7"

@cursor

cursor Bot commented Sep 22, 2026

Copy link
Copy Markdown

Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings.

@sidmorizon sidmorizon changed the title feat: add email otp captcha support for release 6.6.0 feat: add email auth captcha support for release 6.6.0 Sep 22, 2026
@sidmorizon

Copy link
Copy Markdown
Contributor Author

Cursor review failed.

Remote error: cursor_dispatch_reconciliation_required: cursor_dispatch_reconciliation_required

@cursor

cursor Bot commented Sep 22, 2026

Copy link
Copy Markdown

Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings.

Comment on lines +173 to +176
platformEnv.isWeb &&
rootNavigationRef.current
?.getRootState()
?.routes.some((route) => route.name === ERootRoutes.Onboarding)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant