Skip to content

feat(wifi): detect wrong WiFi password during setup and surface it - #166

Merged
KrasimirKralev merged 6 commits into
betafrom
feature/wifi-wrong-password-feedback
Jun 5, 2026
Merged

KrasimirKralev merged 6 commits into
betafrom
feature/wifi-wrong-password-feedback

Conversation

@KrasimirKralev

Copy link
Copy Markdown
Contributor

Summary

During first-boot setup the single-radio box tears down its ClawBox-Setup hotspot to join the user's Wi-Fi. If the password was wrong, the box couldn't join and silently reopened the AP — the user just saw the box "disappear." This detects that failure and surfaces it so they can retry.

What changed

  • network.tsswitchToClient caps the connect at --wait 20, detects a wrong key (WRONG_KEY in the wpa_supplicant journal) and breaks early with a WifiAuthError, and restores the AP fast on failure (SKIP_PRESCAN). A small in-memory ConnectStatus follows the existing scan-status convention.
  • wifi/connect is now fire-and-forget (returns connecting immediately — the synchronous response can't survive the AP teardown); new wifi/connect-status GET lets the wizard poll the outcome.
  • WifiStep polls connect-status and shows a clear "wrong password" / "switching…" message; StatusMessage gains an info variant.
  • translations.tswifi.switching + wifi.wrongPassword.

Verification

Verified on a Jetson end-to-end: a wrong password now surfaces "Wrong Wi-Fi password" (instead of the box vanishing) and the AP reopens for a retry; a correct password completes the handoff.

Scope / notes

Setup Wi-Fi step only. This is the base of a stack — the ethernet-first WiFi step builds on the ConnectStatus / poll plumbing here, so a couple of ConnectStatus fields written here (ssid, at) are consumed by that follow-up, not this PR.

The setup WiFi connect is a single-radio handoff: joining the home network
tears down the setup hotspot, so the browser loses the box mid-connect and a
synchronous result never arrives — the wizard just appeared to hang, with no
indication a wrong password was the cause.

- network.ts: detect the WPA 4-way-handshake failure (wpa_supplicant WRONG_KEY,
  readable by the clawbox service via the adm group), fail fast instead of
  burning 3x90s retries, and throw a typed WifiAuthError. Add a pollable
  connect-status and a --wait 20 cap.
- wifi/connect: run switchToClient fire-and-forget, return {status:connecting}
  immediately (before the AP drops), record the outcome in connect-status.
- wifi/connect-status (new): GET endpoint the wizard polls across the outage.
- WifiStep: poll the status; show wrong-password / connected / handoff hint.
- StatusMessage: add info variant; i18n: wifi.switching + wifi.wrongPassword.
… settle, longer poll)

The wrong-password path was ~80-118s because restoring the AP re-ran the 20s
pre-scan and raced the still-busy radio. Skip the pre-scan when restoring after
a failed connect (SKIP_PRESCAN), add a settle delay before the first restore
attempt, and widen the wizard poll deadline to 130s so a slow restore can't trip
it into mis-reporting a wrong password as success.
@KrasimirKralev
KrasimirKralev requested a review from a team as a code owner June 5, 2026 08:44
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@KrasimirKralev, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 1 minute and 15 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b3e650cf-30c1-436d-a389-b1685a965be9

📥 Commits

Reviewing files that changed from the base of the PR and between a7ab420 and 5e7d47f.

📒 Files selected for processing (9)
  • e2e/helpers/clawbox.ts
  • scripts/start-ap.sh
  • src/app/setup-api/wifi/connect-status/route.ts
  • src/app/setup-api/wifi/connect/route.ts
  • src/components/StatusMessage.tsx
  • src/components/WifiStep.tsx
  • src/lib/network.ts
  • src/lib/translations.ts
  • src/tests/routes/wifi/connect.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/wifi-wrong-password-feedback

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 and usage tips.

…fire-and-forget

- translations.ts: add wifi.switching + wifi.wrongPassword to the 8 remaining
  locales (de/es/fr/it/ja/nl/sv/zh) — the key-parity test requires every locale
  to carry the same keys as en.
- connect.test.ts: the route is now fire-and-forget (returns 'connecting' and
  reports the outcome via the background switchToClient -> setConnectStatus).
  Mock setConnectStatus/WifiAuthError and drive the background with fake timers,
  asserting the recorded status (incl. reason=wrong-password).
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

CI Summary

✅ E2E Install

✅ Tests

  • Result: passed
  • View run
  • Coverage: statements 70.5%, branches 60.08%, functions 66.25%, lines 72.65%

✅ E2E

…sted

vi.mock is hoisted above the file body, so referencing a top-level class in
its factory threw 'Cannot access FakeWifiAuthError before initialization' and
the suite loaded 0 tests. Move the stub into vi.hoisted() so it exists when
the hoisted factory runs.
The wrong-password feature made /wifi/connect fire-and-forget: it returns
"connecting" and the wizard polls /wifi/connect-status for the outcome,
only advancing on phase="connected". The e2e mock still returned the old
{success:true} and never mocked connect-status, so the poll never resolved
and every setup spec timed out waiting for the credentials step.
The update step auto-advances to credentials as soon as it finds nothing to
install. With test timers capped by installClawboxMocks, that can happen
before Playwright catches the update step on screen, so the hard
expect(updateStep).toBeVisible() was losing the race (consistently for
setup-final-loading, flakily for setup-happy-path). Wait for whichever of
update/credentials appears first, and only drive the Continue button when the
update step is actually present.
@KrasimirKralev
KrasimirKralev merged commit 61cb48e into beta Jun 5, 2026
7 checks passed
KrasimirKralev added a commit that referenced this pull request Jun 5, 2026
Resolve WifiStep.tsx: keep beta's fire-and-forget connect-status poll flow
(from #166's wrong-password detection) and surface the IP-primary URL
(primaryUrl from useDeviceAddress) in all connect status messages, since
#164's hook no longer exposes localUrl.
KrasimirKralev added a commit that referenced this pull request Jun 5, 2026
The beta merge layered setup-step1's and #166's copies of these keys in 8
locales; the build rejects duplicate object keys. Keep the copy placed after
wifi.connectedMessage (matches the en/bg canonical structure).
@KrasimirKralev
KrasimirKralev deleted the feature/wifi-wrong-password-feedback branch July 4, 2026 17:41
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