workos 9.0.0 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.github/workflows/docs.yml +2 -2
  4. data/.github/workflows/lint.yml +2 -2
  5. data/.github/workflows/release-please.yml +49 -66
  6. data/.github/workflows/release.yml +2 -2
  7. data/.last-synced-sha +1 -1
  8. data/.oagen-manifest.json +101 -14
  9. data/.release-please-manifest.json +1 -1
  10. data/.ruby-version +1 -1
  11. data/CHANGELOG.md +89 -0
  12. data/Gemfile.lock +4 -4
  13. data/lib/workos/{directory_sync/dsync_deactivated.rb → api_keys/api_key_updated.rb} +2 -2
  14. data/lib/workos/api_keys/api_key_updated_data.rb +49 -0
  15. data/lib/workos/{directory_sync/dsync_deactivated_data_domain.rb → api_keys/api_key_updated_data_owner.rb} +1 -1
  16. data/lib/workos/api_keys/api_key_updated_data_previous_attribute.rb +18 -0
  17. data/lib/workos/api_keys/expire_api_key.rb +18 -0
  18. data/lib/workos/api_keys.rb +25 -0
  19. data/lib/workos/{types/dsync_deactivated_data_type.rb → authorization/create_group_role_assignment.rb} +1 -3
  20. data/lib/workos/authorization/delete_group_role_assignments_by_criteria.rb +7 -0
  21. data/lib/workos/authorization/group_role_assignment.rb +37 -0
  22. data/lib/workos/authorization/group_role_assignment_list.rb +25 -0
  23. data/lib/workos/authorization/group_role_assignment_resource.rb +25 -0
  24. data/lib/workos/authorization/replace_group_role_assignment_entry.rb +7 -0
  25. data/lib/workos/authorization/replace_group_role_assignments.rb +18 -0
  26. data/lib/workos/authorization/user_role_assignment_resource.rb +1 -19
  27. data/lib/workos/authorization.rb +190 -10
  28. data/lib/workos/base_client.rb +19 -2
  29. data/lib/workos/client.rb +8 -0
  30. data/lib/workos/client_api/client_api_token.rb +22 -0
  31. data/lib/workos/client_api/client_api_token_response.rb +18 -0
  32. data/lib/workos/client_api.rb +39 -0
  33. data/lib/workos/connect/user_object.rb +3 -0
  34. data/lib/workos/connect.rb +1 -1
  35. data/lib/workos/directory_sync/dsync_token_created.rb +34 -0
  36. data/lib/workos/directory_sync/dsync_token_created_data.rb +34 -0
  37. data/lib/workos/directory_sync/dsync_token_revoked.rb +34 -0
  38. data/lib/workos/directory_sync/dsync_token_revoked_data.rb +7 -0
  39. data/lib/workos/directory_sync.rb +2 -2
  40. data/lib/workos/events.rb +1 -1
  41. data/lib/workos/groups.rb +2 -2
  42. data/lib/workos/inflections.rb +0 -1
  43. data/lib/workos/organization_membership_service.rb +2 -2
  44. data/lib/workos/organizations.rb +1 -1
  45. data/lib/workos/pipes/connected_account.rb +6 -0
  46. data/lib/workos/pipes/data_integrations_list_response_data.rb +3 -0
  47. data/lib/workos/pipes/data_integrations_list_response_data_connected_account.rb +6 -0
  48. data/lib/workos/pipes.rb +5 -5
  49. data/lib/workos/pipes_provider/configure_data_integration_body.rb +28 -0
  50. data/lib/workos/pipes_provider/data_integration_configuration_list_response.rb +22 -0
  51. data/lib/workos/{directory_sync/dsync_deactivated_data.rb → pipes_provider/data_integration_configuration_response.rb} +13 -13
  52. data/lib/workos/pipes_provider/data_integration_credentials.rb +31 -0
  53. data/lib/workos/pipes_provider.rb +68 -0
  54. data/lib/workos/types/audit_log_configuration_log_stream_type.rb +2 -1
  55. data/lib/workos/types/connected_account_auth_method.rb +13 -0
  56. data/lib/workos/types/create_webhook_endpoint_events.rb +2 -1
  57. data/lib/workos/types/data_integration_access_token_response_error.rb +2 -2
  58. data/lib/workos/types/data_integration_credentials_credentials_type.rb +14 -0
  59. data/lib/workos/types/{dsync_deactivated_data_state.rb → data_integrations_list_response_data_auth_methods.rb} +1 -1
  60. data/lib/workos/types/data_integrations_list_response_data_connected_account_auth_method.rb +9 -0
  61. data/lib/workos/types/radar_standalone_response_control.rb +1 -2
  62. data/lib/workos/types/widget_session_token_scopes.rb +2 -1
  63. data/lib/workos/user_management/create_user.rb +3 -0
  64. data/lib/workos/user_management/email_change_confirmation_user.rb +3 -0
  65. data/lib/workos/user_management/revoke_session.rb +2 -6
  66. data/lib/workos/user_management/update_user.rb +3 -0
  67. data/lib/workos/user_management/user_api_key_updated_data_owner.rb +7 -0
  68. data/lib/workos/user_management.rb +13 -10
  69. data/lib/workos/vault/{object.rb → vault_object.rb} +1 -1
  70. data/lib/workos/vault.rb +4 -4
  71. data/lib/workos/version.rb +1 -1
  72. data/lib/workos/webhooks.rb +1 -1
  73. data/lib/workos/widgets/widget_session_token_response.rb +1 -12
  74. data/lib/workos.rb +2 -0
  75. data/rbi/workos/{dsync_deactivated.rbi → api_key_updated.rbi} +3 -3
  76. data/rbi/workos/api_key_updated_data.rbi +84 -0
  77. data/rbi/workos/api_key_updated_data_owner.rbi +30 -0
  78. data/rbi/workos/api_key_updated_data_previous_attribute.rbi +24 -0
  79. data/rbi/workos/api_keys.rbi +9 -0
  80. data/rbi/workos/authorization.rbi +63 -0
  81. data/rbi/workos/authorization_code_session_authenticate_request.rbi +2 -2
  82. data/rbi/workos/client.rbi +6 -0
  83. data/rbi/workos/client_api.rbi +22 -0
  84. data/rbi/workos/client_api_token.rbi +30 -0
  85. data/rbi/workos/client_api_token_response.rbi +24 -0
  86. data/rbi/workos/configure_data_integration_body.rbi +42 -0
  87. data/rbi/workos/connected_account.rbi +12 -0
  88. data/rbi/workos/create_group_role_assignment.rbi +42 -0
  89. data/rbi/workos/create_user.rbi +6 -0
  90. data/rbi/workos/data_integration_configuration_list_response.rbi +30 -0
  91. data/rbi/workos/{dsync_deactivated_data.rbi → data_integration_configuration_response.rbi} +21 -21
  92. data/rbi/workos/data_integration_credentials.rbi +48 -0
  93. data/rbi/workos/data_integrations_list_response_data.rbi +6 -0
  94. data/rbi/workos/data_integrations_list_response_data_connected_account.rbi +12 -0
  95. data/rbi/workos/delete_group_role_assignments_by_criteria.rbi +42 -0
  96. data/rbi/workos/dsync_token_created.rbi +54 -0
  97. data/rbi/workos/dsync_token_created_data.rbi +54 -0
  98. data/rbi/workos/dsync_token_revoked.rbi +54 -0
  99. data/rbi/workos/dsync_token_revoked_data.rbi +54 -0
  100. data/rbi/workos/email_change_confirmation_user.rbi +6 -0
  101. data/rbi/workos/expire_api_key.rbi +24 -0
  102. data/rbi/workos/group_role_assignment.rbi +60 -0
  103. data/rbi/workos/group_role_assignment_resource.rbi +36 -0
  104. data/rbi/workos/organization_membership_service.rbi +1 -1
  105. data/rbi/workos/pipes.rbi +2 -2
  106. data/rbi/workos/pipes_provider.rbi +34 -0
  107. data/rbi/workos/refresh_token_session_authenticate_request.rbi +2 -2
  108. data/rbi/workos/replace_group_role_assignment_entry.rbi +42 -0
  109. data/rbi/workos/replace_group_role_assignments.rbi +24 -0
  110. data/rbi/workos/revoke_session.rbi +0 -6
  111. data/rbi/workos/update_user.rbi +6 -0
  112. data/rbi/workos/user.rbi +6 -0
  113. data/rbi/workos/{dsync_deactivated_data_domain.rbi → user_api_key_updated_data_owner.rbi} +5 -5
  114. data/rbi/workos/user_management.rbi +8 -7
  115. data/rbi/workos/user_object.rbi +6 -0
  116. data/rbi/workos/vault.rbi +2 -2
  117. data/rbi/workos/{object.rbi → vault_object.rbi} +1 -1
  118. data/renovate.json +1 -61
  119. data/test/workos/test_api_keys.rb +9 -1
  120. data/test/workos/test_authorization.rb +48 -0
  121. data/test/workos/test_base_client.rb +64 -0
  122. data/test/workos/test_client_api.rb +33 -0
  123. data/test/workos/test_model_round_trip.rb +363 -67
  124. data/test/workos/test_pipes.rb +3 -3
  125. data/test/workos/test_pipes_provider.rb +41 -0
  126. data/test/workos/test_user_management.rb +2 -2
  127. data/test/workos/test_vault.rb +0 -1
  128. metadata +61 -17
  129. /data/lib/workos/{authorization → groups}/user_organization_membership_base_list_data.rb +0 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is auto-generated by oagen. Do not edit.
