diff --git a/.last-synced-sha b/.last-synced-sha index f72eb0e2..33f76880 100644 --- a/.last-synced-sha +++ b/.last-synced-sha @@ -1 +1 @@ -92db0495807c86fbbc4d45bd266a6c1f5bcbb59c +ff939ff075453287993e1e6182f1d6f23c67ab80 diff --git a/.oagen-manifest.json b/.oagen-manifest.json index 7dc94e72..dc4c89f7 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -1,7 +1,7 @@ { "version": 2, "language": "php", - "generatedAt": "2026-04-28T15:07:27.545Z", + "generatedAt": "2026-05-03T22:57:49.369Z", "files": [ "lib/Resource/ActionAuthenticationDenied.php", "lib/Resource/ActionAuthenticationDeniedData.php", @@ -17,8 +17,6 @@ "lib/Resource/ApiKeyRevokedData.php", "lib/Resource/ApiKeyRevokedDataOwner.php", "lib/Resource/ApiKeyValidationResponse.php", - "lib/Resource/ApiKeyWithValue.php", - "lib/Resource/ApiKeyWithValueOwner.php", "lib/Resource/ApplicationCredentialsListItem.php", "lib/Resource/AssignRole.php", "lib/Resource/AuditLogActionJson.php", @@ -162,6 +160,7 @@ "lib/Resource/CreateRedirectUri.php", "lib/Resource/CreateRole.php", "lib/Resource/CreateUser.php", + "lib/Resource/CreateUserApiKey.php", "lib/Resource/CreateUserInviteOptions.php", "lib/Resource/CreateUserInviteOptionsLocale.php", "lib/Resource/CreateUserOrganizationMembership.php", @@ -298,6 +297,10 @@ "lib/Resource/MagicAuthCreatedData.php", "lib/Resource/NewConnectApplicationSecret.php", "lib/Resource/Organization.php", + "lib/Resource/OrganizationApiKey.php", + "lib/Resource/OrganizationApiKeyOwner.php", + "lib/Resource/OrganizationApiKeyWithValue.php", + "lib/Resource/OrganizationApiKeyWithValueOwner.php", "lib/Resource/OrganizationCreated.php", "lib/Resource/OrganizationCreatedData.php", "lib/Resource/OrganizationCreatedDataDomain.php", @@ -418,6 +421,10 @@ "lib/Resource/UpdateUserOrganizationMembership.php", "lib/Resource/UpdateWebhookEndpoint.php", "lib/Resource/User.php", + "lib/Resource/UserApiKey.php", + "lib/Resource/UserApiKeyOwner.php", + "lib/Resource/UserApiKeyWithValue.php", + "lib/Resource/UserApiKeyWithValueOwner.php", "lib/Resource/UserAuthenticationFactorEnrollResponse.php", "lib/Resource/UserConsentOption.php", "lib/Resource/UserConsentOptionChoice.php", @@ -439,9 +446,11 @@ "lib/Resource/UserSessionsStatus.php", "lib/Resource/UserUpdated.php", "lib/Resource/ValidateApiKey.php", + "lib/Resource/VaultByokKeyDeleted.php", + "lib/Resource/VaultByokKeyDeletedData.php", + "lib/Resource/VaultByokKeyDeletedDataKeyProvider.php", "lib/Resource/VaultByokKeyVerificationCompleted.php", "lib/Resource/VaultByokKeyVerificationCompletedData.php", - "lib/Resource/VaultByokKeyVerificationCompletedDataKeyProvider.php", "lib/Resource/VaultDataCreated.php", "lib/Resource/VaultDataCreatedData.php", "lib/Resource/VaultDataDeleted.php", @@ -518,8 +527,6 @@ "tests/Fixtures/api_key_revoked_data.json", "tests/Fixtures/api_key_revoked_data_owner.json", "tests/Fixtures/api_key_validation_response.json", - "tests/Fixtures/api_key_with_value.json", - "tests/Fixtures/api_key_with_value_owner.json", "tests/Fixtures/application_credentials_list_item.json", "tests/Fixtures/assign_role.json", "tests/Fixtures/audit_log_action_json.json", @@ -646,6 +653,7 @@ "tests/Fixtures/create_redirect_uri.json", "tests/Fixtures/create_role.json", "tests/Fixtures/create_user.json", + "tests/Fixtures/create_user_api_key.json", "tests/Fixtures/create_user_invite_options.json", "tests/Fixtures/create_user_organization_membership.json", "tests/Fixtures/create_webhook_endpoint.json", @@ -760,7 +768,6 @@ "tests/Fixtures/jwks_response.json", "tests/Fixtures/jwks_response_keys.json", "tests/Fixtures/jwt_template_response.json", - "tests/Fixtures/list_api_key.json", "tests/Fixtures/list_audit_log_action_json.json", "tests/Fixtures/list_audit_log_schema_json.json", "tests/Fixtures/list_authentication_factor.json", @@ -776,8 +783,10 @@ "tests/Fixtures/list_flag.json", "tests/Fixtures/list_group.json", "tests/Fixtures/list_organization.json", + "tests/Fixtures/list_organization_api_key.json", "tests/Fixtures/list_role_assignment.json", "tests/Fixtures/list_user.json", + "tests/Fixtures/list_user_api_key.json", "tests/Fixtures/list_user_invite.json", "tests/Fixtures/list_user_organization_membership.json", "tests/Fixtures/list_user_organization_membership_base_list_data.json", @@ -790,6 +799,10 @@ "tests/Fixtures/mfa_totp_session_authenticate_request.json", "tests/Fixtures/new_connect_application_secret.json", "tests/Fixtures/organization.json", + "tests/Fixtures/organization_api_key.json", + "tests/Fixtures/organization_api_key_owner.json", + "tests/Fixtures/organization_api_key_with_value.json", + "tests/Fixtures/organization_api_key_with_value_owner.json", "tests/Fixtures/organization_created.json", "tests/Fixtures/organization_created_data.json", "tests/Fixtures/organization_created_data_domain.json", @@ -897,6 +910,10 @@ "tests/Fixtures/update_user_organization_membership.json", "tests/Fixtures/update_webhook_endpoint.json", "tests/Fixtures/user.json", + "tests/Fixtures/user_api_key.json", + "tests/Fixtures/user_api_key_owner.json", + "tests/Fixtures/user_api_key_with_value.json", + "tests/Fixtures/user_api_key_with_value_owner.json", "tests/Fixtures/user_authentication_factor_enroll_response.json", "tests/Fixtures/user_consent_option.json", "tests/Fixtures/user_consent_option_choice.json", @@ -912,6 +929,8 @@ "tests/Fixtures/user_sessions_list_item.json", "tests/Fixtures/user_updated.json", "tests/Fixtures/validate_api_key.json", + "tests/Fixtures/vault_byok_key_deleted.json", + "tests/Fixtures/vault_byok_key_deleted_data.json", "tests/Fixtures/vault_byok_key_verification_completed.json", "tests/Fixtures/vault_byok_key_verification_completed_data.json", "tests/Fixtures/vault_data_created.json", @@ -962,14 +981,6 @@ "tests/Service/WidgetsTest.php" ], "operations": { - "POST /api_keys/validations": { - "sdkMethod": "createValidation", - "service": "apiKeys" - }, - "DELETE /api_keys/{id}": { - "sdkMethod": "deleteApiKey", - "service": "apiKeys" - }, "POST /auth/challenges/{id}/verify": { "sdkMethod": "verifyChallenge", "service": "multiFactorAuth" @@ -1506,6 +1517,10 @@ "sdkMethod": "revokeInvitation", "service": "userManagement" }, + "GET /user_management/jwt_template": { + "sdkMethod": "listJWTTemplate", + "service": "userManagement" + }, "PUT /user_management/jwt_template": { "sdkMethod": "updateJWTTemplate", "service": "userManagement" @@ -1606,6 +1621,22 @@ "sdkMethod": "createToken", "service": "widgets" }, + "POST /api_keys/validations": { + "sdkMethod": "createValidation", + "service": "apiKeys" + }, + "DELETE /api_keys/{id}": { + "sdkMethod": "deleteApiKey", + "service": "apiKeys" + }, + "GET /user_management/users/{userId}/api_keys": { + "sdkMethod": "listUserApiKeys", + "service": "userManagement" + }, + "POST /user_management/users/{userId}/api_keys": { + "sdkMethod": "createUserApiKey", + "service": "userManagement" + }, "GET /audit_logs/actions": { "sdkMethod": "listActions", "service": "auditLogs" diff --git a/lib/Resource/ApiKey.php b/lib/Resource/ApiKey.php index 8d5c9236..f191eeae 100644 --- a/lib/Resource/ApiKey.php +++ b/lib/Resource/ApiKey.php @@ -6,7 +6,6 @@ namespace WorkOS\Resource; -/** The API Key object if the value is valid, or `null` if invalid. */ readonly class ApiKey implements \JsonSerializable { use JsonSerializableTrait; diff --git a/lib/Resource/ApiKeyCreatedDataOwner.php b/lib/Resource/ApiKeyCreatedDataOwner.php index 2bd5f0e0..5bc0915d 100644 --- a/lib/Resource/ApiKeyCreatedDataOwner.php +++ b/lib/Resource/ApiKeyCreatedDataOwner.php @@ -6,7 +6,6 @@ namespace WorkOS\Resource; -/** The owner of the API key. */ readonly class ApiKeyCreatedDataOwner implements \JsonSerializable { use JsonSerializableTrait; diff --git a/lib/Resource/ApiKeyOwner.php b/lib/Resource/ApiKeyOwner.php index 30da0231..a52dfe6b 100644 --- a/lib/Resource/ApiKeyOwner.php +++ b/lib/Resource/ApiKeyOwner.php @@ -6,7 +6,6 @@ namespace WorkOS\Resource; -/** The entity that owns the API Key. */ readonly class ApiKeyOwner implements \JsonSerializable { use JsonSerializableTrait; diff --git a/lib/Resource/ApiKeyRevokedDataOwner.php b/lib/Resource/ApiKeyRevokedDataOwner.php index a511766b..7dde8331 100644 --- a/lib/Resource/ApiKeyRevokedDataOwner.php +++ b/lib/Resource/ApiKeyRevokedDataOwner.php @@ -6,7 +6,6 @@ namespace WorkOS\Resource; -/** The owner of the API key. */ readonly class ApiKeyRevokedDataOwner implements \JsonSerializable { use JsonSerializableTrait; diff --git a/lib/Resource/CreateUserApiKey.php b/lib/Resource/CreateUserApiKey.php new file mode 100644 index 00000000..664ef3c5 --- /dev/null +++ b/lib/Resource/CreateUserApiKey.php @@ -0,0 +1,43 @@ +|null + */ + public ?array $permissions = null, + ) { + } + + public static function fromArray(array $data): self + { + return new self( + name: $data['name'], + organizationId: $data['organization_id'], + permissions: $data['permissions'] ?? null, + ); + } + + public function toArray(): array + { + return [ + 'name' => $this->name, + 'organization_id' => $this->organizationId, + 'permissions' => $this->permissions, + ]; + } +} diff --git a/lib/Resource/DirectoryUser.php b/lib/Resource/DirectoryUser.php index e8685590..365dd4bb 100644 --- a/lib/Resource/DirectoryUser.php +++ b/lib/Resource/DirectoryUser.php @@ -44,6 +44,8 @@ public function __construct( public ?string $firstName = null, /** The last name of the user. */ public ?string $lastName = null, + /** The full name of the user. */ + public ?string $name = null, /** * A list of email addresses for the user. * @var array<\WorkOS\Resource\DirectoryUserEmail>|null @@ -85,6 +87,7 @@ public static function fromArray(array $data): self updatedAt: new \DateTimeImmutable($data['updated_at']), firstName: $data['first_name'] ?? null, lastName: $data['last_name'] ?? null, + name: $data['name'] ?? null, emails: isset($data['emails']) ? array_map(fn ($item) => DirectoryUserEmail::fromArray($item), $data['emails']) : null, jobTitle: $data['job_title'] ?? null, username: $data['username'] ?? null, @@ -109,6 +112,7 @@ public function toArray(): array 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'first_name' => $this->firstName, 'last_name' => $this->lastName, + 'name' => $this->name, 'emails' => $this->emails !== null ? array_map(fn ($item) => $item->toArray(), $this->emails) : null, 'job_title' => $this->jobTitle, 'username' => $this->username, diff --git a/lib/Resource/DirectoryUserWithGroups.php b/lib/Resource/DirectoryUserWithGroups.php index b11c7696..9a3a32fc 100644 --- a/lib/Resource/DirectoryUserWithGroups.php +++ b/lib/Resource/DirectoryUserWithGroups.php @@ -41,7 +41,7 @@ public function __construct( /** An ISO 8601 timestamp. */ public \DateTimeImmutable $updatedAt, /** - * The directory groups the user belongs to. Use the List Directory Groups endpoint with a user filter instead. + * The directory groups the user belongs to. Deprecated: starting May 1, 2026, this field returns an empty array by default for newly created teams. Existing teams currently depending on this field should migrate to the new access pattern for better throughput performance — the field is unbounded by user, so users with many group memberships produce large, slow response payloads. Use the List Directory Groups endpoint with a `user` filter to fetch a user's group memberships. * @var array<\WorkOS\Resource\DirectoryGroup> * @deprecated */ @@ -50,6 +50,8 @@ public function __construct( public ?string $firstName = null, /** The last name of the user. */ public ?string $lastName = null, + /** The full name of the user. */ + public ?string $name = null, /** * A list of email addresses for the user. * @var array<\WorkOS\Resource\DirectoryUserWithGroupsEmail>|null @@ -92,6 +94,7 @@ public static function fromArray(array $data): self groups: array_map(fn ($item) => DirectoryGroup::fromArray($item), $data['groups']), firstName: $data['first_name'] ?? null, lastName: $data['last_name'] ?? null, + name: $data['name'] ?? null, emails: isset($data['emails']) ? array_map(fn ($item) => DirectoryUserWithGroupsEmail::fromArray($item), $data['emails']) : null, jobTitle: $data['job_title'] ?? null, username: $data['username'] ?? null, @@ -117,6 +120,7 @@ public function toArray(): array 'groups' => array_map(fn ($item) => $item->toArray(), $this->groups), 'first_name' => $this->firstName, 'last_name' => $this->lastName, + 'name' => $this->name, 'emails' => $this->emails !== null ? array_map(fn ($item) => $item->toArray(), $this->emails) : null, 'job_title' => $this->jobTitle, 'username' => $this->username, diff --git a/lib/Resource/DsyncUserUpdatedData.php b/lib/Resource/DsyncUserUpdatedData.php index 48ec04a7..1385ba46 100644 --- a/lib/Resource/DsyncUserUpdatedData.php +++ b/lib/Resource/DsyncUserUpdatedData.php @@ -45,6 +45,8 @@ public function __construct( public ?string $firstName = null, /** The last name of the user. */ public ?string $lastName = null, + /** The full name of the user. */ + public ?string $name = null, /** * A list of email addresses for the user. * @var array<\WorkOS\Resource\DsyncUserUpdatedDataEmail>|null @@ -88,6 +90,7 @@ public static function fromArray(array $data): self updatedAt: new \DateTimeImmutable($data['updated_at']), firstName: $data['first_name'] ?? null, lastName: $data['last_name'] ?? null, + name: $data['name'] ?? null, emails: isset($data['emails']) ? array_map(fn ($item) => DsyncUserUpdatedDataEmail::fromArray($item), $data['emails']) : null, jobTitle: $data['job_title'] ?? null, username: $data['username'] ?? null, @@ -113,6 +116,7 @@ public function toArray(): array 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'first_name' => $this->firstName, 'last_name' => $this->lastName, + 'name' => $this->name, 'emails' => $this->emails !== null ? array_map(fn ($item) => $item->toArray(), $this->emails) : null, 'job_title' => $this->jobTitle, 'username' => $this->username, diff --git a/lib/Resource/EventContextActorSource.php b/lib/Resource/EventContextActorSource.php index 1fcc2a21..79808ce4 100644 --- a/lib/Resource/EventContextActorSource.php +++ b/lib/Resource/EventContextActorSource.php @@ -10,5 +10,6 @@ enum EventContextActorSource: string { case Api = 'api'; case Dashboard = 'dashboard'; + case AdminPortal = 'admin_portal'; case System = 'system'; } diff --git a/lib/Resource/OrganizationApiKey.php b/lib/Resource/OrganizationApiKey.php new file mode 100644 index 00000000..7ca7626d --- /dev/null +++ b/lib/Resource/OrganizationApiKey.php @@ -0,0 +1,67 @@ + + */ + public array $permissions, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $createdAt, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $updatedAt, + ) { + } + + public static function fromArray(array $data): self + { + return new self( + object: $data['object'] ?? 'api_key', + id: $data['id'], + owner: OrganizationApiKeyOwner::fromArray($data['owner']), + name: $data['name'], + obfuscatedValue: $data['obfuscated_value'], + lastUsedAt: isset($data['last_used_at']) ? new \DateTimeImmutable($data['last_used_at']) : null, + permissions: $data['permissions'], + createdAt: new \DateTimeImmutable($data['created_at']), + updatedAt: new \DateTimeImmutable($data['updated_at']), + ); + } + + public function toArray(): array + { + return [ + 'object' => $this->object, + 'id' => $this->id, + 'owner' => $this->owner->toArray(), + 'name' => $this->name, + 'obfuscated_value' => $this->obfuscatedValue, + 'last_used_at' => $this->lastUsedAt?->format(\DateTimeInterface::RFC3339_EXTENDED), + 'permissions' => $this->permissions, + 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), + ]; + } +} diff --git a/lib/Resource/ApiKeyWithValueOwner.php b/lib/Resource/OrganizationApiKeyOwner.php similarity index 91% rename from lib/Resource/ApiKeyWithValueOwner.php rename to lib/Resource/OrganizationApiKeyOwner.php index fc5d83fe..47f2bc2b 100644 --- a/lib/Resource/ApiKeyWithValueOwner.php +++ b/lib/Resource/OrganizationApiKeyOwner.php @@ -7,7 +7,7 @@ namespace WorkOS\Resource; /** The entity that owns the API Key. */ -readonly class ApiKeyWithValueOwner implements \JsonSerializable +readonly class OrganizationApiKeyOwner implements \JsonSerializable { use JsonSerializableTrait; diff --git a/lib/Resource/OrganizationApiKeyWithValue.php b/lib/Resource/OrganizationApiKeyWithValue.php new file mode 100644 index 00000000..cdb4cd08 --- /dev/null +++ b/lib/Resource/OrganizationApiKeyWithValue.php @@ -0,0 +1,71 @@ + + */ + public array $permissions, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $createdAt, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $updatedAt, + /** The full API Key value. Only returned once at creation time. */ + public string $value, + ) { + } + + public static function fromArray(array $data): self + { + return new self( + object: $data['object'] ?? 'api_key', + id: $data['id'], + owner: OrganizationApiKeyWithValueOwner::fromArray($data['owner']), + name: $data['name'], + obfuscatedValue: $data['obfuscated_value'], + lastUsedAt: isset($data['last_used_at']) ? new \DateTimeImmutable($data['last_used_at']) : null, + permissions: $data['permissions'], + createdAt: new \DateTimeImmutable($data['created_at']), + updatedAt: new \DateTimeImmutable($data['updated_at']), + value: $data['value'], + ); + } + + public function toArray(): array + { + return [ + 'object' => $this->object, + 'id' => $this->id, + 'owner' => $this->owner->toArray(), + 'name' => $this->name, + 'obfuscated_value' => $this->obfuscatedValue, + 'last_used_at' => $this->lastUsedAt?->format(\DateTimeInterface::RFC3339_EXTENDED), + 'permissions' => $this->permissions, + 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'value' => $this->value, + ]; + } +} diff --git a/lib/Resource/OrganizationApiKeyWithValueOwner.php b/lib/Resource/OrganizationApiKeyWithValueOwner.php new file mode 100644 index 00000000..17206c75 --- /dev/null +++ b/lib/Resource/OrganizationApiKeyWithValueOwner.php @@ -0,0 +1,37 @@ + $this->type, + 'id' => $this->id, + ]; + } +} diff --git a/lib/Resource/OrganizationMembership.php b/lib/Resource/OrganizationMembership.php index c36ed72a..aa4d8f98 100644 --- a/lib/Resource/OrganizationMembership.php +++ b/lib/Resource/OrganizationMembership.php @@ -29,6 +29,8 @@ public function __construct( public \DateTimeImmutable $updatedAt, /** The primary role assigned to the user within the organization. */ public SlimRole $role, + /** The user that belongs to the organization through this membership. */ + public User $user, /** The name of the organization which the user belongs to. */ public ?string $organizationName = null, /** @@ -51,6 +53,7 @@ public static function fromArray(array $data): self createdAt: new \DateTimeImmutable($data['created_at']), updatedAt: new \DateTimeImmutable($data['updated_at']), role: SlimRole::fromArray($data['role']), + user: User::fromArray($data['user']), organizationName: $data['organization_name'] ?? null, customAttributes: $data['custom_attributes'] ?? null, ); @@ -68,6 +71,7 @@ public function toArray(): array 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'role' => $this->role->toArray(), + 'user' => $this->user->toArray(), 'organization_name' => $this->organizationName, 'custom_attributes' => $this->customAttributes, ]; diff --git a/lib/Resource/Profile.php b/lib/Resource/Profile.php index ef0d7ba2..34b07f1d 100644 --- a/lib/Resource/Profile.php +++ b/lib/Resource/Profile.php @@ -29,6 +29,8 @@ public function __construct( public ?string $firstName, /** The user's last name. */ public ?string $lastName, + /** The user's full name. */ + public ?string $name, /** * The complete set of raw attributes returned by the identity provider. * @var array @@ -66,6 +68,7 @@ public static function fromArray(array $data): self email: $data['email'], firstName: $data['first_name'] ?? null, lastName: $data['last_name'] ?? null, + name: $data['name'] ?? null, rawAttributes: $data['raw_attributes'], role: isset($data['role']) ? SlimRole::fromArray($data['role']) : null, roles: isset($data['roles']) ? array_map(fn ($item) => SlimRole::fromArray($item), $data['roles']) : null, @@ -86,6 +89,7 @@ public function toArray(): array 'email' => $this->email, 'first_name' => $this->firstName, 'last_name' => $this->lastName, + 'name' => $this->name, 'raw_attributes' => $this->rawAttributes, 'role' => $this->role?->toArray(), 'roles' => $this->roles !== null ? array_map(fn ($item) => $item->toArray(), $this->roles) : null, diff --git a/lib/Resource/UserApiKey.php b/lib/Resource/UserApiKey.php new file mode 100644 index 00000000..e38b32bc --- /dev/null +++ b/lib/Resource/UserApiKey.php @@ -0,0 +1,67 @@ + + */ + public array $permissions, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $createdAt, + /** An ISO 8601 timestamp. */ + public \DateTimeImmutable $updatedAt, + ) { + } + + public static function fromArray(array $data): self + { + return new self( + object: $data['object'] ?? 'api_key', + id: $data['id'], + owner: UserApiKeyOwner::fromArray($data['owner']), + name: $data['name'], + obfuscatedValue: $data['obfuscated_value'], + lastUsedAt: isset($data['last_used_at']) ? new \DateTimeImmutable($data['last_used_at']) : null, + permissions: $data['permissions'], + createdAt: new \DateTimeImmutable($data['created_at']), + updatedAt: new \DateTimeImmutable($data['updated_at']), + ); + } + + public function toArray(): array + { + return [ + 'object' => $this->object, + 'id' => $this->id, + 'owner' => $this->owner->toArray(), + 'name' => $this->name, + 'obfuscated_value' => $this->obfuscatedValue, + 'last_used_at' => $this->lastUsedAt?->format(\DateTimeInterface::RFC3339_EXTENDED), + 'permissions' => $this->permissions, + 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), + ]; + } +} diff --git a/lib/Resource/UserApiKeyOwner.php b/lib/Resource/UserApiKeyOwner.php new file mode 100644 index 00000000..94eb21ad --- /dev/null +++ b/lib/Resource/UserApiKeyOwner.php @@ -0,0 +1,41 @@ + $this->type, + 'id' => $this->id, + 'organization_id' => $this->organizationId, + ]; + } +} diff --git a/lib/Resource/ApiKeyWithValue.php b/lib/Resource/UserApiKeyWithValue.php similarity index 92% rename from lib/Resource/ApiKeyWithValue.php rename to lib/Resource/UserApiKeyWithValue.php index 7142ae56..216990eb 100644 --- a/lib/Resource/ApiKeyWithValue.php +++ b/lib/Resource/UserApiKeyWithValue.php @@ -6,7 +6,7 @@ namespace WorkOS\Resource; -readonly class ApiKeyWithValue implements \JsonSerializable +readonly class UserApiKeyWithValue implements \JsonSerializable { use JsonSerializableTrait; @@ -16,7 +16,7 @@ public function __construct( /** Unique identifier of the API Key. */ public string $id, /** The entity that owns the API Key. */ - public ApiKeyWithValueOwner $owner, + public UserApiKeyWithValueOwner $owner, /** A descriptive name for the API Key. */ public string $name, /** An obfuscated representation of the API Key value. */ @@ -42,7 +42,7 @@ public static function fromArray(array $data): self return new self( object: $data['object'] ?? 'api_key', id: $data['id'], - owner: ApiKeyWithValueOwner::fromArray($data['owner']), + owner: UserApiKeyWithValueOwner::fromArray($data['owner']), name: $data['name'], obfuscatedValue: $data['obfuscated_value'], lastUsedAt: isset($data['last_used_at']) ? new \DateTimeImmutable($data['last_used_at']) : null, diff --git a/lib/Resource/UserApiKeyWithValueOwner.php b/lib/Resource/UserApiKeyWithValueOwner.php new file mode 100644 index 00000000..84a4a0ab --- /dev/null +++ b/lib/Resource/UserApiKeyWithValueOwner.php @@ -0,0 +1,41 @@ + $this->type, + 'id' => $this->id, + 'organization_id' => $this->organizationId, + ]; + } +} diff --git a/lib/Resource/UserOrganizationMembership.php b/lib/Resource/UserOrganizationMembership.php index cfabf3d5..d6daaf00 100644 --- a/lib/Resource/UserOrganizationMembership.php +++ b/lib/Resource/UserOrganizationMembership.php @@ -29,6 +29,8 @@ public function __construct( public \DateTimeImmutable $updatedAt, /** The primary role assigned to the user within the organization. */ public SlimRole $role, + /** The user that belongs to the organization through this membership. */ + public User $user, /** The name of the organization which the user belongs to. */ public ?string $organizationName = null, /** @@ -51,6 +53,7 @@ public static function fromArray(array $data): self createdAt: new \DateTimeImmutable($data['created_at']), updatedAt: new \DateTimeImmutable($data['updated_at']), role: SlimRole::fromArray($data['role']), + user: User::fromArray($data['user']), organizationName: $data['organization_name'] ?? null, customAttributes: $data['custom_attributes'] ?? null, ); @@ -68,6 +71,7 @@ public function toArray(): array 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'role' => $this->role->toArray(), + 'user' => $this->user->toArray(), 'organization_name' => $this->organizationName, 'custom_attributes' => $this->customAttributes, ]; diff --git a/lib/Resource/UserOrganizationMembershipBaseListData.php b/lib/Resource/UserOrganizationMembershipBaseListData.php index 02b90311..8465275b 100644 --- a/lib/Resource/UserOrganizationMembershipBaseListData.php +++ b/lib/Resource/UserOrganizationMembershipBaseListData.php @@ -27,6 +27,8 @@ public function __construct( public \DateTimeImmutable $createdAt, /** An ISO 8601 timestamp. */ public \DateTimeImmutable $updatedAt, + /** The user that belongs to the organization through this membership. */ + public User $user, /** The name of the organization which the user belongs to. */ public ?string $organizationName = null, /** @@ -48,6 +50,7 @@ public static function fromArray(array $data): self directoryManaged: $data['directory_managed'], createdAt: new \DateTimeImmutable($data['created_at']), updatedAt: new \DateTimeImmutable($data['updated_at']), + user: User::fromArray($data['user']), organizationName: $data['organization_name'] ?? null, customAttributes: $data['custom_attributes'] ?? null, ); @@ -64,6 +67,7 @@ public function toArray(): array 'directory_managed' => $this->directoryManaged, 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), 'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'user' => $this->user->toArray(), 'organization_name' => $this->organizationName, 'custom_attributes' => $this->customAttributes, ]; diff --git a/lib/Resource/VaultByokKeyDeleted.php b/lib/Resource/VaultByokKeyDeleted.php new file mode 100644 index 00000000..2a9c1f25 --- /dev/null +++ b/lib/Resource/VaultByokKeyDeleted.php @@ -0,0 +1,50 @@ + $this->id, + 'event' => $this->event, + 'data' => $this->data->toArray(), + 'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED), + 'object' => $this->object, + 'context' => $this->context?->toArray(), + ]; + } +} diff --git a/lib/Resource/VaultByokKeyDeletedData.php b/lib/Resource/VaultByokKeyDeletedData.php new file mode 100644 index 00000000..9df006a4 --- /dev/null +++ b/lib/Resource/VaultByokKeyDeletedData.php @@ -0,0 +1,37 @@ + $this->organizationId, + 'key_provider' => $this->keyProvider->value, + ]; + } +} diff --git a/lib/Resource/VaultByokKeyVerificationCompletedDataKeyProvider.php b/lib/Resource/VaultByokKeyDeletedDataKeyProvider.php similarity index 78% rename from lib/Resource/VaultByokKeyVerificationCompletedDataKeyProvider.php rename to lib/Resource/VaultByokKeyDeletedDataKeyProvider.php index f2786536..2836b7f1 100644 --- a/lib/Resource/VaultByokKeyVerificationCompletedDataKeyProvider.php +++ b/lib/Resource/VaultByokKeyDeletedDataKeyProvider.php @@ -6,7 +6,7 @@ namespace WorkOS\Resource; -enum VaultByokKeyVerificationCompletedDataKeyProvider: string +enum VaultByokKeyDeletedDataKeyProvider: string { case AwsKms = 'AWS_KMS'; case GcpKms = 'GCP_KMS'; diff --git a/lib/Resource/VaultByokKeyVerificationCompletedData.php b/lib/Resource/VaultByokKeyVerificationCompletedData.php index a23530c3..fd18248c 100644 --- a/lib/Resource/VaultByokKeyVerificationCompletedData.php +++ b/lib/Resource/VaultByokKeyVerificationCompletedData.php @@ -15,7 +15,7 @@ public function __construct( /** The unique identifier of the organization. */ public string $organizationId, /** The external key provider used for BYOK. */ - public VaultByokKeyVerificationCompletedDataKeyProvider $keyProvider, + public VaultByokKeyDeletedDataKeyProvider $keyProvider, /** Whether the BYOK key verification completed successfully. */ public bool $verified, ) { @@ -25,7 +25,7 @@ public static function fromArray(array $data): self { return new self( organizationId: $data['organization_id'], - keyProvider: VaultByokKeyVerificationCompletedDataKeyProvider::from($data['key_provider']), + keyProvider: VaultByokKeyDeletedDataKeyProvider::from($data['key_provider']), verified: $data['verified'], ); } diff --git a/lib/Service/ApiKeys.php b/lib/Service/ApiKeys.php index 8b436cca..e06e9fd1 100644 --- a/lib/Service/ApiKeys.php +++ b/lib/Service/ApiKeys.php @@ -6,9 +6,9 @@ namespace WorkOS\Service; -use WorkOS\Resource\ApiKey; use WorkOS\Resource\ApiKeyValidationResponse; -use WorkOS\Resource\ApiKeyWithValue; +use WorkOS\Resource\OrganizationApiKey; +use WorkOS\Resource\OrganizationApiKeyWithValue; class ApiKeys { @@ -17,49 +17,6 @@ public function __construct( ) { } - /** - * Validate API key - * - * Validate an API key value and return the API key object if valid. - * @param string $value The value for an API key. - * @return \WorkOS\Resource\ApiKeyValidationResponse - * @throws \WorkOS\Exception\WorkOSException - */ - public function createValidation( - string $value, - ?\WorkOS\RequestOptions $options = null, - ): \WorkOS\Resource\ApiKeyValidationResponse { - $body = [ - 'value' => $value, - ]; - $response = $this->client->request( - method: 'POST', - path: 'api_keys/validations', - body: $body, - options: $options, - ); - return ApiKeyValidationResponse::fromArray($response); - } - - /** - * Delete an API key - * - * Permanently deletes an API key. This action cannot be undone. Once deleted, any requests using this API key will fail authentication. - * @param string $id The unique ID of the API key. - * @return void - * @throws \WorkOS\Exception\WorkOSException - */ - public function deleteApiKey( - string $id, - ?\WorkOS\RequestOptions $options = null, - ): void { - $this->client->request( - method: 'DELETE', - path: "api_keys/{$id}", - options: $options, - ); - } - /** * List API keys for an organization * @@ -69,7 +26,7 @@ public function deleteApiKey( * @param string|null $after An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. * @param int|null $limit Upper limit on the number of objects to return, between `1` and `100`. Defaults to 10. * @param \WorkOS\Resource\EventsOrder $order Order the results by the creation time. Defaults to "desc". - * @return \WorkOS\PaginatedResponse<\WorkOS\Resource\ApiKey> + * @return \WorkOS\PaginatedResponse<\WorkOS\Resource\OrganizationApiKey> * @throws \WorkOS\Exception\WorkOSException */ public function listOrganizationApiKeys( @@ -88,9 +45,9 @@ public function listOrganizationApiKeys( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "organizations/{$organizationId}/api_keys", + path: 'organizations/' . rawurlencode($organizationId) . '/api_keys', query: $query, - modelClass: ApiKey::class, + modelClass: OrganizationApiKey::class, options: $options, ); } @@ -102,7 +59,7 @@ public function listOrganizationApiKeys( * @param string $organizationId Unique identifier of the Organization. * @param string $name The name for the API key. * @param array|null $permissions The permission slugs to assign to the API key. - * @return \WorkOS\Resource\ApiKeyWithValue + * @return \WorkOS\Resource\OrganizationApiKeyWithValue * @throws \WorkOS\Exception\WorkOSException */ public function createOrganizationApiKey( @@ -110,17 +67,60 @@ public function createOrganizationApiKey( string $name, ?array $permissions = null, ?\WorkOS\RequestOptions $options = null, - ): \WorkOS\Resource\ApiKeyWithValue { + ): \WorkOS\Resource\OrganizationApiKeyWithValue { $body = array_filter([ 'name' => $name, 'permissions' => $permissions, ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "organizations/{$organizationId}/api_keys", + path: 'organizations/' . rawurlencode($organizationId) . '/api_keys', body: $body, options: $options, ); - return ApiKeyWithValue::fromArray($response); + return OrganizationApiKeyWithValue::fromArray($response); + } + + /** + * Validate API key + * + * Validate an API key value and return the API key object if valid. + * @param string $value The value for an API key. + * @return \WorkOS\Resource\ApiKeyValidationResponse + * @throws \WorkOS\Exception\WorkOSException + */ + public function createValidation( + string $value, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\ApiKeyValidationResponse { + $body = [ + 'value' => $value, + ]; + $response = $this->client->request( + method: 'POST', + path: 'api_keys/validations', + body: $body, + options: $options, + ); + return ApiKeyValidationResponse::fromArray($response); + } + + /** + * Delete an API key + * + * Permanently deletes an API key. This action cannot be undone. Once deleted, any requests using this API key will fail authentication. + * @param string $id The unique ID of the API key. + * @return void + * @throws \WorkOS\Exception\WorkOSException + */ + public function deleteApiKey( + string $id, + ?\WorkOS\RequestOptions $options = null, + ): void { + $this->client->request( + method: 'DELETE', + path: 'api_keys/' . rawurlencode($id), + options: $options, + ); } } diff --git a/lib/Service/AuditLogs.php b/lib/Service/AuditLogs.php index 441c6d00..4eda912c 100644 --- a/lib/Service/AuditLogs.php +++ b/lib/Service/AuditLogs.php @@ -33,7 +33,7 @@ public function getOrganizationAuditLogsRetention( ): \WorkOS\Resource\AuditLogsRetentionJson { $response = $this->client->request( method: 'GET', - path: "organizations/{$id}/audit_logs_retention", + path: 'organizations/' . rawurlencode($id) . '/audit_logs_retention', options: $options, ); return AuditLogsRetentionJson::fromArray($response); @@ -58,7 +58,7 @@ public function updateOrganizationAuditLogsRetention( ]; $response = $this->client->request( method: 'PUT', - path: "organizations/{$id}/audit_logs_retention", + path: 'organizations/' . rawurlencode($id) . '/audit_logs_retention', body: $body, options: $options, ); @@ -126,7 +126,7 @@ public function listActionSchemas( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "audit_logs/actions/{$actionName}/schemas", + path: 'audit_logs/actions/' . rawurlencode($actionName) . '/schemas', query: $query, modelClass: AuditLogSchemaJson::class, options: $options, @@ -158,7 +158,7 @@ public function createSchema( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "audit_logs/actions/{$actionName}/schemas", + path: 'audit_logs/actions/' . rawurlencode($actionName) . '/schemas', body: $body, options: $options, ); @@ -257,7 +257,7 @@ public function getExport( ): \WorkOS\Resource\AuditLogExportJson { $response = $this->client->request( method: 'GET', - path: "audit_logs/exports/{$auditLogExportId}", + path: 'audit_logs/exports/' . rawurlencode($auditLogExportId), options: $options, ); return AuditLogExportJson::fromArray($response); diff --git a/lib/Service/Authorization.php b/lib/Service/Authorization.php index 59d0721f..4ae22491 100644 --- a/lib/Service/Authorization.php +++ b/lib/Service/Authorization.php @@ -49,7 +49,7 @@ public function check( } $response = $this->client->request( method: 'POST', - path: "authorization/organization_memberships/{$organizationMembershipId}/check", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/check', body: $body, options: $options, ); @@ -97,7 +97,7 @@ public function listResourcesForMembership( } return $this->client->requestPage( method: 'GET', - path: "authorization/organization_memberships/{$organizationMembershipId}/resources", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/resources', query: $query, modelClass: AuthorizationResource::class, options: $options, @@ -134,7 +134,7 @@ public function listEffectivePermissions( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "authorization/organization_memberships/{$organizationMembershipId}/resources/{$resourceId}/permissions", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/resources/' . rawurlencode($resourceId) . '/permissions', query: $query, modelClass: AuthorizationPermission::class, options: $options, @@ -173,7 +173,7 @@ public function listEffectivePermissionsByExternalId( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "authorization/organization_memberships/{$organizationMembershipId}/resources/{$resourceTypeSlug}/{$externalId}/permissions", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/resources/' . rawurlencode($resourceTypeSlug) . '/' . rawurlencode($externalId) . '/permissions', query: $query, modelClass: AuthorizationPermission::class, options: $options, @@ -208,7 +208,7 @@ public function listRoleAssignments( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "authorization/organization_memberships/{$organizationMembershipId}/role_assignments", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/role_assignments', query: $query, modelClass: RoleAssignment::class, options: $options, @@ -242,7 +242,7 @@ public function assignRole( } $response = $this->client->request( method: 'POST', - path: "authorization/organization_memberships/{$organizationMembershipId}/role_assignments", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/role_assignments', body: $body, options: $options, ); @@ -276,7 +276,7 @@ public function removeRole( } $this->client->request( method: 'DELETE', - path: "authorization/organization_memberships/{$organizationMembershipId}/role_assignments", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/role_assignments', body: $body, options: $options, ); @@ -298,7 +298,7 @@ public function removeRoleAssignment( ): void { $this->client->request( method: 'DELETE', - path: "authorization/organization_memberships/{$organizationMembershipId}/role_assignments/{$roleAssignmentId}", + path: 'authorization/organization_memberships/' . rawurlencode($organizationMembershipId) . '/role_assignments/' . rawurlencode($roleAssignmentId), options: $options, ); } @@ -317,7 +317,7 @@ public function listOrganizationRoles( ): \WorkOS\Resource\RoleList { $response = $this->client->request( method: 'GET', - path: "authorization/organizations/{$organizationId}/roles", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles', options: $options, ); return RoleList::fromArray($response); @@ -351,7 +351,7 @@ public function createOrganizationRole( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "authorization/organizations/{$organizationId}/roles", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles', body: $body, options: $options, ); @@ -374,7 +374,7 @@ public function getOrganizationRole( ): \WorkOS\Resource\Role { $response = $this->client->request( method: 'GET', - path: "authorization/organizations/{$organizationId}/roles/{$slug}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug), options: $options, ); return Role::fromArray($response); @@ -404,7 +404,7 @@ public function updateOrganizationRole( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PATCH', - path: "authorization/organizations/{$organizationId}/roles/{$slug}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug), body: $body, options: $options, ); @@ -427,7 +427,7 @@ public function deleteOrganizationRole( ): void { $this->client->request( method: 'DELETE', - path: "authorization/organizations/{$organizationId}/roles/{$slug}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug), options: $options, ); } @@ -453,7 +453,7 @@ public function addOrganizationRolePermission( ]; $response = $this->client->request( method: 'POST', - path: "authorization/organizations/{$organizationId}/roles/{$slug}/permissions", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug) . '/permissions', body: $body, options: $options, ); @@ -481,7 +481,7 @@ public function setOrganizationRolePermissions( ]; $response = $this->client->request( method: 'PUT', - path: "authorization/organizations/{$organizationId}/roles/{$slug}/permissions", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug) . '/permissions', body: $body, options: $options, ); @@ -506,7 +506,7 @@ public function removeOrganizationRolePermission( ): void { $this->client->request( method: 'DELETE', - path: "authorization/organizations/{$organizationId}/roles/{$slug}/permissions/{$permissionSlug}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/roles/' . rawurlencode($slug) . '/permissions/' . rawurlencode($permissionSlug), options: $options, ); } @@ -529,7 +529,7 @@ public function getResourceByExternalId( ): \WorkOS\Resource\AuthorizationResource { $response = $this->client->request( method: 'GET', - path: "authorization/organizations/{$organizationId}/resources/{$resourceTypeSlug}/{$externalId}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/resources/' . rawurlencode($resourceTypeSlug) . '/' . rawurlencode($externalId), options: $options, ); return AuthorizationResource::fromArray($response); @@ -569,7 +569,7 @@ public function updateResourceByExternalId( } $response = $this->client->request( method: 'PATCH', - path: "authorization/organizations/{$organizationId}/resources/{$resourceTypeSlug}/{$externalId}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/resources/' . rawurlencode($resourceTypeSlug) . '/' . rawurlencode($externalId), body: $body, options: $options, ); @@ -599,7 +599,7 @@ public function deleteResourceByExternalId( ], fn ($v) => $v !== null); $this->client->request( method: 'DELETE', - path: "authorization/organizations/{$organizationId}/resources/{$resourceTypeSlug}/{$externalId}", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/resources/' . rawurlencode($resourceTypeSlug) . '/' . rawurlencode($externalId), query: $query, options: $options, ); @@ -643,7 +643,7 @@ public function listMembershipsForResourceByExternalId( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "authorization/organizations/{$organizationId}/resources/{$resourceTypeSlug}/{$externalId}/organization_memberships", + path: 'authorization/organizations/' . rawurlencode($organizationId) . '/resources/' . rawurlencode($resourceTypeSlug) . '/' . rawurlencode($externalId) . '/organization_memberships', query: $query, modelClass: UserOrganizationMembershipBaseListData::class, options: $options, @@ -761,7 +761,7 @@ public function getResource( ): \WorkOS\Resource\AuthorizationResource { $response = $this->client->request( method: 'GET', - path: "authorization/resources/{$resourceId}", + path: 'authorization/resources/' . rawurlencode($resourceId), options: $options, ); return AuthorizationResource::fromArray($response); @@ -797,7 +797,7 @@ public function updateResource( } $response = $this->client->request( method: 'PATCH', - path: "authorization/resources/{$resourceId}", + path: 'authorization/resources/' . rawurlencode($resourceId), body: $body, options: $options, ); @@ -823,7 +823,7 @@ public function deleteResource( ], fn ($v) => $v !== null); $this->client->request( method: 'DELETE', - path: "authorization/resources/{$resourceId}", + path: 'authorization/resources/' . rawurlencode($resourceId), query: $query, options: $options, ); @@ -863,7 +863,7 @@ public function listMembershipsForResource( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "authorization/resources/{$resourceId}/organization_memberships", + path: 'authorization/resources/' . rawurlencode($resourceId) . '/organization_memberships', query: $query, modelClass: UserOrganizationMembershipBaseListData::class, options: $options, @@ -935,7 +935,7 @@ public function getEnvironmentRole( ): \WorkOS\Resource\Role { $response = $this->client->request( method: 'GET', - path: "authorization/roles/{$slug}", + path: 'authorization/roles/' . rawurlencode($slug), options: $options, ); return Role::fromArray($response); @@ -963,7 +963,7 @@ public function updateEnvironmentRole( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PATCH', - path: "authorization/roles/{$slug}", + path: 'authorization/roles/' . rawurlencode($slug), body: $body, options: $options, ); @@ -989,7 +989,7 @@ public function addEnvironmentRolePermission( ]; $response = $this->client->request( method: 'POST', - path: "authorization/roles/{$slug}/permissions", + path: 'authorization/roles/' . rawurlencode($slug) . '/permissions', body: $body, options: $options, ); @@ -1015,7 +1015,7 @@ public function setEnvironmentRolePermissions( ]; $response = $this->client->request( method: 'PUT', - path: "authorization/roles/{$slug}/permissions", + path: 'authorization/roles/' . rawurlencode($slug) . '/permissions', body: $body, options: $options, ); @@ -1102,7 +1102,7 @@ public function getPermission( ): \WorkOS\Resource\AuthorizationPermission { $response = $this->client->request( method: 'GET', - path: "authorization/permissions/{$slug}", + path: 'authorization/permissions/' . rawurlencode($slug), options: $options, ); return AuthorizationPermission::fromArray($response); @@ -1130,7 +1130,7 @@ public function updatePermission( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PATCH', - path: "authorization/permissions/{$slug}", + path: 'authorization/permissions/' . rawurlencode($slug), body: $body, options: $options, ); @@ -1151,7 +1151,7 @@ public function deletePermission( ): void { $this->client->request( method: 'DELETE', - path: "authorization/permissions/{$slug}", + path: 'authorization/permissions/' . rawurlencode($slug), options: $options, ); } diff --git a/lib/Service/Connect.php b/lib/Service/Connect.php index ab4933ad..0f4c0e50 100644 --- a/lib/Service/Connect.php +++ b/lib/Service/Connect.php @@ -180,7 +180,7 @@ public function getApplication( ): \WorkOS\Resource\ConnectApplication { $response = $this->client->request( method: 'GET', - path: "connect/applications/{$id}", + path: 'connect/applications/' . rawurlencode($id), options: $options, ); return ConnectApplication::fromArray($response); @@ -214,7 +214,7 @@ public function updateApplication( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PUT', - path: "connect/applications/{$id}", + path: 'connect/applications/' . rawurlencode($id), body: $body, options: $options, ); @@ -235,7 +235,7 @@ public function deleteApplication( ): void { $this->client->request( method: 'DELETE', - path: "connect/applications/{$id}", + path: 'connect/applications/' . rawurlencode($id), options: $options, ); } @@ -254,7 +254,7 @@ public function listApplicationClientSecrets( ): array { $response = $this->client->request( method: 'GET', - path: "connect/applications/{$id}/client_secrets", + path: 'connect/applications/' . rawurlencode($id) . '/client_secrets', options: $options, ); return array_map(fn ($item) => ApplicationCredentialsListItem::fromArray($item), $response); @@ -276,7 +276,7 @@ public function createApplicationClientSecret( ]; $response = $this->client->request( method: 'POST', - path: "connect/applications/{$id}/client_secrets", + path: 'connect/applications/' . rawurlencode($id) . '/client_secrets', body: $body, options: $options, ); @@ -297,7 +297,7 @@ public function deleteClientSecret( ): void { $this->client->request( method: 'DELETE', - path: "connect/client_secrets/{$id}", + path: 'connect/client_secrets/' . rawurlencode($id), options: $options, ); } diff --git a/lib/Service/DirectorySync.php b/lib/Service/DirectorySync.php index 640acfdb..ef7ead48 100644 --- a/lib/Service/DirectorySync.php +++ b/lib/Service/DirectorySync.php @@ -73,7 +73,7 @@ public function getDirectory( ): \WorkOS\Resource\Directory { $response = $this->client->request( method: 'GET', - path: "directories/{$id}", + path: 'directories/' . rawurlencode($id), options: $options, ); return Directory::fromArray($response); @@ -93,7 +93,7 @@ public function deleteDirectory( ): void { $this->client->request( method: 'DELETE', - path: "directories/{$id}", + path: 'directories/' . rawurlencode($id), options: $options, ); } @@ -151,7 +151,7 @@ public function getGroup( ): \WorkOS\Resource\DirectoryGroup { $response = $this->client->request( method: 'GET', - path: "directory_groups/{$id}", + path: 'directory_groups/' . rawurlencode($id), options: $options, ); return DirectoryGroup::fromArray($response); @@ -210,7 +210,7 @@ public function getUser( ): \WorkOS\Resource\DirectoryUserWithGroups { $response = $this->client->request( method: 'GET', - path: "directory_users/{$id}", + path: 'directory_users/' . rawurlencode($id), options: $options, ); return DirectoryUserWithGroups::fromArray($response); diff --git a/lib/Service/FeatureFlags.php b/lib/Service/FeatureFlags.php index fa409a6a..841a48c2 100644 --- a/lib/Service/FeatureFlags.php +++ b/lib/Service/FeatureFlags.php @@ -63,7 +63,7 @@ public function getFeatureFlag( ): \WorkOS\Resource\Flag { $response = $this->client->request( method: 'GET', - path: "feature-flags/{$slug}", + path: 'feature-flags/' . rawurlencode($slug), options: $options, ); return Flag::fromArray($response); @@ -83,7 +83,7 @@ public function disableFeatureFlag( ): \WorkOS\Resource\FeatureFlag { $response = $this->client->request( method: 'PUT', - path: "feature-flags/{$slug}/disable", + path: 'feature-flags/' . rawurlencode($slug) . '/disable', options: $options, ); return FeatureFlag::fromArray($response); @@ -103,7 +103,7 @@ public function enableFeatureFlag( ): \WorkOS\Resource\FeatureFlag { $response = $this->client->request( method: 'PUT', - path: "feature-flags/{$slug}/enable", + path: 'feature-flags/' . rawurlencode($slug) . '/enable', options: $options, ); return FeatureFlag::fromArray($response); @@ -125,7 +125,7 @@ public function addFlagTarget( ): mixed { $response = $this->client->request( method: 'POST', - path: "feature-flags/{$slug}/targets/{$resourceId}", + path: 'feature-flags/' . rawurlencode($slug) . '/targets/' . rawurlencode($resourceId), options: $options, ); return $response; @@ -147,7 +147,7 @@ public function removeFlagTarget( ): void { $this->client->request( method: 'DELETE', - path: "feature-flags/{$slug}/targets/{$resourceId}", + path: 'feature-flags/' . rawurlencode($slug) . '/targets/' . rawurlencode($resourceId), options: $options, ); } @@ -180,7 +180,7 @@ public function listOrganizationFeatureFlags( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "organizations/{$organizationId}/feature-flags", + path: 'organizations/' . rawurlencode($organizationId) . '/feature-flags', query: $query, modelClass: Flag::class, options: $options, @@ -215,7 +215,7 @@ public function listUserFeatureFlags( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "user_management/users/{$userId}/feature-flags", + path: 'user_management/users/' . rawurlencode($userId) . '/feature-flags', query: $query, modelClass: Flag::class, options: $options, diff --git a/lib/Service/Groups.php b/lib/Service/Groups.php index 519d2bdd..6e555414 100644 --- a/lib/Service/Groups.php +++ b/lib/Service/Groups.php @@ -44,7 +44,7 @@ public function listOrganizationGroups( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "organizations/{$organizationId}/groups", + path: 'organizations/' . rawurlencode($organizationId) . '/groups', query: $query, modelClass: Group::class, options: $options, @@ -73,7 +73,7 @@ public function createOrganizationGroup( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "organizations/{$organizationId}/groups", + path: 'organizations/' . rawurlencode($organizationId) . '/groups', body: $body, options: $options, ); @@ -96,7 +96,7 @@ public function getOrganizationGroup( ): \WorkOS\Resource\Group { $response = $this->client->request( method: 'GET', - path: "organizations/{$organizationId}/groups/{$groupId}", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId), options: $options, ); return Group::fromArray($response); @@ -126,7 +126,7 @@ public function updateOrganizationGroup( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PATCH', - path: "organizations/{$organizationId}/groups/{$groupId}", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId), body: $body, options: $options, ); @@ -149,7 +149,7 @@ public function deleteOrganizationGroup( ): void { $this->client->request( method: 'DELETE', - path: "organizations/{$organizationId}/groups/{$groupId}", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId), options: $options, ); } @@ -184,7 +184,7 @@ public function listGroupOrganizationMemberships( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "organizations/{$organizationId}/groups/{$groupId}/organization-memberships", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId) . '/organization-memberships', query: $query, modelClass: UserOrganizationMembershipBaseListData::class, options: $options, @@ -212,7 +212,7 @@ public function createGroupOrganizationMembership( ]; $response = $this->client->request( method: 'POST', - path: "organizations/{$organizationId}/groups/{$groupId}/organization-memberships", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId) . '/organization-memberships', body: $body, options: $options, ); @@ -237,7 +237,7 @@ public function deleteGroupOrganizationMembership( ): void { $this->client->request( method: 'DELETE', - path: "organizations/{$organizationId}/groups/{$groupId}/organization-memberships/{$omId}", + path: 'organizations/' . rawurlencode($organizationId) . '/groups/' . rawurlencode($groupId) . '/organization-memberships/' . rawurlencode($omId), options: $options, ); } diff --git a/lib/Service/MultiFactorAuth.php b/lib/Service/MultiFactorAuth.php index 3c649ed9..5a015356 100644 --- a/lib/Service/MultiFactorAuth.php +++ b/lib/Service/MultiFactorAuth.php @@ -38,7 +38,7 @@ public function verifyChallenge( ]; $response = $this->client->request( method: 'POST', - path: "auth/challenges/{$id}/verify", + path: 'auth/challenges/' . rawurlencode($id) . '/verify', body: $body, options: $options, ); @@ -95,7 +95,7 @@ public function getFactor( ): \WorkOS\Resource\AuthenticationFactor { $response = $this->client->request( method: 'GET', - path: "auth/factors/{$id}", + path: 'auth/factors/' . rawurlencode($id), options: $options, ); return AuthenticationFactor::fromArray($response); @@ -115,7 +115,7 @@ public function deleteFactor( ): void { $this->client->request( method: 'DELETE', - path: "auth/factors/{$id}", + path: 'auth/factors/' . rawurlencode($id), options: $options, ); } @@ -139,7 +139,7 @@ public function challengeFactor( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "auth/factors/{$id}/challenge", + path: 'auth/factors/' . rawurlencode($id) . '/challenge', body: $body, options: $options, ); @@ -174,7 +174,7 @@ public function listUserAuthFactors( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "user_management/users/{$userlandUserId}/auth_factors", + path: 'user_management/users/' . rawurlencode($userlandUserId) . '/auth_factors', query: $query, modelClass: AuthenticationFactor::class, options: $options, @@ -209,7 +209,7 @@ public function createUserAuthFactor( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "user_management/users/{$userlandUserId}/auth_factors", + path: 'user_management/users/' . rawurlencode($userlandUserId) . '/auth_factors', body: $body, options: $options, ); diff --git a/lib/Service/OrganizationDomains.php b/lib/Service/OrganizationDomains.php index f1bc1b88..ebdb60ff 100644 --- a/lib/Service/OrganizationDomains.php +++ b/lib/Service/OrganizationDomains.php @@ -57,7 +57,7 @@ public function getOrganizationDomain( ): \WorkOS\Resource\OrganizationDomainStandAlone { $response = $this->client->request( method: 'GET', - path: "organization_domains/{$id}", + path: 'organization_domains/' . rawurlencode($id), options: $options, ); return OrganizationDomainStandAlone::fromArray($response); @@ -77,7 +77,7 @@ public function deleteOrganizationDomain( ): void { $this->client->request( method: 'DELETE', - path: "organization_domains/{$id}", + path: 'organization_domains/' . rawurlencode($id), options: $options, ); } @@ -96,7 +96,7 @@ public function verifyOrganizationDomain( ): \WorkOS\Resource\OrganizationDomainStandAlone { $response = $this->client->request( method: 'POST', - path: "organization_domains/{$id}/verify", + path: 'organization_domains/' . rawurlencode($id) . '/verify', options: $options, ); return OrganizationDomainStandAlone::fromArray($response); diff --git a/lib/Service/Organizations.php b/lib/Service/Organizations.php index 9ae36893..71db6291 100644 --- a/lib/Service/Organizations.php +++ b/lib/Service/Organizations.php @@ -108,7 +108,7 @@ public function getOrganizationByExternalId( ): \WorkOS\Resource\Organization { $response = $this->client->request( method: 'GET', - path: "organizations/external_id/{$externalId}", + path: 'organizations/external_id/' . rawurlencode($externalId), options: $options, ); return Organization::fromArray($response); @@ -128,7 +128,7 @@ public function getOrganization( ): \WorkOS\Resource\Organization { $response = $this->client->request( method: 'GET', - path: "organizations/{$id}", + path: 'organizations/' . rawurlencode($id), options: $options, ); return Organization::fromArray($response); @@ -171,7 +171,7 @@ public function updateOrganization( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PUT', - path: "organizations/{$id}", + path: 'organizations/' . rawurlencode($id), body: $body, options: $options, ); @@ -192,7 +192,7 @@ public function deleteOrganization( ): void { $this->client->request( method: 'DELETE', - path: "organizations/{$id}", + path: 'organizations/' . rawurlencode($id), options: $options, ); } @@ -211,7 +211,7 @@ public function getAuditLogConfiguration( ): \WorkOS\Resource\AuditLogConfiguration { $response = $this->client->request( method: 'GET', - path: "organizations/{$id}/audit_log_configuration", + path: 'organizations/' . rawurlencode($id) . '/audit_log_configuration', options: $options, ); return AuditLogConfiguration::fromArray($response); diff --git a/lib/Service/Pipes.php b/lib/Service/Pipes.php index 7ef9e7d5..398d251d 100644 --- a/lib/Service/Pipes.php +++ b/lib/Service/Pipes.php @@ -43,7 +43,7 @@ public function authorizeDataIntegration( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "data-integrations/{$slug}/authorize", + path: 'data-integrations/' . rawurlencode($slug) . '/authorize', body: $body, options: $options, ); @@ -72,7 +72,7 @@ public function createDataIntegrationToken( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "data-integrations/{$slug}/token", + path: 'data-integrations/' . rawurlencode($slug) . '/token', body: $body, options: $options, ); @@ -100,7 +100,7 @@ public function getUserConnectedAccount( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'GET', - path: "user_management/users/{$userId}/connected_accounts/{$slug}", + path: 'user_management/users/' . rawurlencode($userId) . '/connected_accounts/' . rawurlencode($slug), query: $query, options: $options, ); @@ -128,7 +128,7 @@ public function deleteUserConnectedAccount( ], fn ($v) => $v !== null); $this->client->request( method: 'DELETE', - path: "user_management/users/{$userId}/connected_accounts/{$slug}", + path: 'user_management/users/' . rawurlencode($userId) . '/connected_accounts/' . rawurlencode($slug), query: $query, options: $options, ); @@ -153,7 +153,7 @@ public function listUserDataProviders( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'GET', - path: "user_management/users/{$userId}/data_providers", + path: 'user_management/users/' . rawurlencode($userId) . '/data_providers', query: $query, options: $options, ); diff --git a/lib/Service/Radar.php b/lib/Service/Radar.php index d6a8439a..c20c7b05 100644 --- a/lib/Service/Radar.php +++ b/lib/Service/Radar.php @@ -80,7 +80,7 @@ public function updateAttempt( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PUT', - path: "radar/attempts/{$id}", + path: 'radar/attempts/' . rawurlencode($id), body: $body, options: $options, ); @@ -108,7 +108,7 @@ public function addListEntry( ]; $response = $this->client->request( method: 'POST', - path: "radar/lists/{$type->value}/{$action->value}", + path: 'radar/lists/' . rawurlencode($type->value) . '/' . rawurlencode($action->value), body: $body, options: $options, ); @@ -136,7 +136,7 @@ public function removeListEntry( ]; $this->client->request( method: 'DELETE', - path: "radar/lists/{$type->value}/{$action->value}", + path: 'radar/lists/' . rawurlencode($type->value) . '/' . rawurlencode($action->value), body: $body, options: $options, ); diff --git a/lib/Service/SSO.php b/lib/Service/SSO.php index 6c7ded53..18a99ce9 100644 --- a/lib/Service/SSO.php +++ b/lib/Service/SSO.php @@ -77,7 +77,7 @@ public function getConnection( ): \WorkOS\Resource\Connection { $response = $this->client->request( method: 'GET', - path: "connections/{$id}", + path: 'connections/' . rawurlencode($id), options: $options, ); return Connection::fromArray($response); @@ -97,7 +97,7 @@ public function deleteConnection( ): void { $this->client->request( method: 'DELETE', - path: "connections/{$id}", + path: 'connections/' . rawurlencode($id), options: $options, ); } diff --git a/lib/Service/UserManagement.php b/lib/Service/UserManagement.php index ac43d0b3..29e9041d 100644 --- a/lib/Service/UserManagement.php +++ b/lib/Service/UserManagement.php @@ -23,6 +23,8 @@ use WorkOS\Resource\ResetPasswordResponse; use WorkOS\Resource\SendVerificationEmailResponse; use WorkOS\Resource\User; +use WorkOS\Resource\UserApiKey; +use WorkOS\Resource\UserApiKeyWithValue; use WorkOS\Resource\UserIdentitiesGetItem; use WorkOS\Resource\UserInvite; use WorkOS\Resource\UserOrganizationMembership; @@ -50,7 +52,7 @@ public function getJwks( ): \WorkOS\Resource\JwksResponse { $response = $this->client->request( method: 'GET', - path: "sso/jwks/{$clientId}", + path: 'sso/jwks/' . rawurlencode($clientId), options: $options, ); return JwksResponse::fromArray($response); @@ -528,7 +530,7 @@ public function getEmailVerification( ): \WorkOS\Resource\EmailVerification { $response = $this->client->request( method: 'GET', - path: "user_management/email_verification/{$id}", + path: 'user_management/email_verification/' . rawurlencode($id), options: $options, ); return EmailVerification::fromArray($response); @@ -599,7 +601,7 @@ public function getPasswordReset( ): \WorkOS\Resource\PasswordReset { $response = $this->client->request( method: 'GET', - path: "user_management/password_reset/{$id}", + path: 'user_management/password_reset/' . rawurlencode($id), options: $options, ); return PasswordReset::fromArray($response); @@ -708,7 +710,7 @@ public function getUserByExternalId( ): \WorkOS\Resource\User { $response = $this->client->request( method: 'GET', - path: "user_management/users/external_id/{$externalId}", + path: 'user_management/users/external_id/' . rawurlencode($externalId), options: $options, ); return User::fromArray($response); @@ -728,7 +730,7 @@ public function getUser( ): \WorkOS\Resource\User { $response = $this->client->request( method: 'GET', - path: "user_management/users/{$id}", + path: 'user_management/users/' . rawurlencode($id), options: $options, ); return User::fromArray($response); @@ -779,7 +781,7 @@ public function updateUser( } $response = $this->client->request( method: 'PUT', - path: "user_management/users/{$id}", + path: 'user_management/users/' . rawurlencode($id), body: $body, options: $options, ); @@ -800,7 +802,7 @@ public function deleteUser( ): void { $this->client->request( method: 'DELETE', - path: "user_management/users/{$id}", + path: 'user_management/users/' . rawurlencode($id), options: $options, ); } @@ -824,7 +826,7 @@ public function confirmEmailChange( ]; $response = $this->client->request( method: 'POST', - path: "user_management/users/{$id}/email_change/confirm", + path: 'user_management/users/' . rawurlencode($id) . '/email_change/confirm', body: $body, options: $options, ); @@ -850,7 +852,7 @@ public function sendEmailChange( ]; $response = $this->client->request( method: 'POST', - path: "user_management/users/{$id}/email_change/send", + path: 'user_management/users/' . rawurlencode($id) . '/email_change/send', body: $body, options: $options, ); @@ -876,7 +878,7 @@ public function verifyEmail( ]; $response = $this->client->request( method: 'POST', - path: "user_management/users/{$id}/email_verification/confirm", + path: 'user_management/users/' . rawurlencode($id) . '/email_verification/confirm', body: $body, options: $options, ); @@ -897,7 +899,7 @@ public function sendVerificationEmail( ): \WorkOS\Resource\SendVerificationEmailResponse { $response = $this->client->request( method: 'POST', - path: "user_management/users/{$id}/email_verification/send", + path: 'user_management/users/' . rawurlencode($id) . '/email_verification/send', options: $options, ); return SendVerificationEmailResponse::fromArray($response); @@ -917,7 +919,7 @@ public function getUserIdentities( ): array { $response = $this->client->request( method: 'GET', - path: "user_management/users/{$id}/identities", + path: 'user_management/users/' . rawurlencode($id) . '/identities', options: $options, ); return array_map(fn ($item) => UserIdentitiesGetItem::fromArray($item), $response); @@ -951,7 +953,7 @@ public function listSessions( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "user_management/users/{$id}/sessions", + path: 'user_management/users/' . rawurlencode($id) . '/sessions', query: $query, modelClass: UserSessionsListItem::class, options: $options, @@ -1050,7 +1052,7 @@ public function findInvitationByToken( ): \WorkOS\Resource\UserInvite { $response = $this->client->request( method: 'GET', - path: "user_management/invitations/by_token/{$token}", + path: 'user_management/invitations/by_token/' . rawurlencode($token), options: $options, ); return UserInvite::fromArray($response); @@ -1070,7 +1072,7 @@ public function getInvitation( ): \WorkOS\Resource\UserInvite { $response = $this->client->request( method: 'GET', - path: "user_management/invitations/{$id}", + path: 'user_management/invitations/' . rawurlencode($id), options: $options, ); return UserInvite::fromArray($response); @@ -1090,7 +1092,7 @@ public function acceptInvitation( ): \WorkOS\Resource\Invitation { $response = $this->client->request( method: 'POST', - path: "user_management/invitations/{$id}/accept", + path: 'user_management/invitations/' . rawurlencode($id) . '/accept', options: $options, ); return Invitation::fromArray($response); @@ -1115,7 +1117,7 @@ public function resendInvitation( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'POST', - path: "user_management/invitations/{$id}/resend", + path: 'user_management/invitations/' . rawurlencode($id) . '/resend', body: $body, options: $options, ); @@ -1136,12 +1138,30 @@ public function revokeInvitation( ): \WorkOS\Resource\Invitation { $response = $this->client->request( method: 'POST', - path: "user_management/invitations/{$id}/revoke", + path: 'user_management/invitations/' . rawurlencode($id) . '/revoke', options: $options, ); return Invitation::fromArray($response); } + /** + * Get JWT template + * + * Get the JWT template for the current environment. + * @return \WorkOS\Resource\JWTTemplateResponse + * @throws \WorkOS\Exception\WorkOSException + */ + public function listJWTTemplate( + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\JWTTemplateResponse { + $response = $this->client->request( + method: 'GET', + path: 'user_management/jwt_template', + options: $options, + ); + return JWTTemplateResponse::fromArray($response); + } + /** * Update JWT template * @@ -1207,7 +1227,7 @@ public function getMagicAuth( ): \WorkOS\Resource\MagicAuth { $response = $this->client->request( method: 'GET', - path: "user_management/magic_auth/{$id}", + path: 'user_management/magic_auth/' . rawurlencode($id), options: $options, ); return MagicAuth::fromArray($response); @@ -1305,7 +1325,7 @@ public function getOrganizationMembership( ): \WorkOS\Resource\UserOrganizationMembership { $response = $this->client->request( method: 'GET', - path: "user_management/organization_memberships/{$id}", + path: 'user_management/organization_memberships/' . rawurlencode($id), options: $options, ); return UserOrganizationMembership::fromArray($response); @@ -1334,7 +1354,7 @@ public function updateOrganizationMembership( } $response = $this->client->request( method: 'PUT', - path: "user_management/organization_memberships/{$id}", + path: 'user_management/organization_memberships/' . rawurlencode($id), body: $body, options: $options, ); @@ -1355,7 +1375,7 @@ public function deleteOrganizationMembership( ): void { $this->client->request( method: 'DELETE', - path: "user_management/organization_memberships/{$id}", + path: 'user_management/organization_memberships/' . rawurlencode($id), options: $options, ); } @@ -1379,7 +1399,7 @@ public function deactivateOrganizationMembership( ): \WorkOS\Resource\OrganizationMembership { $response = $this->client->request( method: 'PUT', - path: "user_management/organization_memberships/{$id}/deactivate", + path: 'user_management/organization_memberships/' . rawurlencode($id) . '/deactivate', options: $options, ); return OrganizationMembership::fromArray($response); @@ -1404,7 +1424,7 @@ public function reactivateOrganizationMembership( ): \WorkOS\Resource\UserOrganizationMembership { $response = $this->client->request( method: 'PUT', - path: "user_management/organization_memberships/{$id}/reactivate", + path: 'user_management/organization_memberships/' . rawurlencode($id) . '/reactivate', options: $options, ); return UserOrganizationMembership::fromArray($response); @@ -1462,7 +1482,7 @@ public function listUserAuthorizedApplications( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "user_management/users/{$userId}/authorized_applications", + path: 'user_management/users/' . rawurlencode($userId) . '/authorized_applications', query: $query, modelClass: AuthorizedConnectApplicationListData::class, options: $options, @@ -1485,8 +1505,78 @@ public function deleteUserAuthorizedApplication( ): void { $this->client->request( method: 'DELETE', - path: "user_management/users/{$userId}/authorized_applications/{$applicationId}", + path: 'user_management/users/' . rawurlencode($userId) . '/authorized_applications/' . rawurlencode($applicationId), + options: $options, + ); + } + + /** + * List API keys for a user + * + * Get a list of API keys owned by a specific user. + * @param string $userId Unique identifier of the user. + * @param string|null $before An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. + * @param string|null $after An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. + * @param int|null $limit Upper limit on the number of objects to return, between `1` and `100`. Defaults to 10. + * @param \WorkOS\Resource\EventsOrder $order Order the results by the creation time. Defaults to "desc". + * @param string|null $organizationId The ID of the organization to filter user API keys by. When provided, only API keys created against that organization membership are returned. + * @return \WorkOS\PaginatedResponse<\WorkOS\Resource\UserApiKey> + * @throws \WorkOS\Exception\WorkOSException + */ + public function listUserApiKeys( + string $userId, + ?string $before = null, + ?string $after = null, + ?int $limit = null, + \WorkOS\Resource\EventsOrder $order = \WorkOS\Resource\EventsOrder::Desc, + ?string $organizationId = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\PaginatedResponse { + $query = array_filter([ + 'before' => $before, + 'after' => $after, + 'limit' => $limit, + 'order' => $order->value, + 'organization_id' => $organizationId, + ], fn ($v) => $v !== null); + return $this->client->requestPage( + method: 'GET', + path: 'user_management/users/' . rawurlencode($userId) . '/api_keys', + query: $query, + modelClass: UserApiKey::class, + options: $options, + ); + } + + /** + * Create an API key for a user + * + * Create a new API key owned by a user. The user must have an active membership in the specified organization. + * @param string $userId Unique identifier of the user. + * @param string $name A descriptive name for the API key. + * @param string $organizationId The ID of the organization the user API key is associated with. The user must have an active membership in this organization. + * @param array|null $permissions The permission slugs to assign to the API key. Each permission must be enabled for user API keys. + * @return \WorkOS\Resource\UserApiKeyWithValue + * @throws \WorkOS\Exception\WorkOSException + */ + public function createUserApiKey( + string $userId, + string $name, + string $organizationId, + ?array $permissions = null, + ?\WorkOS\RequestOptions $options = null, + ): \WorkOS\Resource\UserApiKeyWithValue { + $body = array_filter([ + 'name' => $name, + 'organization_id' => $organizationId, + 'permissions' => $permissions, + ], fn ($v) => $v !== null); + $response = $this->client->request( + method: 'POST', + path: 'user_management/users/' . rawurlencode($userId) . '/api_keys', + body: $body, options: $options, ); + return UserApiKeyWithValue::fromArray($response); } } diff --git a/lib/Service/UserManagementOrganizationMembershipGroups.php b/lib/Service/UserManagementOrganizationMembershipGroups.php index 1179033a..bb908a62 100644 --- a/lib/Service/UserManagementOrganizationMembershipGroups.php +++ b/lib/Service/UserManagementOrganizationMembershipGroups.php @@ -43,7 +43,7 @@ public function listOrganizationMembershipGroups( ], fn ($v) => $v !== null); return $this->client->requestPage( method: 'GET', - path: "user_management/organization_memberships/{$omId}/groups", + path: 'user_management/organization_memberships/' . rawurlencode($omId) . '/groups', query: $query, modelClass: Group::class, options: $options, diff --git a/lib/Service/Webhooks.php b/lib/Service/Webhooks.php index a6bcee24..c77b178e 100644 --- a/lib/Service/Webhooks.php +++ b/lib/Service/Webhooks.php @@ -100,7 +100,7 @@ public function updateWebhookEndpoint( ], fn ($v) => $v !== null); $response = $this->client->request( method: 'PATCH', - path: "webhook_endpoints/{$id}", + path: 'webhook_endpoints/' . rawurlencode($id), body: $body, options: $options, ); @@ -121,7 +121,7 @@ public function deleteWebhookEndpoint( ): void { $this->client->request( method: 'DELETE', - path: "webhook_endpoints/{$id}", + path: 'webhook_endpoints/' . rawurlencode($id), options: $options, ); } diff --git a/lib/WorkOS.php b/lib/WorkOS.php index c4269869..66cb71e7 100644 --- a/lib/WorkOS.php +++ b/lib/WorkOS.php @@ -51,7 +51,6 @@ public static function setClientId(?string $id): void { self::$clientId = $id; } - private ?Service\ApiKeys $apiKeys = null; private ?Service\MultiFactorAuth $multiFactorAuth = null; private ?Service\Connect $connect = null; private ?Service\Authorization $authorization = null; @@ -62,6 +61,7 @@ public static function setClientId(?string $id): void private ?Service\FeatureFlags $featureFlags = null; private ?Service\OrganizationDomains $organizationDomains = null; private ?Service\Organizations $organizations = null; + private ?Service\ApiKeys $apiKeys = null; private ?Service\Groups $groups = null; private ?Service\AdminPortal $adminPortal = null; private ?Service\Radar $radar = null; @@ -85,11 +85,6 @@ public function __construct( $this->httpClient = new HttpClient($apiKey, $clientId, $baseUrl, $timeout, $maxRetries, $handler, $userAgent); } - public function apiKeys(): ApiKeys - { - return $this->apiKeys ??= new Service\ApiKeys($this->httpClient); - } - public function multiFactorAuth(): MultiFactorAuth { return $this->multiFactorAuth ??= new Service\MultiFactorAuth($this->httpClient); @@ -140,6 +135,11 @@ public function organizations(): Organizations return $this->organizations ??= new Service\Organizations($this->httpClient); } + public function apiKeys(): ApiKeys + { + return $this->apiKeys ??= new Service\ApiKeys($this->httpClient); + } + public function groups(): Groups { return $this->groups ??= new Service\Groups($this->httpClient); diff --git a/tests/Fixtures/create_user_api_key.json b/tests/Fixtures/create_user_api_key.json new file mode 100644 index 00000000..4bdce131 --- /dev/null +++ b/tests/Fixtures/create_user_api_key.json @@ -0,0 +1,8 @@ +{ + "name": "Production API Key", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", + "permissions": [ + "posts:read", + "posts:write" + ] +} diff --git a/tests/Fixtures/directory_user.json b/tests/Fixtures/directory_user.json index 68d037ee..54b60741 100644 --- a/tests/Fixtures/directory_user.json +++ b/tests/Fixtures/directory_user.json @@ -33,5 +33,6 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" } diff --git a/tests/Fixtures/directory_user_with_groups.json b/tests/Fixtures/directory_user_with_groups.json index d7d35220..d48e0900 100644 --- a/tests/Fixtures/directory_user_with_groups.json +++ b/tests/Fixtures/directory_user_with_groups.json @@ -48,5 +48,6 @@ "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z" } - ] + ], + "name": "Marcelina Davis" } diff --git a/tests/Fixtures/dsync_group_user_added.json b/tests/Fixtures/dsync_group_user_added.json index 61c5aac6..5405b4c7 100644 --- a/tests/Fixtures/dsync_group_user_added.json +++ b/tests/Fixtures/dsync_group_user_added.json @@ -38,7 +38,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "group": { "object": "directory_group", diff --git a/tests/Fixtures/dsync_group_user_added_data.json b/tests/Fixtures/dsync_group_user_added_data.json index 5ef37883..8895262e 100644 --- a/tests/Fixtures/dsync_group_user_added_data.json +++ b/tests/Fixtures/dsync_group_user_added_data.json @@ -35,7 +35,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "group": { "object": "directory_group", diff --git a/tests/Fixtures/dsync_group_user_removed.json b/tests/Fixtures/dsync_group_user_removed.json index 3b991f47..cc50e53a 100644 --- a/tests/Fixtures/dsync_group_user_removed.json +++ b/tests/Fixtures/dsync_group_user_removed.json @@ -38,7 +38,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "group": { "object": "directory_group", diff --git a/tests/Fixtures/dsync_group_user_removed_data.json b/tests/Fixtures/dsync_group_user_removed_data.json index 5ef37883..8895262e 100644 --- a/tests/Fixtures/dsync_group_user_removed_data.json +++ b/tests/Fixtures/dsync_group_user_removed_data.json @@ -35,7 +35,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "group": { "object": "directory_group", diff --git a/tests/Fixtures/dsync_user_created.json b/tests/Fixtures/dsync_user_created.json index aa1bbc76..8ca23073 100644 --- a/tests/Fixtures/dsync_user_created.json +++ b/tests/Fixtures/dsync_user_created.json @@ -36,7 +36,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/tests/Fixtures/dsync_user_deleted.json b/tests/Fixtures/dsync_user_deleted.json index 26942d25..f702ef3a 100644 --- a/tests/Fixtures/dsync_user_deleted.json +++ b/tests/Fixtures/dsync_user_deleted.json @@ -36,7 +36,8 @@ } ], "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "name": "Marcelina Davis" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/tests/Fixtures/dsync_user_updated.json b/tests/Fixtures/dsync_user_updated.json index 6c0266bf..27eb02f1 100644 --- a/tests/Fixtures/dsync_user_updated.json +++ b/tests/Fixtures/dsync_user_updated.json @@ -39,7 +39,8 @@ "updated_at": "2026-01-15T12:00:00.000Z", "previous_attributes": { "key": {} - } + }, + "name": "Marcelina Davis" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/tests/Fixtures/dsync_user_updated_data.json b/tests/Fixtures/dsync_user_updated_data.json index 0073a535..79662824 100644 --- a/tests/Fixtures/dsync_user_updated_data.json +++ b/tests/Fixtures/dsync_user_updated_data.json @@ -36,5 +36,6 @@ "updated_at": "2026-01-15T12:00:00.000Z", "previous_attributes": { "key": {} - } + }, + "name": "Marcelina Davis" } diff --git a/tests/Fixtures/jwt_template_response.json b/tests/Fixtures/jwt_template_response.json index b691ce73..00ce7dab 100644 --- a/tests/Fixtures/jwt_template_response.json +++ b/tests/Fixtures/jwt_template_response.json @@ -1,6 +1,6 @@ { "object": "jwt_template", - "content": "{\"iss\": \"{{environment.id}}\", \"sub\": \"{{user.id}}\"}", + "content": "{\"urn:myapp:full_name\": \"{{user.first_name}} {{user.last_name}}\", \"urn:myapp:email\": \"{{user.email}}\"}", "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z" } diff --git a/tests/Fixtures/list_directory_user_with_groups.json b/tests/Fixtures/list_directory_user_with_groups.json index 58432bad..dbb44d56 100644 --- a/tests/Fixtures/list_directory_user_with_groups.json +++ b/tests/Fixtures/list_directory_user_with_groups.json @@ -9,6 +9,7 @@ "email": "marcelina.davis@example.com", "first_name": "Marcelina", "last_name": "Davis", + "name": "Marcelina Davis", "emails": [ { "primary": true, diff --git a/tests/Fixtures/list_organization_api_key.json b/tests/Fixtures/list_organization_api_key.json new file mode 100644 index 00000000..f6b9c99c --- /dev/null +++ b/tests/Fixtures/list_organization_api_key.json @@ -0,0 +1,25 @@ +{ + "data": [ + { + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "organization", + "id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/tests/Fixtures/list_user_api_key.json b/tests/Fixtures/list_user_api_key.json new file mode 100644 index 00000000..a6409aaa --- /dev/null +++ b/tests/Fixtures/list_user_api_key.json @@ -0,0 +1,26 @@ +{ + "data": [ + { + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "user", + "id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/tests/Fixtures/list_user_organization_membership.json b/tests/Fixtures/list_user_organization_membership.json index cdb823aa..b0764c60 100644 --- a/tests/Fixtures/list_user_organization_membership.json +++ b/tests/Fixtures/list_user_organization_membership.json @@ -3,7 +3,7 @@ { "object": "organization_membership", "id": "om_01HXYZ123456789ABCDEFGHIJ", - "user_id": "user_01EHQTV6MWP9P1F4ZXGXMC8ABB", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", "status": "active", "directory_managed": false, @@ -17,6 +17,23 @@ "updated_at": "2026-01-15T12:00:00.000Z", "role": { "slug": "admin" + }, + "user": { + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "first_name": "Marcelina", + "last_name": "Davis", + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "email": "marcelina.davis@example.com", + "email_verified": true, + "external_id": "f1ffa2b2-c20b-4d39-be5c-212726e11222", + "metadata": { + "timezone": "America/New_York" + }, + "last_sign_in_at": "2025-06-25T19:07:33.155Z", + "locale": "en-US", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" } } ], diff --git a/tests/Fixtures/list_user_organization_membership_base_list_data.json b/tests/Fixtures/list_user_organization_membership_base_list_data.json index b992a1b9..f6dc992a 100644 --- a/tests/Fixtures/list_user_organization_membership_base_list_data.json +++ b/tests/Fixtures/list_user_organization_membership_base_list_data.json @@ -3,7 +3,7 @@ { "object": "organization_membership", "id": "om_01HXYZ123456789ABCDEFGHIJ", - "user_id": "user_01EHQTV6MWP9P1F4ZXGXMC8ABB", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", "status": "active", "directory_managed": false, @@ -14,7 +14,24 @@ "location": "Brooklyn" }, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "user": { + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "first_name": "Marcelina", + "last_name": "Davis", + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "email": "marcelina.davis@example.com", + "email_verified": true, + "external_id": "f1ffa2b2-c20b-4d39-be5c-212726e11222", + "metadata": { + "timezone": "America/New_York" + }, + "last_sign_in_at": "2025-06-25T19:07:33.155Z", + "locale": "en-US", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } } ], "list_metadata": { diff --git a/tests/Fixtures/organization_api_key.json b/tests/Fixtures/organization_api_key.json new file mode 100644 index 00000000..e05b1db2 --- /dev/null +++ b/tests/Fixtures/organization_api_key.json @@ -0,0 +1,17 @@ +{ + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "organization", + "id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/tests/Fixtures/organization_api_key_owner.json b/tests/Fixtures/organization_api_key_owner.json new file mode 100644 index 00000000..ddbfe81d --- /dev/null +++ b/tests/Fixtures/organization_api_key_owner.json @@ -0,0 +1,4 @@ +{ + "type": "organization", + "id": "org_01EHZNVPK3SFK441A1RGBFSHRT" +} diff --git a/tests/Fixtures/organization_api_key_with_value.json b/tests/Fixtures/organization_api_key_with_value.json new file mode 100644 index 00000000..9c85f194 --- /dev/null +++ b/tests/Fixtures/organization_api_key_with_value.json @@ -0,0 +1,18 @@ +{ + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "organization", + "id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + "value": "sk_abcdefghijklmnop123456" +} diff --git a/tests/Fixtures/organization_api_key_with_value_owner.json b/tests/Fixtures/organization_api_key_with_value_owner.json new file mode 100644 index 00000000..ddbfe81d --- /dev/null +++ b/tests/Fixtures/organization_api_key_with_value_owner.json @@ -0,0 +1,4 @@ +{ + "type": "organization", + "id": "org_01EHZNVPK3SFK441A1RGBFSHRT" +} diff --git a/tests/Fixtures/organization_membership.json b/tests/Fixtures/organization_membership.json index afc05d1e..efba3046 100644 --- a/tests/Fixtures/organization_membership.json +++ b/tests/Fixtures/organization_membership.json @@ -15,5 +15,22 @@ "updated_at": "2026-01-15T12:00:00.000Z", "role": { "slug": "admin" + }, + "user": { + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "first_name": "Marcelina", + "last_name": "Davis", + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "email": "marcelina.davis@example.com", + "email_verified": true, + "external_id": "f1ffa2b2-c20b-4d39-be5c-212726e11222", + "metadata": { + "timezone": "America/New_York" + }, + "last_sign_in_at": "2025-06-25T19:07:33.155Z", + "locale": "en-US", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" } } diff --git a/tests/Fixtures/profile.json b/tests/Fixtures/profile.json index 485a13ce..2efd7924 100644 --- a/tests/Fixtures/profile.json +++ b/tests/Fixtures/profile.json @@ -25,5 +25,6 @@ }, "raw_attributes": { "key": {} - } + }, + "name": "Todd Rundgren" } diff --git a/tests/Fixtures/sso_token_response.json b/tests/Fixtures/sso_token_response.json index 757c3fb1..7d3b7695 100644 --- a/tests/Fixtures/sso_token_response.json +++ b/tests/Fixtures/sso_token_response.json @@ -29,7 +29,8 @@ }, "raw_attributes": { "key": {} - } + }, + "name": "Todd Rundgren" }, "oauth_tokens": { "provider": "GoogleOAuth", diff --git a/tests/Fixtures/update_jwt_template.json b/tests/Fixtures/update_jwt_template.json index bb613667..160996e7 100644 --- a/tests/Fixtures/update_jwt_template.json +++ b/tests/Fixtures/update_jwt_template.json @@ -1,3 +1,3 @@ { - "content": "{\"iss\": \"{{environment.id}}\", \"sub\": \"{{user.id}}\"}" + "content": "{\"urn:myapp:full_name\": \"{{user.first_name}} {{user.last_name}}\", \"urn:myapp:email\": \"{{user.email}}\"}" } diff --git a/tests/Fixtures/user_api_key.json b/tests/Fixtures/user_api_key.json new file mode 100644 index 00000000..0b527caf --- /dev/null +++ b/tests/Fixtures/user_api_key.json @@ -0,0 +1,18 @@ +{ + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "user", + "id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/tests/Fixtures/user_api_key_owner.json b/tests/Fixtures/user_api_key_owner.json new file mode 100644 index 00000000..a0fb2ade --- /dev/null +++ b/tests/Fixtures/user_api_key_owner.json @@ -0,0 +1,5 @@ +{ + "type": "user", + "id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" +} diff --git a/tests/Fixtures/user_api_key_with_value.json b/tests/Fixtures/user_api_key_with_value.json new file mode 100644 index 00000000..99d28c9a --- /dev/null +++ b/tests/Fixtures/user_api_key_with_value.json @@ -0,0 +1,19 @@ +{ + "object": "api_key", + "id": "api_key_01EHZNVPK3SFK441A1RGBFSHRT", + "owner": { + "type": "user", + "id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" + }, + "name": "Production API Key", + "obfuscated_value": "sk_...3456", + "last_used_at": null, + "permissions": [ + "posts:read", + "posts:write" + ], + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + "value": "sk_abcdefghijklmnop123456" +} diff --git a/tests/Fixtures/user_api_key_with_value_owner.json b/tests/Fixtures/user_api_key_with_value_owner.json new file mode 100644 index 00000000..a0fb2ade --- /dev/null +++ b/tests/Fixtures/user_api_key_with_value_owner.json @@ -0,0 +1,5 @@ +{ + "type": "user", + "id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" +} diff --git a/tests/Fixtures/user_organization_membership.json b/tests/Fixtures/user_organization_membership.json index d6acfbe6..184279d9 100644 --- a/tests/Fixtures/user_organization_membership.json +++ b/tests/Fixtures/user_organization_membership.json @@ -1,7 +1,7 @@ { "object": "organization_membership", "id": "om_01HXYZ123456789ABCDEFGHIJ", - "user_id": "user_01EHQTV6MWP9P1F4ZXGXMC8ABB", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", "status": "active", "directory_managed": false, @@ -15,5 +15,22 @@ "updated_at": "2026-01-15T12:00:00.000Z", "role": { "slug": "admin" + }, + "user": { + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "first_name": "Marcelina", + "last_name": "Davis", + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "email": "marcelina.davis@example.com", + "email_verified": true, + "external_id": "f1ffa2b2-c20b-4d39-be5c-212726e11222", + "metadata": { + "timezone": "America/New_York" + }, + "last_sign_in_at": "2025-06-25T19:07:33.155Z", + "locale": "en-US", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" } } diff --git a/tests/Fixtures/user_organization_membership_base_list_data.json b/tests/Fixtures/user_organization_membership_base_list_data.json index a4e9ebde..f3a20339 100644 --- a/tests/Fixtures/user_organization_membership_base_list_data.json +++ b/tests/Fixtures/user_organization_membership_base_list_data.json @@ -1,7 +1,7 @@ { "object": "organization_membership", "id": "om_01HXYZ123456789ABCDEFGHIJ", - "user_id": "user_01EHQTV6MWP9P1F4ZXGXMC8ABB", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", "status": "active", "directory_managed": false, @@ -12,5 +12,22 @@ "location": "Brooklyn" }, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "user": { + "object": "user", + "id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "first_name": "Marcelina", + "last_name": "Davis", + "profile_picture_url": "https://workoscdn.com/images/v1/123abc", + "email": "marcelina.davis@example.com", + "email_verified": true, + "external_id": "f1ffa2b2-c20b-4d39-be5c-212726e11222", + "metadata": { + "timezone": "America/New_York" + }, + "last_sign_in_at": "2025-06-25T19:07:33.155Z", + "locale": "en-US", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } } diff --git a/tests/Fixtures/vault_byok_key_deleted.json b/tests/Fixtures/vault_byok_key_deleted.json new file mode 100644 index 00000000..cd179cb3 --- /dev/null +++ b/tests/Fixtures/vault_byok_key_deleted.json @@ -0,0 +1,30 @@ +{ + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "vault.byok_key.deleted", + "data": { + "organization_id": "org_01EHT88Z8J8795GZNQ4ZP1J81T", + "key_provider": "AWS_KMS" + }, + "created_at": "2026-01-15T12:00:00.000Z", + "context": { + "google_analytics_client_id": "GA1.2.1234567890.1234567890", + "google_analytics_sessions": [ + { + "containerId": "GTM-ABCDEF", + "sessionId": "1234567890", + "sessionNumber": "1" + } + ], + "ajs_anonymous_id": "ajs_anon_01EHWNCE74X7JSDV0X3SZ3KJNY", + "client_id": "client_01EHWNCE74X7JSDV0X3SZ3KJNY", + "actor": { + "id": "user_01EHWNCE74X7JSDV0X3SZ3KJNY", + "source": "api", + "name": "Jane Doe" + }, + "previous_attributes": { + "key": {} + } + }, + "object": "event" +} diff --git a/tests/Fixtures/vault_byok_key_deleted_data.json b/tests/Fixtures/vault_byok_key_deleted_data.json new file mode 100644 index 00000000..ceb94fe7 --- /dev/null +++ b/tests/Fixtures/vault_byok_key_deleted_data.json @@ -0,0 +1,4 @@ +{ + "organization_id": "org_01EHT88Z8J8795GZNQ4ZP1J81T", + "key_provider": "AWS_KMS" +} diff --git a/tests/Service/ApiKeysTest.php b/tests/Service/ApiKeysTest.php index 352270c5..a1797080 100644 --- a/tests/Service/ApiKeysTest.php +++ b/tests/Service/ApiKeysTest.php @@ -13,32 +13,9 @@ class ApiKeysTest extends TestCase { use TestHelper; - public function testCreateValidation(): void - { - $fixture = $this->loadFixture('api_key_validation_response'); - $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); - $result = $client->apiKeys()->createValidation(value: 'test_value'); - $this->assertInstanceOf(\WorkOS\Resource\ApiKeyValidationResponse::class, $result); - $this->assertIsArray($result->toArray()); - $request = $this->getLastRequest(); - $this->assertSame('POST', $request->getMethod()); - $this->assertStringEndsWith('api_keys/validations', $request->getUri()->getPath()); - $body = json_decode((string) $request->getBody(), true); - $this->assertSame('test_value', $body['value']); - } - - public function testDeleteApiKey(): void - { - $client = $this->createMockClient([['status' => 204]]); - $client->apiKeys()->deleteApiKey('test_id'); - $request = $this->getLastRequest(); - $this->assertSame('DELETE', $request->getMethod()); - $this->assertStringEndsWith('api_keys/test_id', $request->getUri()->getPath()); - } - public function testListOrganizationApiKeys(): void { - $fixture = $this->loadFixture('list_api_key'); + $fixture = $this->loadFixture('list_organization_api_key'); $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); $result = $client->apiKeys()->listOrganizationApiKeys('test_organizationId', before: 'test_value', after: 'test_value', limit: 1, order: \WorkOS\Resource\EventsOrder::Normal); $this->assertInstanceOf(\WorkOS\PaginatedResponse::class, $result); @@ -54,10 +31,10 @@ public function testListOrganizationApiKeys(): void public function testCreateOrganizationApiKey(): void { - $fixture = $this->loadFixture('api_key_with_value'); + $fixture = $this->loadFixture('organization_api_key_with_value'); $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); $result = $client->apiKeys()->createOrganizationApiKey('test_organizationId', name: 'test_value'); - $this->assertInstanceOf(\WorkOS\Resource\ApiKeyWithValue::class, $result); + $this->assertInstanceOf(\WorkOS\Resource\OrganizationApiKeyWithValue::class, $result); $this->assertSame($fixture['id'], $result->id); $this->assertSame($fixture['name'], $result->name); $this->assertIsArray($result->toArray()); @@ -68,9 +45,32 @@ public function testCreateOrganizationApiKey(): void $this->assertSame('test_value', $body['name']); } + public function testCreateValidation(): void + { + $fixture = $this->loadFixture('api_key_validation_response'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->apiKeys()->createValidation(value: 'test_value'); + $this->assertInstanceOf(\WorkOS\Resource\ApiKeyValidationResponse::class, $result); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('POST', $request->getMethod()); + $this->assertStringEndsWith('api_keys/validations', $request->getUri()->getPath()); + $body = json_decode((string) $request->getBody(), true); + $this->assertSame('test_value', $body['value']); + } + + public function testDeleteApiKey(): void + { + $client = $this->createMockClient([['status' => 204]]); + $client->apiKeys()->deleteApiKey('test_id'); + $request = $this->getLastRequest(); + $this->assertSame('DELETE', $request->getMethod()); + $this->assertStringEndsWith('api_keys/test_id', $request->getUri()->getPath()); + } + public function testPaginationBoundary(): void { - $fixture = $this->loadFixture('list_api_key'); + $fixture = $this->loadFixture('list_organization_api_key'); // Ensure cursors are null (first/last page boundary) $fixture['list_metadata']['before'] = null; $fixture['list_metadata']['after'] = null; diff --git a/tests/Service/UserManagementTest.php b/tests/Service/UserManagementTest.php index ada83794..a9d1a10c 100644 --- a/tests/Service/UserManagementTest.php +++ b/tests/Service/UserManagementTest.php @@ -432,6 +432,19 @@ public function testRevokeInvitation(): void $this->assertStringEndsWith('user_management/invitations/test_id/revoke', $request->getUri()->getPath()); } + public function testListJWTTemplate(): void + { + $fixture = $this->loadFixture('jwt_template_response'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->userManagement()->listJWTTemplate(); + $this->assertInstanceOf(\WorkOS\Resource\JWTTemplateResponse::class, $result); + $this->assertSame($fixture['content'], $result->content); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('GET', $request->getMethod()); + $this->assertStringEndsWith('user_management/jwt_template', $request->getUri()->getPath()); + } + public function testUpdateJWTTemplate(): void { $fixture = $this->loadFixture('jwt_template_response'); @@ -618,6 +631,40 @@ public function testDeleteUserAuthorizedApplication(): void $this->assertStringEndsWith('user_management/users/test_user_id/authorized_applications/test_application_id', $request->getUri()->getPath()); } + public function testListUserApiKeys(): void + { + $fixture = $this->loadFixture('list_user_api_key'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->userManagement()->listUserApiKeys('test_userId', before: 'test_value', after: 'test_value', limit: 1, order: \WorkOS\Resource\EventsOrder::Normal, organizationId: 'test_value'); + $this->assertInstanceOf(\WorkOS\PaginatedResponse::class, $result); + $request = $this->getLastRequest(); + $this->assertSame('GET', $request->getMethod()); + $this->assertStringEndsWith('user_management/users/test_userId/api_keys', $request->getUri()->getPath()); + parse_str($request->getUri()->getQuery(), $query); + $this->assertSame('test_value', $query['before']); + $this->assertSame('test_value', $query['after']); + $this->assertArrayHasKey('limit', $query); + $this->assertSame('normal', $query['order']); + $this->assertSame('test_value', $query['organization_id']); + } + + public function testCreateUserApiKey(): void + { + $fixture = $this->loadFixture('user_api_key_with_value'); + $client = $this->createMockClient([['status' => 200, 'body' => $fixture]]); + $result = $client->userManagement()->createUserApiKey('test_userId', name: 'test_value', organizationId: 'test_value'); + $this->assertInstanceOf(\WorkOS\Resource\UserApiKeyWithValue::class, $result); + $this->assertSame($fixture['id'], $result->id); + $this->assertSame($fixture['name'], $result->name); + $this->assertIsArray($result->toArray()); + $request = $this->getLastRequest(); + $this->assertSame('POST', $request->getMethod()); + $this->assertStringEndsWith('user_management/users/test_userId/api_keys', $request->getUri()->getPath()); + $body = json_decode((string) $request->getBody(), true); + $this->assertSame('test_value', $body['name']); + $this->assertSame('test_value', $body['organization_id']); + } + public function testAuthenticateWithPassword(): void { $fixture = $this->loadFixture('authenticate_response');