From a6cb845a2bc963459dd5f7d04a11650c20064d6f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 20:32:35 +0000 Subject: [PATCH 1/2] chore: add Managed Auth API planning doc --- .stats.yml | 8 +- api.md | 39 +- src/client.ts | 9 + src/resources/agents/auth/auth.ts | 162 +++- src/resources/agents/auth/invocations.ts | 65 +- src/resources/auth.ts | 3 + src/resources/auth/auth.ts | 43 + src/resources/auth/connections.ts | 843 ++++++++++++++++++ src/resources/auth/index.ts | 18 + src/resources/credential-providers.ts | 94 +- src/resources/index.ts | 3 + tests/api-resources/auth/connections.test.ts | 154 ++++ .../credential-providers.test.ts | 14 + 13 files changed, 1346 insertions(+), 109 deletions(-) create mode 100644 src/resources/auth.ts create mode 100644 src/resources/auth/auth.ts create mode 100644 src/resources/auth/connections.ts create mode 100644 src/resources/auth/index.ts create mode 100644 tests/api-resources/auth/connections.test.ts diff --git a/.stats.yml b/.stats.yml index 91fd3b6..2964321 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 100 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-a6d93dc291278035c96add38bb6150ec2b9ba8bbabb4676e3dbbb8444cf3b1e4.yml -openapi_spec_hash: 694bcc56d94fd0ff0d1f7b0fc1dae8ba -config_hash: 62e33cf2ed8fe0b4ceebba63367481ad +configured_endpoints: 108 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-3fbe762c99e8a120c426ac22bc1fa257c9127d631b12a38a6440a37f52935543.yml +openapi_spec_hash: 5a190df210ed90b20a71c5061ff43917 +config_hash: 38c9b3b355025daf9bb643040e4af94e diff --git a/api.md b/api.md index 1f78038..8037ef0 100644 --- a/api.md +++ b/api.md @@ -203,6 +203,30 @@ Methods: - client.profiles.delete(idOrName) -> void - client.profiles.download(idOrName) -> Response +# Auth + +## Connections + +Types: + +- LoginRequest +- LoginResponse +- ManagedAuth +- ManagedAuthCreateRequest +- SubmitFieldsRequest +- SubmitFieldsResponse +- ConnectionFollowResponse + +Methods: + +- client.auth.connections.create({ ...params }) -> ManagedAuth +- client.auth.connections.retrieve(id) -> ManagedAuth +- client.auth.connections.list({ ...params }) -> ManagedAuthsOffsetPagination +- client.auth.connections.delete(id) -> void +- client.auth.connections.follow(id) -> ConnectionFollowResponse +- client.auth.connections.login(id, { ...params }) -> LoginResponse +- client.auth.connections.submit(id, { ...params }) -> SubmitFieldsResponse + # Proxies Types: @@ -312,15 +336,18 @@ Types: - CreateCredentialProviderRequest - CredentialProvider +- CredentialProviderItem - CredentialProviderTestResult - UpdateCredentialProviderRequest - CredentialProviderListResponse +- CredentialProviderListItemsResponse Methods: -- client.credentialProviders.create({ ...params }) -> CredentialProvider -- client.credentialProviders.retrieve(id) -> CredentialProvider -- client.credentialProviders.update(id, { ...params }) -> CredentialProvider -- client.credentialProviders.list() -> CredentialProviderListResponse -- client.credentialProviders.delete(id) -> void -- client.credentialProviders.test(id) -> CredentialProviderTestResult +- client.credentialProviders.create({ ...params }) -> CredentialProvider +- client.credentialProviders.retrieve(id) -> CredentialProvider +- client.credentialProviders.update(id, { ...params }) -> CredentialProvider +- client.credentialProviders.list() -> CredentialProviderListResponse +- client.credentialProviders.delete(id) -> void +- client.credentialProviders.listItems(id) -> CredentialProviderListItemsResponse +- client.credentialProviders.test(id) -> CredentialProviderTestResult diff --git a/src/client.ts b/src/client.ts index 90ca176..5732b17 100644 --- a/src/client.ts +++ b/src/client.ts @@ -34,6 +34,8 @@ import { CreateCredentialProviderRequest, CredentialProvider, CredentialProviderCreateParams, + CredentialProviderItem, + CredentialProviderListItemsResponse, CredentialProviderListResponse, CredentialProviderTestResult, CredentialProviderUpdateParams, @@ -96,6 +98,7 @@ import { ProxyRetrieveResponse, } from './resources/proxies'; import { Agents } from './resources/agents/agents'; +import { Auth } from './resources/auth/auth'; import { BrowserCreateParams, BrowserCreateResponse, @@ -891,6 +894,7 @@ export class Kernel { invocations: API.Invocations = new API.Invocations(this); browsers: API.Browsers = new API.Browsers(this); profiles: API.Profiles = new API.Profiles(this); + auth: API.Auth = new API.Auth(this); proxies: API.Proxies = new API.Proxies(this); extensions: API.Extensions = new API.Extensions(this); browserPools: API.BrowserPools = new API.BrowserPools(this); @@ -904,6 +908,7 @@ Kernel.Apps = Apps; Kernel.Invocations = Invocations; Kernel.Browsers = Browsers; Kernel.Profiles = Profiles; +Kernel.Auth = Auth; Kernel.Proxies = Proxies; Kernel.Extensions = Extensions; Kernel.BrowserPools = BrowserPools; @@ -979,6 +984,8 @@ export declare namespace Kernel { type ProfileCreateParams as ProfileCreateParams, }; + export { Auth as Auth }; + export { Proxies as Proxies, type ProxyCreateResponse as ProxyCreateResponse, @@ -1026,9 +1033,11 @@ export declare namespace Kernel { CredentialProviders as CredentialProviders, type CreateCredentialProviderRequest as CreateCredentialProviderRequest, type CredentialProvider as CredentialProvider, + type CredentialProviderItem as CredentialProviderItem, type CredentialProviderTestResult as CredentialProviderTestResult, type UpdateCredentialProviderRequest as UpdateCredentialProviderRequest, type CredentialProviderListResponse as CredentialProviderListResponse, + type CredentialProviderListItemsResponse as CredentialProviderListItemsResponse, type CredentialProviderCreateParams as CredentialProviderCreateParams, type CredentialProviderUpdateParams as CredentialProviderUpdateParams, }; diff --git a/src/resources/agents/auth/auth.ts b/src/resources/agents/auth/auth.ts index 570308e..e4de6ba 100644 --- a/src/resources/agents/auth/auth.ts +++ b/src/resources/agents/auth/auth.ts @@ -19,46 +19,33 @@ export class Auth extends APIResource { invocations: InvocationsAPI.Invocations = new InvocationsAPI.Invocations(this._client); /** - * 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: 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. * - * @example - * ```ts - * const authAgent = await client.agents.auth.create({ - * domain: 'netflix.com', - * profile_name: 'user-123', - * }); - * ``` + * @deprecated */ create(body: AuthCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/agents/auth', { body, ...options }); } /** - * Retrieve an auth agent by its ID. Returns the current authentication status of - * the managed profile. + * **Deprecated: Use GET /auth/connections/{id} instead.** Retrieve an auth agent + * by its ID. Returns the current authentication status of the managed profile. * - * @example - * ```ts - * const authAgent = await client.agents.auth.retrieve('id'); - * ``` + * @deprecated */ retrieve(id: string, options?: RequestOptions): APIPromise { return this._client.get(path`/agents/auth/${id}`, options); } /** - * List auth agents with optional filters for profile_name and domain. + * **Deprecated: Use GET /auth/connections instead.** List auth agents with + * optional filters for profile_name and domain. * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const authAgent of client.agents.auth.list()) { - * // ... - * } - * ``` + * @deprecated */ list( query: AuthListParams | null | undefined = {}, @@ -68,16 +55,14 @@ export class Auth extends APIResource { } /** - * Deletes an auth agent and terminates its workflow. This will: + * **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 * - * @example - * ```ts - * await client.agents.auth.delete('id'); - * ``` + * @deprecated */ delete(id: string, options?: RequestOptions): APIPromise { return this._client.delete(path`/agents/auth/${id}`, { @@ -126,13 +111,12 @@ export interface AgentAuthInvocationResponse { | 'expired'; /** - * The invocation type: + * The session type: * - * - login: First-time authentication - * - reauth: Re-authentication for previously authenticated agents - * - auto_login: Legacy type (no longer created, kept for backward compatibility) + * - login: User-initiated authentication + * - reauth: System-triggered re-authentication (via health check) */ - type: 'login' | 'auto_login' | 'reauth'; + type: 'login' | 'reauth'; /** * Error message explaining why the invocation failed (present when status=FAILED) @@ -188,9 +172,9 @@ export namespace AgentAuthInvocationResponse { label: string; /** - * The MFA delivery method type + * The MFA delivery method type (includes password for auth method selection pages) */ - type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'security_key'; + type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'password'; /** * Additional instructions from the site @@ -263,6 +247,21 @@ export interface AuthAgent { * 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 */ allowed_domains?: Array; @@ -273,14 +272,19 @@ export interface AuthAgent { can_reauth?: boolean; /** - * ID of the linked credential for automatic re-authentication + * 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_id?: string; + credential?: AuthAgent.Credential; /** - * Name of the linked credential for automatic re-authentication + * ID of the linked Kernel credential for automatic re-authentication (deprecated, + * use credential) */ - credential_name?: string; + credential_id?: string; /** * Whether this auth agent has stored selectors for deterministic re-authentication @@ -299,6 +303,37 @@ export interface AuthAgent { post_login_url?: string; } +export namespace AuthAgent { + /** + * 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 + */ + export interface Credential { + /** + * If true, lookup by domain from the specified provider + */ + auto?: boolean; + + /** + * Kernel credential name + */ + name?: string; + + /** + * Provider-specific path (e.g., "VaultName/ItemName" for 1Password) + */ + path?: string; + + /** + * External provider name (e.g., "my-1p") + */ + provider?: string; + } +} + /** * Request to create or find an auth agent */ @@ -317,6 +352,21 @@ export interface AuthAgentCreateRequest { * 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 */ allowed_domains?: Array; @@ -393,13 +443,12 @@ export interface AuthAgentInvocationCreateResponse { invocation_id: string; /** - * The invocation type: + * The session type: * - * - login: First-time authentication - * - reauth: Re-authentication for previously authenticated agents - * - auto_login: Legacy type (no longer created, kept for backward compatibility) + * - login: User-initiated authentication + * - reauth: System-triggered re-authentication (via health check) */ - type: 'login' | 'auto_login' | 'reauth'; + type: 'login' | 'reauth'; } /** @@ -426,6 +475,12 @@ export interface DiscoveredField { */ type: 'text' | 'email' | 'password' | 'tel' | 'number' | 'url' | 'code' | 'totp'; + /** + * If this field is associated with an MFA option, the type of that option (e.g., + * password field linked to "Enter password" option) + */ + linked_mfa_type?: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'password' | null; + /** * Field placeholder */ @@ -452,6 +507,21 @@ export interface AuthCreateParams { * 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 */ allowed_domains?: Array; diff --git a/src/resources/agents/auth/invocations.ts b/src/resources/agents/auth/invocations.ts index 3a25011..b41ea8e 100644 --- a/src/resources/agents/auth/invocations.ts +++ b/src/resources/agents/auth/invocations.ts @@ -8,17 +8,11 @@ import { path } from '../../../internal/utils/path'; export class Invocations extends APIResource { /** - * 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: 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. * - * @example - * ```ts - * const authAgentInvocationCreateResponse = - * await client.agents.auth.invocations.create({ - * auth_agent_id: 'abc123xyz', - * }); - * ``` + * @deprecated */ create( body: InvocationCreateParams, @@ -28,33 +22,22 @@ export class Invocations extends APIResource { } /** - * Returns invocation details including status, app_name, and domain. Supports both - * API key and JWT (from exchange endpoint) authentication. + * **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. * - * @example - * ```ts - * const agentAuthInvocationResponse = - * await client.agents.auth.invocations.retrieve( - * 'invocation_id', - * ); - * ``` + * @deprecated */ retrieve(invocationID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/agents/auth/invocations/${invocationID}`, options); } /** - * Validates the handoff code and returns a JWT token for subsequent requests. No - * authentication required (the handoff code serves as the credential). + * **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). * - * @example - * ```ts - * const response = - * await client.agents.auth.invocations.exchange( - * 'invocation_id', - * { code: 'abc123xyz' }, - * ); - * ``` + * @deprecated */ exchange( invocationID: string, @@ -65,23 +48,11 @@ export class Invocations extends APIResource { } /** - * 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: 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. * - * @example - * ```ts - * const agentAuthSubmitResponse = - * await client.agents.auth.invocations.submit( - * 'invocation_id', - * { - * field_values: { - * email: 'user@example.com', - * password: '********', - * }, - * }, - * ); - * ``` + * @deprecated */ submit( invocationID: string, @@ -150,9 +121,9 @@ export declare namespace InvocationSubmitParams { export interface Variant2 { /** - * The MFA delivery method type + * The MFA delivery method type (includes password for auth method selection pages) */ - selected_mfa_type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'security_key'; + selected_mfa_type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'password'; } } diff --git a/src/resources/auth.ts b/src/resources/auth.ts new file mode 100644 index 0000000..b64faa1 --- /dev/null +++ b/src/resources/auth.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './auth/index'; diff --git a/src/resources/auth/auth.ts b/src/resources/auth/auth.ts new file mode 100644 index 0000000..2aaa817 --- /dev/null +++ b/src/resources/auth/auth.ts @@ -0,0 +1,43 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import * as ConnectionsAPI from './connections'; +import { + ConnectionCreateParams, + ConnectionFollowResponse, + ConnectionListParams, + ConnectionLoginParams, + ConnectionSubmitParams, + Connections, + LoginRequest, + LoginResponse, + ManagedAuth, + ManagedAuthCreateRequest, + ManagedAuthsOffsetPagination, + SubmitFieldsRequest, + SubmitFieldsResponse, +} from './connections'; + +export class Auth extends APIResource { + connections: ConnectionsAPI.Connections = new ConnectionsAPI.Connections(this._client); +} + +Auth.Connections = Connections; + +export declare namespace Auth { + export { + Connections as Connections, + type LoginRequest as LoginRequest, + type LoginResponse as LoginResponse, + type ManagedAuth as ManagedAuth, + type ManagedAuthCreateRequest as ManagedAuthCreateRequest, + type SubmitFieldsRequest as SubmitFieldsRequest, + type SubmitFieldsResponse as SubmitFieldsResponse, + type ConnectionFollowResponse as ConnectionFollowResponse, + type ManagedAuthsOffsetPagination as ManagedAuthsOffsetPagination, + type ConnectionCreateParams as ConnectionCreateParams, + type ConnectionListParams as ConnectionListParams, + type ConnectionLoginParams as ConnectionLoginParams, + type ConnectionSubmitParams as ConnectionSubmitParams, + }; +} diff --git a/src/resources/auth/connections.ts b/src/resources/auth/connections.ts new file mode 100644 index 0000000..3479a5e --- /dev/null +++ b/src/resources/auth/connections.ts @@ -0,0 +1,843 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import * as Shared from '../shared'; +import * as AuthAPI from '../agents/auth/auth'; +import { APIPromise } from '../../core/api-promise'; +import { OffsetPagination, type OffsetPaginationParams, PagePromise } from '../../core/pagination'; +import { Stream } from '../../core/streaming'; +import { buildHeaders } from '../../internal/headers'; +import { RequestOptions } from '../../internal/request-options'; +import { path } from '../../internal/utils/path'; + +export class Connections extends APIResource { + /** + * Creates managed authentication for a profile and domain combination. Returns 409 + * Conflict if managed auth already exists for the given profile and domain. + * + * @example + * ```ts + * const managedAuth = await client.auth.connections.create({ + * domain: 'netflix.com', + * profile_name: 'user-123', + * }); + * ``` + */ + create(body: ConnectionCreateParams, options?: RequestOptions): APIPromise { + return this._client.post('/auth/connections', { body, ...options }); + } + + /** + * Retrieve managed auth by its ID. Includes current flow state if a login is in + * progress. + * + * @example + * ```ts + * const managedAuth = await client.auth.connections.retrieve( + * 'id', + * ); + * ``` + */ + retrieve(id: string, options?: RequestOptions): APIPromise { + return this._client.get(path`/auth/connections/${id}`, options); + } + + /** + * List managed auths with optional filters for profile_name and domain. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const managedAuth of client.auth.connections.list()) { + * // ... + * } + * ``` + */ + list( + query: ConnectionListParams | null | undefined = {}, + options?: RequestOptions, + ): PagePromise { + return this._client.getAPIList('/auth/connections', OffsetPagination, { query, ...options }); + } + + /** + * Deletes managed auth and terminates its workflow. This will: + * + * - Delete the managed auth record + * - Terminate the Temporal workflow + * - Cancel any in-progress login flows + * + * @example + * ```ts + * await client.auth.connections.delete('id'); + * ``` + */ + delete(id: string, options?: RequestOptions): APIPromise { + return this._client.delete(path`/auth/connections/${id}`, { + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + + /** + * Establishes a Server-Sent Events (SSE) stream that delivers real-time login flow + * state updates. The stream terminates automatically once the flow reaches a + * terminal state (SUCCESS, FAILED, EXPIRED, CANCELED). + * + * @example + * ```ts + * const response = await client.auth.connections.follow('id'); + * ``` + */ + follow(id: string, options?: RequestOptions): APIPromise> { + return this._client.get(path`/auth/connections/${id}/events`, { + ...options, + headers: buildHeaders([{ Accept: 'text/event-stream' }, options?.headers]), + stream: true, + }) as APIPromise>; + } + + /** + * 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 + * credentials are stored. + * + * @example + * ```ts + * const loginResponse = await client.auth.connections.login( + * 'id', + * ); + * ``` + */ + login( + id: string, + body: ConnectionLoginParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + return this._client.post(path`/auth/connections/${id}/login`, { body, ...options }); + } + + /** + * Submits field values for the login form. Poll the managed auth to track progress + * and get results. + * + * @example + * ```ts + * const submitFieldsResponse = + * await client.auth.connections.submit('id', { + * fields: { + * email: 'user@example.com', + * password: 'secret', + * }, + * }); + * ``` + */ + submit( + id: string, + body: ConnectionSubmitParams, + options?: RequestOptions, + ): APIPromise { + return this._client.post(path`/auth/connections/${id}/submit`, { body, ...options }); + } +} + +export type ManagedAuthsOffsetPagination = OffsetPagination; + +/** + * Request to start a login flow + */ +export interface LoginRequest { + /** + * If provided, saves credentials under this name upon successful login + */ + save_credential_as?: string; +} + +/** + * Response from starting a login flow + */ +export interface LoginResponse { + /** + * Managed auth ID + */ + id: string; + + /** + * When the login flow expires + */ + flow_expires_at: string; + + /** + * Type of login flow started + */ + flow_type: 'LOGIN' | 'REAUTH'; + + /** + * URL to redirect user to for login + */ + hosted_url: string; + + /** + * One-time code for handoff (internal use) + */ + handoff_code?: string; + + /** + * Browser live view URL for watching the login flow + */ + live_view_url?: string; +} + +/** + * Managed authentication that keeps a profile logged into a specific domain. Flow + * fields (flow_status, flow_step, discovered_fields, mfa_options) reflect the most + * recent login flow and are null when no flow has been initiated. + */ +export interface ManagedAuth { + /** + * Unique identifier for the managed auth + */ + id: string; + + /** + * Target domain for authentication + */ + domain: string; + + /** + * Name of the profile associated with this managed auth + */ + profile_name: string; + + /** + * Current authentication status of the managed profile + */ + status: 'AUTHENTICATED' | 'NEEDS_AUTH'; + + /** + * Additional domains that are valid for this auth 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 + */ + allowed_domains?: Array; + + /** + * Whether automatic re-authentication is possible (has credential, selectors, and + * login_url) + */ + can_reauth?: boolean; + + /** + * 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?: ManagedAuth.Credential; + + /** + * Fields awaiting input (present when flow_step=awaiting_input) + */ + discovered_fields?: Array | null; + + /** + * Error message (present when flow_status=failed) + */ + error_message?: string | null; + + /** + * Instructions for external action (present when + * flow_step=awaiting_external_action) + */ + external_action_message?: string | null; + + /** + * When the current flow expires (null when no flow in progress) + */ + flow_expires_at?: string | null; + + /** + * Current flow status (null when no flow in progress) + */ + flow_status?: 'IN_PROGRESS' | 'SUCCESS' | 'FAILED' | 'EXPIRED' | 'CANCELED' | null; + + /** + * Current step in the flow (null when no flow in progress) + */ + flow_step?: + | 'DISCOVERING' + | 'AWAITING_INPUT' + | 'AWAITING_EXTERNAL_ACTION' + | 'SUBMITTING' + | 'COMPLETED' + | null; + + /** + * Type of the current flow (null when no flow in progress) + */ + flow_type?: 'LOGIN' | 'REAUTH' | null; + + /** + * 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). + */ + health_check_interval?: number | null; + + /** + * URL to redirect user to for hosted login (present when flow in progress) + */ + hosted_url?: string | null; + + /** + * When the profile was last successfully authenticated + */ + last_auth_at?: string; + + /** + * Browser live view URL for debugging (present when flow in progress) + */ + live_view_url?: string | null; + + /** + * MFA method options (present when flow_step=awaiting_input and MFA selection + * required) + */ + mfa_options?: Array | null; + + /** + * SSO buttons available (present when flow_step=awaiting_input) + */ + pending_sso_buttons?: Array | null; + + /** + * URL where the browser landed after successful login + */ + post_login_url?: string; + + /** + * SSO provider being used (e.g., google, github, microsoft) + */ + sso_provider?: string | null; + + /** + * Visible error message from the website (e.g., 'Incorrect password'). Present + * when the website displays an error during login. + */ + website_error?: string | null; +} + +export namespace ManagedAuth { + /** + * 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 + */ + export interface Credential { + /** + * If true, lookup by domain from the specified provider + */ + auto?: boolean; + + /** + * Kernel credential name + */ + name?: string; + + /** + * Provider-specific path (e.g., "VaultName/ItemName" for 1Password) + */ + path?: string; + + /** + * External provider name (e.g., "my-1p") + */ + provider?: string; + } + + /** + * An MFA method option for verification + */ + export interface MfaOption { + /** + * The visible option text + */ + label: string; + + /** + * The MFA delivery method type (includes password for auth method selection pages) + */ + type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'password'; + + /** + * Additional instructions from the site + */ + description?: string | null; + + /** + * The masked destination (phone/email) if shown + */ + target?: string | null; + } + + /** + * An SSO button for signing in with an external identity provider + */ + export interface PendingSSOButton { + /** + * Visible button text + */ + label: string; + + /** + * Identity provider name + */ + provider: string; + + /** + * XPath selector for the button + */ + selector: string; + } +} + +/** + * Request to create managed auth for a profile and domain + */ +export interface ManagedAuthCreateRequest { + /** + * Domain for authentication + */ + domain: string; + + /** + * Name of the profile to manage authentication for + */ + profile_name: string; + + /** + * Additional domains valid for this auth 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 + */ + allowed_domains?: Array; + + /** + * 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?: ManagedAuthCreateRequest.Credential; + + /** + * 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). + */ + health_check_interval?: number; + + /** + * Optional login page URL to skip discovery + */ + login_url?: string; + + /** + * Optional proxy configuration + */ + proxy?: ManagedAuthCreateRequest.Proxy; +} + +export namespace ManagedAuthCreateRequest { + /** + * 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 + */ + export interface Credential { + /** + * If true, lookup by domain from the specified provider + */ + auto?: boolean; + + /** + * Kernel credential name + */ + name?: string; + + /** + * Provider-specific path (e.g., "VaultName/ItemName" for 1Password) + */ + path?: string; + + /** + * External provider name (e.g., "my-1p") + */ + provider?: string; + } + + /** + * Optional proxy configuration + */ + export interface Proxy { + /** + * ID of the proxy to use + */ + proxy_id?: string; + } +} + +/** + * Request to submit field values for login + */ +export interface SubmitFieldsRequest { + /** + * Map of field name to value + */ + fields: { [key: string]: string }; + + /** + * Optional MFA option ID if user selected an MFA method + */ + mfa_option_id?: string; + + /** + * Optional XPath selector if user chose to click an SSO button instead + */ + sso_button_selector?: string; +} + +/** + * Response from submitting field values + */ +export interface SubmitFieldsResponse { + /** + * Whether the submission was accepted for processing + */ + accepted: boolean; +} + +/** + * Union type representing any managed auth event. + */ +export type ConnectionFollowResponse = + | ConnectionFollowResponse.ManagedAuthStateEvent + | Shared.ErrorEvent + | Shared.HeartbeatEvent; + +export namespace ConnectionFollowResponse { + /** + * An event representing the current state of a managed auth flow. + */ + export interface ManagedAuthStateEvent { + /** + * Event type identifier (always "managed_auth_state"). + */ + event: 'managed_auth_state'; + + /** + * Current flow status. + */ + flow_status: 'IN_PROGRESS' | 'SUCCESS' | 'FAILED' | 'EXPIRED' | 'CANCELED'; + + /** + * Current step in the flow. + */ + flow_step: 'DISCOVERING' | 'AWAITING_INPUT' | 'AWAITING_EXTERNAL_ACTION' | 'SUBMITTING' | 'COMPLETED'; + + /** + * Time the state was reported. + */ + timestamp: string; + + /** + * Fields awaiting input (present when flow_step=AWAITING_INPUT). + */ + discovered_fields?: Array; + + /** + * Error message (present when flow_status=FAILED). + */ + error_message?: string; + + /** + * Instructions for external action (present when + * flow_step=AWAITING_EXTERNAL_ACTION). + */ + external_action_message?: string; + + /** + * Type of the current flow. + */ + flow_type?: 'LOGIN' | 'REAUTH'; + + /** + * URL to redirect user to for hosted login. + */ + hosted_url?: string; + + /** + * Browser live view URL for debugging. + */ + live_view_url?: string; + + /** + * MFA method options (present when flow_step=AWAITING_INPUT and MFA selection + * required). + */ + mfa_options?: Array; + + /** + * SSO buttons available (present when flow_step=AWAITING_INPUT). + */ + pending_sso_buttons?: Array; + + /** + * URL where the browser landed after successful login. + */ + post_login_url?: string; + + /** + * Visible error message from the website (e.g., 'Incorrect password'). Present + * when the website displays an error during login. + */ + website_error?: string; + } + + export namespace ManagedAuthStateEvent { + /** + * An MFA method option for verification + */ + export interface MfaOption { + /** + * The visible option text + */ + label: string; + + /** + * The MFA delivery method type (includes password for auth method selection pages) + */ + type: 'sms' | 'call' | 'email' | 'totp' | 'push' | 'password'; + + /** + * Additional instructions from the site + */ + description?: string | null; + + /** + * The masked destination (phone/email) if shown + */ + target?: string | null; + } + + /** + * An SSO button for signing in with an external identity provider + */ + export interface PendingSSOButton { + /** + * Visible button text + */ + label: string; + + /** + * Identity provider name + */ + provider: string; + + /** + * XPath selector for the button + */ + selector: string; + } + } +} + +export interface ConnectionCreateParams { + /** + * Domain for authentication + */ + domain: string; + + /** + * Name of the profile to manage authentication for + */ + profile_name: string; + + /** + * Additional domains valid for this auth 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 + */ + allowed_domains?: Array; + + /** + * 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?: ConnectionCreateParams.Credential; + + /** + * 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). + */ + health_check_interval?: number; + + /** + * Optional login page URL to skip discovery + */ + login_url?: string; + + /** + * Optional proxy configuration + */ + proxy?: ConnectionCreateParams.Proxy; +} + +export namespace ConnectionCreateParams { + /** + * 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 + */ + export interface Credential { + /** + * If true, lookup by domain from the specified provider + */ + auto?: boolean; + + /** + * Kernel credential name + */ + name?: string; + + /** + * Provider-specific path (e.g., "VaultName/ItemName" for 1Password) + */ + path?: string; + + /** + * External provider name (e.g., "my-1p") + */ + provider?: string; + } + + /** + * Optional proxy configuration + */ + export interface Proxy { + /** + * ID of the proxy to use + */ + proxy_id?: string; + } +} + +export interface ConnectionListParams extends OffsetPaginationParams { + /** + * Filter by domain + */ + domain?: string; + + /** + * Filter by profile name + */ + profile_name?: string; +} + +export interface ConnectionLoginParams { + /** + * If provided, saves credentials under this name upon successful login + */ + save_credential_as?: string; +} + +export interface ConnectionSubmitParams { + /** + * Map of field name to value + */ + fields: { [key: string]: string }; + + /** + * Optional MFA option ID if user selected an MFA method + */ + mfa_option_id?: string; + + /** + * Optional XPath selector if user chose to click an SSO button instead + */ + sso_button_selector?: string; +} + +export declare namespace Connections { + export { + type LoginRequest as LoginRequest, + type LoginResponse as LoginResponse, + type ManagedAuth as ManagedAuth, + type ManagedAuthCreateRequest as ManagedAuthCreateRequest, + type SubmitFieldsRequest as SubmitFieldsRequest, + type SubmitFieldsResponse as SubmitFieldsResponse, + type ConnectionFollowResponse as ConnectionFollowResponse, + type ManagedAuthsOffsetPagination as ManagedAuthsOffsetPagination, + type ConnectionCreateParams as ConnectionCreateParams, + type ConnectionListParams as ConnectionListParams, + type ConnectionLoginParams as ConnectionLoginParams, + type ConnectionSubmitParams as ConnectionSubmitParams, + }; +} diff --git a/src/resources/auth/index.ts b/src/resources/auth/index.ts new file mode 100644 index 0000000..4debc7e --- /dev/null +++ b/src/resources/auth/index.ts @@ -0,0 +1,18 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export { Auth } from './auth'; +export { + Connections, + type LoginRequest, + type LoginResponse, + type ManagedAuth, + type ManagedAuthCreateRequest, + type SubmitFieldsRequest, + type SubmitFieldsResponse, + type ConnectionFollowResponse, + type ConnectionCreateParams, + type ConnectionListParams, + type ConnectionLoginParams, + type ConnectionSubmitParams, + type ManagedAuthsOffsetPagination, +} from './connections'; diff --git a/src/resources/credential-providers.ts b/src/resources/credential-providers.ts index 596e9e5..42733a9 100644 --- a/src/resources/credential-providers.ts +++ b/src/resources/credential-providers.ts @@ -16,12 +16,13 @@ export class CredentialProviders extends APIResource { * const credentialProvider = * await client.credentialProviders.create({ * token: 'ops_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...', + * name: 'my-1password', * provider_type: 'onepassword', * }); * ``` */ create(body: CredentialProviderCreateParams, options?: RequestOptions): APIPromise { - return this._client.post('/org/credential-providers', { body, ...options }); + return this._client.post('/org/credential_providers', { body, ...options }); } /** @@ -34,7 +35,7 @@ export class CredentialProviders extends APIResource { * ``` */ retrieve(id: string, options?: RequestOptions): APIPromise { - return this._client.get(path`/org/credential-providers/${id}`, options); + return this._client.get(path`/org/credential_providers/${id}`, options); } /** @@ -51,7 +52,7 @@ export class CredentialProviders extends APIResource { body: CredentialProviderUpdateParams, options?: RequestOptions, ): APIPromise { - return this._client.patch(path`/org/credential-providers/${id}`, { body, ...options }); + return this._client.patch(path`/org/credential_providers/${id}`, { body, ...options }); } /** @@ -64,7 +65,7 @@ export class CredentialProviders extends APIResource { * ``` */ list(options?: RequestOptions): APIPromise { - return this._client.get('/org/credential-providers', options); + return this._client.get('/org/credential_providers', options); } /** @@ -76,12 +77,27 @@ export class CredentialProviders extends APIResource { * ``` */ delete(id: string, options?: RequestOptions): APIPromise { - return this._client.delete(path`/org/credential-providers/${id}`, { + return this._client.delete(path`/org/credential_providers/${id}`, { ...options, headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), }); } + /** + * Returns available credential items (e.g., 1Password login items) from the + * provider. + * + * @example + * ```ts + * const response = await client.credentialProviders.listItems( + * 'id', + * ); + * ``` + */ + listItems(id: string, options?: RequestOptions): APIPromise { + return this._client.get(path`/org/credential_providers/${id}/items`, options); + } + /** * Validate the credential provider's token and list accessible vaults. * @@ -92,7 +108,7 @@ export class CredentialProviders extends APIResource { * ``` */ test(id: string, options?: RequestOptions): APIPromise { - return this._client.post(path`/org/credential-providers/${id}/test`, options); + return this._client.post(path`/org/credential_providers/${id}/test`, options); } } @@ -105,6 +121,11 @@ export interface CreateCredentialProviderRequest { */ token: string; + /** + * Human-readable name for this provider instance (unique per org) + */ + name: string; + /** * Type of credential provider */ @@ -136,6 +157,11 @@ export interface CredentialProvider { */ enabled: boolean; + /** + * Human-readable name for this provider instance + */ + name: string; + /** * Priority order for credential lookups (lower numbers are checked first) */ @@ -152,6 +178,41 @@ export interface CredentialProvider { updated_at: string; } +/** + * A credential item from an external provider (e.g., a 1Password login item) + */ +export interface CredentialProviderItem { + /** + * Unique identifier for the item within the provider + */ + id: string; + + /** + * Path to reference this item (VaultName/ItemTitle format) + */ + path: string; + + /** + * Display name of the credential item + */ + title: string; + + /** + * ID of the vault containing this item + */ + vault_id: string; + + /** + * Name of the vault containing this item + */ + vault_name: string; + + /** + * URLs associated with this credential + */ + urls?: Array; +} + /** * Result of testing a credential provider connection */ @@ -205,6 +266,11 @@ export interface UpdateCredentialProviderRequest { */ enabled?: boolean; + /** + * Human-readable name for this provider instance + */ + name?: string; + /** * Priority order for credential lookups (lower numbers are checked first) */ @@ -213,12 +279,21 @@ export interface UpdateCredentialProviderRequest { export type CredentialProviderListResponse = Array; +export interface CredentialProviderListItemsResponse { + items?: Array; +} + export interface CredentialProviderCreateParams { /** * Service account token for the provider (e.g., 1Password service account token) */ token: string; + /** + * Human-readable name for this provider instance (unique per org) + */ + name: string; + /** * Type of credential provider */ @@ -246,6 +321,11 @@ export interface CredentialProviderUpdateParams { */ enabled?: boolean; + /** + * Human-readable name for this provider instance + */ + name?: string; + /** * Priority order for credential lookups (lower numbers are checked first) */ @@ -256,9 +336,11 @@ export declare namespace CredentialProviders { export { type CreateCredentialProviderRequest as CreateCredentialProviderRequest, type CredentialProvider as CredentialProvider, + type CredentialProviderItem as CredentialProviderItem, type CredentialProviderTestResult as CredentialProviderTestResult, type UpdateCredentialProviderRequest as UpdateCredentialProviderRequest, type CredentialProviderListResponse as CredentialProviderListResponse, + type CredentialProviderListItemsResponse as CredentialProviderListItemsResponse, type CredentialProviderCreateParams as CredentialProviderCreateParams, type CredentialProviderUpdateParams as CredentialProviderUpdateParams, }; diff --git a/src/resources/index.ts b/src/resources/index.ts index a2d913f..d29baae 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -8,6 +8,7 @@ export { type AppListParams, type AppListResponsesOffsetPagination, } from './apps'; +export { Auth } from './auth/auth'; export { BrowserPools, type BrowserPool, @@ -39,9 +40,11 @@ export { CredentialProviders, type CreateCredentialProviderRequest, type CredentialProvider, + type CredentialProviderItem, type CredentialProviderTestResult, type UpdateCredentialProviderRequest, type CredentialProviderListResponse, + type CredentialProviderListItemsResponse, type CredentialProviderCreateParams, type CredentialProviderUpdateParams, } from './credential-providers'; diff --git a/tests/api-resources/auth/connections.test.ts b/tests/api-resources/auth/connections.test.ts new file mode 100644 index 0000000..14c2abf --- /dev/null +++ b/tests/api-resources/auth/connections.test.ts @@ -0,0 +1,154 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Kernel from '@onkernel/sdk'; + +const client = new Kernel({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource connections', () => { + // Prism tests are disabled + test.skip('create: only required params', async () => { + const responsePromise = client.auth.connections.create({ + domain: 'netflix.com', + profile_name: 'user-123', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('create: required and optional params', async () => { + const response = await client.auth.connections.create({ + domain: 'netflix.com', + profile_name: 'user-123', + allowed_domains: ['login.netflix.com', 'auth.netflix.com'], + credential: { + auto: true, + name: 'my-netflix-creds', + path: 'Personal/Netflix', + provider: 'my-1p', + }, + health_check_interval: 3600, + login_url: 'https://netflix.com/login', + proxy: { proxy_id: 'proxy_id' }, + }); + }); + + // Prism tests are disabled + test.skip('retrieve', async () => { + const responsePromise = client.auth.connections.retrieve('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('list', async () => { + const responsePromise = client.auth.connections.list(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('list: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.auth.connections.list( + { + domain: 'domain', + limit: 100, + offset: 0, + profile_name: 'profile_name', + }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Kernel.NotFoundError); + }); + + // Prism tests are disabled + test.skip('delete', async () => { + const responsePromise = client.auth.connections.delete('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism doesn't support text/event-stream responses + test.skip('follow', async () => { + const responsePromise = client.auth.connections.follow('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('login', async () => { + const responsePromise = client.auth.connections.login('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('login: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.auth.connections.login( + 'id', + { save_credential_as: 'my-netflix-login' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Kernel.NotFoundError); + }); + + // Prism tests are disabled + test.skip('submit: only required params', async () => { + const responsePromise = client.auth.connections.submit('id', { + fields: { email: 'user@example.com', password: 'secret' }, + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('submit: required and optional params', async () => { + const response = await client.auth.connections.submit('id', { + fields: { email: 'user@example.com', password: 'secret' }, + mfa_option_id: 'sms', + sso_button_selector: "xpath=//button[contains(text(), 'Continue with Google')]", + }); + }); +}); diff --git a/tests/api-resources/credential-providers.test.ts b/tests/api-resources/credential-providers.test.ts index 5a20da8..5327b20 100644 --- a/tests/api-resources/credential-providers.test.ts +++ b/tests/api-resources/credential-providers.test.ts @@ -12,6 +12,7 @@ describe('resource credentialProviders', () => { test.skip('create: only required params', async () => { const responsePromise = client.credentialProviders.create({ token: 'ops_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...', + name: 'my-1password', provider_type: 'onepassword', }); const rawResponse = await responsePromise.asResponse(); @@ -27,6 +28,7 @@ describe('resource credentialProviders', () => { test.skip('create: required and optional params', async () => { const response = await client.credentialProviders.create({ token: 'ops_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...', + name: 'my-1password', provider_type: 'onepassword', cache_ttl_seconds: 300, }); @@ -80,6 +82,18 @@ describe('resource credentialProviders', () => { expect(dataAndResponse.response).toBe(rawResponse); }); + // Prism tests are disabled + test.skip('listItems', async () => { + const responsePromise = client.credentialProviders.listItems('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + // Prism tests are disabled test.skip('test', async () => { const responsePromise = client.credentialProviders.test('id'); From 08b1c2cd294567df0e7265266d782ff83bd07101 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 20:32:53 +0000 Subject: [PATCH 2/2] release: 0.31.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8e3d955..85df471 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.31.0" + ".": "0.31.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eedd70..14d2cc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.31.1 (2026-02-06) + +Full Changelog: [v0.31.0...v0.31.1](https://github.com/kernel/kernel-node-sdk/compare/v0.31.0...v0.31.1) + +### Chores + +* add Managed Auth API planning doc ([a6cb845](https://github.com/kernel/kernel-node-sdk/commit/a6cb845a2bc963459dd5f7d04a11650c20064d6f)) + ## 0.31.0 (2026-02-06) Full Changelog: [v0.30.0...v0.31.0](https://github.com/kernel/kernel-node-sdk/compare/v0.30.0...v0.31.0) diff --git a/package.json b/package.json index 53f4cbd..5b65c05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@onkernel/sdk", - "version": "0.31.0", + "version": "0.31.1", "description": "The official TypeScript library for the Kernel API", "author": "Kernel <>", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index b6314c2..c71c0da 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.31.0'; // x-release-please-version +export const VERSION = '0.31.1'; // x-release-please-version