4
+
5
+ # typed: strong
6
+
7
+ module WorkOS
8
+ class PipesProvider
9
+ sig { params(client: WorkOS::BaseClient).void }
10
+ def initialize(client); end
11
+
12
+ sig do
13
+ params(
14
+ organization_id: String,
15
+ request_options: T::Hash[Symbol, T.untyped]
16
+ ).returns(WorkOS::DataIntegrationConfigurationListResponse)
17
+ end
18
+ def list_organization_data_integration_configurations(organization_id:, request_options:); end
19
+
20
+ sig do
21
+ params(
22
+ organization_id: String,
23
+ slug: String,
24
+ enabled: T.nilable(T::Boolean),
25
+ scopes: T.nilable(T::Array[String]),
26
+ client_id: T.nilable(String),
27
+ client_secret: T.nilable(String),
28
+ request_options: T::Hash[Symbol, T.untyped]
29
+ ).returns(WorkOS::DataIntegrationConfigurationResponse)
30
+ end
31
+ def update_organization_data_integration_configuration(organization_id:, slug:, enabled:, scopes:, client_id:, client_secret:, request_options:); end
32
+
33
+ end
34
+ end
@@ -15,10 +15,10 @@ module WorkOS
15
15
  sig { params(value: String).returns(String) }
16
16
  def client_id=(value); end
