Skip to content

feat(dw-desktop): surface env auth type, edit credentials, friendlier connection errors#25

Open
nicped wants to merge 1 commit into
mainfrom
feat/env-auth-visibility-and-errors
Open

feat(dw-desktop): surface env auth type, edit credentials, friendlier connection errors#25
nicped wants to merge 1 commit into
mainfrom
feat/env-auth-visibility-and-errors

Conversation

@nicped

@nicped nicped commented Jun 1, 2026

Copy link
Copy Markdown
Member

What & why

Three related improvements to the environment/auth experience in dw-desktop, driven by usability gaps:

1. Auth type is visible in the environment list

Each row in the sidebar now shows a small badge — API key, OAuth, or Username — so you can tell at a glance how each environment authenticates.

2. Edit environment can change auth mode & credentials

The Edit dialog previously only let you change the display name, host, and local folder. It now mirrors the Add flow's auth section:

  • Client ID and Username are loaded back from the keychain and pre-filled (these aren't secrets), so you can see and edit them.
  • Client secret, API key, and Password stay as masked fields and start blank — blank means "keep the current credential", entering a value replaces it.
  • The stored API key is shown as an obfuscated hint (abcd…wxyz) so you can recognize which key is in use when comparing environments. The raw key is never returned to the renderer.
  • Switching auth type requires fresh credentials; OAuth requires client id + secret together.

Supporting changes: the username is now persisted for password auth (it was previously discarded), and both Add and Edit exchange password credentials for an API key via loginPassword.

3. Connection errors are surfaced and humanized

Previously a failed remote connection just showed an empty pane.

  • loadRemote now records the failure; the remote pane shows an error banner with a Retry button, and a toast fires when the initial connect fails.
  • Low-level errors are translated into plain language via a new shared humanizeAuthError helper:
    • fetch failed / ENOTFOUND"Couldn't reach "host". Check that the address is correct and the site is online."
    • OAuth token request failed (401) / invalid_client"Authentication failed. Double-check your credentials for this environment."
    • plus 404 / 5xx / timeout / TLS / missing-credentials variants.
  • The original technical text is still preserved in the Debug panel.

Security notes

  • Secrets remain write-only from the renderer's perspective. The new auth:getHints IPC returns only client id, username, and an obfuscated API-key preview — never the full secret.

Testing

  • npm run typecheck — clean.
  • npm test36 passing (added coverage for humanizeAuthError, obfuscateSecret, getCredentialHints (asserts the raw key never leaks), username persistence, and updated the listFiles 401 assertion to the humanized message).

Notes / caveats

  • The large diff in dw-api.ts and DualPaneBrowser.tsx is mostly Prettier reflowing pre-existing long lines in files I touched — the functional changes are small.
  • Password-auth environments created before this change have no stored username, so their Username field starts blank until credentials are next saved (a never-persisted username can't be recovered).

🤖 Generated with Claude Code

… connection errors

Environment list now shows an auth-type badge (API key / OAuth / Username).

Edit environment can now change the auth mode and credentials, mirroring the
Add flow. Non-secret values (client id, username) are loaded back from the
keychain and pre-filled; secrets stay write-only and blank-means-unchanged.
The stored API key is shown as an obfuscated hint (abcd…wxyz) so the active
key is recognizable when comparing environments. Username is now persisted
for password auth, and both modals exchange password credentials for an API
key via loginPassword.

Connection failures are no longer silent: loadRemote records the error, the
remote pane shows an error banner with Retry, and a toast fires on connect.
Low-level errors (fetch failed, OAuth 401, ...) are translated into plain
language via a shared humanizeAuthError helper; the raw text is still kept in
the Debug panel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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