feat: [ENG-1540] style localhost OAuth callback page to match brv brand#566
feat: [ENG-1540] style localhost OAuth callback page to match brv brand#566cuongdo-byterover wants to merge 3 commits intomainfrom
Conversation
The local HTTP callback served after `brv login` was responding with plain text on a default white page, which clashed with the brv dark theme. Replace it with self-contained HTML that mirrors the design spec: black background with a soft green/warm radial glow, faint grid overlay, brand wordmark, and a centered card carrying a status icon, heading, and supporting copy. Also adds a matching error variant that shows the OAuth error message in a red-tinted code block. Auto-closes the tab 2.5s after success.
|
Claude finished @cuongdo-byterover's task in 1m 14s —— View job PR Review: feat: [ENG-1540] Style localhost OAuth callback page
SummaryThe change replaces a plain-text HTTP response with a self-contained, branded HTML page for the OAuth callback. The implementation is clean and well-structured. XSS is correctly handled via the Overall score: 3 / 5 Issuesblocker — Missing tests (
|
Addresses the PR #566 review feedback: - Export `escapeHtml` and add tests covering the five HTML metacharacters, passthrough for safe text, ampersand-first ordering, and a realistic XSS payload. - Add `firstQueryParam` helper to safely coerce Express's `string | string[] | ParsedQs | ParsedQs[]` query values into a single string. Use it for `error`, `error_description`, `code`, and `state` so arrays and nested objects can no longer reach the user-facing message. - Add HTTP-level tests for the three `/callback` branches: success (200 + branded HTML + BYTEROVER wordmark), provider error (400 + escaped description), and missing code/state (400 + diagnostic). - Note in the inline `<script>` that auto-close would be blocked under a strict CSP, so future-proofing is captured if a CSP is ever added.
|
Claude finished @cuongdo-byterover's task in 1m 28s —— View job PR Review: feat: [ENG-1540] Style localhost OAuth callback page
SummaryBoth blockers from the previous review are now resolved: Overall score: 4 / 5 Issuesissue —
|
Browsers refuse to honour `window.close()` on tabs they did not open themselves. The OAuth tab is opened by `brv login` via an OS shell command (open / xdg-open / start), so the inline `setTimeout(() => window.close(), 2500)` was a silent no-op in every supported browser since 2022 and only added an unnecessary inline-script CSP risk. Drop the script. The success page already tells the user "You can now safely close this tab", which is the correct affordance for a manually opened tab. Also relax the firstQueryParam helper signature so the parameter is optional, matching the practical usage where Express may omit a missing key entirely.
|
Claude finished @cuongdo-byterover's task in 1m 56s —— View job PR Review: feat: [ENG-1540] Style localhost OAuth callback page
SummaryAll issues from the two previous review rounds are now resolved. The remaining typecheck failure ( Overall score: 5 / 5 Changes since last reviewFixed — Dropped — The Remaining nitpick (pre-existing, out of scope)
Positives
|
The local HTTP callback served after
brv loginwas responding with plain text on a default white page, which clashed with the brv dark theme. Replace it with self-contained HTML that mirrors the design spec (Figma: CLI-focused, node9584-10575): black background with a soft green/warm radial glow, faint grid overlay, BYTEROVER wordmark, and a centered card carrying a status icon, heading, and supporting copy. Adds a matching error variant that shows the OAuth error message in a red-tinted code block.Summary
brv login, the localhost OAuth callback rendered plain text on a default white background — visually jarring against the rest of brv's dark surface./callbackroute on the localhost OAuth callback server now responds with self-contained HTML (success + error variants) styled to match the Figma spec. Plus afirstQueryParamguard that coerces Express'sstring | string[] | ParsedQs | ParsedQs[]query values to a single string, and full unit coverage of both helpers and the three response variants./callbackroute shape, env vars, or any other CLI surface. Auto-closing the tab is also out of scope (browser security restriction — see Risks).Type of change
Scope (select all touched areas)
Linked issues
Root cause (bug fixes only, otherwise write
N/A)src/server/infra/http/callback-server.tsresponded toGET /callbackwithres.status(200).send('Authentication successful. You can close this window.')— plain text against the browser default white. No theming, no brand, no logo.Test plan
test/unit/infra/http/callback-server.test.tsescapeHtml— five metachars, safe-text passthrough, ampersand-first ordering (avoids double-escaping), realistic XSS payloadfirstQueryParam— string / array of strings / empty array / non-string-first array / object / number / null / undefinedGET /callbacksuccess → 200,Content-Type: text/html, body containsAuthentication Successful+BYTEROVERGET /callbackwitherror+error_description→ 400, body containsAuthentication Failed+ the escaped descriptionGET /callbackwith<script>inerror_description→ escaped entities present, raw tag absentGET /callbackwith missingstate→ 400, body containsMissing code or state parameterUser-visible changes
brv login, the browser tab now shows a dark, branded confirmation page instead of plain text on white.window.close()on tabs they did not open themselves, so the script was a silent no-op. The copy directs the user to close manually, which is the correct affordance.Evidence
Checklist
npm test)npm run lint)npm run typecheck)npm run build)mainRisks and mitigations
res.send(SUCCESS_HTML)becomesres.redirect(...).<style>on the response would be blocked if a strict CSP is ever added to this localhost server.