17
17
 
18
- sig { returns(String) }
18
+ sig { returns(T.nilable(String)) }
19
19
  def client_secret; end
20
20
 
21
- sig { params(value: String).returns(String) }
21
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
22
22
  def client_secret=(value); end
23
23
 
24
24
  sig { returns(String) }
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is auto-generated by oagen. Do not edit.
4
+
5
+ # typed: strong
6
+
7
+ module WorkOS
8
+ class ReplaceGroupRoleAssignmentEntry
9
+ sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void }
10
+ def initialize(json); end
11
+
12
+ sig { returns(String) }
13
+ def role_slug; end
14
+
15
+ sig { params(value: String).returns(String) }
16
+ def role_slug=(value); end
17
+
18
+ sig { returns(T.nilable(String)) }
19
+ def resource_id; end
20
+
21
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
22
+ def resource_id=(value); end
23
+
24
+ sig { returns(T.nilable(String)) }
25
+ def resource_external_id; end
26
+
27
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
28
+ def resource_external_id=(value); end
29
+
30
+ sig { returns(T.nilable(String)) }
31
+ def resource_type_slug; end
32
+
33
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
34
+ def resource_type_slug=(value); end
35
+
36
+ sig { returns(T::Hash[Symbol, T.untyped]) }
37
+ def to_h; end
38
+
39
+ sig { params(args: T.untyped).returns(String) }
40
+ def to_json(*args); end
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is auto-generated by oagen. Do not edit.
4
+
5
+ # typed: strong
6
+
7
+ module WorkOS
8
+ class ReplaceGroupRoleAssignments
9
+ sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void }
10
+ def initialize(json); end
11
+
12
+ sig { returns(T::Array[WorkOS::ReplaceGroupRoleAssignmentEntry]) }
13
+ def role_assignments; end
14
+
15
+ sig { params(value: T::Array[WorkOS::ReplaceGroupRoleAssignmentEntry]).returns(T::Array[WorkOS::ReplaceGroupRoleAssignmentEntry]) }
16
+ def role_assignments=(value); end
17
+
18
+ sig { returns(T::Hash[Symbol, T.untyped]) }
19
+ def to_h; end
20
+
21
+ sig { params(args: T.untyped).returns(String) }
22
+ def to_json(*args); end
23
+ end
24
+ end
@@ -15,12 +15,6 @@ module WorkOS
15
15
  sig { params(value: String).returns(String) }
