Skip to content

Commit 822ebd0

Browse files
authored
Merge branch 'main' into hypeship/unified-cua-template
2 parents 143a6eb + 55a2b93 commit 822ebd0

18 files changed

Lines changed: 1672 additions & 157 deletions

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ Commands with JSON output support:
217217
- `--output json`, `-o json` - Output JSON with liveViewUrl
218218
- `kernel browsers get <id>` - Get detailed browser session info
219219
- `--output json`, `-o json` - Output raw JSON object
220+
- `kernel browsers curl <id> <url>` - Make HTTP requests through a browser session's Chrome network stack
221+
- `-X, --request <method>` - HTTP method (default: GET; defaults to POST when `--data` is set)
222+
- `-H, --header <header>` - HTTP header, repeatable (`"Key: Value"` format)
223+
- `-d, --data <body>` - Request body
224+
- `--data-file <path>` - Read request body from file
225+
- `--max-time <seconds>` - Maximum time allowed for the request (default: 30)
226+
- `-o, --output <path>` - Write response body to file
227+
- `-I, --head` - Fetch headers only
228+
- `-i, --include` - Include response headers in output
229+
- `-D, --dump-header <path>` - Write received headers to file (use `-` for stdout)
230+
- `-w, --write-out <format>` - Output text after completion; supports `%{http_code}`, `%{response_code}`, `%{time_total}`, and `%{size_download}`
231+
- `-f, --fail` - Fail with no body output on HTTP errors
232+
- `-s, --silent` - Suppress progress output
233+
- _Note: redirects are followed automatically by Chromium._
220234

221235
### Browser Pools
222236

@@ -593,6 +607,21 @@ kernel browsers delete browser123
593607
# Get live view URL
594608
kernel browsers view browser123
595609

610+
# Make an HTTP request through the browser session
611+
kernel browsers curl browser123 https://example.com
612+
613+
# Include response headers and save the response to a file
614+
kernel browsers curl browser123 -i -o page.html https://example.com
615+
616+
# Send JSON and print curl-style status metrics
617+
kernel browsers curl browser123 https://api.example.com \
618+
-H "Content-Type: application/json" \
619+
-d '{"key":"value"}' \
620+
-w 'status=%{http_code} bytes=%{size_download}\n'
621+
622+
# Fail on HTTP errors without printing the response body
623+
kernel browsers curl browser123 -f https://example.com/missing
624+
596625
# Stream browser logs
597626
kernel browsers logs stream my-browser --source supervisor --follow --supervisor-process chromium
598627

