diff --git a/.changelog-pending/2026-09-16T19-24-30-949c30cb87778129af801fadc33546518853d045.md b/.changelog-pending/2026-09-16T19-24-30-949c30cb87778129af801fadc33546518853d045.md index 1ad748dc..0469270b 100644 --- a/.changelog-pending/2026-09-16T19-24-30-949c30cb87778129af801fadc33546518853d045.md +++ b/.changelog-pending/2026-09-16T19-24-30-949c30cb87778129af801fadc33546518853d045.md @@ -16,13 +16,12 @@ * Added enum `DataIntegrationInstallationConnectionRole` * Added `connection_owner` to `DataIntegrationsGetDataIntegrationAuthorizeUrlRequest` * Added enum `DataIntegrationsGetDataIntegrationAuthorizeUrlRequestConnectionOwner` + * Added the organization connected-account operations on `Pipes`: `$workos->pipes().getOrganizationConnectedAccount`, `createOrganizationConnectedAccount`, `updateOrganizationConnectedAccount`, `deleteOrganizationConnectedAccount`, `listOrganizationDataProviders` * **[connect](https://workos.com/docs/reference/workos-connect/standalone)**: * Added `connection_role` to `ConnectedAccount` * Added `account_identifier` to `ConnectedAccount` * Added `account_display_name` to `ConnectedAccount` * Added enum `ConnectedAccountConnectionRole` - * **[organizations](https://workos.com/docs/reference/organization)**: - * Added service `OrganizationsDataProviders` * **[webhooks](https://workos.com/docs/reference/webhooks)**: * Added `pipes.account_connection.add_failed` to `CreateWebhookEndpointEvents` * Added `pipes.account_connection.connected` to `CreateWebhookEndpointEvents` diff --git a/.changelog-pending/2026-09-17T20-59-49-bfe7aedb3cf7296ffb6ead1e287e844186479702.md b/.changelog-pending/2026-09-17T20-59-49-bfe7aedb3cf7296ffb6ead1e287e844186479702.md new file mode 100644 index 00000000..07727835 --- /dev/null +++ b/.changelog-pending/2026-09-17T20-59-49-bfe7aedb3cf7296ffb6ead1e287e844186479702.md @@ -0,0 +1,7 @@ +* [#446](https://github.com/workos/workos-php/pull/446) fix(generated): regenerate from spec (2 changes) + + **Fixes** + * **[pipes](https://workos.com/docs/reference/pipes)**: + * Removed unused types left behind by earlier renames: `CreateDataIntegrationAuthMethods` + * **[multi_factor_auth](https://workos.com/docs/reference/authkit/mfa)**: + * Changed errors for endpoint `POST /auth/factors/{id}/challenge` diff --git a/.oagen-manifest.json b/.oagen-manifest.json index e6106cd1..d73f28ef 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -245,7 +245,6 @@ "lib/Resource/CreateConnectionSAMLOptions.php", "lib/Resource/CreateConnectionStandardAttributes.php", "lib/Resource/CreateDataIntegration.php", - "lib/Resource/CreateDataIntegrationAuthMethods.php", "lib/Resource/CreateDataKeyRequest.php", "lib/Resource/CreateDataKeyResponse.php", "lib/Resource/CreateGroup.php", @@ -710,7 +709,6 @@ "lib/Service/OrganizationDomains.php", "lib/Service/OrganizationMembershipService.php", "lib/Service/Organizations.php", - "lib/Service/OrganizationsDataProviders.php", "lib/Service/ParentByExternalId.php", "lib/Service/ParentById.php", "lib/Service/ParentResourceByExternalId.php", @@ -1392,7 +1390,6 @@ "tests/Service/MultiFactorAuthTest.php", "tests/Service/OrganizationDomainsTest.php", "tests/Service/OrganizationMembershipTest.php", - "tests/Service/OrganizationsDataProvidersTest.php", "tests/Service/OrganizationsTest.php", "tests/Service/PipesProviderTest.php", "tests/Service/PipesTest.php", @@ -1405,6 +1402,34 @@ "tests/Service/WidgetsTest.php" ], "operations": { + "GET /agents/blueprints": { + "sdkMethod": "listBlueprints", + "service": "agents" + }, + "POST /agents/blueprints": { + "sdkMethod": "createBlueprint", + "service": "agents" + }, + "GET /agents/blueprints/{agent_blueprint_id}": { + "sdkMethod": "getBlueprint", + "service": "agents" + }, + "PATCH /agents/blueprints/{agent_blueprint_id}": { + "sdkMethod": "updateBlueprint", + "service": "agents" + }, + "DELETE /agents/blueprints/{agent_blueprint_id}": { + "sdkMethod": "deleteBlueprint", + "service": "agents" + }, + "POST /agents/blueprints/{agent_blueprint_id}/tokens": { + "sdkMethod": "createBlueprintToken", + "service": "agents" + }, + "POST /agents/blueprints/{agent_blueprint_id}/tokens/validate": { + "sdkMethod": "validateBlueprintToken", + "service": "agents" + }, "PATCH /agents/claims/attempts": { "sdkMethod": "updateAttempts", "service": "agents" @@ -1417,6 +1442,30 @@ "sdkMethod": "getRegistration", "service": "agents" }, + "GET /agents/instances": { + "sdkMethod": "listInstances", + "service": "agents" + }, + "GET /agents/instances/{agent_instance_id}": { + "sdkMethod": "getInstance", + "service": "agents" + }, + "DELETE /agents/instances/{agent_instance_id}": { + "sdkMethod": "deleteInstance", + "service": "agents" + }, + "GET /agents/sessions": { + "sdkMethod": "listSessions", + "service": "agents" + }, + "GET /agents/sessions/{agent_instance_session_id}": { + "sdkMethod": "getSession", + "service": "agents" + }, + "POST /agents/sessions/{agent_instance_session_id}/revoke": { + "sdkMethod": "revokeSession", + "service": "agents" + }, "POST /auth/challenges/{id}/verify": { "sdkMethod": "verifyChallenge", "service": "multiFactorAuth" @@ -1661,10 +1710,54 @@ "sdkMethod": "listConnections", "service": "sso" }, + "POST /connections": { + "sdkMethod": "createConnection", + "service": "sso" + }, + "GET /connections/{connectionId}/saml_idp_signing_certs": { + "sdkMethod": "listConnectionSAMLIdpSigningCerts", + "service": "sso" + }, + "POST /connections/{connectionId}/saml_idp_signing_certs": { + "sdkMethod": "createConnectionSAMLIdpSigningCert", + "service": "sso" + }, + "DELETE /connections/{connectionId}/saml_idp_signing_certs/{certificateId}": { + "sdkMethod": "deleteConnectionSAMLIdpSigningCert", + "service": "sso" + }, + "GET /connections/{connectionId}/saml_sp_encryption_certs": { + "sdkMethod": "listConnectionSAMLSpEncryptionCerts", + "service": "sso" + }, + "POST /connections/{connectionId}/saml_sp_encryption_certs": { + "sdkMethod": "createConnectionSAMLSpEncryptionCert", + "service": "sso" + }, + "DELETE /connections/{connectionId}/saml_sp_encryption_certs/{certificateId}": { + "sdkMethod": "deleteConnectionSAMLSpEncryptionCert", + "service": "sso" + }, + "GET /connections/{connectionId}/saml_sp_signing_cert": { + "sdkMethod": "listConnectionSAMLSpSigningCert", + "service": "sso" + }, + "POST /connections/{connectionId}/saml_sp_signing_cert": { + "sdkMethod": "createConnectionSAMLSpSigningCert", + "service": "sso" + }, + "DELETE /connections/{connectionId}/saml_sp_signing_cert/{certificateId}": { + "sdkMethod": "deleteConnectionSAMLSpSigningCert", + "service": "sso" + }, "GET /connections/{id}": { "sdkMethod": "getConnection", "service": "sso" }, + "PATCH /connections/{id}": { + "sdkMethod": "updateConnection", + "service": "sso" + }, "DELETE /connections/{id}": { "sdkMethod": "deleteConnection", "service": "sso" @@ -1697,10 +1790,26 @@ "sdkMethod": "authorizeDataIntegration", "service": "pipes" }, + "PUT /data-integrations/{slug}/client-credentials": { + "sdkMethod": "updateDataIntegrationClientCredentials", + "service": "pipes" + }, "POST /data-integrations/{slug}/credentials": { "sdkMethod": "createDataIntegrationCredential", "service": "pipes" }, + "GET /data-integrations/{slug}/organization": { + "sdkMethod": "listDataIntegrationOrganization", + "service": "pipes" + }, + "PUT /data-integrations/{slug}/organization": { + "sdkMethod": "updateDataIntegrationOrganization", + "service": "pipes" + }, + "DELETE /data-integrations/{slug}/organization": { + "sdkMethod": "deleteDataIntegrationOrganization", + "service": "pipes" + }, "POST /data-integrations/{provider}/token": { "sdkMethod": "getAccessToken", "service": "pipes" @@ -1869,6 +1978,54 @@ "sdkMethod": "listAuthorizedApplications", "service": "organizations" }, + "GET /organizations/{organization_id}/connected_accounts/{slug}": { + "sdkMethod": "getOrganizationConnectedAccount", + "service": "pipes" + }, + "POST /organizations/{organization_id}/connected_accounts/{slug}": { + "sdkMethod": "createOrganizationConnectedAccount", + "service": "pipes" + }, + "PUT /organizations/{organization_id}/connected_accounts/{slug}": { + "sdkMethod": "updateOrganizationConnectedAccount", + "service": "pipes" + }, + "DELETE /organizations/{organization_id}/connected_accounts/{slug}": { + "sdkMethod": "deleteOrganizationConnectedAccount", + "service": "pipes" + }, + "GET /organizations/{organization_id}/data_providers": { + "sdkMethod": "listOrganizationDataProviders", + "service": "pipes" + }, + "GET /organizations/{organization_id}/it_contacts": { + "sdkMethod": "listItContacts", + "service": "organizations" + }, + "POST /organizations/{organization_id}/it_contacts": { + "sdkMethod": "createItContact", + "service": "organizations" + }, + "DELETE /organizations/{organization_id}/it_contacts/{contact_id}": { + "sdkMethod": "deleteItContact", + "service": "organizations" + }, + "POST /organizations/{organization_id}/it_contacts/{contact_id}/invite": { + "sdkMethod": "inviteItContact", + "service": "organizations" + }, + "POST /organizations/{organization_id}/it_contacts/{contact_id}/revoke": { + "sdkMethod": "revokeItContact", + "service": "organizations" + }, + "POST /platform/teams": { + "sdkMethod": "createTeam", + "service": "platformTeams" + }, + "GET /platform/teams/{team_id}": { + "sdkMethod": "getTeam", + "service": "platformTeams" + }, "POST /portal/generate_link": { "sdkMethod": "generateLink", "service": "adminPortal" @@ -1941,6 +2098,18 @@ "sdkMethod": "revokeSession", "service": "userManagement" }, + "GET /user_management/authkit_oauth_resources": { + "sdkMethod": "listAuthkitOAuthResources", + "service": "userManagement" + }, + "POST /user_management/authkit_oauth_resources": { + "sdkMethod": "createAuthkitOAuthResource", + "service": "userManagement" + }, + "DELETE /user_management/authkit_oauth_resources/{id}": { + "sdkMethod": "deleteAuthkitOAuthResource", + "service": "userManagement" + }, "GET /user_management/cors_origins": { "sdkMethod": "listCorsOrigins", "service": "userManagement" @@ -2141,6 +2310,34 @@ "sdkMethod": "createUserAuthFactor", "service": "multiFactorAuth" }, + "DELETE /user_management/waitlist_entries/{id}": { + "sdkMethod": "deleteWaitlistEntry", + "service": "userManagement" + }, + "POST /user_management/waitlist_entries/{id}/approve": { + "sdkMethod": "createWaitlistEntryApprove", + "service": "userManagement" + }, + "POST /user_management/waitlist_entries/{id}/deny": { + "sdkMethod": "createWaitlistEntryDeny", + "service": "userManagement" + }, + "GET /user_management/waitlists": { + "sdkMethod": "listWaitlists", + "service": "userManagement" + }, + "GET /user_management/waitlists/{id}": { + "sdkMethod": "getWaitlist", + "service": "userManagement" + }, + "GET /user_management/waitlists/{id}/entries": { + "sdkMethod": "listWaitlistEntries", + "service": "userManagement" + }, + "POST /user_management/waitlists/{id}/entries": { + "sdkMethod": "createWaitlistEntry", + "service": "userManagement" + }, "POST /vault/v1/keys/data-key": { "sdkMethod": "createDataKey", "service": "vault" @@ -2248,206 +2445,6 @@ "GET /audit_logs/exports/{auditLogExportId}": { "sdkMethod": "getExport", "service": "auditLogs" - }, - "PUT /data-integrations/{slug}/client-credentials": { - "sdkMethod": "updateDataIntegrationClientCredentials", - "service": "pipes" - }, - "GET /agents/blueprints": { - "sdkMethod": "listBlueprints", - "service": "agents" - }, - "POST /agents/blueprints": { - "sdkMethod": "createBlueprint", - "service": "agents" - }, - "GET /agents/blueprints/{agent_blueprint_id}": { - "sdkMethod": "getBlueprint", - "service": "agents" - }, - "PATCH /agents/blueprints/{agent_blueprint_id}": { - "sdkMethod": "updateBlueprint", - "service": "agents" - }, - "DELETE /agents/blueprints/{agent_blueprint_id}": { - "sdkMethod": "deleteBlueprint", - "service": "agents" - }, - "POST /agents/blueprints/{agent_blueprint_id}/tokens": { - "sdkMethod": "createBlueprintToken", - "service": "agents" - }, - "GET /agents/instances": { - "sdkMethod": "listInstances", - "service": "agents" - }, - "GET /agents/instances/{agent_instance_id}": { - "sdkMethod": "getInstance", - "service": "agents" - }, - "DELETE /agents/instances/{agent_instance_id}": { - "sdkMethod": "deleteInstance", - "service": "agents" - }, - "GET /agents/sessions": { - "sdkMethod": "listSessions", - "service": "agents" - }, - "GET /agents/sessions/{agent_instance_session_id}": { - "sdkMethod": "getSession", - "service": "agents" - }, - "POST /agents/sessions/{agent_instance_session_id}/revoke": { - "sdkMethod": "revokeSession", - "service": "agents" - }, - "POST /connections": { - "sdkMethod": "createConnection", - "service": "sso" - }, - "GET /connections/{connectionId}/saml_idp_signing_certs": { - "sdkMethod": "listConnectionSAMLIdpSigningCerts", - "service": "sso" - }, - "POST /connections/{connectionId}/saml_idp_signing_certs": { - "sdkMethod": "createConnectionSAMLIdpSigningCert", - "service": "sso" - }, - "DELETE /connections/{connectionId}/saml_idp_signing_certs/{certificateId}": { - "sdkMethod": "deleteConnectionSAMLIdpSigningCert", - "service": "sso" - }, - "GET /connections/{connectionId}/saml_sp_encryption_certs": { - "sdkMethod": "listConnectionSAMLSpEncryptionCerts", - "service": "sso" - }, - "POST /connections/{connectionId}/saml_sp_encryption_certs": { - "sdkMethod": "createConnectionSAMLSpEncryptionCert", - "service": "sso" - }, - "DELETE /connections/{connectionId}/saml_sp_encryption_certs/{certificateId}": { - "sdkMethod": "deleteConnectionSAMLSpEncryptionCert", - "service": "sso" - }, - "GET /connections/{connectionId}/saml_sp_signing_cert": { - "sdkMethod": "listConnectionSAMLSpSigningCert", - "service": "sso" - }, - "POST /connections/{connectionId}/saml_sp_signing_cert": { - "sdkMethod": "createConnectionSAMLSpSigningCert", - "service": "sso" - }, - "DELETE /connections/{connectionId}/saml_sp_signing_cert/{certificateId}": { - "sdkMethod": "deleteConnectionSAMLSpSigningCert", - "service": "sso" - }, - "PATCH /connections/{id}": { - "sdkMethod": "updateConnection", - "service": "sso" - }, - "GET /organizations/{organization_id}/it_contacts": { - "sdkMethod": "listItContacts", - "service": "organizations" - }, - "POST /organizations/{organization_id}/it_contacts": { - "sdkMethod": "createItContact", - "service": "organizations" - }, - "DELETE /organizations/{organization_id}/it_contacts/{contact_id}": { - "sdkMethod": "deleteItContact", - "service": "organizations" - }, - "POST /organizations/{organization_id}/it_contacts/{contact_id}/invite": { - "sdkMethod": "inviteItContact", - "service": "organizations" - }, - "POST /organizations/{organization_id}/it_contacts/{contact_id}/revoke": { - "sdkMethod": "revokeItContact", - "service": "organizations" - }, - "POST /platform/teams": { - "sdkMethod": "createTeam", - "service": "platformTeams" - }, - "GET /platform/teams/{team_id}": { - "sdkMethod": "getTeam", - "service": "platformTeams" - }, - "DELETE /user_management/waitlist_entries/{id}": { - "sdkMethod": "deleteWaitlistEntry", - "service": "userManagement" - }, - "POST /user_management/waitlist_entries/{id}/approve": { - "sdkMethod": "createWaitlistEntryApprove", - "service": "userManagement" - }, - "POST /user_management/waitlist_entries/{id}/deny": { - "sdkMethod": "createWaitlistEntryDeny", - "service": "userManagement" - }, - "GET /user_management/waitlists": { - "sdkMethod": "listWaitlists", - "service": "userManagement" - }, - "GET /user_management/waitlists/{id}": { - "sdkMethod": "getWaitlist", - "service": "userManagement" - }, - "GET /user_management/waitlists/{id}/entries": { - "sdkMethod": "listWaitlistEntries", - "service": "userManagement" - }, - "POST /user_management/waitlists/{id}/entries": { - "sdkMethod": "createWaitlistEntry", - "service": "userManagement" - }, - "POST /agents/blueprints/{agent_blueprint_id}/tokens/validate": { - "sdkMethod": "validateBlueprintToken", - "service": "agents" - }, - "GET /data-integrations/{slug}/organization": { - "sdkMethod": "listDataIntegrationOrganization", - "service": "pipes" - }, - "PUT /data-integrations/{slug}/organization": { - "sdkMethod": "updateDataIntegrationOrganization", - "service": "pipes" - }, - "DELETE /data-integrations/{slug}/organization": { - "sdkMethod": "deleteDataIntegrationOrganization", - "service": "pipes" - }, - "GET /user_management/authkit_oauth_resources": { - "sdkMethod": "listAuthkitOAuthResources", - "service": "userManagement" - }, - "POST /user_management/authkit_oauth_resources": { - "sdkMethod": "createAuthkitOAuthResource", - "service": "userManagement" - }, - "DELETE /user_management/authkit_oauth_resources/{id}": { - "sdkMethod": "deleteAuthkitOAuthResource", - "service": "userManagement" - }, - "GET /organizations/{organization_id}/connected_accounts/{slug}": { - "sdkMethod": "getOrganizationConnectedAccount", - "service": "organizationsDataProviders" - }, - "POST /organizations/{organization_id}/connected_accounts/{slug}": { - "sdkMethod": "createOrganizationConnectedAccount", - "service": "organizationsDataProviders" - }, - "PUT /organizations/{organization_id}/connected_accounts/{slug}": { - "sdkMethod": "updateOrganizationConnectedAccount", - "service": "organizationsDataProviders" - }, - "DELETE /organizations/{organization_id}/connected_accounts/{slug}": { - "sdkMethod": "deleteOrganizationConnectedAccount", - "service": "organizationsDataProviders" - }, - "GET /organizations/{organization_id}/data_providers": { - "sdkMethod": "listOrganizationDataProviders", - "service": "organizationsDataProviders" } } } diff --git a/lib/Resource/CreateDataIntegrationAuthMethods.php b/lib/Resource/CreateDataIntegrationAuthMethods.php deleted file mode 100644 index acbbfe78..00000000 --- a/lib/Resource/CreateDataIntegrationAuthMethods.php +++ /dev/null @@ -1,13 +0,0 @@ - $supportsMultipleConnections, - 'connected_account_id' => $connectedAccountId, - ], fn ($v) => $v !== null); - $response = $this->client->request( - method: 'GET', - path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), - query: $query, - options: $options, - ); - return ConnectedAccount::fromArray($response); - } - - /** - * Import an organization connected account - * - * Imports an organization-owned [connected account](https://workos.com/docs/reference/pipes/connected-account) by providing OAuth tokens directly. Use this to migrate existing connections or set up connections without going through the OAuth flow. - * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. - * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). - * @param string|null $accessToken The OAuth access token for the connected account. - * @param string|null $refreshToken The OAuth refresh token for the connected account. - * @param \DateTimeImmutable|null $expiresAt The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire. - * @param array|null $scopes The OAuth scopes granted for this connection. - * @param \WorkOS\Resource\PipeConnectedAccountState|null $state Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided. - * @return \WorkOS\Resource\ConnectedAccount - * @throws \WorkOS\Exception\WorkOSException - */ - public function createOrganizationConnectedAccount( - string $organizationId, - string $slug, - ?string $accessToken = null, - ?string $refreshToken = null, - ?\DateTimeImmutable $expiresAt = null, - ?array $scopes = null, - ?\WorkOS\Resource\PipeConnectedAccountState $state = null, - ?\WorkOS\RequestOptions $options = null, - ): \WorkOS\Resource\ConnectedAccount { - $body = array_filter([ - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'expires_at' => $expiresAt?->format(\DateTimeInterface::RFC3339_EXTENDED), - 'scopes' => $scopes, - 'state' => $state?->value, - ], fn ($v) => $v !== null); - $response = $this->client->request( - method: 'POST', - path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), - body: $body, - options: $options, - ); - return ConnectedAccount::fromArray($response); - } - - /** - * Update an organization connected account - * - * Updates an organization's [connected account](https://workos.com/docs/reference/pipes/connected-account) tokens, scopes, or state for a specific provider. - * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. - * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). - * @param string|null $accessToken The OAuth access token for the connected account. - * @param string|null $refreshToken The OAuth refresh token for the connected account. - * @param \DateTimeImmutable|null $expiresAt The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire. - * @param array|null $scopes The OAuth scopes granted for this connection. - * @param \WorkOS\Resource\PipeConnectedAccountState|null $state Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided. - * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. - * @param string|null $connectedAccountId A [connected account](https://workos.com/docs/reference/pipes/connected-account) identifier. Use this to select the connection to update. - * @return \WorkOS\Resource\ConnectedAccount - * @throws \WorkOS\Exception\WorkOSException - */ - public function updateOrganizationConnectedAccount( - string $organizationId, - string $slug, - ?string $accessToken = null, - ?string $refreshToken = null, - ?\DateTimeImmutable $expiresAt = null, - ?array $scopes = null, - ?\WorkOS\Resource\PipeConnectedAccountState $state = null, - ?bool $supportsMultipleConnections = null, - ?string $connectedAccountId = null, - ?\WorkOS\RequestOptions $options = null, - ): \WorkOS\Resource\ConnectedAccount { - $body = array_filter([ - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'expires_at' => $expiresAt?->format(\DateTimeInterface::RFC3339_EXTENDED), - 'scopes' => $scopes, - 'state' => $state?->value, - ], fn ($v) => $v !== null); - $response = $this->client->request( - method: 'PUT', - path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), - body: $body, - options: $options, - ); - return ConnectedAccount::fromArray($response); - } - - /** - * Delete an organization connected account - * - * Disconnects the organization's account for the provider, including removing any stored access and refresh tokens. A member will need to reauthorize if the organization wants to reconnect. This does not revoke access on the provider side. - * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. - * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). - * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. - * @param string|null $connectedAccountId A [connected account](https://workos.com/docs/reference/pipes/connected-account) identifier. Use this to select the connection to delete. - * @return void - * @throws \WorkOS\Exception\WorkOSException - */ - public function deleteOrganizationConnectedAccount( - string $organizationId, - string $slug, - ?bool $supportsMultipleConnections = null, - ?string $connectedAccountId = null, - ?\WorkOS\RequestOptions $options = null, - ): void { - $query = array_filter([ - 'supports_multiple_connections' => $supportsMultipleConnections, - 'connected_account_id' => $connectedAccountId, - ], fn ($v) => $v !== null); - $this->client->request( - method: 'DELETE', - path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), - query: $query, - options: $options, - ); - } - - /** - * List providers for an organization - * - * Retrieves the organization-owned providers configured for your environment and the organization's [connected account](https://workos.com/docs/reference/pipes/connected-account) information for each. Providers owned by individual users are not included. - * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier to list providers and connected accounts for. - * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. - * @return \WorkOS\Resource\DataIntegrationsListResponse - * @throws \WorkOS\Exception\WorkOSException - */ - public function listOrganizationDataProviders( - string $organizationId, - ?bool $supportsMultipleConnections = null, - ?\WorkOS\RequestOptions $options = null, - ): \WorkOS\Resource\DataIntegrationsListResponse { - $query = array_filter([ - 'supports_multiple_connections' => $supportsMultipleConnections, - ], fn ($v) => $v !== null); - $response = $this->client->request( - method: 'GET', - path: 'organizations/' . rawurlencode($organizationId) . '/data_providers', - query: $query, - options: $options, - ); - return DataIntegrationsListResponse::fromArray($response); - } -} diff --git a/lib/Service/Pipes.php b/lib/Service/Pipes.php index 4af17686..3065e5f7 100644 --- a/lib/Service/Pipes.php +++ b/lib/Service/Pipes.php @@ -463,6 +463,177 @@ public function getAccessToken( return DataIntegrationAccessTokenResponse::fromArray($response); } + /** + * Get an organization connected account + * + * Retrieves an organization's [connected account](https://workos.com/docs/reference/pipes/connected-account) for a specific provider. + * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. + * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. + * @param string|null $connectedAccountId A [connected account](https://workos.com/docs/reference/pipes/connected-account) identifier. Use this to select a specific connection when the organization has several for this provider. + * @return \WorkOS\Resource\ConnectedAccount + * @throws \WorkOS\Exception\WorkOSException + */ + public function getOrganizationConnectedAccount( + string $organizationId, + string $slug, + ?bool $supportsMultipleConnections = null, + ?string $connectedAccountId = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\ConnectedAccount { + $query = array_filter([ + 'supports_multiple_connections' => $supportsMultipleConnections, + 'connected_account_id' => $connectedAccountId, + ], fn ($v) => $v !== null); + $response = $this->client->request( + method: 'GET', + path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), + query: $query, + options: $options, + ); + return ConnectedAccount::fromArray($response); + } + + /** + * Import an organization connected account + * + * Imports an organization-owned [connected account](https://workos.com/docs/reference/pipes/connected-account) by providing OAuth tokens directly. Use this to migrate existing connections or set up connections without going through the OAuth flow. + * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. + * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @param string|null $accessToken The OAuth access token for the connected account. + * @param string|null $refreshToken The OAuth refresh token for the connected account. + * @param \DateTimeImmutable|null $expiresAt The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire. + * @param array|null $scopes The OAuth scopes granted for this connection. + * @param \WorkOS\Resource\PipeConnectedAccountState|null $state Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided. + * @return \WorkOS\Resource\ConnectedAccount + * @throws \WorkOS\Exception\WorkOSException + */ + public function createOrganizationConnectedAccount( + string $organizationId, + string $slug, + ?string $accessToken = null, + ?string $refreshToken = null, + ?\DateTimeImmutable $expiresAt = null, + ?array $scopes = null, + ?\WorkOS\Resource\PipeConnectedAccountState $state = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\ConnectedAccount { + $body = array_filter([ + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'expires_at' => $expiresAt?->format(\DateTimeInterface::RFC3339_EXTENDED), + 'scopes' => $scopes, + 'state' => $state?->value, + ], fn ($v) => $v !== null); + $response = $this->client->request( + method: 'POST', + path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), + body: $body, + options: $options, + ); + return ConnectedAccount::fromArray($response); + } + + /** + * Update an organization connected account + * + * Updates an organization's [connected account](https://workos.com/docs/reference/pipes/connected-account) tokens, scopes, or state for a specific provider. + * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. + * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @param string|null $accessToken The OAuth access token for the connected account. + * @param string|null $refreshToken The OAuth refresh token for the connected account. + * @param \DateTimeImmutable|null $expiresAt The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire. + * @param array|null $scopes The OAuth scopes granted for this connection. + * @param \WorkOS\Resource\PipeConnectedAccountState|null $state Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided. + * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. + * @param string|null $connectedAccountId A [connected account](https://workos.com/docs/reference/pipes/connected-account) identifier. Use this to select the connection to update. + * @return \WorkOS\Resource\ConnectedAccount + * @throws \WorkOS\Exception\WorkOSException + */ + public function updateOrganizationConnectedAccount( + string $organizationId, + string $slug, + ?string $accessToken = null, + ?string $refreshToken = null, + ?\DateTimeImmutable $expiresAt = null, + ?array $scopes = null, + ?\WorkOS\Resource\PipeConnectedAccountState $state = null, + ?bool $supportsMultipleConnections = null, + ?string $connectedAccountId = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\ConnectedAccount { + $body = array_filter([ + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'expires_at' => $expiresAt?->format(\DateTimeInterface::RFC3339_EXTENDED), + 'scopes' => $scopes, + 'state' => $state?->value, + ], fn ($v) => $v !== null); + $response = $this->client->request( + method: 'PUT', + path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), + body: $body, + options: $options, + ); + return ConnectedAccount::fromArray($response); + } + + /** + * Delete an organization connected account + * + * Disconnects the organization's account for the provider, including removing any stored access and refresh tokens. A member will need to reauthorize if the organization wants to reconnect. This does not revoke access on the provider side. + * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier. + * @param string $slug The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. + * @param string|null $connectedAccountId A [connected account](https://workos.com/docs/reference/pipes/connected-account) identifier. Use this to select the connection to delete. + * @return void + * @throws \WorkOS\Exception\WorkOSException + */ + public function deleteOrganizationConnectedAccount( + string $organizationId, + string $slug, + ?bool $supportsMultipleConnections = null, + ?string $connectedAccountId = null, + ?\WorkOS\RequestOptions $options = null, + ): void { + $query = array_filter([ + 'supports_multiple_connections' => $supportsMultipleConnections, + 'connected_account_id' => $connectedAccountId, + ], fn ($v) => $v !== null); + $this->client->request( + method: 'DELETE', + path: 'organizations/' . rawurlencode($organizationId) . '/connected_accounts/' . rawurlencode($slug), + query: $query, + options: $options, + ); + } + + /** + * List providers for an organization + * + * Retrieves the organization-owned providers configured for your environment and the organization's [connected account](https://workos.com/docs/reference/pipes/connected-account) information for each. Providers owned by individual users are not included. + * @param string $organizationId An [Organization](https://workos.com/docs/reference/organization) identifier to list providers and connected accounts for. + * @param bool|null $supportsMultipleConnections Set to `true` to use the plural connection contract. When omitted or `false`, only the compatibility connection is considered. + * @return \WorkOS\Resource\DataIntegrationsListResponse + * @throws \WorkOS\Exception\WorkOSException + */ + public function listOrganizationDataProviders( + string $organizationId, + ?bool $supportsMultipleConnections = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\DataIntegrationsListResponse { + $query = array_filter([ + 'supports_multiple_connections' => $supportsMultipleConnections, + ], fn ($v) => $v !== null); + $response = $this->client->request( + method: 'GET', + path: 'organizations/' . rawurlencode($organizationId) . '/data_providers', + query: $query, + options: $options, + ); + return DataIntegrationsListResponse::fromArray($response); + } + /** * Get a connected account * diff --git a/lib/WorkOS.php b/lib/WorkOS.php index 7bbf97b1..57ca39a4 100644 --- a/lib/WorkOS.php +++ b/lib/WorkOS.php @@ -21,7 +21,6 @@ use WorkOS\Service\OrganizationDomains; use WorkOS\Service\OrganizationMembershipService; use WorkOS\Service\Organizations; -use WorkOS\Service\OrganizationsDataProviders; use WorkOS\Service\Pipes; use WorkOS\Service\PipesProvider; use WorkOS\Service\PlatformTeams; @@ -72,7 +71,6 @@ public static function setClientId(?string $id): void private ?Service\ApiKeys $apiKeys = null; private ?Service\PipesProvider $pipesProvider = null; private ?Service\Groups $groups = null; - private ?Service\OrganizationsDataProviders $organizationsDataProviders = null; private ?Service\PlatformTeams $platformTeams = null; private ?Service\AdminPortal $adminPortal = null; private ?Service\Radar $radar = null; @@ -172,11 +170,6 @@ public function groups(): Groups return $this->groups ??= new Service\Groups($this->httpClient); } - public function organizationsDataProviders(): OrganizationsDataProviders - { - return $this->organizationsDataProviders ??= new Service\OrganizationsDataProviders($this->httpClient); - } - public function platformTeams(): PlatformTeams { return $this->platformTeams ??= new Service\PlatformTeams($this->httpClient); diff --git a/tests/Service/OrganizationsDataProvidersTest.php b/tests/Service/OrganizationsDataProvidersTest.php deleted file mode 100644 index 2ee853a3..00000000 --- a/tests/Service/OrganizationsDataProvidersTest.php +++ /dev/null @@ -1,78 +0,0 @@ -loadFixture('connected_account'); - $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); - $result = $client->organizationsDataProviders()->getOrganizationConnectedAccount('test_organization_id', 'test_slug'); - $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); - $this->assertSame($fixture['id'], $result->id); - $this->assertSame($fixture['created_at'], $result->createdAt); - $this->assertIsArray($result->toArray()); - $request = $this->getLastRequest(); - $this->assertSame('GET', $request->getMethod()); - $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); - } - - public function testCreateOrganizationConnectedAccount(): void - { - $fixture = $this->loadFixture('connected_account'); - $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); - $result = $client->organizationsDataProviders()->createOrganizationConnectedAccount('test_organization_id', 'test_slug'); - $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); - $this->assertSame($fixture['id'], $result->id); - $this->assertSame($fixture['created_at'], $result->createdAt); - $this->assertIsArray($result->toArray()); - $request = $this->getLastRequest(); - $this->assertSame('POST', $request->getMethod()); - $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); - } - - public function testUpdateOrganizationConnectedAccount(): void - { - $fixture = $this->loadFixture('connected_account'); - $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); - $result = $client->organizationsDataProviders()->updateOrganizationConnectedAccount('test_organization_id', 'test_slug'); - $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); - $this->assertSame($fixture['id'], $result->id); - $this->assertSame($fixture['created_at'], $result->createdAt); - $this->assertIsArray($result->toArray()); - $request = $this->getLastRequest(); - $this->assertSame('PUT', $request->getMethod()); - $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); - } - - public function testDeleteOrganizationConnectedAccount(): void - { - $client = $this->createMockClient([['status' => 204]]); - $client->organizationsDataProviders()->deleteOrganizationConnectedAccount('test_organization_id', 'test_slug'); - $request = $this->getLastRequest(); - $this->assertSame('DELETE', $request->getMethod()); - $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); - } - - public function testListOrganizationDataProviders(): void - { - $fixture = $this->loadFixture('data_integrations_list_response'); - $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); - $result = $client->organizationsDataProviders()->listOrganizationDataProviders('test_organization_id'); - $this->assertInstanceOf(\WorkOS\Resource\DataIntegrationsListResponse::class, $result); - $this->assertIsArray($result->toArray()); - $request = $this->getLastRequest(); - $this->assertSame('GET', $request->getMethod()); - $this->assertStringEndsWith('organizations/test_organization_id/data_providers', $request->getUri()->getPath()); - } -} diff --git a/tests/Service/PipesTest.php b/tests/Service/PipesTest.php index 006b7fbd..efbadb1c 100644 --- a/tests/Service/PipesTest.php +++ b/tests/Service/PipesTest.php @@ -198,6 +198,69 @@ public function testGetAccessToken(): void $this->assertSame('test_value', $body['user_id']); } + public function testGetOrganizationConnectedAccount(): void + { + $fixture = $this->loadFixture('connected_account'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->pipes()->getOrganizationConnectedAccount('test_organization_id', 'test_slug'); + $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); + $this->assertSame($fixture['id'], $result->id); + $this->assertSame($fixture['created_at'], $result->createdAt); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('GET', $request->getMethod()); + $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); + } + + public function testCreateOrganizationConnectedAccount(): void + { + $fixture = $this->loadFixture('connected_account'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->pipes()->createOrganizationConnectedAccount('test_organization_id', 'test_slug'); + $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); + $this->assertSame($fixture['id'], $result->id); + $this->assertSame($fixture['created_at'], $result->createdAt); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('POST', $request->getMethod()); + $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); + } + + public function testUpdateOrganizationConnectedAccount(): void + { + $fixture = $this->loadFixture('connected_account'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->pipes()->updateOrganizationConnectedAccount('test_organization_id', 'test_slug'); + $this->assertInstanceOf(\WorkOS\Resource\ConnectedAccount::class, $result); + $this->assertSame($fixture['id'], $result->id); + $this->assertSame($fixture['created_at'], $result->createdAt); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('PUT', $request->getMethod()); + $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); + } + + public function testDeleteOrganizationConnectedAccount(): void + { + $client = $this->createMockClient([['status' => 204]]); + $client->pipes()->deleteOrganizationConnectedAccount('test_organization_id', 'test_slug'); + $request = $this->getLastRequest(); + $this->assertSame('DELETE', $request->getMethod()); + $this->assertStringEndsWith('organizations/test_organization_id/connected_accounts/test_slug', $request->getUri()->getPath()); + } + + public function testListOrganizationDataProviders(): void + { + $fixture = $this->loadFixture('data_integrations_list_response'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->pipes()->listOrganizationDataProviders('test_organization_id'); + $this->assertInstanceOf(\WorkOS\Resource\DataIntegrationsListResponse::class, $result); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('GET', $request->getMethod()); + $this->assertStringEndsWith('organizations/test_organization_id/data_providers', $request->getUri()->getPath()); + } + public function testGetUserConnectedAccount(): void { $fixture = $this->loadFixture('connected_account');