16
16
  def session_id=(value); end
17
17
 
18
- sig { returns(T.nilable(String)) }
19
- def return_to; end
20
-
21
- sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
22
- def return_to=(value); end
23
-
24
18
  sig { returns(T::Hash[Symbol, T.untyped]) }
25
19
  def to_h; end
26
20
 
@@ -27,6 +27,12 @@ module WorkOS
27
27
  sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
28
28
  def last_name=(value); end
29
29
 
30
+ sig { returns(T.nilable(String)) }
31
+ def name; end
32
+
33
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
34
+ def name=(value); end
35
+
30
36
  sig { returns(T.nilable(T::Boolean)) }
31
37
  def email_verified; end
32
38
 
data/rbi/workos/user.rbi CHANGED
@@ -33,6 +33,12 @@ module WorkOS
33
33
  sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
34
34
  def last_name=(value); end
35
35
 
36
+ sig { returns(T.nilable(String)) }
37
+ def name; end
38
+
39
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
40
+ def name=(value); end
41
+
36
42
  sig { returns(T.nilable(String)) }
37
43
  def profile_picture_url; end
38
44
 
@@ -5,15 +5,15 @@
5
5
  # typed: strong
6
6
 
7
7
  module WorkOS
8
- class DsyncDeactivatedDataDomain
8
+ class UserApiKeyUpdatedDataOwner
9
9
  sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void }
10
10
  def initialize(json); end
11
11
 
12
12
  sig { returns(String) }
13
- def object; end
13
+ def type; end
14
14
 
15
15
  sig { params(value: String).returns(String) }
16
- def object=(value); end
16
+ def type=(value); end
17
17
 
18
18
  sig { returns(String) }
19
19
  def id; end
@@ -22,10 +22,10 @@ module WorkOS
22
22
  def id=(value); end
23
23
 
24
24
  sig { returns(String) }
25
- def domain; end
25
+ def organization_id; end
26
26
 
27
27
  sig { params(value: String).returns(String) }
28
- def domain=(value); end
28
+ def organization_id=(value); end
29
29
 
30
30
  sig { returns(T::Hash[Symbol, T.untyped]) }
31
31
  def to_h; end
@@ -48,9 +48,9 @@ module WorkOS
48
48
  sig do
49
49
  params(
50
50
  client_id: String,
51
- client_secret: String,
52
51
  grant_type: String,
53
52
  code: String,
53
+ client_secret: T.nilable(String),
54
54
  code_verifier: T.nilable(String),
55
55
  invitation_token: T.nilable(String),
56
56
  ip_address: T.nilable(String),
@@ -59,7 +59,7 @@ module WorkOS
59
59
  request_options: T::Hash[Symbol, T.untyped]
60
60
  ).returns(WorkOS::AuthenticateResponse)
61
61
  end
62
- def create_authenticate(client_id:, client_secret:, grant_type:, code:, code_verifier:, invitation_token:, ip_address:, device_id:, user_agent:, request_options:); end
62
+ def create_authenticate(client_id:, grant_type:, code:, client_secret:, code_verifier:, invitation_token:, ip_address:, device_id:, user_agent:, request_options:); end
63
63
 
64
64
  sig do
