Skip to content

[fix] stop leaking the Go package prefix into the UI - #151

Merged
malickyeu merged 6 commits into
mainfrom
fix/error-prefix
Aug 6, 2026
Merged

[fix] stop leaking the Go package prefix into the UI#151
malickyeu merged 6 commits into
mainfrom
fix/error-prefix

Conversation

@malickyeu

Copy link
Copy Markdown
Contributor

Summary

Two things, both found by taking screenshots of the 1.6.0 authentication work.

Error messages were reaching the UI with their Go package prefix. Every error in this codebase carries one — auth: this account already has the maximum number of authenticators — which is right for a log line and wrong on a screen. It showed up as auth: passkeys need HTTPS (or localhost) under the greyed-out Add a passkey button, and I only noticed because it was in a picture about to be committed to the manual.

Stripped in writeErr, so every handler gets it without having to remember, and on /auth/webauthn/support's reason field. By an allowlist of this app's own prefixes rather than "everything before the first colon" — messages legitimately contain colons, and eating half of cannot reach host: connection refused would be worse than the prefix.

Three screenshots the 1.6.0 work had none of. Everything shipped in #141#148 lives on /profile and the sign-in screen, and the generator visited neither.

  • login.png — the sign-in screen with the passkey option beside the password.
  • login_2fa.png — the second step, offering the code box and a passkey.
  • profile_security.png — sessions, both kinds of factor, and the passwordless switch.

Referenced from docs/getting-started.md and docs/users.md.

Generator changes

  • A /profile shot that opens the Security tab.
  • A logged-out pass before the API login, so the sign-in screen can be photographed at all.
  • The login goto no longer swallows errors. It had a .catch(() => {}), which on a refused connection screenshotted a blank page and reported ✓ login. That is how the first attempt at this produced an empty PNG.

Type of change

  • Bug fix
  • New feature
  • Docs only
  • Refactor / chore

Checklist

  • go test -short ./... and go vet ./... pass
  • gofmt gate is clean
  • Frontend type-checks — no UI source change
  • Rebuilt web/dist — nothing under web/src changed
  • Added tests for the change
  • Updated docs/ and CHANGELOG.md

Notes for reviewers

New internal/api/respond_test.go covers both the allowlist behaviour and the end-to-end strip; mutation-verified by reverting writeErr to pass the message through.

The screenshots were taken against a throwaway instance on a temp data dir with seeded demo accounts, not against a real deployment — the Security tab shows live session IPs and user agents, and those should not be in a public manual. The Docker-derived pages are untouched here; re-shooting those still needs an instance with real data.

Worth knowing for whoever re-runs the generator: the shots must be taken over http://localhost:…, not http://127.0.0.1:…. An IP literal cannot be a WebAuthn relying party, so every passkey control correctly renders as unavailable — which is exactly what the first run produced.

Every error here carries one — "auth: this account already has the maximum
number of authenticators" — which is right for a log and wrong on a screen. It
reached one as "auth: passkeys need HTTPS (or localhost)", under the greyed-out
Add a passkey button, and I only saw it because it was in a screenshot going into
the manual.

Stripped in writeErr, so every handler gets it without remembering to, by an
allowlist of our own prefixes — "everything before the first colon" would eat
half of "cannot reach host: connection refused".

Also adds the three screenshots the 1.6.0 work had none of: the sign-in screen,
the second step offering a passkey beside the code, and Profile → Security with
sessions, both kinds of factor and the passwordless switch. The generator grew a
/profile shot and a logged-out pass; its login goto no longer swallows a refused
connection, which had silently produced a blank PNG.
Copilot AI lite review requested due to automatic review settings August 6, 2026 14:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

After a wrong password the page stays on the sign-in form, which the second-step
check read as "this instance signed in without a second factor" — blaming the
instance for a wrong DC_PASS. It now says the credentials were refused.
Copilot AI review requested due to automatic review settings August 6, 2026 14:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The second-step shot submitted the sign-in form BEFORE the API login, so every
run spent two attempts. The server allows five per fifteen minutes, so two runs
with a typo locked the operator out of their own instance — which is a poor thing
for a screenshot tool to do.

The form is now driven only after the API login has confirmed the credentials,
where it costs a successful login and resets the budget instead. A 429 says how
to clear it: restart, the limiter is in memory.
Copilot AI review requested due to automatic review settings August 6, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The committed set was shot by hand at 2560x1353; the generator produces
2560x1440. Re-shot through the generator so the manual is finally consistent, and
so the pages that changed in 1.6.0 show what they now do.

Profile → Security keeps the demo-instance shot deliberately: it shows an
authenticator app and a passkey side by side with passwordless sign-in turned on,
which is what the page is documenting. A shot from a real instance shows whatever
that operator happens to have paired, plus their live session addresses.

The generator gained the five agendas it could not reach: the three Settings
tabs, the network graph view and the new-project dialog.
Copilot AI review requested due to automatic review settings August 6, 2026 14:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Settings' three tabs, the network graph view and the new-project dialog were the
last ones still at the hand-shot 2560x1353. The whole set is now one resolution.

Checked before committing: the Email and LDAP tabs are unconfigured on the
instance they came from, so they show placeholder hosts rather than anyone's real
mail relay or directory.
Copilot AI review requested due to automatic review settings August 6, 2026 14:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

# Conflicts:
#	CHANGELOG.md
Copilot AI review requested due to automatic review settings August 6, 2026 15:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@malickyeu
malickyeu merged commit 9d9b33f into main Aug 6, 2026
3 checks passed
@malickyeu
malickyeu deleted the fix/error-prefix branch August 6, 2026 15:25
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.

2 participants