diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f04d089..57dc0c3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.32.0" + ".": "0.33.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index ad62343..bc10806 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 108 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-f967d3024897a6125d5d18c4577dbb2cc22d742d487e6a43165198685f992379.yml -openapi_spec_hash: e1c40ef0aee3a79168eb9cc854a9e403 -config_hash: 3b1fbbb6bda0dac7e8b42e155cd7da56 +configured_endpoints: 100 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-92e99f12ad95d7c00047c3f8226cd705174c68c555b42f137f3051768fdf76ae.yml +openapi_spec_hash: 886e96ba621aecde2a3920825771f260 +config_hash: 82f0a04081a3ab7111d3a9c68cd3ff2b diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a99391..90a1b9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## 0.33.0 (2026-02-11) + +Full Changelog: [v0.32.0...v0.33.0](https://github.com/kernel/kernel-go-sdk/compare/v0.32.0...v0.33.0) + +### Features + +* **auth:** plan-based min health check intervals ([b2f5bc2](https://github.com/kernel/kernel-go-sdk/commit/b2f5bc203e14397ab9b4f2641f42e1286935d0fc)) +* Browser API endpoint grouping ([b772828](https://github.com/kernel/kernel-go-sdk/commit/b7728287d7e63d612f6fedd2c4e199bda93440e5)) + + +### Bug Fixes + +* **encoder:** correctly serialize NullStruct ([85ac49d](https://github.com/kernel/kernel-go-sdk/commit/85ac49d67563554db23e8d39694d27d381d0b1c3)) +* use kernel-internal app token in update-cli-coverage workflow ([789d161](https://github.com/kernel/kernel-go-sdk/commit/789d1616fac976f15e44eae364442fc47cad381e)) + + +### Refactors + +* **api:** remove deprecated agent-auth endpoints from stainless.… ([cb2010d](https://github.com/kernel/kernel-go-sdk/commit/cb2010d43ca2a93f21442218d978524329e9a57e)) +* **auth:** simplify proxy configuration in OpenAPI schema ([7302183](https://github.com/kernel/kernel-go-sdk/commit/73021835cd291ba1e86172670daa599d49e76172)) + ## 0.32.0 (2026-02-07) Full Changelog: [v0.31.1...v0.32.0](https://github.com/kernel/kernel-go-sdk/compare/v0.31.1...v0.32.0) diff --git a/README.md b/README.md index 3128dd0..61ceb83 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Or to pin the version: ```sh -go get -u 'github.com/kernel/kernel-go-sdk@v0.32.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.33.0' ``` diff --git a/agent.go b/agent.go deleted file mode 100644 index 4de711d..0000000 --- a/agent.go +++ /dev/null @@ -1,28 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package kernel - -import ( - "github.com/kernel/kernel-go-sdk/option" -) - -// AgentService contains methods and other services that help with interacting with -// the kernel API. -// -// Note, unlike clients, this service does not read variables from the environment -// automatically. You should not instantiate this service directly, and instead use -// the [NewAgentService] method instead. -type AgentService struct { - Options []option.RequestOption - Auth AgentAuthService -} - -// NewAgentService generates a new service that applies the given options to each -// request. These options are applied after the parent client's options (if there -// is one), and before any request-specific options. -func NewAgentService(opts ...option.RequestOption) (r AgentService) { - r = AgentService{} - r.Options = opts - r.Auth = NewAgentAuthService(opts...) - return -} diff --git a/agentauth.go b/agentauth.go deleted file mode 100644 index 52029c9..0000000 --- a/agentauth.go +++ /dev/null @@ -1,644 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package kernel - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - "slices" - "time" - - "github.com/kernel/kernel-go-sdk/internal/apijson" - "github.com/kernel/kernel-go-sdk/internal/apiquery" - shimjson "github.com/kernel/kernel-go-sdk/internal/encoding/json" - "github.com/kernel/kernel-go-sdk/internal/requestconfig" - "github.com/kernel/kernel-go-sdk/option" - "github.com/kernel/kernel-go-sdk/packages/pagination" - "github.com/kernel/kernel-go-sdk/packages/param" - "github.com/kernel/kernel-go-sdk/packages/respjson" -) - -// AgentAuthService contains methods and other services that help with interacting -// with the kernel API. -// -// Note, unlike clients, this service does not read variables from the environment -// automatically. You should not instantiate this service directly, and instead use -// the [NewAgentAuthService] method instead. -type AgentAuthService struct { - Options []option.RequestOption - Invocations AgentAuthInvocationService -} - -// NewAgentAuthService generates a new service that applies the given options to -// each request. These options are applied after the parent client's options (if -// there is one), and before any request-specific options. -func NewAgentAuthService(opts ...option.RequestOption) (r AgentAuthService) { - r = AgentAuthService{} - r.Options = opts - r.Invocations = NewAgentAuthInvocationService(opts...) - return -} - -// **Deprecated: Use POST /auth/connections instead.** Creates a new auth agent for -// the specified domain and profile combination, or returns an existing one if it -// already exists. This is idempotent - calling with the same domain and profile -// will return the same agent. Does NOT start an invocation - use POST -// /agents/auth/invocations to start an auth flow. -// -// Deprecated: deprecated -func (r *AgentAuthService) New(ctx context.Context, body AgentAuthNewParams, opts ...option.RequestOption) (res *AuthAgent, err error) { - opts = slices.Concat(r.Options, opts) - path := "agents/auth" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return -} - -// **Deprecated: Use GET /auth/connections/{id} instead.** Retrieve an auth agent -// by its ID. Returns the current authentication status of the managed profile. -// -// Deprecated: deprecated -func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *AuthAgent, err error) { - opts = slices.Concat(r.Options, opts) - if id == "" { - err = errors.New("missing required id parameter") - return - } - path := fmt.Sprintf("agents/auth/%s", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) - return -} - -// **Deprecated: Use GET /auth/connections instead.** List auth agents with -// optional filters for profile_name and domain. -// -// Deprecated: deprecated -func (r *AgentAuthService) List(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[AuthAgent], err error) { - var raw *http.Response - opts = slices.Concat(r.Options, opts) - opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) - path := "agents/auth" - cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, query, &res, opts...) - if err != nil { - return nil, err - } - err = cfg.Execute() - if err != nil { - return nil, err - } - res.SetPageConfig(cfg, raw) - return res, nil -} - -// **Deprecated: Use GET /auth/connections instead.** List auth agents with -// optional filters for profile_name and domain. -// -// Deprecated: deprecated -func (r *AgentAuthService) ListAutoPaging(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[AuthAgent] { - return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...)) -} - -// **Deprecated: Use DELETE /auth/connections/{id} instead.** Deletes an auth agent -// and terminates its workflow. This will: -// -// - Soft delete the auth agent record -// - Gracefully terminate the agent's Temporal workflow -// - Cancel any in-progress invocations -// -// Deprecated: deprecated -func (r *AgentAuthService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (err error) { - opts = slices.Concat(r.Options, opts) - opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...) - if id == "" { - err = errors.New("missing required id parameter") - return - } - path := fmt.Sprintf("agents/auth/%s", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...) - return -} - -// Response from get invocation endpoint -type AgentAuthInvocationResponse struct { - // App name (org name at time of invocation creation) - AppName string `json:"app_name,required"` - // Domain for authentication - Domain string `json:"domain,required"` - // When the handoff code expires - ExpiresAt time.Time `json:"expires_at,required" format:"date-time"` - // Invocation status - // - // Any of "IN_PROGRESS", "SUCCESS", "EXPIRED", "CANCELED", "FAILED". - Status AgentAuthInvocationResponseStatus `json:"status,required"` - // Current step in the invocation workflow - // - // Any of "initialized", "discovering", "awaiting_input", - // "awaiting_external_action", "submitting", "completed", "expired". - Step AgentAuthInvocationResponseStep `json:"step,required"` - // The session type: - // - // - login: User-initiated authentication - // - reauth: System-triggered re-authentication (via health check) - // - // Any of "login", "reauth". - Type AgentAuthInvocationResponseType `json:"type,required"` - // Error message explaining why the invocation failed (present when status=FAILED) - ErrorMessage string `json:"error_message,nullable"` - // Instructions for user when external action is required (present when - // step=awaiting_external_action) - ExternalActionMessage string `json:"external_action_message,nullable"` - // Browser live view URL for debugging the invocation - LiveViewURL string `json:"live_view_url,nullable"` - // MFA method options to choose from (present when step=awaiting_input and MFA - // selection is required) - MfaOptions []AgentAuthInvocationResponseMfaOption `json:"mfa_options,nullable"` - // Fields currently awaiting input (present when step=awaiting_input) - PendingFields []DiscoveredField `json:"pending_fields,nullable"` - // SSO buttons available on the page (present when step=awaiting_input) - PendingSSOButtons []AgentAuthInvocationResponsePendingSSOButton `json:"pending_sso_buttons,nullable"` - // SSO provider being used for authentication (e.g., google, github, microsoft) - SSOProvider string `json:"sso_provider,nullable"` - // Names of fields that have been submitted (present when step=submitting or later) - SubmittedFields []string `json:"submitted_fields,nullable"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - AppName respjson.Field - Domain respjson.Field - ExpiresAt respjson.Field - Status respjson.Field - Step respjson.Field - Type respjson.Field - ErrorMessage respjson.Field - ExternalActionMessage respjson.Field - LiveViewURL respjson.Field - MfaOptions respjson.Field - PendingFields respjson.Field - PendingSSOButtons respjson.Field - SSOProvider respjson.Field - SubmittedFields respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AgentAuthInvocationResponse) RawJSON() string { return r.JSON.raw } -func (r *AgentAuthInvocationResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Invocation status -type AgentAuthInvocationResponseStatus string - -const ( - AgentAuthInvocationResponseStatusInProgress AgentAuthInvocationResponseStatus = "IN_PROGRESS" - AgentAuthInvocationResponseStatusSuccess AgentAuthInvocationResponseStatus = "SUCCESS" - AgentAuthInvocationResponseStatusExpired AgentAuthInvocationResponseStatus = "EXPIRED" - AgentAuthInvocationResponseStatusCanceled AgentAuthInvocationResponseStatus = "CANCELED" - AgentAuthInvocationResponseStatusFailed AgentAuthInvocationResponseStatus = "FAILED" -) - -// Current step in the invocation workflow -type AgentAuthInvocationResponseStep string - -const ( - AgentAuthInvocationResponseStepInitialized AgentAuthInvocationResponseStep = "initialized" - AgentAuthInvocationResponseStepDiscovering AgentAuthInvocationResponseStep = "discovering" - AgentAuthInvocationResponseStepAwaitingInput AgentAuthInvocationResponseStep = "awaiting_input" - AgentAuthInvocationResponseStepAwaitingExternalAction AgentAuthInvocationResponseStep = "awaiting_external_action" - AgentAuthInvocationResponseStepSubmitting AgentAuthInvocationResponseStep = "submitting" - AgentAuthInvocationResponseStepCompleted AgentAuthInvocationResponseStep = "completed" - AgentAuthInvocationResponseStepExpired AgentAuthInvocationResponseStep = "expired" -) - -// The session type: -// -// - login: User-initiated authentication -// - reauth: System-triggered re-authentication (via health check) -type AgentAuthInvocationResponseType string - -const ( - AgentAuthInvocationResponseTypeLogin AgentAuthInvocationResponseType = "login" - AgentAuthInvocationResponseTypeReauth AgentAuthInvocationResponseType = "reauth" -) - -// An MFA method option for verification -type AgentAuthInvocationResponseMfaOption struct { - // The visible option text - Label string `json:"label,required"` - // The MFA delivery method type (includes password for auth method selection pages) - // - // Any of "sms", "call", "email", "totp", "push", "password". - Type string `json:"type,required"` - // Additional instructions from the site - Description string `json:"description,nullable"` - // The masked destination (phone/email) if shown - Target string `json:"target,nullable"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Label respjson.Field - Type respjson.Field - Description respjson.Field - Target respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AgentAuthInvocationResponseMfaOption) RawJSON() string { return r.JSON.raw } -func (r *AgentAuthInvocationResponseMfaOption) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// An SSO button for signing in with an external identity provider -type AgentAuthInvocationResponsePendingSSOButton struct { - // Visible button text - Label string `json:"label,required"` - // Identity provider name - Provider string `json:"provider,required"` - // XPath selector for the button - Selector string `json:"selector,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Label respjson.Field - Provider respjson.Field - Selector respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AgentAuthInvocationResponsePendingSSOButton) RawJSON() string { return r.JSON.raw } -func (r *AgentAuthInvocationResponsePendingSSOButton) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Response from submit endpoint - returns immediately after submission is accepted -type AgentAuthSubmitResponse struct { - // Whether the submission was accepted for processing - Accepted bool `json:"accepted,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Accepted respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AgentAuthSubmitResponse) RawJSON() string { return r.JSON.raw } -func (r *AgentAuthSubmitResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// An auth agent that manages authentication for a specific domain and profile -// combination -type AuthAgent struct { - // Unique identifier for the auth agent - ID string `json:"id,required"` - // Target domain for authentication - Domain string `json:"domain,required"` - // Name of the profile associated with this auth agent - ProfileName string `json:"profile_name,required"` - // Current authentication status of the managed profile - // - // Any of "AUTHENTICATED", "NEEDS_AUTH". - Status AuthAgentStatus `json:"status,required"` - // Additional domains that are valid for this auth agent's authentication flow - // (besides the primary domain). Useful when login pages redirect to different - // domains. - // - // The following SSO/OAuth provider domains are automatically allowed by default - // and do not need to be specified: - // - // - Google: accounts.google.com - // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com - // - Okta: _.okta.com, _.oktapreview.com - // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com - // - Apple: appleid.apple.com - // - GitHub: github.com - // - Facebook/Meta: www.facebook.com - // - LinkedIn: www.linkedin.com - // - Amazon Cognito: \*.amazoncognito.com - // - OneLogin: \*.onelogin.com - // - Ping Identity: _.pingone.com, _.pingidentity.com - AllowedDomains []string `json:"allowed_domains"` - // Whether automatic re-authentication is possible (has credential_id, selectors, - // and login_url) - CanReauth bool `json:"can_reauth"` - // Reason why automatic re-authentication is or is not possible - CanReauthReason string `json:"can_reauth_reason"` - // Reference to credentials for managed auth. Use one of: - // - // - { name } for Kernel credentials - // - { provider, path } for external provider item - // - { provider, auto: true } for external provider domain lookup - Credential AuthAgentCredential `json:"credential"` - // ID of the linked Kernel credential for automatic re-authentication (deprecated, - // use credential) - CredentialID string `json:"credential_id"` - // Whether this auth agent has stored selectors for deterministic re-authentication - HasSelectors bool `json:"has_selectors"` - // When the last authentication check was performed - LastAuthCheckAt time.Time `json:"last_auth_check_at" format:"date-time"` - // URL where the browser landed after successful login. Query parameters and - // fragments are stripped for privacy. - PostLoginURL string `json:"post_login_url" format:"uri"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ID respjson.Field - Domain respjson.Field - ProfileName respjson.Field - Status respjson.Field - AllowedDomains respjson.Field - CanReauth respjson.Field - CanReauthReason respjson.Field - Credential respjson.Field - CredentialID respjson.Field - HasSelectors respjson.Field - LastAuthCheckAt respjson.Field - PostLoginURL respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AuthAgent) RawJSON() string { return r.JSON.raw } -func (r *AuthAgent) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Current authentication status of the managed profile -type AuthAgentStatus string - -const ( - AuthAgentStatusAuthenticated AuthAgentStatus = "AUTHENTICATED" - AuthAgentStatusNeedsAuth AuthAgentStatus = "NEEDS_AUTH" -) - -// Reference to credentials for managed auth. Use one of: -// -// - { name } for Kernel credentials -// - { provider, path } for external provider item -// - { provider, auto: true } for external provider domain lookup -type AuthAgentCredential struct { - // If true, lookup by domain from the specified provider - Auto bool `json:"auto"` - // Kernel credential name - Name string `json:"name"` - // Provider-specific path (e.g., "VaultName/ItemName" for 1Password) - Path string `json:"path"` - // External provider name (e.g., "my-1p") - Provider string `json:"provider"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Auto respjson.Field - Name respjson.Field - Path respjson.Field - Provider respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AuthAgentCredential) RawJSON() string { return r.JSON.raw } -func (r *AuthAgentCredential) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Request to create or find an auth agent -// -// The properties Domain, ProfileName are required. -type AuthAgentCreateRequestParam struct { - // Domain for authentication - Domain string `json:"domain,required"` - // Name of the profile to use for this auth agent - ProfileName string `json:"profile_name,required"` - // Optional name of an existing credential to use for this auth agent. If provided, - // the credential will be linked to the agent and its values will be used to - // auto-fill the login form on invocation. - CredentialName param.Opt[string] `json:"credential_name,omitzero"` - // Optional login page URL. If provided, will be stored on the agent and used to - // skip discovery in future invocations. - LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"` - // Additional domains that are valid for this auth agent's authentication flow - // (besides the primary domain). Useful when login pages redirect to different - // domains. - // - // The following SSO/OAuth provider domains are automatically allowed by default - // and do not need to be specified: - // - // - Google: accounts.google.com - // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com - // - Okta: _.okta.com, _.oktapreview.com - // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com - // - Apple: appleid.apple.com - // - GitHub: github.com - // - Facebook/Meta: www.facebook.com - // - LinkedIn: www.linkedin.com - // - Amazon Cognito: \*.amazoncognito.com - // - OneLogin: \*.onelogin.com - // - Ping Identity: _.pingone.com, _.pingidentity.com - AllowedDomains []string `json:"allowed_domains,omitzero"` - // Optional proxy configuration - Proxy AuthAgentCreateRequestProxyParam `json:"proxy,omitzero"` - paramObj -} - -func (r AuthAgentCreateRequestParam) MarshalJSON() (data []byte, err error) { - type shadow AuthAgentCreateRequestParam - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AuthAgentCreateRequestParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Optional proxy configuration -type AuthAgentCreateRequestProxyParam struct { - // ID of the proxy to use - ProxyID param.Opt[string] `json:"proxy_id,omitzero"` - paramObj -} - -func (r AuthAgentCreateRequestProxyParam) MarshalJSON() (data []byte, err error) { - type shadow AuthAgentCreateRequestProxyParam - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AuthAgentCreateRequestProxyParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Request to create an invocation for an existing auth agent -// -// The property AuthAgentID is required. -type AuthAgentInvocationCreateRequestParam struct { - // ID of the auth agent to create an invocation for - AuthAgentID string `json:"auth_agent_id,required"` - // If provided, saves the submitted credentials under this name upon successful - // login. The credential will be linked to the auth agent for automatic - // re-authentication. - SaveCredentialAs param.Opt[string] `json:"save_credential_as,omitzero"` - paramObj -} - -func (r AuthAgentInvocationCreateRequestParam) MarshalJSON() (data []byte, err error) { - type shadow AuthAgentInvocationCreateRequestParam - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AuthAgentInvocationCreateRequestParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Response from creating an invocation. Always returns an invocation_id. -type AuthAgentInvocationCreateResponse struct { - // When the handoff code expires. - ExpiresAt time.Time `json:"expires_at,required" format:"date-time"` - // One-time code for handoff. - HandoffCode string `json:"handoff_code,required"` - // URL to redirect user to. - HostedURL string `json:"hosted_url,required" format:"uri"` - // Unique identifier for the invocation. - InvocationID string `json:"invocation_id,required"` - // The session type: - // - // - login: User-initiated authentication - // - reauth: System-triggered re-authentication (via health check) - // - // Any of "login", "reauth". - Type AuthAgentInvocationCreateResponseType `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ExpiresAt respjson.Field - HandoffCode respjson.Field - HostedURL respjson.Field - InvocationID respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AuthAgentInvocationCreateResponse) RawJSON() string { return r.JSON.raw } -func (r *AuthAgentInvocationCreateResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// The session type: -// -// - login: User-initiated authentication -// - reauth: System-triggered re-authentication (via health check) -type AuthAgentInvocationCreateResponseType string - -const ( - AuthAgentInvocationCreateResponseTypeLogin AuthAgentInvocationCreateResponseType = "login" - AuthAgentInvocationCreateResponseTypeReauth AuthAgentInvocationCreateResponseType = "reauth" -) - -// A discovered form field -type DiscoveredField struct { - // Field label - Label string `json:"label,required"` - // Field name - Name string `json:"name,required"` - // CSS selector for the field - Selector string `json:"selector,required"` - // Field type - // - // Any of "text", "email", "password", "tel", "number", "url", "code", "totp". - Type DiscoveredFieldType `json:"type,required"` - // If this field is associated with an MFA option, the type of that option (e.g., - // password field linked to "Enter password" option) - // - // Any of "sms", "call", "email", "totp", "push", "password". - LinkedMfaType DiscoveredFieldLinkedMfaType `json:"linked_mfa_type,nullable"` - // Field placeholder - Placeholder string `json:"placeholder"` - // Whether field is required - Required bool `json:"required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Label respjson.Field - Name respjson.Field - Selector respjson.Field - Type respjson.Field - LinkedMfaType respjson.Field - Placeholder respjson.Field - Required respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r DiscoveredField) RawJSON() string { return r.JSON.raw } -func (r *DiscoveredField) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Field type -type DiscoveredFieldType string - -const ( - DiscoveredFieldTypeText DiscoveredFieldType = "text" - DiscoveredFieldTypeEmail DiscoveredFieldType = "email" - DiscoveredFieldTypePassword DiscoveredFieldType = "password" - DiscoveredFieldTypeTel DiscoveredFieldType = "tel" - DiscoveredFieldTypeNumber DiscoveredFieldType = "number" - DiscoveredFieldTypeURL DiscoveredFieldType = "url" - DiscoveredFieldTypeCode DiscoveredFieldType = "code" - DiscoveredFieldTypeTotp DiscoveredFieldType = "totp" -) - -// If this field is associated with an MFA option, the type of that option (e.g., -// password field linked to "Enter password" option) -type DiscoveredFieldLinkedMfaType string - -const ( - DiscoveredFieldLinkedMfaTypeSMS DiscoveredFieldLinkedMfaType = "sms" - DiscoveredFieldLinkedMfaTypeCall DiscoveredFieldLinkedMfaType = "call" - DiscoveredFieldLinkedMfaTypeEmail DiscoveredFieldLinkedMfaType = "email" - DiscoveredFieldLinkedMfaTypeTotp DiscoveredFieldLinkedMfaType = "totp" - DiscoveredFieldLinkedMfaTypePush DiscoveredFieldLinkedMfaType = "push" - DiscoveredFieldLinkedMfaTypePassword DiscoveredFieldLinkedMfaType = "password" -) - -type AgentAuthNewParams struct { - // Request to create or find an auth agent - AuthAgentCreateRequest AuthAgentCreateRequestParam - paramObj -} - -func (r AgentAuthNewParams) MarshalJSON() (data []byte, err error) { - return shimjson.Marshal(r.AuthAgentCreateRequest) -} -func (r *AgentAuthNewParams) UnmarshalJSON(data []byte) error { - return json.Unmarshal(data, &r.AuthAgentCreateRequest) -} - -type AgentAuthListParams struct { - // Filter by domain - Domain param.Opt[string] `query:"domain,omitzero" json:"-"` - // Maximum number of results to return - Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` - // Number of results to skip - Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Filter by profile name - ProfileName param.Opt[string] `query:"profile_name,omitzero" json:"-"` - paramObj -} - -// URLQuery serializes [AgentAuthListParams]'s query parameters as `url.Values`. -func (r AgentAuthListParams) URLQuery() (v url.Values, err error) { - return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ - ArrayFormat: apiquery.ArrayQueryFormatComma, - NestedFormat: apiquery.NestedQueryFormatBrackets, - }) -} diff --git a/agentauth_test.go b/agentauth_test.go deleted file mode 100644 index aceb973..0000000 --- a/agentauth_test.go +++ /dev/null @@ -1,122 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package kernel_test - -import ( - "context" - "errors" - "os" - "testing" - - "github.com/kernel/kernel-go-sdk" - "github.com/kernel/kernel-go-sdk/internal/testutil" - "github.com/kernel/kernel-go-sdk/option" -) - -func TestAgentAuthNewWithOptionalParams(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.New(context.TODO(), kernel.AgentAuthNewParams{ - AuthAgentCreateRequest: kernel.AuthAgentCreateRequestParam{ - Domain: "netflix.com", - ProfileName: "user-123", - AllowedDomains: []string{"login.netflix.com", "auth.netflix.com"}, - CredentialName: kernel.String("my-netflix-login"), - LoginURL: kernel.String("https://netflix.com/login"), - Proxy: kernel.AuthAgentCreateRequestProxyParam{ - ProxyID: kernel.String("proxy_id"), - }, - }, - }) - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthGet(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.Get(context.TODO(), "id") - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthListWithOptionalParams(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.List(context.TODO(), kernel.AgentAuthListParams{ - Domain: kernel.String("domain"), - Limit: kernel.Int(100), - Offset: kernel.Int(0), - ProfileName: kernel.String("profile_name"), - }) - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthDelete(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - err := client.Agents.Auth.Delete(context.TODO(), "id") - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} diff --git a/agentauthinvocation.go b/agentauthinvocation.go deleted file mode 100644 index 7226c53..0000000 --- a/agentauthinvocation.go +++ /dev/null @@ -1,222 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package kernel - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "slices" - - "github.com/kernel/kernel-go-sdk/internal/apijson" - shimjson "github.com/kernel/kernel-go-sdk/internal/encoding/json" - "github.com/kernel/kernel-go-sdk/internal/requestconfig" - "github.com/kernel/kernel-go-sdk/option" - "github.com/kernel/kernel-go-sdk/packages/param" - "github.com/kernel/kernel-go-sdk/packages/respjson" -) - -// AgentAuthInvocationService contains methods and other services that help with -// interacting with the kernel API. -// -// Note, unlike clients, this service does not read variables from the environment -// automatically. You should not instantiate this service directly, and instead use -// the [NewAgentAuthInvocationService] method instead. -type AgentAuthInvocationService struct { - Options []option.RequestOption -} - -// NewAgentAuthInvocationService generates a new service that applies the given -// options to each request. These options are applied after the parent client's -// options (if there is one), and before any request-specific options. -func NewAgentAuthInvocationService(opts ...option.RequestOption) (r AgentAuthInvocationService) { - r = AgentAuthInvocationService{} - r.Options = opts - return -} - -// **Deprecated: Use POST /auth/connections/{id}/login instead.** Creates a new -// authentication invocation for the specified auth agent. This starts the auth -// flow and returns a hosted URL for the user to complete authentication. -// -// Deprecated: deprecated -func (r *AgentAuthInvocationService) New(ctx context.Context, body AgentAuthInvocationNewParams, opts ...option.RequestOption) (res *AuthAgentInvocationCreateResponse, err error) { - opts = slices.Concat(r.Options, opts) - path := "agents/auth/invocations" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return -} - -// **Deprecated: Use GET /auth/connections/{id} instead.** Returns invocation -// details including status, app_name, and domain. Supports both API key and JWT -// (from exchange endpoint) authentication. -// -// Deprecated: deprecated -func (r *AgentAuthInvocationService) Get(ctx context.Context, invocationID string, opts ...option.RequestOption) (res *AgentAuthInvocationResponse, err error) { - opts = slices.Concat(r.Options, opts) - if invocationID == "" { - err = errors.New("missing required invocation_id parameter") - return - } - path := fmt.Sprintf("agents/auth/invocations/%s", invocationID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) - return -} - -// **Deprecated: Use POST /auth/connections/{id}/exchange instead.** Validates the -// handoff code and returns a JWT token for subsequent requests. No authentication -// required (the handoff code serves as the credential). -// -// Deprecated: deprecated -func (r *AgentAuthInvocationService) Exchange(ctx context.Context, invocationID string, body AgentAuthInvocationExchangeParams, opts ...option.RequestOption) (res *AgentAuthInvocationExchangeResponse, err error) { - opts = slices.Concat(r.Options, opts) - if invocationID == "" { - err = errors.New("missing required invocation_id parameter") - return - } - path := fmt.Sprintf("agents/auth/invocations/%s/exchange", invocationID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return -} - -// **Deprecated: Use POST /auth/connections/{id}/submit instead.** Submits field -// values for the discovered login form. Returns immediately after submission is -// accepted. Poll the invocation endpoint to track progress and get results. -// -// Deprecated: deprecated -func (r *AgentAuthInvocationService) Submit(ctx context.Context, invocationID string, body AgentAuthInvocationSubmitParams, opts ...option.RequestOption) (res *AgentAuthSubmitResponse, err error) { - opts = slices.Concat(r.Options, opts) - if invocationID == "" { - err = errors.New("missing required invocation_id parameter") - return - } - path := fmt.Sprintf("agents/auth/invocations/%s/submit", invocationID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return -} - -// Response from exchange endpoint -type AgentAuthInvocationExchangeResponse struct { - // Invocation ID - InvocationID string `json:"invocation_id,required"` - // JWT token with invocation_id claim (30 minute TTL) - Jwt string `json:"jwt,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - InvocationID respjson.Field - Jwt respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} - -// Returns the unmodified JSON received from the API -func (r AgentAuthInvocationExchangeResponse) RawJSON() string { return r.JSON.raw } -func (r *AgentAuthInvocationExchangeResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -type AgentAuthInvocationNewParams struct { - // Request to create an invocation for an existing auth agent - AuthAgentInvocationCreateRequest AuthAgentInvocationCreateRequestParam - paramObj -} - -func (r AgentAuthInvocationNewParams) MarshalJSON() (data []byte, err error) { - return shimjson.Marshal(r.AuthAgentInvocationCreateRequest) -} -func (r *AgentAuthInvocationNewParams) UnmarshalJSON(data []byte) error { - return json.Unmarshal(data, &r.AuthAgentInvocationCreateRequest) -} - -type AgentAuthInvocationExchangeParams struct { - // Handoff code from start endpoint - Code string `json:"code,required"` - paramObj -} - -func (r AgentAuthInvocationExchangeParams) MarshalJSON() (data []byte, err error) { - type shadow AgentAuthInvocationExchangeParams - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AgentAuthInvocationExchangeParams) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -type AgentAuthInvocationSubmitParams struct { - - // - // Request body variants - // - - // This field is a request body variant, only one variant field can be set. - OfFieldValues *AgentAuthInvocationSubmitParamsBodyFieldValues `json:",inline"` - // This field is a request body variant, only one variant field can be set. - OfSSOButton *AgentAuthInvocationSubmitParamsBodySSOButton `json:",inline"` - // This field is a request body variant, only one variant field can be set. - OfSelectedMfaType *AgentAuthInvocationSubmitParamsBodySelectedMfaType `json:",inline"` - - paramObj -} - -func (u AgentAuthInvocationSubmitParams) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfFieldValues, u.OfSSOButton, u.OfSelectedMfaType) -} -func (r *AgentAuthInvocationSubmitParams) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// The property FieldValues is required. -type AgentAuthInvocationSubmitParamsBodyFieldValues struct { - // Values for the discovered login fields - FieldValues map[string]string `json:"field_values,omitzero,required"` - paramObj -} - -func (r AgentAuthInvocationSubmitParamsBodyFieldValues) MarshalJSON() (data []byte, err error) { - type shadow AgentAuthInvocationSubmitParamsBodyFieldValues - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AgentAuthInvocationSubmitParamsBodyFieldValues) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// The property SSOButton is required. -type AgentAuthInvocationSubmitParamsBodySSOButton struct { - // Selector of SSO button to click - SSOButton string `json:"sso_button,required"` - paramObj -} - -func (r AgentAuthInvocationSubmitParamsBodySSOButton) MarshalJSON() (data []byte, err error) { - type shadow AgentAuthInvocationSubmitParamsBodySSOButton - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AgentAuthInvocationSubmitParamsBodySSOButton) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// The property SelectedMfaType is required. -type AgentAuthInvocationSubmitParamsBodySelectedMfaType struct { - // The MFA delivery method type (includes password for auth method selection pages) - // - // Any of "sms", "call", "email", "totp", "push", "password". - SelectedMfaType string `json:"selected_mfa_type,omitzero,required"` - paramObj -} - -func (r AgentAuthInvocationSubmitParamsBodySelectedMfaType) MarshalJSON() (data []byte, err error) { - type shadow AgentAuthInvocationSubmitParamsBodySelectedMfaType - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *AgentAuthInvocationSubmitParamsBodySelectedMfaType) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -func init() { - apijson.RegisterFieldValidator[AgentAuthInvocationSubmitParamsBodySelectedMfaType]( - "selected_mfa_type", "sms", "call", "email", "totp", "push", "password", - ) -} diff --git a/agentauthinvocation_test.go b/agentauthinvocation_test.go deleted file mode 100644 index cdfac3a..0000000 --- a/agentauthinvocation_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package kernel_test - -import ( - "context" - "errors" - "os" - "testing" - - "github.com/kernel/kernel-go-sdk" - "github.com/kernel/kernel-go-sdk/internal/testutil" - "github.com/kernel/kernel-go-sdk/option" -) - -func TestAgentAuthInvocationNewWithOptionalParams(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.Invocations.New(context.TODO(), kernel.AgentAuthInvocationNewParams{ - AuthAgentInvocationCreateRequest: kernel.AuthAgentInvocationCreateRequestParam{ - AuthAgentID: "abc123xyz", - SaveCredentialAs: kernel.String("my-netflix-login"), - }, - }) - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthInvocationGet(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.Invocations.Get(context.TODO(), "invocation_id") - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthInvocationExchange(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.Invocations.Exchange( - context.TODO(), - "invocation_id", - kernel.AgentAuthInvocationExchangeParams{ - Code: "abc123xyz", - }, - ) - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} - -func TestAgentAuthInvocationSubmit(t *testing.T) { - t.Skip("Prism tests are disabled") - baseURL := "http://localhost:4010" - if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { - baseURL = envURL - } - if !testutil.CheckTestServer(t, baseURL) { - return - } - client := kernel.NewClient( - option.WithBaseURL(baseURL), - option.WithAPIKey("My API Key"), - ) - _, err := client.Agents.Auth.Invocations.Submit( - context.TODO(), - "invocation_id", - kernel.AgentAuthInvocationSubmitParams{ - OfFieldValues: &kernel.AgentAuthInvocationSubmitParamsBodyFieldValues{ - FieldValues: map[string]string{ - "email": "user@example.com", - "password": "********", - }, - }, - }, - ) - if err != nil { - var apierr *kernel.Error - if errors.As(err, &apierr) { - t.Log(string(apierr.DumpRequest(true))) - } - t.Fatalf("err should be nil: %s", err.Error()) - } -} diff --git a/api.md b/api.md index 72fd646..da5c65c 100644 --- a/api.md +++ b/api.md @@ -284,43 +284,6 @@ Methods: - client.BrowserPools.Flush(ctx context.Context, idOrName string) error - client.BrowserPools.Release(ctx context.Context, idOrName string, body kernel.BrowserPoolReleaseParams) error -# Agents - -## Auth - -Params Types: - -- kernel.AuthAgentCreateRequestParam -- kernel.AuthAgentInvocationCreateRequestParam - -Response Types: - -- kernel.AgentAuthInvocationResponse -- kernel.AgentAuthSubmitResponse -- kernel.AuthAgent -- kernel.AuthAgentInvocationCreateResponse -- kernel.DiscoveredField - -Methods: - -- client.Agents.Auth.New(ctx context.Context, body kernel.AgentAuthNewParams) (\*kernel.AuthAgent, error) -- client.Agents.Auth.Get(ctx context.Context, id string) (\*kernel.AuthAgent, error) -- client.Agents.Auth.List(ctx context.Context, query kernel.AgentAuthListParams) (\*pagination.OffsetPagination[kernel.AuthAgent], error) -- client.Agents.Auth.Delete(ctx context.Context, id string) error - -### Invocations - -Response Types: - -- kernel.AgentAuthInvocationExchangeResponse - -Methods: - -- client.Agents.Auth.Invocations.New(ctx context.Context, body kernel.AgentAuthInvocationNewParams) (\*kernel.AuthAgentInvocationCreateResponse, error) -- client.Agents.Auth.Invocations.Get(ctx context.Context, invocationID string) (\*kernel.AgentAuthInvocationResponse, error) -- client.Agents.Auth.Invocations.Exchange(ctx context.Context, invocationID string, body kernel.AgentAuthInvocationExchangeParams) (\*kernel.AgentAuthInvocationExchangeResponse, error) -- client.Agents.Auth.Invocations.Submit(ctx context.Context, invocationID string, body kernel.AgentAuthInvocationSubmitParams) (\*kernel.AgentAuthSubmitResponse, error) - # Credentials Params Types: diff --git a/authconnection.go b/authconnection.go index 44d3eba..89a9dcf 100644 --- a/authconnection.go +++ b/authconnection.go @@ -44,8 +44,8 @@ func NewAuthConnectionService(opts ...option.RequestOption) (r AuthConnectionSer return } -// Creates managed authentication for a profile and domain combination. Returns 409 -// Conflict if managed auth already exists for the given profile and domain. +// Creates an auth connection for a profile and domain combination. Returns 409 +// Conflict if an auth connection already exists for the given profile and domain. func (r *AuthConnectionService) New(ctx context.Context, body AuthConnectionNewParams, opts ...option.RequestOption) (res *ManagedAuth, err error) { opts = slices.Concat(r.Options, opts) path := "auth/connections" @@ -53,8 +53,8 @@ func (r *AuthConnectionService) New(ctx context.Context, body AuthConnectionNewP return } -// Retrieve managed auth by its ID. Includes current flow state if a login is in -// progress. +// Retrieve an auth connection by its ID. Includes current flow state if a login is +// in progress. func (r *AuthConnectionService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *ManagedAuth, err error) { opts = slices.Concat(r.Options, opts) if id == "" { @@ -66,7 +66,7 @@ func (r *AuthConnectionService) Get(ctx context.Context, id string, opts ...opti return } -// List managed auths with optional filters for profile_name and domain. +// List auth connections with optional filters for profile_name and domain. func (r *AuthConnectionService) List(ctx context.Context, query AuthConnectionListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[ManagedAuth], err error) { var raw *http.Response opts = slices.Concat(r.Options, opts) @@ -84,14 +84,14 @@ func (r *AuthConnectionService) List(ctx context.Context, query AuthConnectionLi return res, nil } -// List managed auths with optional filters for profile_name and domain. +// List auth connections with optional filters for profile_name and domain. func (r *AuthConnectionService) ListAutoPaging(ctx context.Context, query AuthConnectionListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[ManagedAuth] { return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...)) } -// Deletes managed auth and terminates its workflow. This will: +// Deletes an auth connection and terminates its workflow. This will: // -// - Delete the managed auth record +// - Delete the auth connection record // - Terminate the Temporal workflow // - Cancel any in-progress login flows func (r *AuthConnectionService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (err error) { @@ -125,8 +125,8 @@ func (r *AuthConnectionService) FollowStreaming(ctx context.Context, id string, return ssestream.NewStream[AuthConnectionFollowResponseUnion](ssestream.NewDecoder(raw), err) } -// Starts a login flow for the managed auth. Returns immediately with a hosted URL -// for the user to complete authentication, or triggers automatic re-auth if +// Starts a login flow for the auth connection. Returns immediately with a hosted +// URL for the user to complete authentication, or triggers automatic re-auth if // credentials are stored. func (r *AuthConnectionService) Login(ctx context.Context, id string, body AuthConnectionLoginParams, opts ...option.RequestOption) (res *LoginResponse, err error) { opts = slices.Concat(r.Options, opts) @@ -139,8 +139,8 @@ func (r *AuthConnectionService) Login(ctx context.Context, id string, body AuthC return } -// Submits field values for the login form. Poll the managed auth to track progress -// and get results. +// Submits field values for the login form. Poll the auth connection to track +// progress and get results. func (r *AuthConnectionService) Submit(ctx context.Context, id string, body AuthConnectionSubmitParams, opts ...option.RequestOption) (res *SubmitFieldsResponse, err error) { opts = slices.Concat(r.Options, opts) if id == "" { @@ -156,6 +156,9 @@ func (r *AuthConnectionService) Submit(ctx context.Context, id string, body Auth type LoginRequestParam struct { // If provided, saves credentials under this name upon successful login SaveCredentialAs param.Opt[string] `json:"save_credential_as,omitzero"` + // Proxy selection. Provide either id or name. The proxy must belong to the + // caller's org. + Proxy LoginRequestProxyParam `json:"proxy,omitzero"` paramObj } @@ -167,9 +170,27 @@ func (r *LoginRequestParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Proxy selection. Provide either id or name. The proxy must belong to the +// caller's org. +type LoginRequestProxyParam struct { + // Proxy ID + ID param.Opt[string] `json:"id,omitzero"` + // Proxy name + Name param.Opt[string] `json:"name,omitzero"` + paramObj +} + +func (r LoginRequestProxyParam) MarshalJSON() (data []byte, err error) { + type shadow LoginRequestProxyParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *LoginRequestProxyParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // Response from starting a login flow type LoginResponse struct { - // Managed auth ID + // Auth connection ID ID string `json:"id,required"` // When the login flow expires FlowExpiresAt time.Time `json:"flow_expires_at,required" format:"date-time"` @@ -214,11 +235,11 @@ const ( // fields (flow_status, flow_step, discovered_fields, mfa_options) reflect the most // recent login flow and are null when no flow has been initiated. type ManagedAuth struct { - // Unique identifier for the managed auth + // Unique identifier for the auth connection ID string `json:"id,required"` // Target domain for authentication Domain string `json:"domain,required"` - // Name of the profile associated with this managed auth + // Name of the profile associated with this auth connection ProfileName string `json:"profile_name,required"` // Current authentication status of the managed profile // @@ -247,14 +268,14 @@ type ManagedAuth struct { CanReauth bool `json:"can_reauth"` // Reason why automatic re-authentication is or is not possible CanReauthReason string `json:"can_reauth_reason"` - // Reference to credentials for managed auth. Use one of: + // Reference to credentials for the auth connection. Use one of: // // - { name } for Kernel credentials // - { provider, path } for external provider item // - { provider, auto: true } for external provider domain lookup Credential ManagedAuthCredential `json:"credential"` // Fields awaiting input (present when flow_step=awaiting_input) - DiscoveredFields []DiscoveredField `json:"discovered_fields,nullable"` + DiscoveredFields []ManagedAuthDiscoveredField `json:"discovered_fields,nullable"` // Error message (present when flow_status=failed) ErrorMessage string `json:"error_message,nullable"` // Instructions for external action (present when @@ -277,8 +298,9 @@ type ManagedAuth struct { FlowType ManagedAuthFlowType `json:"flow_type,nullable"` // Interval in seconds between automatic health checks. When set, the system // periodically verifies the authentication status and triggers re-authentication - // if needed. Must be between 300 (5 minutes) and 86400 (24 hours). Default is 3600 - // (1 hour). + // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour). The minimum + // depends on your plan: Enterprise: 300 (5 minutes), Startup: 1200 (20 minutes), + // Hobbyist: 3600 (1 hour). HealthCheckInterval int64 `json:"health_check_interval,nullable"` // URL to redirect user to for hosted login (present when flow in progress) HostedURL string `json:"hosted_url,nullable" format:"uri"` @@ -343,7 +365,7 @@ const ( ManagedAuthStatusNeedsAuth ManagedAuthStatus = "NEEDS_AUTH" ) -// Reference to credentials for managed auth. Use one of: +// Reference to credentials for the auth connection. Use one of: // // - { name } for Kernel credentials // - { provider, path } for external provider item @@ -374,6 +396,47 @@ func (r *ManagedAuthCredential) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// A discovered form field +type ManagedAuthDiscoveredField struct { + // Field label + Label string `json:"label,required"` + // Field name + Name string `json:"name,required"` + // CSS selector for the field + Selector string `json:"selector,required"` + // Field type + // + // Any of "text", "email", "password", "tel", "number", "url", "code", "totp". + Type string `json:"type,required"` + // If this field is associated with an MFA option, the type of that option (e.g., + // password field linked to "Enter password" option) + // + // Any of "sms", "call", "email", "totp", "push", "password". + LinkedMfaType string `json:"linked_mfa_type,nullable"` + // Field placeholder + Placeholder string `json:"placeholder"` + // Whether field is required + Required bool `json:"required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Label respjson.Field + Name respjson.Field + Selector respjson.Field + Type respjson.Field + LinkedMfaType respjson.Field + Placeholder respjson.Field + Required respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ManagedAuthDiscoveredField) RawJSON() string { return r.JSON.raw } +func (r *ManagedAuthDiscoveredField) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // Current flow status (null when no flow in progress) type ManagedAuthFlowStatus string @@ -457,7 +520,7 @@ func (r *ManagedAuthPendingSSOButton) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Request to create managed auth for a profile and domain +// Request to create an auth connection for a profile and domain // // The properties Domain, ProfileName are required. type ManagedAuthCreateRequestParam struct { @@ -467,8 +530,9 @@ type ManagedAuthCreateRequestParam struct { ProfileName string `json:"profile_name,required"` // Interval in seconds between automatic health checks. When set, the system // periodically verifies the authentication status and triggers re-authentication - // if needed. Must be between 300 (5 minutes) and 86400 (24 hours). Default is 3600 - // (1 hour). + // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour). The minimum + // depends on your plan: Enterprise: 300 (5 minutes), Startup: 1200 (20 minutes), + // Hobbyist: 3600 (1 hour). HealthCheckInterval param.Opt[int64] `json:"health_check_interval,omitzero"` // Optional login page URL to skip discovery LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"` @@ -490,13 +554,14 @@ type ManagedAuthCreateRequestParam struct { // - OneLogin: \*.onelogin.com // - Ping Identity: _.pingone.com, _.pingidentity.com AllowedDomains []string `json:"allowed_domains,omitzero"` - // Reference to credentials for managed auth. Use one of: + // Reference to credentials for the auth connection. Use one of: // // - { name } for Kernel credentials // - { provider, path } for external provider item // - { provider, auto: true } for external provider domain lookup Credential ManagedAuthCreateRequestCredentialParam `json:"credential,omitzero"` - // Optional proxy configuration + // Proxy selection. Provide either id or name. The proxy must belong to the + // caller's org. Proxy ManagedAuthCreateRequestProxyParam `json:"proxy,omitzero"` paramObj } @@ -509,7 +574,7 @@ func (r *ManagedAuthCreateRequestParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Reference to credentials for managed auth. Use one of: +// Reference to credentials for the auth connection. Use one of: // // - { name } for Kernel credentials // - { provider, path } for external provider item @@ -534,10 +599,13 @@ func (r *ManagedAuthCreateRequestCredentialParam) UnmarshalJSON(data []byte) err return apijson.UnmarshalRoot(data, r) } -// Optional proxy configuration +// Proxy selection. Provide either id or name. The proxy must belong to the +// caller's org. type ManagedAuthCreateRequestProxyParam struct { - // ID of the proxy to use - ProxyID param.Opt[string] `json:"proxy_id,omitzero"` + // Proxy ID + ID param.Opt[string] `json:"id,omitzero"` + // Proxy name + Name param.Opt[string] `json:"name,omitzero"` paramObj } @@ -605,7 +673,7 @@ type AuthConnectionFollowResponseUnion struct { FlowStep string `json:"flow_step"` Timestamp time.Time `json:"timestamp"` // This field is from variant [AuthConnectionFollowResponseManagedAuthState]. - DiscoveredFields []DiscoveredField `json:"discovered_fields"` + DiscoveredFields []AuthConnectionFollowResponseManagedAuthStateDiscoveredField `json:"discovered_fields"` // This field is from variant [AuthConnectionFollowResponseManagedAuthState]. ErrorMessage string `json:"error_message"` // This field is from variant [AuthConnectionFollowResponseManagedAuthState]. @@ -714,7 +782,7 @@ type AuthConnectionFollowResponseManagedAuthState struct { // Time the state was reported. Timestamp time.Time `json:"timestamp,required" format:"date-time"` // Fields awaiting input (present when flow_step=AWAITING_INPUT). - DiscoveredFields []DiscoveredField `json:"discovered_fields"` + DiscoveredFields []AuthConnectionFollowResponseManagedAuthStateDiscoveredField `json:"discovered_fields"` // Error message (present when flow_status=FAILED). ErrorMessage string `json:"error_message"` // Instructions for external action (present when @@ -765,6 +833,49 @@ func (r *AuthConnectionFollowResponseManagedAuthState) UnmarshalJSON(data []byte return apijson.UnmarshalRoot(data, r) } +// A discovered form field +type AuthConnectionFollowResponseManagedAuthStateDiscoveredField struct { + // Field label + Label string `json:"label,required"` + // Field name + Name string `json:"name,required"` + // CSS selector for the field + Selector string `json:"selector,required"` + // Field type + // + // Any of "text", "email", "password", "tel", "number", "url", "code", "totp". + Type string `json:"type,required"` + // If this field is associated with an MFA option, the type of that option (e.g., + // password field linked to "Enter password" option) + // + // Any of "sms", "call", "email", "totp", "push", "password". + LinkedMfaType string `json:"linked_mfa_type,nullable"` + // Field placeholder + Placeholder string `json:"placeholder"` + // Whether field is required + Required bool `json:"required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Label respjson.Field + Name respjson.Field + Selector respjson.Field + Type respjson.Field + LinkedMfaType respjson.Field + Placeholder respjson.Field + Required respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r AuthConnectionFollowResponseManagedAuthStateDiscoveredField) RawJSON() string { + return r.JSON.raw +} +func (r *AuthConnectionFollowResponseManagedAuthStateDiscoveredField) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // An MFA method option for verification type AuthConnectionFollowResponseManagedAuthStateMfaOption struct { // The visible option text @@ -821,7 +932,7 @@ func (r *AuthConnectionFollowResponseManagedAuthStatePendingSSOButton) Unmarshal } type AuthConnectionNewParams struct { - // Request to create managed auth for a profile and domain + // Request to create an auth connection for a profile and domain ManagedAuthCreateRequest ManagedAuthCreateRequestParam paramObj } diff --git a/authconnection_test.go b/authconnection_test.go index d619ada..fd8b397 100644 --- a/authconnection_test.go +++ b/authconnection_test.go @@ -40,7 +40,8 @@ func TestAuthConnectionNewWithOptionalParams(t *testing.T) { HealthCheckInterval: kernel.Int(3600), LoginURL: kernel.String("https://netflix.com/login"), Proxy: kernel.ManagedAuthCreateRequestProxyParam{ - ProxyID: kernel.String("proxy_id"), + ID: kernel.String("id"), + Name: kernel.String("name"), }, }, }) @@ -145,6 +146,10 @@ func TestAuthConnectionLoginWithOptionalParams(t *testing.T) { "id", kernel.AuthConnectionLoginParams{ LoginRequest: kernel.LoginRequestParam{ + Proxy: kernel.LoginRequestProxyParam{ + ID: kernel.String("id"), + Name: kernel.String("name"), + }, SaveCredentialAs: kernel.String("my-netflix-login"), }, }, diff --git a/client.go b/client.go index 4106fd4..dab4e13 100644 --- a/client.go +++ b/client.go @@ -26,7 +26,6 @@ type Client struct { Proxies ProxyService Extensions ExtensionService BrowserPools BrowserPoolService - Agents AgentService Credentials CredentialService CredentialProviders CredentialProviderService } @@ -62,7 +61,6 @@ func NewClient(opts ...option.RequestOption) (r Client) { r.Proxies = NewProxyService(opts...) r.Extensions = NewExtensionService(opts...) r.BrowserPools = NewBrowserPoolService(opts...) - r.Agents = NewAgentService(opts...) r.Credentials = NewCredentialService(opts...) r.CredentialProviders = NewCredentialProviderService(opts...) diff --git a/internal/version.go b/internal/version.go index 5a62e29..6e4c570 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.32.0" // x-release-please-version +const PackageVersion = "0.33.0" // x-release-please-version diff --git a/packages/param/encoder.go b/packages/param/encoder.go index 7de2b4a..14ef222 100644 --- a/packages/param/encoder.go +++ b/packages/param/encoder.go @@ -83,6 +83,9 @@ func MarshalUnion[T ParamStruct](metadata T, variants ...any) ([]byte, error) { } } if nPresent == 0 || presentIdx == -1 { + if metadata.null() { + return []byte("null"), nil + } if ovr, ok := metadata.Overrides(); ok { return shimjson.Marshal(ovr) } diff --git a/packages/param/encoder_test.go b/packages/param/encoder_test.go index 6fbf534..db41620 100644 --- a/packages/param/encoder_test.go +++ b/packages/param/encoder_test.go @@ -363,3 +363,15 @@ func TestOverriddenUnion(t *testing.T) { }) } } + +func TestNullStructUnion(t *testing.T) { + nullUnion := param.NullStruct[PrimitiveUnion]() + + b, err := json.Marshal(nullUnion) + if err != nil { + t.Fatalf("didn't expect error %v", err) + } + if string(b) != "null" { + t.Fatalf("expected null, received %s", string(b)) + } +}