65
65
  params(
@@ -72,11 +72,10 @@ module WorkOS
72
72
  sig do
73
73
  params(
74
74
  session_id: String,
75
- return_to: T.nilable(String),
76
75
  request_options: T::Hash[Symbol, T.untyped]
77
76
  ).returns(NilClass)
78
77
  end
79
- def revoke_session(session_id:, return_to:, request_options:); end
78
+ def revoke_session(session_id:, request_options:); end
80
79
 
81
80
  sig do
82
81
  params(
@@ -138,6 +137,7 @@ module WorkOS
138
137
  email: String,
139
138
  first_name: T.nilable(String),
140
139
  last_name: T.nilable(String),
140
+ name: T.nilable(String),
141
141
  email_verified: T.nilable(T::Boolean),
142
142
  metadata: T.nilable(T::Hash[String, String]),
143
143
  external_id: T.nilable(String),
@@ -145,7 +145,7 @@ module WorkOS
145
145
  request_options: T::Hash[Symbol, T.untyped]
146
146
  ).returns(WorkOS::User)
147
147
  end
148
- def create_user(email:, first_name:, last_name:, email_verified:, metadata:, external_id:, password:, request_options:); end
148
+ def create_user(email:, first_name:, last_name:, name:, email_verified:, metadata:, external_id:, password:, request_options:); end
149
149
 
150
150
  sig do
151
151
  params(
@@ -169,6 +169,7 @@ module WorkOS
169
169
  email: T.nilable(String),
170
170
  first_name: T.nilable(String),
171
171
  last_name: T.nilable(String),
172
+ name: T.nilable(String),
172
173
  email_verified: T.nilable(T::Boolean),
173
174
  metadata: T.nilable(T::Hash[String, String]),
174
175
  external_id: T.nilable(String),
@@ -177,7 +178,7 @@ module WorkOS
177
178
  request_options: T::Hash[Symbol, T.untyped]
178
179
  ).returns(WorkOS::User)
179
180
  end
180
- def update_user(id:, email:, first_name:, last_name:, email_verified:, metadata:, external_id:, locale:, password:, request_options:); end
181
+ def update_user(id:, email:, first_name:, last_name:, name:, email_verified:, metadata:, external_id:, locale:, password:, request_options:); end
181
182
 
182
183
  sig do
183
184
  params(
@@ -251,7 +252,7 @@ module WorkOS
251
252
  organization_id: T.nilable(String),
252
253
  email: T.nilable(String),
253
254
  request_options: T::Hash[Symbol, T.untyped]
254
- ).returns(T::Array[WorkOS::UserInvite])
255
+ ).returns(WorkOS::Types::ListStruct)
255
256
  end
256
257
  def list_invitations(before:, after:, limit:, order:, organization_id:, email:, request_options:); end
257
258
 
@@ -33,6 +33,12 @@ module WorkOS
33
33
  sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
34
34
  def last_name=(value); end
35
35
 
36
+ sig { returns(T.nilable(String)) }
37
+ def name; end
38
+
39
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
40
+ def name=(value); end
41
+
36
42
  sig { returns(T.nilable(T::Hash[String, String])) }
37
43
  def metadata; end
38
44
 
data/rbi/workos/vault.rbi CHANGED
@@ -61,7 +61,7 @@ module WorkOS
61
61
  params(
62
62
  name: String,
63
63
  request_options: T::Hash[Symbol, T.untyped]
64
- ).returns(WorkOS::ObjectModel)
64
+ ).returns(WorkOS::VaultObject)
65
65
  end
66
66
  def get_name(name:, request_options:); end
67
67
 
@@ -69,7 +69,7 @@ module WorkOS
69
69
  params(
70
70
  id: String,
71
71
  request_options: T::Hash[Symbol, T.untyped]
72
- ).returns(WorkOS::ObjectModel)
72
+ ).returns(WorkOS::VaultObject)
73
73
  end
74
74
  def get_kv(id:, request_options:); end
75
75
 
@@ -5,7 +5,7 @@
5
5
  # typed: strong
6
6
 
7
7
  module WorkOS
8
- class ObjectModel
8
+ class VaultObject
9
9
  sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void }
10
10
  def initialize(json); end
11
11
 