cmd/auth_connections.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ func (c AuthConnectionCmd) Create(ctx context.Context, in AuthConnectionCreateIn
151151
}
152152
if in.CredentialPath != "" {
153153
params.ManagedAuthCreateRequest.Credential.Path = kernel.Opt(in.CredentialPath)
154+
} else {
155+
// Default to domain auto-lookup when no explicit --credential-path is
156+
// given. This matches the dashboard's UX, where picking a provider
157+
// without a specific item always means "look up by domain". Without
158+
// this default, the server receives { provider } with no path or
159+
// auto flag, which is a valid-but-inert credential reference that
160+
// causes the managed auth session to never fetch credentials.
161+
params.ManagedAuthCreateRequest.Credential.Auto = kernel.Opt(true)
154162
}
155163
if in.CredentialAuto {
156164
params.ManagedAuthCreateRequest.Credential.Auto = kernel.Opt(true)
@@ -797,7 +805,7 @@ func init() {
797805
authConnectionsCreateCmd.Flags().String("credential-name", "", "Kernel credential name to use")
798806
authConnectionsCreateCmd.Flags().String("credential-provider", "", "External credential provider name")
799807
authConnectionsCreateCmd.Flags().String("credential-path", "", "Provider-specific path (e.g., VaultName/ItemName)")
800-
authConnectionsCreateCmd.Flags().Bool("credential-auto", false, "Lookup by domain from the specified provider")
808+
authConnectionsCreateCmd.Flags().Bool("credential-auto", false, "Lookup by domain from the specified provider (defaults to true when --credential-provider is set without --credential-path)")
801809
authConnectionsCreateCmd.Flags().String("proxy-id", "", "Proxy ID to use")
802810
authConnectionsCreateCmd.Flags().String("proxy-name", "", "Proxy name to use")
803811
authConnectionsCreateCmd.Flags().Bool("no-save-credentials", false, "Disable saving credentials after successful login")

cmd/auth_connections_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,122 @@ func TestAuthConnectionsList_JSONOutput_PrintsRawResponse(t *testing.T) {
205205
assert.Contains(t, out, "\"raf-leaseweb\"")
206206
}
207207

208+
// Regression test for the 1Password auto-lookup UX gap: before this fix,
209+
// `kernel auth connections create --credential-provider foo` sent a
210+
// CredentialReference of { provider } with no auto flag, which the API accepted
211+
// as valid-but-inert — the managed auth session would never fetch credentials
212+
// and would prompt the user for manual input. The dashboard already defaults
213+
// to auto: true for this case (see packages/dashboard/src/components/create-managed-auth-dialog.tsx);
214+
// the CLI now matches that UX.
215+
func TestAuthConnectionsCreate_ProviderWithoutPath_DefaultsAutoTrue(t *testing.T) {
216+
var captured kernel.AuthConnectionNewParams
217+
fake := &FakeAuthConnectionService{
218+
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
219+
captured = body
220+
return &kernel.ManagedAuth{ID: "conn-new"}, nil
221+
},
222+
}
223+
224+
c := AuthConnectionCmd{svc: fake}
225+
err := c.Create(context.Background(), AuthConnectionCreateInput{
226+
Domain: "google.com",
227+
ProfileName: "my-profile",
228+
CredentialProvider: "my-1p",
229+
Output: "json",
230+
})
231+
require.NoError(t, err)
232+
233+
cred := captured.ManagedAuthCreateRequest.Credential
234+
require.True(t, cred.Provider.Valid())
235+
assert.Equal(t, "my-1p", cred.Provider.Value)
236+
assert.False(t, cred.Path.Valid(), "path should not be set when only --credential-provider is given")
237+
require.True(t, cred.Auto.Valid(), "auto should default to true when provider is set without path")
238+
assert.True(t, cred.Auto.Value)
239+
}
240+
241+
// Explicit --credential-path should keep the credential reference as a pinned
242+
// path lookup (no implicit auto).
243+
func TestAuthConnectionsCreate_ProviderWithPath_DoesNotSetAuto(t *testing.T) {
244+
var captured kernel.AuthConnectionNewParams
245+
fake := &FakeAuthConnectionService{
246+
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
247+
captured = body
248+
return &kernel.ManagedAuth{ID: "conn-new"}, nil
249+
},
250+
}
251+
252+
c := AuthConnectionCmd{svc: fake}
253+
err := c.Create(context.Background(), AuthConnectionCreateInput{
254+
Domain: "google.com",
255+
ProfileName: "my-profile",
256+
CredentialProvider: "my-1p",
257+
CredentialPath: "Employees/Google Workspace",
258+
Output: "json",
259+
})
260+
require.NoError(t, err)
261+
262+
cred := captured.ManagedAuthCreateRequest.Credential
263+
require.True(t, cred.Provider.Valid())
264+
assert.Equal(t, "my-1p", cred.Provider.Value)
265+
require.True(t, cred.Path.Valid())
266+
assert.Equal(t, "Employees/Google Workspace", cred.Path.Value)
267+
assert.False(t, cred.Auto.Valid(), "auto should remain unset when --credential-path is explicit")
268+
}
269+
270+
// --credential-auto should still be honored (it was a no-op redundant flag
271+
// before the default changed, but callers may pass it for clarity).
272+
func TestAuthConnectionsCreate_ProviderWithExplicitAuto_SetsAuto(t *testing.T) {
273+
var captured kernel.AuthConnectionNewParams
274+
fake := &FakeAuthConnectionService{
275+
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
276+
captured = body
277+
return &kernel.ManagedAuth{ID: "conn-new"}, nil
278+
},
279+
}
280+
281+
c := AuthConnectionCmd{svc: fake}
282+
err := c.Create(context.Background(), AuthConnectionCreateInput{
283+
Domain: "google.com",
284+
ProfileName: "my-profile",
285+
CredentialProvider: "my-1p",
286+
CredentialAuto: true,
287+
Output: "json",
288+
})
289+
require.NoError(t, err)
290+
291+
cred := captured.ManagedAuthCreateRequest.Credential
292+
require.True(t, cred.Auto.Valid())
293+
assert.True(t, cred.Auto.Value)
294+
}
295+
296+
// --credential-name references a Kernel-managed credential and should never
297+
// carry a provider/auto/path — the default-auto logic must not kick in here.
298+
func TestAuthConnectionsCreate_CredentialName_UnaffectedByAutoDefault(t *testing.T) {
299+
var captured kernel.AuthConnectionNewParams
300+
fake := &FakeAuthConnectionService{
301+
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
302+
captured = body
303+
return &kernel.ManagedAuth{ID: "conn-new"}, nil
304+
},
305+
}
306+
307+
c := AuthConnectionCmd{svc: fake}
308+
err := c.Create(context.Background(), AuthConnectionCreateInput{
309+
Domain: "google.com",
310+
ProfileName: "my-profile",
311+
CredentialName: "my-google-creds",
312+
Output: "json",
313+
})
314+
require.NoError(t, err)
315+
316+
cred := captured.ManagedAuthCreateRequest.Credential
317+
require.True(t, cred.Name.Valid())
318+
assert.Equal(t, "my-google-creds", cred.Name.Value)
319+
assert.False(t, cred.Provider.Valid())
320+
assert.False(t, cred.Auto.Valid())
321+
assert.False(t, cred.Path.Valid())
322+
}
323+
208324
func TestAuthConnectionsUpdate_MapsParams(t *testing.T) {
209325
var captured kernel.AuthConnectionUpdateParams
210326
fake := &FakeAuthConnectionService{

0 commit comments

Comments
 (0)