Improve auth flow and append code in auth request URL#102
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a helper to build auth URLs with an optional one-time code query parameter, updates browser-fallback messaging and one-time code placement in formatter/UI, and adds tests for URL construction and updated formatting behavior. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
internal/output/events.go (1)
59-79: Add first-class emit helpers for the new status events.
InstanceInfoEventandServiceResourcesEventare in theEventunion now, but callers still have to fall back to the genericEmit, and the usual helper/test pattern for new events is incomplete. MatchingEmitInstanceInfo/EmitServiceResourceshelpers would keep producers consistent and make parity coverage easier to extend.♻️ Suggested helpers
+func EmitInstanceInfo(sink Sink, event InstanceInfoEvent) { + Emit(sink, event) +} + +func EmitServiceResources(sink Sink, event ServiceResourcesEvent) { + Emit(sink, event) +}Based on learnings: When adding a new event type, update
internal/output/events.go(event type +Eventunion constraint + emit helper),internal/output/plain_format.go(line formatting fallback), and tests ininternal/output/*_test.gofor formatter/sink behavior parity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/output/events.go` around lines 59 - 79, Add first-class emitter helpers for the two new event types so callers don't need to call the generic Emit directly: implement EmitInstanceInfo(ctx, e InstanceInfoEvent) and EmitServiceResources(ctx, e ServiceResourcesEvent) (matching the existing helper signatures/pattern used by other events) and have them call the generic Emit with the concrete struct; update any tests to use these helpers. Ensure you reference the types InstanceInfoEvent and ServiceResourcesEvent and follow the existing helper naming/parameter conventions used by other emit helpers in this package so formatter/sink parity remains consistent.internal/ui/app.go (1)
151-159: Avoid duplicatingAuthEventwording in the TUI.The new fallback text now lives here and in
internal/output/plain_format.go, so plain and TUI rendering can drift on the next copy change. Prefer deriving the text from the shared formatter and only applying TUI-specific styling in this branch.Based on learnings: UI should consume shared output events directly; reuse
FormatEventLine(event any)for line-oriented rendering so plain and TUI stay consistent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/ui/app.go` around lines 151 - 159, The TUI branch handling the AuthEvent duplicates plain-text wording instead of reusing the shared formatter; change the AuthEvent case in the switch (the block that appends to a.lines using appendLine and styledLine) to call the shared FormatEventLine(event any) (or the existing formatter function) to obtain the canonical line(s) for the event and then apply only TUI-specific styling (e.g., wrap/mark as secondary) before appending to a.lines, so the TUI text stays consistent with internal/output/plain_format.go; keep the existing styledLine/appendLine usage but derive the content from FormatEventLine rather than hardcoding strings.internal/output/plain_format.go (1)
151-153: Prefer emulator wording in the status details.
CONTAINER:is now part of the user-facing status output. That exposes the runtime implementation instead of the emulator concept the CLI uses elsewhere.Based on learnings: In user-facing CLI/help/docs, prefer
emulatorovercontainer/runtime; usecontainer/runtimeonly for internal implementation details.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/output/plain_format.go` around lines 151 - 153, Replace the user-facing "CONTAINER: "+e.ContainerName entry with emulator wording so the status shows the emulator label; modify the code that appends to meta (the block that checks e.ContainerName in plain_format.go) to use "EMULATOR: " (or the agreed-upon emulator label) instead of "CONTAINER: ", leaving the rest of the logic (e.ContainerName and meta append) unchanged.test/integration/status_test.go (1)
15-23: Force non-interactive mode in these tests.These assertions are for plain-text output, but the command path is chosen at runtime. Right now the tests rely on whatever
runLstkdoes with stdio; if that ever becomes terminal-backed,statuswill switch to Bubble Tea and these tests will become flaky or hang. Please pass the non-interactive flag/env explicitly here so the plain-sink path is pinned.As per coding guidelines:
**/integration/**/*_test.go: "Integration tests that run the CLI binary with Bubble Tea must use a PTY (github.com/creack/pty) since Bubble Tea requires a terminal; usepty.Start(cmd)instead ofcmd.CombinedOutput()..."Also applies to: 25-59, 61-87
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/integration/status_test.go` around lines 15 - 23, The test TestStatusCommandFailsWhenNotRunning (and the other tests in ranges 25-59 and 61-87) currently invoke runLstk which may pick a terminal-backed path and trigger Bubble Tea; update these tests to force non-interactive/plain-sink mode by passing the explicit non-interactive flag or environment to runLstk (e.g., add "--no-interactive" or set a NO_INTERACTIVE env var via the runLstk call) so the CLI takes the plain-text path; modify the calls to runLstk(testContext(t), ...) in TestStatusCommandFailsWhenNotRunning and the other affected tests to include that non-interactive indicator so assertions against stderr/stdout remain stable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/auth/login.go`:
- Around line 39-45: The call to browser.OpenURL(authURL) in the login flow
currently discards its error; update the login handler to check the returned
error from browser.OpenURL(authURL) and handle it (e.g., log a warning via
processLogger or l.sink, or return the error up the call stack) instead of
ignoring it. Locate the code around buildAuthURL(...), output.EmitAuth(...), and
the browser.OpenURL(authURL) call and ensure the OpenURL error is captured,
logged with context (including authURL or authReq.ID), and then either
propagated from the enclosing function or used to trigger a fallback path (such
as instructing the user to open authURL manually).
In `@internal/container/status.go`:
- Around line 122-125: The loop that parses NDJSON lines currently does
json.Unmarshal into the local variable chunk (map[string][]instanceResource) and
simply continues on error, which silently drops malformed resource chunks;
change this to surface the problem by returning or propagating an error (or at
minimum logging a warning) instead of continuing: when
json.Unmarshal([]byte(line), &chunk) fails, call the enclosing function's error
return (or processLogger.Warn/Error with the line content and err) so callers
see incomplete parsing; update the code path that uses chunk (the loop handling
map[string][]instanceResource) to handle the propagated error accordingly.
- Around line 35-58: The code currently leaks internal container identifiers via
c.Name() into error messages and the user-facing output
(InstanceInfoEvent.ContainerName); update the runtime checks and event
population to use the user-facing label c.DisplayName() instead of the raw
container name: replace uses of name in fmt.Errorf("checking %s running: %w",
...) and fmt.Errorf("%s is not running", ...) with c.DisplayName(), and set
InstanceInfoEvent.ContainerName = c.DisplayName() (keep using c.Name() only for
internal calls to rt.IsRunning and rt.ContainerStartedAt where the real
identifier is required).
In `@internal/output/plain_format.go`:
- Around line 101-105: The renderer currently prints the manual fallback copy
whenever AuthEvent.URL is set because AuthEvent only has Preamble/URL; fix by
making AuthEvent carry a domain fact for which flow is active (e.g., add a
Mode/Flow enum or a bool like BrowserFlow/ManualFallback on the AuthEvent
struct) and update the plain_format.go rendering logic that reads e.URL to
branch on that new field: when Mode==auto (browser) print the "Opening browser
to login..." path, and when Mode==manual print the "Browser didn't open? Visit
<URL>" fallback. Ensure Preamble is still rendered as before and update any
constructors sending AuthEvent to populate the new field.
---
Nitpick comments:
In `@internal/output/events.go`:
- Around line 59-79: Add first-class emitter helpers for the two new event types
so callers don't need to call the generic Emit directly: implement
EmitInstanceInfo(ctx, e InstanceInfoEvent) and EmitServiceResources(ctx, e
ServiceResourcesEvent) (matching the existing helper signatures/pattern used by
other events) and have them call the generic Emit with the concrete struct;
update any tests to use these helpers. Ensure you reference the types
InstanceInfoEvent and ServiceResourcesEvent and follow the existing helper
naming/parameter conventions used by other emit helpers in this package so
formatter/sink parity remains consistent.
In `@internal/output/plain_format.go`:
- Around line 151-153: Replace the user-facing "CONTAINER: "+e.ContainerName
entry with emulator wording so the status shows the emulator label; modify the
code that appends to meta (the block that checks e.ContainerName in
plain_format.go) to use "EMULATOR: " (or the agreed-upon emulator label) instead
of "CONTAINER: ", leaving the rest of the logic (e.ContainerName and meta
append) unchanged.
In `@internal/ui/app.go`:
- Around line 151-159: The TUI branch handling the AuthEvent duplicates
plain-text wording instead of reusing the shared formatter; change the AuthEvent
case in the switch (the block that appends to a.lines using appendLine and
styledLine) to call the shared FormatEventLine(event any) (or the existing
formatter function) to obtain the canonical line(s) for the event and then apply
only TUI-specific styling (e.g., wrap/mark as secondary) before appending to
a.lines, so the TUI text stays consistent with internal/output/plain_format.go;
keep the existing styledLine/appendLine usage but derive the content from
FormatEventLine rather than hardcoding strings.
In `@test/integration/status_test.go`:
- Around line 15-23: The test TestStatusCommandFailsWhenNotRunning (and the
other tests in ranges 25-59 and 61-87) currently invoke runLstk which may pick a
terminal-backed path and trigger Bubble Tea; update these tests to force
non-interactive/plain-sink mode by passing the explicit non-interactive flag or
environment to runLstk (e.g., add "--no-interactive" or set a NO_INTERACTIVE env
var via the runLstk call) so the CLI takes the plain-text path; modify the calls
to runLstk(testContext(t), ...) in TestStatusCommandFailsWhenNotRunning and the
other affected tests to include that non-interactive indicator so assertions
against stderr/stdout remain stable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 4dbdcd7e-5a02-48ed-a390-82718cb3975a
📒 Files selected for processing (20)
cmd/root.gocmd/status.gointernal/auth/login.gointernal/auth/login_test.gointernal/auth/mock_token_storage.gointernal/container/status.gointernal/output/events.gointernal/output/events_test.gointernal/output/plain_format.gointernal/output/plain_format_test.gointernal/output/plain_sink_test.gointernal/runtime/docker.gointernal/runtime/mock_runtime.gointernal/runtime/runtime.gointernal/ui/app.gointernal/ui/components/input_prompt.gointernal/ui/run_status.gotest/integration/env/env.gotest/integration/login_test.gotest/integration/status_test.go
silv-io
left a comment
There was a problem hiding this comment.
TBH I like it more with the code displayed. It makes it look more actionable?
What if the link fails somehow and the code isn't copied? What if there is a MITM somehow? I think it should still be easily recognizable what the code is.
773ef44 to
f335355
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/output/events.go (1)
61-77: Consider adding emit helper functions for new event types.The new
InstanceInfoEventandServiceResourcesEventtypes are added to the Event union but lack corresponding emit helpers likeEmitInstanceInfoandEmitServiceResources. While callers can useEmit()directly, the pattern established by other events (e.g.,EmitAuth,EmitStatus) suggests helpers improve discoverability and consistency.♻️ Suggested helpers
func EmitInstanceInfo(sink Sink, event InstanceInfoEvent) { Emit(sink, event) } func EmitServiceResources(sink Sink, event ServiceResourcesEvent) { Emit(sink, event) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/output/events.go` around lines 61 - 77, Add two thin emitter helpers to mirror existing patterns: implement EmitInstanceInfo(sink Sink, event InstanceInfoEvent) and EmitServiceResources(sink Sink, event ServiceResourcesEvent) that simply call Emit(sink, event). Place them alongside other emit helpers so callers can use EmitInstanceInfo and EmitServiceResources instead of calling Emit directly; reference the existing Emit function and the types InstanceInfoEvent, ServiceResourcesEvent and the Sink type when adding these helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/output/events.go`:
- Around line 61-77: Add two thin emitter helpers to mirror existing patterns:
implement EmitInstanceInfo(sink Sink, event InstanceInfoEvent) and
EmitServiceResources(sink Sink, event ServiceResourcesEvent) that simply call
Emit(sink, event). Place them alongside other emit helpers so callers can use
EmitInstanceInfo and EmitServiceResources instead of calling Emit directly;
reference the existing Emit function and the types InstanceInfoEvent,
ServiceResourcesEvent and the Sink type when adding these helpers.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 51c3bffe-ee4c-4bba-a970-f458e3760618
📒 Files selected for processing (19)
cmd/root.gocmd/status.gointernal/auth/login.gointernal/auth/login_test.gointernal/auth/mock_token_storage.gointernal/container/status.gointernal/output/events.gointernal/output/events_test.gointernal/output/plain_format.gointernal/output/plain_format_test.gointernal/output/plain_sink_test.gointernal/runtime/docker.gointernal/runtime/mock_runtime.gointernal/runtime/runtime.gointernal/ui/app.gointernal/ui/run_status.gotest/integration/env/env.gotest/integration/login_test.gotest/integration/status_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
- internal/auth/mock_token_storage.go
- internal/runtime/runtime.go
- cmd/status.go
- test/integration/login_test.go
- cmd/root.go
- internal/runtime/docker.go
- internal/container/status.go
f335355 to
5ed2e10
Compare
|
Good point on the code print, @silv-io! Added the code separately on its own line, but moved it further below using secondary text since with the auto-fill this is no longer an important instruction for users to follow. ✔️ Updated also screenshots in the PR description. ✔️ Adding an updated plan ahead for more context on the direction for future reference:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/output/events_test.go (1)
17-43: Test coverage is limited to URL-only scenario.This test only validates the
AuthEventwithout aCodefield. Whileplain_format_test.gocovers the full scenario withCode, consider adding a second test case here to verifyEmitAuthbehavior whenCodeis populated, ensuring the emit helper and formatter work together correctly for both paths.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/output/events_test.go` around lines 17 - 43, Add a second test case that calls EmitAuth(sink, AuthEvent{Preamble: "Welcome", URL: "https://example.com", Code: "1234"}) and then asserts sink.events length, type-asserts the stored event to AuthEvent, checks event.Code, event.URL and event.Preamble, and finally calls FormatEventLine(event) and compares the returned line to the expected formatted string for the Code-present path; update the test to exercise EmitAuth, AuthEvent and FormatEventLine together for the Code-populated scenario.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/output/events_test.go`:
- Around line 17-43: Add a second test case that calls EmitAuth(sink,
AuthEvent{Preamble: "Welcome", URL: "https://example.com", Code: "1234"}) and
then asserts sink.events length, type-asserts the stored event to AuthEvent,
checks event.Code, event.URL and event.Preamble, and finally calls
FormatEventLine(event) and compares the returned line to the expected formatted
string for the Code-present path; update the test to exercise EmitAuth,
AuthEvent and FormatEventLine together for the Code-populated scenario.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: e5067e66-307e-4470-b054-b6b523b9e5d7
📒 Files selected for processing (8)
internal/auth/login.gointernal/auth/login_test.gointernal/output/events_test.gointernal/output/plain_format.gointernal/output/plain_format_test.gointernal/output/plain_sink_test.gointernal/ui/app.gotest/integration/login_test.go
✅ Files skipped from review due to trivial changes (1)
- internal/output/plain_sink_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
- internal/auth/login.go
- internal/auth/login_test.go
- internal/ui/app.go
5ed2e10 to
d3bdae1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
internal/auth/login.go (1)
41-46:⚠️ Potential issue | 🟡 MinorStill handle the
browser.OpenURLfailure path.Line 46 still ignores the error from
browser.OpenURL(authURL), so this flow cannot distinguish “browser opened” from “browser launch failed” and always shows the optimistic path. Please check it and downgrade to a warning/manual-open flow when the launch fails. As per coding guidelines "Errors returned by functions should always be checked unless in test files".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/auth/login.go` around lines 41 - 46, The call to browser.OpenURL(authURL) in internal/auth/login.go is ignoring its returned error; update the logic after output.EmitAuth(...) to capture the error from browser.OpenURL(authURL), check it, and on failure downgrade to a warning/manual-open flow: call the logger (or output) to emit a warning that the browser launch failed and instruct the user to open authURL manually (instead of assuming success). Reference the browser.OpenURL call and the EmitAuth/output.AuthEvent usage so you modify the branch where the URL is opened and emit an alternate message when err != nil rather than discarding the error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/auth/login.go`:
- Around line 70-78: The buildAuthURL function can produce a double-slash when
webAppURL ends with '/', so normalize webAppURL by trimming any trailing '/'
before concatenating the auth path (e.g. use strings.TrimSuffix or TrimRight on
the webAppURL in buildAuthURL), then rebuild the URL as normalizedWebAppURL +
"/auth/request/" + authRequestID and preserve the existing query behavior for
code; also add a regression unit test in internal/auth/login_test.go that passes
a webAppURL with a trailing slash and asserts the returned URL does not contain
a double '//' before "auth/request".
---
Duplicate comments:
In `@internal/auth/login.go`:
- Around line 41-46: The call to browser.OpenURL(authURL) in
internal/auth/login.go is ignoring its returned error; update the logic after
output.EmitAuth(...) to capture the error from browser.OpenURL(authURL), check
it, and on failure downgrade to a warning/manual-open flow: call the logger (or
output) to emit a warning that the browser launch failed and instruct the user
to open authURL manually (instead of assuming success). Reference the
browser.OpenURL call and the EmitAuth/output.AuthEvent usage so you modify the
branch where the URL is opened and emit an alternate message when err != nil
rather than discarding the error.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 84d754e3-63a7-4db5-a001-8652c470508c
📒 Files selected for processing (8)
internal/auth/login.gointernal/auth/login_test.gointernal/output/events_test.gointernal/output/plain_format.gointernal/output/plain_format_test.gointernal/output/plain_sink_test.gointernal/ui/app.gotest/integration/login_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
- internal/output/plain_sink_test.go
- test/integration/login_test.go
- internal/output/plain_format.go
- internal/output/events_test.go
|
Thanks for taking a look, @carole-lavillonniere @silv-io! 🏀 |
Fix DES-160 and DES-157.