Skip to content

fix(tunnel): surface daemon login failures + 401 status hint - #29

Merged
racerxdl merged 1 commit into
mainfrom
teske/fix-hsh-login-daemon-silent-skip
Jun 3, 2026
Merged

racerxdl merged 1 commit into
mainfrom
teske/fix-hsh-login-daemon-silent-skip

Conversation

@racerxdl

@racerxdl racerxdl commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Problem

Two related UX gaps found while using the newest build against sandbox.hoop.dev:

  1. hsh login silently skipped a failed daemon login. loginDaemon(optional:true) treated every 'daemon not usable' case — including a daemon that is installed but whose control token couldn't be read — as 'not installed' and skipped silently. So hsh login reported success while the daemon kept its old (expired) token. The only way to recover was to discover hsh tunnel login and run it by hand.

  2. hsh tunnel status showed Auth: authenticated next to an opaque 401 Unauthorized. The daemon reports 'authenticated' whenever it merely holds a token; a rejected/expired token only surfaces as a buried last_error HTTP string, leaving the user with no idea the fix is to log in again.

Fix

  1. Distinguish absent vs. present-but-unusable. Optional-mode now only skips silently when the daemon is genuinely absent (no IPC socket on disk). When the socket exists but the daemon is unreachable / unconfigured / its login errors, loginDaemon warns —

    Your CLI is logged in, but the tunnel daemon still holds its previous token.
    Run hsh tunnel login to update the daemon.

    — and returns false; hsh login exits non-zero so the failure is visible. The CLI login itself still succeeds (only the daemon leg is flagged).

  2. hsh tunnel status auth hint. A new isAuthError heuristic detects 401 / unauthorized / access denied / token-expired in last_error and prints a concrete next step pointing at hsh tunnel login.

Testing

  • tests/login-daemon.test.ts: absent daemon → silent skip; installed-but-unauthenticatable → returns false. Driven via the HSH_TUNNELD_SOCKET override, no real daemon contacted.
  • tests/tunnel-status-auth-hint.test.ts: isAuthError matches the real serverinfo 401 string and bare auth signals, ignores network/route failures.
  • Full suite: 445 pass, typecheck clean.

Context

Root cause of the stale token was the daemon storing a 12h-expiry access token with no refresh path; that's a separate, larger discussion. This PR makes the failure mode honest and actionable rather than silent.

Automated by MisterMal

Two UX fixes uncovered in the field:

1. hsh login silently skipped a FAILED daemon login
   loginDaemon(optional:true) treated every 'daemon not usable' case —
   including a daemon that IS installed but whose control token we
   couldn't read — as 'not installed' and skipped silently. Result:
   hsh login reported success while the daemon kept its old (expired)
   token, forcing the user to discover and run hsh tunnel login by hand.

   Now optional-mode only skips silently when the daemon is GENUINELY
   absent (no IPC socket on disk). When the socket exists but we can't
   reach it, it's unconfigured, or its login errors, loginDaemon warns
   ('CLI is logged in but the daemon still holds its previous token —
   run hsh tunnel login') and returns false; hsh login then exits
   non-zero so the failure is visible.

2. hsh tunnel status now hints re-login on auth errors
   The daemon shows Auth=authenticated whenever it merely holds a
   token; a rejected/expired token only appeared as a buried
   '401 Unauthorized / access denied' in last_error. status now detects
   that (isAuthError) and prints a concrete next step:
   'saved login expired or was rejected — hsh tunnel login'.

Tests: login-daemon.test.ts (absent → silent skip; present-but-unusable
→ failure) and tunnel-status-auth-hint.test.ts (isAuthError matches the
real serverinfo 401 string and the bare auth signals, ignores
network/route failures).

 🤖 Generated with Mister Maluco

Co-Authored-By: MisterMal <teskeslab@lucasteske.dev>
@racerxdl racerxdl added the bug Something isn't working label Jun 3, 2026
@racerxdl
racerxdl merged commit bae6106 into main Jun 3, 2026
3 checks passed
@racerxdl
racerxdl deleted the teske/fix-hsh-login-daemon-silent-skip branch June 3, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant