Skip to content

feat: harvest the v1 login UI and rewire it to the facade - #911

Merged
FSM1 merged 3 commits into
mainfrom
feat/804-harvest-v1-login-ui
Aug 1, 2026
Merged

feat: harvest the v1 login UI and rewire it to the facade#911
FSM1 merged 3 commits into
mainfrom
feat/804-harvest-v1-login-ui

Conversation

@FSM1

@FSM1 FSM1 commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Closes #804

Brings the v1 login page back and rewires it onto the v2 facade. Everything in this diff lives in apps/webno packages/client files were touched, so it does not collide with #907.

What the login flow now does

  1. Core Kit runs on the UI thread and authenticates the person (loginWithOAuth: Google, or Web3Auth's email-passwordless flow seeded with the address typed into the form).
  2. useAuth hands the exported login secret to the engine exactly once through the web: land the useSyncExternalStore snapshot adapter and Core Kit login handoff #803 handoff — handOffLoginSecretfacade.start(secret) — and registers the session with the LoginSecretSource so a leadership failover can re-export it.
  3. Every derivation happens in Rust. The hook derives nothing and holds no token; facade.start runs the engine's own challenge-signature login.
  4. SIWE stays secondary: wagmi collects the wallet signature on the UI thread and useAuth forwards it to facade.siweLogin(message, signature).
  5. Logout runs facade.logout() plus the Core Kit teardown, disarms the secret source, clears the UI auth store, and asks EngineProvider for a fresh client — facade.logout closes this tab's client permanently, so without that the tab could never log in again.

Harvested from v1 vs written fresh

Harvested largely as-is Rewritten
routes/Login.tsx structure, copy, footer hooks/useAuth.ts — the v1 hook drove the vault bootstrap, IPNS derivation, and token lifecycle in TS; all of that is engine-side now
components/MatrixBackground.tsx, components/StagingBanner.tsx GoogleLoginButton — v1 loaded Google Identity Services and posted the idToken to a CipherBox identity endpoint; Core Kit owns the OAuth round-trip now, so the button is a button
index.css design tokens, the login half of App.css EmailLoginForm — the v2 API has no OTP endpoint; the code is entered in Web3Auth's own window, so the two-step form collapses to one
lib/wagmi/*, WalletLoginButton connector-picker UX and SIWE message shape WalletLoginButton transport — v1 called identityWalletNonce/identityWalletVerify; this posts the signature to facade.siweLogin
LogoutButton lib/web3auth/*auth/coreKit.ts — a narrow CoreKitSession seam so useAuth never sees a Web3Auth parameter shape and a test can substitute a plain object

Deliberately not harvested: the MFA / REQUIRED_SHARE screens (DeviceWaitingScreen, RecoveryInput) — #809 defers the mfa specs; a device without its factor gets a plain error. Also dropped: the health-check gating on the login buttons, the GIS One Tap fallback, and the placeholder help/privacy/terms footer links.

The one architectural debt: the SIWE nonce

facade.siweLogin exists but nothing exposes the challenge an EIP-4361 message has to embed — the engine's ApiClient::siwe_challenge is unreachable from the facade. Wiring one through would have meant editing protocol.ts, transport.ts, both transports, serve.ts, facade.ts, crates/wasm, and the engine facade — precisely #907's blast radius.

So apps/web/src/auth/siweNonce.ts fetches the public, single-use nonce straight from POST /auth/siwe/challenge, bounded and under a timeout. It is the only direct API call in apps/web and it contradicts the blueprint's "no seams in apps/web". Filed as #910 with a dependency edge back here.

Review gates

/simplify, /security-review, and /crypto-privacy-review all ran against git diff main...HEAD. Folded back in:

  • wagmi persisted the wallet address. createConfig defaults storage to localStorage, and its partialize writes connections[].accounts — the address — to wagmi.store. disconnect() normally clears it seconds later, but a tab closed while the signing prompt is open leaves it indefinitely. Now storage: null, verified in the browser: the key no longer appears.
  • A refused handoff left a live Core Kit session behind a signed-out UI. session.method()/email() call getUserInfo(), which throws when Core Kit is not logged in, and they sat outside the failure envelope — so a throw after a successful start left the secret source armed with the UI rendering signed out. They are read before arming now, and a handoff the engine refuses ends the Core Kit session rather than leaving a 24-hour bearer credential the user has no button to clear.
  • The Core Kit storage comment was false. It claimed "session metadata only"; Core Kit persists a device-factor share and a sessionId that reconstitutes a logged-in instance. The comment now says what is actually stored, and web: decide the Core Kit storage scope and gate its key set #913 makes the storage scope an explicit decision with a web-e2e assertion over the key set.
  • The CoreKitProvider StrictMode claim was false — constructing in an effect is what causes a double construction. The session and its restore promise are latched in refs now, so a remount reuses the instance instead of racing a second init() against the same store.
  • The once-per-tab guards were per-hook-instance. LogoutButton also calls useAuth, so on a direct load of /files with a surviving session it was the logout button driving facade.start. The guards are module-scoped now, keyed on the session object, and a collision rejects instead of resolving silently.
  • window.location.assign('/') as teardown moved up a layer: EngineProvider rebuilds its client, so any logout path works rather than only the one that remembered to reload.
  • SIWE nonce: AbortSignal.timeout, an upper length bound, and new URL resolution. Signing pins account: accounts[0]. 0x stripping is conditional.
  • VITE_ENVIRONMENT rejects an unrecognized value rather than defaulting it — a typo would silently pick the wrong Web3Auth network, deriving a different identity over an empty vault.
  • Simplify/reuse: one .terminal-btn rule replaces three near-identical button rule sets, LoginError and errorMessage are shared, MatrixBackground drops unused props and redundant per-column canvas state writes, and dead CSS and unused design tokens are gone.

Two findings were too deep to fix here and are filed instead: #914 (auth state is a tab-local optimistic store, not derived from the engine — log out in one tab and another keeps rendering /files; the event stream carries nothing auth-shaped yet) and the SIWE encoding bugs added to #910 (the facade sends unprefixed hex where the API DTO requires 0x, and the API does not validate uri).

Verified vs blocked

Verified:

  • apps/web unit suite — 65 tests green. The useAuth suite asserts each method dispatches the handoff, that SIWE routes to facade.siweLogin while exporting no secret at all, that logout tears both sides down and yields a fresh client, that a Core Kit session surviving a reload re-hands the secret, and that a refused start leaves the tab signed out with the buffer scrubbed, the re-export capability disarmed, and the Core Kit session ended.
  • The page in a real browser via Puppeteer: renders, the three methods and the wallet connector picker work, computed styles match the harvested design, and after a login attempt localStorage holds only Web3Auth loglevel keys — nothing key-shaped, no wallet address.
  • tsc -b, eslint, prettier, and the production vite build are clean.

Not verifiable yet:

  • A real end-to-end login. It needs a Web3Auth verifier configured against VITE_WEB3AUTH_CLIENT_ID / VITE_WEB3AUTH_VERIFIER, and the rest of the v2 web runtime is still stubbed. The flow dispatches correctly; whether Web3Auth's popup returns a usable TSS key against a v2 verifier is a human check.
  • The wallet path end to end. facade.siweLogin is a Command, so the engine refuses it with NotStarted before start, and the facade's signature encoding does not match the API DTO. Both are tracked on web: move the SIWE challenge below the facade #910; the path is fail-closed today, so nothing lands the tab in an authenticated state it has not earned.
  • The storage assertion in useAuth.test.tsx was renamed to what it actually proves — a fake session has no SDK behind it, so only web-e2e can assert the real key set (web: decide the Core Kit storage scope and gate its key set #913).

New build-time environment keys

VITE_ENVIRONMENT, VITE_WEB3AUTH_CLIENT_ID, VITE_WEB3AUTH_VERIFIER — all declared in vite-env.d.ts; the app fails loudly at Core Kit construction if the last two are absent.

Summary by CodeRabbit

  • New Features
    • Added Google, passwordless email, and wallet sign-in options.
    • Added session restoration, authentication status, loading states, and logout handling.
    • Added SIWE wallet authentication with connector selection and clear error states.
    • Added a terminal-themed login experience with responsive styling and accessibility improvements.
    • Added an animated Matrix background and staging-environment warning banner.
  • Bug Fixes
    • Improved authentication cleanup and engine recovery after logout or failed sign-in.
    • Added validation and timeout handling for sign-in challenges.
  • Tests
    • Expanded coverage for authentication flows, wallet sign-in, session recovery, and configuration validation.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@FSM1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a057931c-3840-48ba-847d-3ea3ebf90979

📥 Commits

Reviewing files that changed from the base of the PR and between af74145 and 2137b07.

📒 Files selected for processing (8)
  • apps/web/src/auth/coreKit.ts
  • apps/web/src/auth/useAuth.test.tsx
  • apps/web/src/components/auth/LogoutButton.tsx
  • apps/web/src/components/auth/WalletLoginButton.tsx
  • apps/web/src/engine/config.test.ts
  • apps/web/src/engine/config.ts
  • apps/web/src/index.css
  • apps/web/src/test/authFakes.tsx

Walkthrough

The web app adds Core Kit and SIWE authentication, authentication state orchestration, provider wiring, login and logout controls, environment validation, wallet configuration, terminal-themed styling, and related tests.

Changes

Web authentication and shell

Layer / File(s) Summary
Authentication foundations
apps/web/src/auth/*, apps/web/src/engine/config.*, apps/web/src/vite-env.d.ts
Adds Core Kit session creation and restoration, validated environment configuration, and SIWE nonce retrieval.
Authentication orchestration
apps/web/src/auth/useAuth.*, apps/web/src/providers/EngineProvider.tsx, apps/web/src/lib/errorMessage.ts, apps/web/src/test/authFakes.tsx
Coordinates login, secret handoff, session recovery, logout cleanup, engine rebuilding, error conversion, and authentication test fixtures.
Wallet authentication flow
apps/web/src/components/auth/WalletLoginButton.tsx, apps/web/src/lib/wagmi.ts
Adds wallet connector discovery and the SIWE connect, nonce, sign, submit, and disconnect flow.
Login and authenticated shell
apps/web/src/routes/LoginPage.tsx, apps/web/src/routes/FilesPage.tsx, apps/web/src/components/auth/*, apps/web/src/components/{MatrixBackground,StagingBanner}.tsx, apps/web/src/index.css, apps/web/src/styles/login.css
Adds the login screen, authentication controls, logout control, staging warning, Matrix background, and terminal-themed styles.
Application provider wiring
apps/web/src/main.tsx, apps/web/src/App.test.tsx
Wires the authentication and wallet providers into the application and updates routed rendering tests to use authentication fixtures.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the restoration of the v1 login UI and its connection to the facade.
Docstring Coverage ✅ Passed Docstring coverage is 81.48% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/804-harvest-v1-login-ui

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

FSM1 added 2 commits August 1, 2026 01:39
Brings back the login page, its three methods, and the terminal styling from
v1, driving them through the P2 login handoff instead of the v1 vault
bootstrap: Core Kit authenticates on the UI thread, the exported secret is
transferred once to the engine, and every derivation happens in Rust.

Wallet login collects the SIWE signature with wagmi and forwards it to
facade.siweLogin; logout runs facade.logout plus the Core Kit teardown.

Closes #804
Security and crypto review: wagmi no longer persists the wallet address,
the SIWE nonce fetch is bounded and timed out, the wallet signature pins
the account the message names, the Core Kit storage comment now states
what is actually persisted, and a handoff the engine refuses ends the
Core Kit session instead of leaving a live credential behind a
signed-out UI.

Altitude: the once-per-tab login guards moved to module scope so a second
useAuth consumer cannot drive a second cold start, and EngineProvider
rebuilds its client after logout rather than a leaf button reloading the
document.

Simplify and reuse: one terminal-button rule replaces three near-identical
copies, LoginError and errorMessage are shared, MatrixBackground drops
its unused props and redundant per-column canvas state writes, and dead
CSS and design tokens are gone.
@FSM1
FSM1 force-pushed the feat/804-harvest-v1-login-ui branch from 829ab79 to af74145 Compare July 31, 2026 23:41
@FSM1

FSM1 commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 55 minutes.

@FSM1

FSM1 commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 8

🧹 Nitpick comments (5)
apps/web/src/test/authFakes.tsx (1)

102-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Create the QueryClient once per wrapper.

Line 107 constructs a new QueryClient on every render of Wrapper. Wagmi hooks then lose their cache on each re-render, which makes wallet-flow tests order dependent. Build the client in the enclosing closure.

♻️ Proposed refactor
 export function pageWrapper(client: EngineClient, session: CoreKitSession) {
   const Auth = authWrapper(client, session);
+  const queries = new QueryClient();
   return function Wrapper({ children }: { children: ReactNode }) {
     return (
       <WagmiProvider config={wagmiConfig} reconnectOnMount={false}>
-        <QueryClientProvider client={new QueryClient()}>
+        <QueryClientProvider client={queries}>
           <Auth>{children}</Auth>
         </QueryClientProvider>
       </WagmiProvider>
     );
   };
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/test/authFakes.tsx` around lines 102 - 113, The pageWrapper
function currently creates a new QueryClient on every Wrapper render;
instantiate one QueryClient in the enclosing pageWrapper closure and reuse it in
QueryClientProvider, preserving the existing provider hierarchy and behavior.
apps/web/src/auth/useAuth.test.tsx (1)

20-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test for the serialized-transition guard.

useAuth keeps inFlight at module scope so a second transition rejects rather than starting a second login. No test covers that rejection. Add a case that starts a login which does not settle, then calls loginWithGoogle again and asserts the rejection message another sign-in is already in progress.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/auth/useAuth.test.tsx` around lines 20 - 38, Add a test in the
useAuth suite that starts a login with an unresolved transition, invokes
loginWithGoogle again before it settles, and asserts the second call rejects
with “another sign-in is already in progress.” Use the existing mount and fake
engine/Core Kit helpers, and ensure the pending transition is cleaned up so it
does not affect other tests.
apps/web/src/components/auth/WalletLoginButton.tsx (1)

67-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move the 0x strip into fromHex.

fromHex only accepts bare hex, so strip0x is needed here, but decoding wallet signatures in apps/web violates the UTF-8 codec boundary. Put the 0x handling in @cipherbox/client/src/seams/bytes.ts, or use hexToBytes from viem instead of adding codec state to the UI layer.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/auth/WalletLoginButton.tsx` at line 67, Update the
WalletLoginButton login flow to stop decoding the signature with fromHex and
strip0x in the UI layer; use hexToBytes from viem or move 0x-prefix handling
into the shared bytes seam, then pass the resulting bytes to onLogin.

Source: Coding guidelines

apps/web/src/index.css (2)

73-74: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fix the keyword-case lint error for text-rendering.

Stylelint flags optimizeLegibility as violating value-keyword-case. Use the lowercase keyword to satisfy the project's lint configuration.

🎨 Proposed fix for the keyword case
-  text-rendering: optimizeLegibility;
+  text-rendering: optimizelegibility;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/index.css` around lines 73 - 74, Update the text-rendering
declaration near font-synthesis to use the lowercase optimizelegibility keyword
required by the value-keyword-case lint rule.

Source: Linters/SAST tools


123-133: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace the deprecated clip property.

Stylelint flags clip as deprecated (property-no-deprecated). Use clip-path: inset(50%) for the visually-hidden pattern instead.

🎨 Proposed fix to replace the deprecated property
 .sr-only {
   position: absolute;
   width: 1px;
   height: 1px;
   padding: 0;
   margin: -1px;
   overflow: hidden;
-  clip: rect(0, 0, 0, 0);
+  clip-path: inset(50%);
   white-space: nowrap;
   border: 0;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/index.css` around lines 123 - 133, Update the .sr-only visually
hidden style to replace the deprecated clip property with clip-path: inset(50%),
while preserving the existing accessibility-focused hiding behavior and other
declarations.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/auth/coreKit.ts`:
- Around line 49-64: Update login in the CoreKit wrapper to invoke the available
Core Kit cleanup/logout flow when this.coreKit.status is not
COREKIT_STATUS.LOGGED_IN, before throwing the approval or recovery error. Ensure
partial OAuth/tKey state is cleared from the instance and local storage, while
preserving the existing commitChanges path for successful logins.

In `@apps/web/src/auth/useAuth.ts`:
- Around line 31-37: Move the login busy state from per-instance useAuth state
into shared auth state, such as authStore or an external store consumed by
useSyncExternalStore. Update the useAuth login flow and all isBusy reads so
every useAuth consumer observes the same in-flight transition, including
disabling LogoutButton while LoginPage is authenticating; preserve the existing
inFlight guard and error behavior.

In `@apps/web/src/components/auth/LogoutButton.tsx`:
- Around line 9-22: Update the LogoutButton signOut invocation to catch and
swallow rejected logout promises, matching LoginPage’s established
login.catch(() => undefined) handling while preserving the existing
navigate('/') finally behavior.

In `@apps/web/src/components/auth/WalletLoginButton.tsx`:
- Around line 83-95: Update the WalletLoginButton component’s picking flow to
move focus to the first interactive wallet-picker element after the picker
renders, and restore focus to the [WALLET] trigger when cancellation closes it.
Use refs and an effect or equivalent lifecycle handling tied to picking,
preserve existing busy/no-provider behavior, and verify the keyboard focus path
in the browser.
- Around line 49-53: In the WalletLoginButton connection flow, validate that
accounts contains a usable first account immediately after connectAsync returns
and before setPhase('signing') or createSiweMessage. Handle the empty-account
case through the existing user-facing error path, and only build the SIWE
message when accounts[0] is defined.

In `@apps/web/src/components/StagingBanner.tsx`:
- Line 8: Update the root banner element in StagingBanner to use role="alert"
instead of role="banner", and remove its aria-live="polite" attribute while
preserving the existing test id and className.

In `@apps/web/src/engine/config.ts`:
- Around line 10-12: Update apiBaseUrl to treat an empty VITE_API_URL as absent,
matching the existing environment helper, so it returns DEFAULT_API_URL instead
of propagating an empty string to EngineHostConfig and URL construction.

In `@apps/web/src/main.tsx`:
- Line 33: Update the createCoreKitSession flow used by CoreKitProvider so
Web3AuthMPCCoreKit does not receive window.localStorage for device-factor or
login-state persistence; configure session restoration to require a new factor
or use the project’s supported non-Web-Storage/ephemeral storage option, while
preserving normal session creation.

---

Nitpick comments:
In `@apps/web/src/auth/useAuth.test.tsx`:
- Around line 20-38: Add a test in the useAuth suite that starts a login with an
unresolved transition, invokes loginWithGoogle again before it settles, and
asserts the second call rejects with “another sign-in is already in progress.”
Use the existing mount and fake engine/Core Kit helpers, and ensure the pending
transition is cleaned up so it does not affect other tests.

In `@apps/web/src/components/auth/WalletLoginButton.tsx`:
- Line 67: Update the WalletLoginButton login flow to stop decoding the
signature with fromHex and strip0x in the UI layer; use hexToBytes from viem or
move 0x-prefix handling into the shared bytes seam, then pass the resulting
bytes to onLogin.

In `@apps/web/src/index.css`:
- Around line 73-74: Update the text-rendering declaration near font-synthesis
to use the lowercase optimizelegibility keyword required by the
value-keyword-case lint rule.
- Around line 123-133: Update the .sr-only visually hidden style to replace the
deprecated clip property with clip-path: inset(50%), while preserving the
existing accessibility-focused hiding behavior and other declarations.

In `@apps/web/src/test/authFakes.tsx`:
- Around line 102-113: The pageWrapper function currently creates a new
QueryClient on every Wrapper render; instantiate one QueryClient in the
enclosing pageWrapper closure and reuse it in QueryClientProvider, preserving
the existing provider hierarchy and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 319897e4-5674-4cda-85f3-da71e889f924

📥 Commits

Reviewing files that changed from the base of the PR and between fefcfbe and af74145.

📒 Files selected for processing (26)
  • apps/web/src/App.test.tsx
  • apps/web/src/auth/CoreKitProvider.tsx
  • apps/web/src/auth/coreKit.ts
  • apps/web/src/auth/siweNonce.test.ts
  • apps/web/src/auth/siweNonce.ts
  • apps/web/src/auth/useAuth.test.tsx
  • apps/web/src/auth/useAuth.ts
  • apps/web/src/components/MatrixBackground.tsx
  • apps/web/src/components/StagingBanner.tsx
  • apps/web/src/components/auth/EmailLoginForm.tsx
  • apps/web/src/components/auth/GoogleLoginButton.tsx
  • apps/web/src/components/auth/LoginError.tsx
  • apps/web/src/components/auth/LogoutButton.tsx
  • apps/web/src/components/auth/WalletLoginButton.tsx
  • apps/web/src/engine/config.test.ts
  • apps/web/src/engine/config.ts
  • apps/web/src/index.css
  • apps/web/src/lib/errorMessage.ts
  • apps/web/src/lib/wagmi.ts
  • apps/web/src/main.tsx
  • apps/web/src/providers/EngineProvider.tsx
  • apps/web/src/routes/FilesPage.tsx
  • apps/web/src/routes/LoginPage.tsx
  • apps/web/src/styles/login.css
  • apps/web/src/test/authFakes.tsx
  • apps/web/src/vite-env.d.ts

Comment thread apps/web/src/auth/coreKit.ts
Comment thread apps/web/src/auth/useAuth.ts
Comment thread apps/web/src/components/auth/LogoutButton.tsx
Comment thread apps/web/src/components/auth/WalletLoginButton.tsx Outdated
Comment thread apps/web/src/components/auth/WalletLoginButton.tsx
Comment thread apps/web/src/components/StagingBanner.tsx
Comment thread apps/web/src/engine/config.ts
Comment thread apps/web/src/main.tsx
Drop the partial Core Kit session when a login lands short of LOGGED_IN,
swallow the rejected logout promise the button discarded, guard an empty
wallet account tuple, move keyboard focus with the wallet picker, and read
a blank VITE_API_URL as unconfigured rather than as a base URL.
@FSM1

FSM1 commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

Nitpick verdicts

The five nitpicks live in the review body rather than in threads, so the verdicts are here. Fixes are in 2137b07.

apps/web/src/test/authFakes.tsx:102-113 — create the QueryClient once per wrapper. Fixed. pageWrapper now builds one client in the enclosing closure so wagmi's cache survives a re-render instead of being rebuilt under it.

apps/web/src/auth/useAuth.test.tsx:20-38 — cover the serialized-transition guard. Added, as "refuses a second sign-in while the first is still in flight". It parks the first login on an unresolved facade.start, asserts the second call rejects with another sign-in is already in progress and that Core Kit saw only one login, then releases the pending promise so the module-scoped inFlight does not leak into the rest of the file. apps/web is now 9 files / 67 tests, all green.

apps/web/src/components/auth/WalletLoginButton.tsx:67 — move the 0x strip out of the UI layer. Fixed, by the viem route. hexToBytes(signature) replaces fromHex(strip0x(signature)) and the local strip0x helper is gone. viem is already this file's SIWE dependency and it is what produced the hex, so the decode now lives with the library that owns the format instead of in a UI-local helper.

apps/web/src/index.css:73-74 — lowercase optimizeLegibility. Not applied. There is no Stylelint in this repo — no config file and no dependency:

$ find . -name '.stylelintrc*' -not -path '*/node_modules/*'   # no output
$ rg -n stylelint --glob package.json --glob '!**/node_modules/**'   # no output

value-keyword-case is therefore not a gate here, and optimizeLegibility is the spelling the CSS Fonts spec and MDN use. Lowercasing it to satisfy a linter that is not configured would trade readability for nothing.

apps/web/src/index.css:123-133 — replace the deprecated clip. Applied, on its own merits rather than the lint one. clip is genuinely deprecated and .sr-only is live — apps/web/src/components/auth/EmailLoginForm.tsx:27 uses it for the email field's label — so clip-path: inset(50%) is the right modern spelling of the pattern.

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.

web: harvest the v1 login UI and rewire it to the facade

1 participant