data/renovate.json CHANGED
@@ -1,66 +1,6 @@
1
1
  {
2
2
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
3
  "extends": [
4
- "github>workos/renovate-config"
5
- ],
6
- "dependencyDashboard": false,
7
- "schedule": [
8
- "on the 15th day of the month before 12pm"
9
- ],
10
- "timezone": "UTC",
11
- "rebaseWhen": "conflicted",
12
- "packageRules": [
13
- {
14
- "matchManagers": [
15
- "github-actions"
16
- ],
17
- "pinDigests": true,
18
- "extractVersion": "^v(?<version>\\d+\\.\\d+\\.\\d+)$"
19
- },
20
- {
21
- "matchUpdateTypes": [
22
- "minor",
23
- "patch"
24
- ],
25
- "automerge": true,
26
- "groupName": "minor and patch updates"
27
- },
28
- {
29
- "matchUpdateTypes": [
30
- "major"
31
- ],
32
- "automerge": false
33
- },
34
- {
35
- "matchUpdateTypes": [
36
- "digest"
37
- ],
38
- "automerge": false
39
- },
40
- {
41
- "matchManagers": [
42
- "github-actions"
43
- ],
44
- "matchUpdateTypes": [
45
- "minor",
46
- "patch",
47
- "digest",
48
- "pinDigest"
49
- ],
50
- "groupName": "github actions non-major",
51
- "groupSlug": "github-actions-non-major",
52
- "automerge": true
53
- },
54
- {
55
- "matchManagers": [
56
- "github-actions"
57
- ],
58
- "matchUpdateTypes": [
59
- "major"
60
- ],
61
- "groupName": "github actions major",
62
- "groupSlug": "github-actions-major",
63
- "automerge": false
64
- }
4
+ "github>workos/renovate-config:public"
65
5
  ]
66
6
  }
@@ -39,12 +39,20 @@ class ApiKeysTest < Minitest::Test
39
39
  assert_nil result
40
40
  end
41
41
 
42
+ def test_create_api_key_expire_returns_expected_result
43
+ stub_request(:post, %r{\Ahttps://api\.workos\.com/api_keys/stub/expire(\?|\z)})
44
+ .to_return(body: "{}", status: 200)
45
+ result = @client.api_keys.create_api_key_expire(id: "stub")
46
+ refute_nil result
47
+ end
48
+
42
49
  # Parameterized authentication error tests (one per endpoint).
43
50
  [
44
51
  {name: :list_organization_api_keys, verb: :get, url: %r{\Ahttps://api\.workos\.com/organizations/stub/api_keys(\?|\z)}, args: {organization_id: "stub"}},
45
52
  {name: :create_organization_api_key, verb: :post, url: %r{\Ahttps://api\.workos\.com/organizations/stub/api_keys(\?|\z)}, args: {organization_id: "stub", name: "stub"}},
46
53
  {name: :create_validation, verb: :post, url: %r{\Ahttps://api\.workos\.com/api_keys/validations(\?|\z)}, args: {value: "stub"}},
47
- {name: :delete_api_key, verb: :delete, url: %r{\Ahttps://api\.workos\.com/api_keys/stub(\?|\z)}, args: {id: "stub"}}
54
+ {name: :delete_api_key, verb: :delete, url: %r{\Ahttps://api\.workos\.com/api_keys/stub(\?|\z)}, args: {id: "stub"}},
55
+ {name: :create_api_key_expire, verb: :post, url: %r{\Ahttps://api\.workos\.com/api_keys/stub/expire(\?|\z)}, args: {id: "stub"}}
48
56
  ].each do |spec|
49
57
  define_method("test_#{spec[:name]}_raises_authentication_error_on_401") do
50
58
  stub_request(spec[:verb], spec[:url])
@@ -11,6 +11,48 @@ class AuthorizationTest < Minitest::Test
11
11
  @client = WorkOS::Client.new(api_key: "sk_test_123")
12
12
  end
13
13
 
14
+ def test_list_group_role_assignments_returns_expected_result
15
+ stub_request(:get, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)})
16
+ .to_return(body: '{"data": [], "list_metadata": {}}', status: 200)
17
+ result = @client.authorization.list_group_role_assignments(group_id: "stub")
18
+ assert_kind_of WorkOS::Types::ListStruct, result
19
+ end
20
+
21
+ def test_create_group_role_assignment_returns_expected_result
22
+ stub_request(:post, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)})
23
+ .to_return(body: "{}", status: 200)
24
+ result = @client.authorization.create_group_role_assignment(group_id: "stub", role_slug: "stub")
25
+ refute_nil result
26
+ end
27
+
28
+ def test_update_group_role_assignments_returns_expected_result
29
+ stub_request(:put, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)})
30
+ .to_return(body: '{"data": [], "list_metadata": {}}', status: 200)
31
+ result = @client.authorization.update_group_role_assignments(group_id: "stub", role_assignments: [{}])
32
+ assert_kind_of WorkOS::Types::ListStruct, result
33
+ end
34
+
35
+ def test_delete_group_role_assignments_returns_expected_result
36
+ stub_request(:delete, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)})
37
+ .to_return(body: "{}", status: 200)
38
+ result = @client.authorization.delete_group_role_assignments(group_id: "stub", role_slug: "stub")
39
+ assert_nil result
40
+ end
41
+
42
+ def test_get_group_role_assignment_returns_expected_result
43
+ stub_request(:get, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments/stub(\?|\z)})
44
+ .to_return(body: "{}", status: 200)
45
+ result = @client.authorization.get_group_role_assignment(group_id: "stub", role_assignment_id: "stub")
46
+ refute_nil result
47
+ end
48
+
49
+ def test_delete_group_role_assignment_returns_expected_result
50
+ stub_request(:delete, %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments/stub(\?|\z)})
51
+ .to_return(body: "{}", status: 200)
52
+ result = @client.authorization.delete_group_role_assignment(group_id: "stub", role_assignment_id: "stub")
53
+ assert_nil result
54
+ end
55
+
14
56
  def test_check_returns_expected_result
15
57
  stub_request(:post, %r{\Ahttps://api\.workos\.com/authorization/organization_memberships/stub/check(\?|\z)})
16
58
  .with(body: hash_including("permission_slug" => "stub", "resource_id" => "stub"))
@@ -352,6 +394,12 @@ class AuthorizationTest < Minitest::Test
352
394
 
353
395
  # Parameterized authentication error tests (one per endpoint).
354
396
  [
397
+ {name: :list_group_role_assignments, verb: :get, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)}, args: {group_id: "stub"}},
398
+ {name: :create_group_role_assignment, verb: :post, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)}, args: {group_id: "stub", role_slug: "stub"}},
399
+ {name: :update_group_role_assignments, verb: :put, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)}, args: {group_id: "stub", role_assignments: [{}]}},
400
+ {name: :delete_group_role_assignments, verb: :delete, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments(\?|\z)}, args: {group_id: "stub", role_slug: "stub"}},
401
+ {name: :get_group_role_assignment, verb: :get, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments/stub(\?|\z)}, args: {group_id: "stub", role_assignment_id: "stub"}},
402
+ {name: :delete_group_role_assignment, verb: :delete, url: %r{\Ahttps://api\.workos\.com/authorization/groups/stub/role_assignments/stub(\?|\z)}, args: {group_id: "stub", role_assignment_id: "stub"}},
355
403
  {name: :check, verb: :post, url: %r{\Ahttps://api\.workos\.com/authorization/organization_memberships/stub/check(\?|\z)}, args: {organization_membership_id: "stub", permission_slug: "stub", resource_target: WorkOS::Authorization::ResourceTargetById.new(resource_id: "stub")}},
356
404
  {name: :list_resources_for_membership, verb: :get, url: %r{\Ahttps://api\.workos\.com/authorization/organization_memberships/stub/resources(\?|\z)}, args: {organization_membership_id: "stub", permission_slug: "stub", parent_resource: WorkOS::Authorization::ParentResourceById.new(parent_resource_id: "stub")}},
357
405
  {name: :list_effective_permissions, verb: :get, url: %r{\Ahttps://api\.workos\.com/authorization/organization_memberships/stub/resources/stub/permissions(\?|\z)}, args: {organization_membership_id: "stub", resource_id: "stub"}},
@@ -86,6 +86,14 @@ class BaseClientTest < Minitest::Test
86
86
  @client = WorkOS::BaseClient.new(api_key: "sk_test_123", max_retries: 1)
87
87
  end
88
88
 
89
+ def teardown
90
+ super
91
+ # Close any open connections and clear the thread-local cache to avoid
92
+ # leaking sockets between tests.
93
+ @client.shutdown
94
+ Thread.current[:workos_connections] = nil
95
+ end
96
+
89
97
  def test_request_dispatches_known_methods
90
98
  client = RecordingClient.new(api_key: "sk_test_123")
91
99
 
@@ -171,6 +179,62 @@ class BaseClientTest < Minitest::Test
171
179
  refute keep.finished
172
180
  end
173
181
 
182
+ # Regression test for https://github.com/workos/workos-ruby/issues/496
183
+ #
184
+ # The connection cache must be isolated per thread. A previous version
185
+ # keyed it on Fiber[] (inheritable fiber storage), which is inherited *by
186
+ # reference* by child threads — so a Net::HTTP socket warmed in a parent
187
+ # thread leaked into every worker thread spawned afterward (Solid Queue,
188
+ # Puma, etc.) and got driven concurrently, corrupting the stream.
189
+ def test_connection_cache_is_not_shared_with_threads_spawned_after_warming
190
+ # Warm a connection in the "parent" thread before spawning workers.
191
+ parent_cache = @client.send(:thread_connections)
192
+ warm = FakeConnection.new
193
+ parent_cache["https:api.workos.com:443:30"] = warm
194
+
195
+ results = Array.new(4) do
196
+ Thread.new do
197
+ cache = @client.send(:thread_connections)
198
+ {cache_id: cache.object_id, leaked: cache.value?(warm), size: cache.size}
199
+ end
200
+ end.map(&:value)
201
+
202
+ results.each do |r|
203
+ refute_equal parent_cache.object_id, r[:cache_id],
204
+ "worker thread must not share the parent thread's connection cache"
205
+ refute r[:leaked],
206
+ "parent thread's warmed connection leaked into a worker thread"
207
+ assert_equal 0, r[:size],
208
+ "worker thread should start with an empty, isolated cache"
209
+ end
210
+
211
+ # The parent's own cache is left intact.
212
+ assert_same warm, parent_cache["https:api.workos.com:443:30"]
213
+ end
214
+
215
+ # Exercises the connection_for path (not just the storage helper):
216
+ # each thread must open and cache its *own* Net::HTTP connection rather
217
+ # than reusing one established on another thread.
218
+ #
219
+ # Net::HTTP#start is stubbed to avoid real TCP+TLS connections.
220
+ def test_connection_for_opens_a_distinct_connection_per_thread
221
+ original_start = Net::HTTP.instance_method(:start)
222
+ Net::HTTP.define_method(:start) { self }
223
+
224
+ parent_conn = @client.send(:connection_for, "https://api.workos.com", 30)
225
+
226
+ worker_conns = Array.new(4) do
227
+ Thread.new { @client.send(:connection_for, "https://api.workos.com", 30).object_id }
228
+ end.map(&:value)
229
+
230
+ refute_includes worker_conns, parent_conn.object_id,
231
+ "a worker thread reused a connection opened on another thread"
232
+ assert_equal worker_conns.length, worker_conns.uniq.length,
233
+ "worker threads must each get a distinct connection"
234
+ ensure
235
+ Net::HTTP.define_method(:start, original_start)
236
+ end
237
+
174
238
  def test_redact_path_strips_invitation_token_segment
175
239
  redacted = @client.send(:redact_path, "/user_management/invitations/by_token/invtoken_secret123")
176
240
  assert_equal "/user_management/invitations/by_token/[REDACTED]", redacted
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is auto-generated by oagen. Do not edit.
4
+
5
+ require "test_helper"
6
+
7
+ class ClientApiTest < Minitest::Test
8
+ include FixtureHelper
9
+
10
+ def setup
11
+ @client = WorkOS::Client.new(api_key: "sk_test_123")
12
+ end
13
+
14
+ def test_create_token_returns_expected_result
15
+ stub_request(:post, %r{\Ahttps://api\.workos\.com/client/token(\?|\z)})
16
+ .to_return(body: "{}", status: 200)
17
+ result = @client.client_api.create_token(organization_id: "stub", user_id: "stub")
18
+ refute_nil result
19
+ end
20
+
21
+ # Parameterized authentication error tests (one per endpoint).
22
+ [
23
+ {name: :create_token, verb: :post, url: %r{\Ahttps://api\.workos\.com/client/token(\?|\z)}, args: {organization_id: "stub", user_id: "stub"}}
24
+ ].each do |spec|
25
+ define_method("test_#{spec[:name]}_raises_authentication_error_on_401") do
26
+ stub_request(spec[:verb], spec[:url])
27
+ .to_return(body: '{"message": "Unauthorized"}', status: 401)
28
+ assert_raises(WorkOS::AuthenticationError) do
29
+ @client.client_api.send(spec[:name], **(spec[:args] || {}))
30
+ end
31
+ end
32
+ end
33
+ end