workos 7.1.2 → 8.0.1

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 (120) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +49 -0
  3. data/.github/workflows/release-please.yml +2 -2
  4. data/.gitignore +2 -0
  5. data/.last-synced-sha +1 -1
  6. data/.oagen-manifest.json +61 -40
  7. data/.release-please-manifest.json +1 -1
  8. data/.yardopts +6 -0
  9. data/CHANGELOG.md +36 -0
  10. data/Gemfile +6 -0
  11. data/Gemfile.lock +33 -2
  12. data/README.md +19 -0
  13. data/docs/V7_MIGRATION_GUIDE.md +21 -0
  14. data/lib/workos/actions.rb +1 -1
  15. data/lib/workos/api_keys/api_key.rb +1 -1
  16. data/lib/workos/api_keys/api_key_created_data.rb +1 -1
  17. data/lib/workos/api_keys/organization_api_key.rb +43 -0
  18. data/lib/workos/{types/events_order.rb → api_keys/organization_api_key_owner.rb} +1 -3
  19. data/lib/workos/api_keys/organization_api_key_with_value.rb +46 -0
  20. data/lib/workos/{types/audit_logs_order.rb → api_keys/organization_api_key_with_value_owner.rb} +1 -3
  21. data/lib/workos/api_keys.rb +46 -46
  22. data/lib/workos/audit_logs.rb +4 -4
  23. data/lib/workos/authorization/user_organization_membership_base_list_data.rb +5 -2
  24. data/lib/workos/authorization/{role_assignment.rb → user_role_assignment.rb} +5 -2
  25. data/lib/workos/authorization/{role_assignment_resource.rb → user_role_assignment_resource.rb} +1 -1
  26. data/lib/workos/authorization.rb +122 -22
  27. data/lib/workos/base_client.rb +71 -5
  28. data/lib/workos/client.rb +4 -4
  29. data/lib/workos/connect.rb +2 -2
  30. data/lib/workos/directory_sync/directory_user.rb +3 -0
  31. data/lib/workos/directory_sync/directory_user_with_groups.rb +4 -1
  32. data/lib/workos/directory_sync/dsync_user_updated_data.rb +3 -0
  33. data/lib/workos/directory_sync.rb +6 -6
  34. data/lib/workos/encryptors/aes_gcm.rb +19 -5
  35. data/lib/workos/events.rb +2 -2
  36. data/lib/workos/feature_flags.rb +6 -6
  37. data/lib/workos/groups.rb +4 -4
  38. data/lib/workos/multi_factor_auth.rb +2 -2
  39. data/lib/workos/organizations.rb +2 -2
  40. data/lib/workos/session.rb +28 -7
  41. data/lib/workos/session_manager.rb +24 -1
  42. data/lib/workos/sso/profile.rb +3 -0
  43. data/lib/workos/sso.rb +2 -2
  44. data/lib/workos/types/event_context_actor_source.rb +2 -1
  45. data/lib/workos/types/{applications_order.rb → pagination_order.rb} +1 -1
  46. data/lib/workos/types/{vault_byok_key_verification_completed_data_key_provider.rb → vault_byok_key_provider.rb} +1 -1
  47. data/lib/workos/user_management/create_user_api_key.rb +25 -0
  48. data/lib/workos/user_management/organization_membership.rb +5 -2
  49. data/lib/workos/user_management/user_api_key.rb +43 -0
  50. data/lib/workos/user_management/user_api_key_created_data_owner.rb +25 -0
  51. data/lib/workos/{api_keys/api_key_with_value_owner.rb → user_management/user_api_key_owner.rb} +1 -1
  52. data/lib/workos/{types/webhooks_order.rb → user_management/user_api_key_revoked_data_owner.rb} +1 -3
  53. data/lib/workos/{api_keys/api_key_with_value.rb → user_management/user_api_key_with_value.rb} +2 -2
  54. data/lib/workos/{types/groups_order.rb → user_management/user_api_key_with_value_owner.rb} +1 -3
  55. data/lib/workos/user_management/user_organization_membership.rb +5 -2
  56. data/lib/workos/user_management.rb +114 -10
  57. data/lib/workos/user_management_organization_membership_groups.rb +2 -2
  58. data/lib/workos/vault/vault_byok_key_deleted.rb +34 -0
  59. data/lib/workos/vault/vault_byok_key_deleted_data.rb +22 -0
  60. data/lib/workos/version.rb +1 -1
  61. data/lib/workos/webhooks.rb +3 -3
  62. data/rbi/workos/api_key.rbi +2 -2
  63. data/rbi/workos/api_key_created_data.rbi +2 -2
  64. data/rbi/workos/api_key_revoked_data.rbi +2 -2
  65. data/rbi/workos/api_keys.rbi +17 -17
  66. data/rbi/workos/authorization.rbi +27 -1
  67. data/rbi/workos/client.rbi +3 -3
  68. data/rbi/workos/create_user_api_key.rbi +36 -0
  69. data/rbi/workos/directory_user.rbi +6 -0
  70. data/rbi/workos/directory_user_with_groups.rbi +6 -0
  71. data/rbi/workos/dsync_user_updated_data.rbi +6 -0
  72. data/rbi/workos/organization_api_key.rbi +72 -0
  73. data/rbi/workos/{api_key_with_value_owner.rbi → organization_api_key_owner.rbi} +1 -1
  74. data/rbi/workos/organization_api_key_with_value.rbi +78 -0
  75. data/rbi/workos/organization_api_key_with_value_owner.rbi +30 -0
  76. data/rbi/workos/organization_membership.rbi +6 -0
  77. data/rbi/workos/profile.rbi +6 -0
  78. data/rbi/workos/user_api_key.rbi +72 -0
  79. data/rbi/workos/user_api_key_created_data_owner.rbi +36 -0
  80. data/rbi/workos/user_api_key_owner.rbi +36 -0
  81. data/rbi/workos/user_api_key_revoked_data_owner.rbi +36 -0
  82. data/rbi/workos/{api_key_with_value.rbi → user_api_key_with_value.rbi} +3 -3
  83. data/rbi/workos/user_api_key_with_value_owner.rbi +36 -0
  84. data/rbi/workos/user_management.rbi +31 -0
  85. data/rbi/workos/user_organization_membership.rbi +6 -0
  86. data/rbi/workos/user_organization_membership_base_list_data.rbi +6 -0
  87. data/rbi/workos/{role_assignment.rbi → user_role_assignment.rbi} +9 -3
  88. data/rbi/workos/{role_assignment_resource.rbi → user_role_assignment_resource.rbi} +1 -1
  89. data/rbi/workos/vault_byok_key_deleted.rbi +54 -0
  90. data/rbi/workos/vault_byok_key_deleted_data.rbi +30 -0
  91. data/script/docs +16 -0
  92. data/script/docs-serve +12 -0
  93. data/script/llms-txt +37 -0
  94. data/test/workos/test_actions.rb +9 -0
  95. data/test/workos/test_api_keys.rb +17 -17
  96. data/test/workos/test_authorization.rb +16 -0
  97. data/test/workos/test_base_client.rb +44 -0
  98. data/test/workos/test_encryptors_aes_gcm.rb +16 -1
  99. data/test/workos/test_model_round_trip.rb +278 -83
  100. data/test/workos/test_session.rb +43 -4
  101. data/test/workos/test_user_management.rb +25 -1
  102. data/test/workos/test_webhook_verify.rb +11 -0
  103. metadata +39 -33
  104. data/lib/workos/types/authorization_order.rb +0 -9
  105. data/lib/workos/types/connections_order.rb +0 -9
  106. data/lib/workos/types/directories_order.rb +0 -9
  107. data/lib/workos/types/directory_groups_order.rb +0 -9
  108. data/lib/workos/types/directory_users_order.rb +0 -9
  109. data/lib/workos/types/feature_flags_order.rb +0 -9
  110. data/lib/workos/types/organizations_api_keys_order.rb +0 -9
  111. data/lib/workos/types/organizations_feature_flags_order.rb +0 -9
  112. data/lib/workos/types/organizations_order.rb +0 -9
  113. data/lib/workos/types/permissions_order.rb +0 -9
  114. data/lib/workos/types/user_management_invitations_order.rb +0 -9
  115. data/lib/workos/types/user_management_multi_factor_authentication_order.rb +0 -9
  116. data/lib/workos/types/user_management_organization_membership_groups_order.rb +0 -9
  117. data/lib/workos/types/user_management_organization_membership_order.rb +0 -9
  118. data/lib/workos/types/user_management_users_authorized_applications_order.rb +0 -9
  119. data/lib/workos/types/user_management_users_feature_flags_order.rb +0 -9
  120. data/lib/workos/types/user_management_users_order.rb +0 -9
@@ -709,6 +709,20 @@ class ModelRoundTripTest < Minitest::Test
709
709
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
710
710
  end
711
711
 
712
+ def test_create_user_api_key_round_trip
713
+ fixture = {
714
+ "name" => "stub",
715
+ "organization_id" => "stub",
716
+ "permissions" => []
717
+ }
718
+ model = WorkOS::CreateUserApiKey.new(fixture.to_json)
719
+ json = model.to_h
720
+ assert_kind_of Hash, json
721
+ assert_equal fixture["name"], json[:name]
722
+ assert_equal fixture["organization_id"], json[:organization_id]
723
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
724
+ end
725
+
712
726
  def test_create_user_round_trip
713
727
  fixture = {
714
728
  "email" => "stub",
@@ -1183,19 +1197,21 @@ class ModelRoundTripTest < Minitest::Test
1183
1197
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1184
1198
  end
1185
1199
 
1186
- def test_role_assignment_round_trip
1200
+ def test_user_role_assignment_round_trip
1187
1201
  fixture = {
1188
1202
  "object" => "role_assignment",
1189
1203
  "id" => "stub",
1204
+ "organization_membership_id" => "stub",
1190
1205
  "role" => {},
1191
1206
  "resource" => {},
1192
1207
  "created_at" => "stub",
1193
1208
  "updated_at" => "stub"
1194
1209
  }
1195
- model = WorkOS::RoleAssignment.new(fixture.to_json)
1210
+ model = WorkOS::UserRoleAssignment.new(fixture.to_json)
1196
1211
  json = model.to_h
1197
1212
  assert_kind_of Hash, json
1198
1213
  assert_equal fixture["id"], json[:id]
1214
+ assert_equal fixture["organization_membership_id"], json[:organization_membership_id]
1199
1215
  assert_equal fixture["created_at"], json[:created_at]
1200
1216
  assert_equal fixture["updated_at"], json[:updated_at]
1201
1217
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
@@ -1238,6 +1254,38 @@ class ModelRoundTripTest < Minitest::Test
1238
1254
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1239
1255
  end
1240
1256
 
1257
+ def test_user_round_trip
1258
+ fixture = {
1259
+ "object" => "user",
1260
+ "id" => "stub",
1261
+ "first_name" => nil,
1262
+ "last_name" => nil,
1263
+ "profile_picture_url" => nil,
1264
+ "email" => "stub",
1265
+ "email_verified" => true,
1266
+ "external_id" => nil,
1267
+ "metadata" => {},
1268
+ "last_sign_in_at" => nil,
1269
+ "locale" => nil,
1270
+ "created_at" => "stub",
1271
+ "updated_at" => "stub"
1272
+ }
1273
+ model = WorkOS::User.new(fixture.to_json)
1274
+ json = model.to_h
1275
+ assert_kind_of Hash, json
1276
+ assert_equal fixture["id"], json[:id]
1277
+ assert_nil json[:first_name]
1278
+ assert_nil json[:last_name]
1279
+ assert_nil json[:profile_picture_url]
1280
+ assert_equal fixture["email"], json[:email]
1281
+ assert_equal fixture["email_verified"], json[:email_verified]
1282
+ assert_nil json[:external_id]
1283
+ assert_nil json[:last_sign_in_at]
1284
+ assert_equal fixture["created_at"], json[:created_at]
1285
+ assert_equal fixture["updated_at"], json[:updated_at]
1286
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1287
+ end
1288
+
1241
1289
  def test_connection_round_trip
1242
1290
  fixture = {
1243
1291
  "object" => "connection",
@@ -1341,6 +1389,7 @@ class ModelRoundTripTest < Minitest::Test
1341
1389
  "email" => nil,
1342
1390
  "first_name" => nil,
1343
1391
  "last_name" => nil,
1392
+ "name" => nil,
1344
1393
  "emails" => [],
1345
1394
  "job_title" => nil,
1346
1395
  "username" => nil,
@@ -1427,6 +1476,7 @@ class ModelRoundTripTest < Minitest::Test
1427
1476
  "email" => nil,
1428
1477
  "first_name" => nil,
1429
1478
  "last_name" => nil,
1479
+ "name" => nil,
1430
1480
  "emails" => [],
1431
1481
  "job_title" => nil,
1432
1482
  "username" => nil,
@@ -1451,38 +1501,6 @@ class ModelRoundTripTest < Minitest::Test
1451
1501
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1452
1502
  end
1453
1503
 
1454
- def test_user_round_trip
1455
- fixture = {
1456
- "object" => "user",
1457
- "id" => "stub",
1458
- "first_name" => nil,
1459
- "last_name" => nil,
1460
- "profile_picture_url" => nil,
1461
- "email" => "stub",
1462
- "email_verified" => true,
1463
- "external_id" => nil,
1464
- "metadata" => {},
1465
- "last_sign_in_at" => nil,
1466
- "locale" => nil,
1467
- "created_at" => "stub",
1468
- "updated_at" => "stub"
1469
- }
1470
- model = WorkOS::User.new(fixture.to_json)
1471
- json = model.to_h
1472
- assert_kind_of Hash, json
1473
- assert_equal fixture["id"], json[:id]
1474
- assert_nil json[:first_name]
1475
- assert_nil json[:last_name]
1476
- assert_nil json[:profile_picture_url]
1477
- assert_equal fixture["email"], json[:email]
1478
- assert_equal fixture["email_verified"], json[:email_verified]
1479
- assert_nil json[:external_id]
1480
- assert_nil json[:last_sign_in_at]
1481
- assert_equal fixture["created_at"], json[:created_at]
1482
- assert_equal fixture["updated_at"], json[:updated_at]
1483
- fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1484
- end
1485
-
1486
1504
  def test_waitlist_user_round_trip
1487
1505
  fixture = {
1488
1506
  "object" => "waitlist_user",
@@ -1657,6 +1675,20 @@ class ModelRoundTripTest < Minitest::Test
1657
1675
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1658
1676
  end
1659
1677
 
1678
+ def test_user_api_key_created_data_owner_round_trip
1679
+ fixture = {
1680
+ "type" => "user",
1681
+ "id" => "stub",
1682
+ "organization_id" => "stub"
1683
+ }
1684
+ model = WorkOS::UserApiKeyCreatedDataOwner.new(fixture.to_json)
1685
+ json = model.to_h
1686
+ assert_kind_of Hash, json
1687
+ assert_equal fixture["id"], json[:id]
1688
+ assert_equal fixture["organization_id"], json[:organization_id]
1689
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1690
+ end
1691
+
1660
1692
  def test_api_key_revoked_round_trip
1661
1693
  fixture = {
1662
1694
  "id" => "stub",
@@ -1710,6 +1742,20 @@ class ModelRoundTripTest < Minitest::Test
1710
1742
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1711
1743
  end
1712
1744
 
1745
+ def test_user_api_key_revoked_data_owner_round_trip
1746
+ fixture = {
1747
+ "type" => "user",
1748
+ "id" => "stub",
1749
+ "organization_id" => "stub"
1750
+ }
1751
+ model = WorkOS::UserApiKeyRevokedDataOwner.new(fixture.to_json)
1752
+ json = model.to_h
1753
+ assert_kind_of Hash, json
1754
+ assert_equal fixture["id"], json[:id]
1755
+ assert_equal fixture["organization_id"], json[:organization_id]
1756
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
1757
+ end
1758
+
1713
1759
  def test_authentication_email_verification_failed_round_trip
1714
1760
  fixture = {
1715
1761
  "id" => "stub",
@@ -3109,6 +3155,7 @@ class ModelRoundTripTest < Minitest::Test
3109
3155
  "email" => nil,
3110
3156
  "first_name" => nil,
3111
3157
  "last_name" => nil,
3158
+ "name" => nil,
3112
3159
  "emails" => [],
3113
3160
  "job_title" => nil,
3114
3161
  "username" => nil,
@@ -5161,6 +5208,35 @@ class ModelRoundTripTest < Minitest::Test
5161
5208
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5162
5209
  end
5163
5210
 
5211
+ def test_vault_byok_key_deleted_round_trip
5212
+ fixture = {
5213
+ "id" => "stub",
5214
+ "event" => "vault.byok_key.deleted",
5215
+ "data" => {},
5216
+ "created_at" => "stub",
5217
+ "context" => {},
5218
+ "object" => "event"
5219
+ }
5220
+ model = WorkOS::VaultByokKeyDeleted.new(fixture.to_json)
5221
+ json = model.to_h
5222
+ assert_kind_of Hash, json
5223
+ assert_equal fixture["id"], json[:id]
5224
+ assert_equal fixture["created_at"], json[:created_at]
5225
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5226
+ end
5227
+
5228
+ def test_vault_byok_key_deleted_data_round_trip
5229
+ fixture = {
5230
+ "organization_id" => "stub",
5231
+ "key_provider" => "stub"
5232
+ }
5233
+ model = WorkOS::VaultByokKeyDeletedData.new(fixture.to_json)
5234
+ json = model.to_h
5235
+ assert_kind_of Hash, json
5236
+ assert_equal fixture["organization_id"], json[:organization_id]
5237
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5238
+ end
5239
+
5164
5240
  def test_vault_byok_key_verification_completed_round_trip
5165
5241
  fixture = {
5166
5242
  "id" => "stub",
@@ -5548,22 +5624,6 @@ class ModelRoundTripTest < Minitest::Test
5548
5624
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5549
5625
  end
5550
5626
 
5551
- def test_jwt_template_response_round_trip
5552
- fixture = {
5553
- "object" => "jwt_template",
5554
- "content" => "stub",
5555
- "created_at" => "stub",
5556
- "updated_at" => "stub"
5557
- }
5558
- model = WorkOS::JWTTemplateResponse.new(fixture.to_json)
5559
- json = model.to_h
5560
- assert_kind_of Hash, json
5561
- assert_equal fixture["content"], json[:content]
5562
- assert_equal fixture["created_at"], json[:created_at]
5563
- assert_equal fixture["updated_at"], json[:updated_at]
5564
- fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5565
- end
5566
-
5567
5627
  def test_organization_domain_stand_alone_round_trip
5568
5628
  fixture = {
5569
5629
  "object" => "organization_domain",
@@ -5616,7 +5676,31 @@ class ModelRoundTripTest < Minitest::Test
5616
5676
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5617
5677
  end
5618
5678
 
5619
- def test_api_key_with_value_round_trip
5679
+ def test_organization_api_key_round_trip
5680
+ fixture = {
5681
+ "object" => "api_key",
5682
+ "id" => "stub",
5683
+ "owner" => {},
5684
+ "name" => "stub",
5685
+ "obfuscated_value" => "stub",
5686
+ "last_used_at" => nil,
5687
+ "permissions" => [],
5688
+ "created_at" => "stub",
5689
+ "updated_at" => "stub"
5690
+ }
5691
+ model = WorkOS::OrganizationApiKey.new(fixture.to_json)
5692
+ json = model.to_h
5693
+ assert_kind_of Hash, json
5694
+ assert_equal fixture["id"], json[:id]
5695
+ assert_equal fixture["name"], json[:name]
5696
+ assert_equal fixture["obfuscated_value"], json[:obfuscated_value]
5697
+ assert_nil json[:last_used_at]
5698
+ assert_equal fixture["created_at"], json[:created_at]
5699
+ assert_equal fixture["updated_at"], json[:updated_at]
5700
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5701
+ end
5702
+
5703
+ def test_organization_api_key_with_value_round_trip
5620
5704
  fixture = {
5621
5705
  "object" => "api_key",
5622
5706
  "id" => "stub",
@@ -5629,7 +5713,7 @@ class ModelRoundTripTest < Minitest::Test
5629
5713
  "updated_at" => "stub",
5630
5714
  "value" => "stub"
5631
5715
  }
5632
- model = WorkOS::ApiKeyWithValue.new(fixture.to_json)
5716
+ model = WorkOS::OrganizationApiKeyWithValue.new(fixture.to_json)
5633
5717
  json = model.to_h
5634
5718
  assert_kind_of Hash, json
5635
5719
  assert_equal fixture["id"], json[:id]
@@ -5879,7 +5963,8 @@ class ModelRoundTripTest < Minitest::Test
5879
5963
  "custom_attributes" => {},
5880
5964
  "created_at" => "stub",
5881
5965
  "updated_at" => "stub",
5882
- "role" => {}
5966
+ "role" => {},
5967
+ "user" => {}
5883
5968
  }
5884
5969
  model = WorkOS::UserOrganizationMembership.new(fixture.to_json)
5885
5970
  json = model.to_h
@@ -5893,6 +5978,56 @@ class ModelRoundTripTest < Minitest::Test
5893
5978
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
5894
5979
  end
5895
5980
 
5981
+ def test_user_api_key_round_trip
5982
+ fixture = {
5983
+ "object" => "api_key",
5984
+ "id" => "stub",
5985
+ "owner" => {},
5986
+ "name" => "stub",
5987
+ "obfuscated_value" => "stub",
5988
+ "last_used_at" => nil,
5989
+ "permissions" => [],
5990
+ "created_at" => "stub",
5991
+ "updated_at" => "stub"
5992
+ }
5993
+ model = WorkOS::UserApiKey.new(fixture.to_json)
5994
+ json = model.to_h
5995
+ assert_kind_of Hash, json
5996
+ assert_equal fixture["id"], json[:id]
5997
+ assert_equal fixture["name"], json[:name]
5998
+ assert_equal fixture["obfuscated_value"], json[:obfuscated_value]
5999
+ assert_nil json[:last_used_at]
6000
+ assert_equal fixture["created_at"], json[:created_at]
6001
+ assert_equal fixture["updated_at"], json[:updated_at]
6002
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6003
+ end
6004
+
6005
+ def test_user_api_key_with_value_round_trip
6006
+ fixture = {
6007
+ "object" => "api_key",
6008
+ "id" => "stub",
6009
+ "owner" => {},
6010
+ "name" => "stub",
6011
+ "obfuscated_value" => "stub",
6012
+ "last_used_at" => nil,
6013
+ "permissions" => [],
6014
+ "created_at" => "stub",
6015
+ "updated_at" => "stub",
6016
+ "value" => "stub"
6017
+ }
6018
+ model = WorkOS::UserApiKeyWithValue.new(fixture.to_json)
6019
+ json = model.to_h
6020
+ assert_kind_of Hash, json
6021
+ assert_equal fixture["id"], json[:id]
6022
+ assert_equal fixture["name"], json[:name]
6023
+ assert_equal fixture["obfuscated_value"], json[:obfuscated_value]
6024
+ assert_nil json[:last_used_at]
6025
+ assert_equal fixture["created_at"], json[:created_at]
6026
+ assert_equal fixture["updated_at"], json[:updated_at]
6027
+ assert_equal fixture["value"], json[:value]
6028
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6029
+ end
6030
+
5896
6031
  def test_email_verification_round_trip
5897
6032
  fixture = {
5898
6033
  "object" => "email_verification",
@@ -6081,6 +6216,7 @@ class ModelRoundTripTest < Minitest::Test
6081
6216
  "email" => "stub",
6082
6217
  "first_name" => nil,
6083
6218
  "last_name" => nil,
6219
+ "name" => nil,
6084
6220
  "role" => nil,
6085
6221
  "roles" => nil,
6086
6222
  "groups" => [],
@@ -6097,6 +6233,7 @@ class ModelRoundTripTest < Minitest::Test
6097
6233
  assert_equal fixture["email"], json[:email]
6098
6234
  assert_nil json[:first_name]
6099
6235
  assert_nil json[:last_name]
6236
+ assert_nil json[:name]
6100
6237
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6101
6238
  end
6102
6239
 
@@ -6139,6 +6276,22 @@ class ModelRoundTripTest < Minitest::Test
6139
6276
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6140
6277
  end
6141
6278
 
6279
+ def test_jwt_template_response_round_trip
6280
+ fixture = {
6281
+ "object" => "jwt_template",
6282
+ "content" => "stub",
6283
+ "created_at" => "stub",
6284
+ "updated_at" => "stub"
6285
+ }
6286
+ model = WorkOS::JWTTemplateResponse.new(fixture.to_json)
6287
+ json = model.to_h
6288
+ assert_kind_of Hash, json
6289
+ assert_equal fixture["content"], json[:content]
6290
+ assert_equal fixture["created_at"], json[:created_at]
6291
+ assert_equal fixture["updated_at"], json[:updated_at]
6292
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6293
+ end
6294
+
6142
6295
  def test_jwks_response_keys_round_trip
6143
6296
  fixture = {
6144
6297
  "alg" => "RS256",
@@ -6209,6 +6362,34 @@ class ModelRoundTripTest < Minitest::Test
6209
6362
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6210
6363
  end
6211
6364
 
6365
+ def test_user_api_key_with_value_owner_round_trip
6366
+ fixture = {
6367
+ "type" => "user",
6368
+ "id" => "stub",
6369
+ "organization_id" => "stub"
6370
+ }
6371
+ model = WorkOS::UserApiKeyWithValueOwner.new(fixture.to_json)
6372
+ json = model.to_h
6373
+ assert_kind_of Hash, json
6374
+ assert_equal fixture["id"], json[:id]
6375
+ assert_equal fixture["organization_id"], json[:organization_id]
6376
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6377
+ end
6378
+
6379
+ def test_user_api_key_owner_round_trip
6380
+ fixture = {
6381
+ "type" => "user",
6382
+ "id" => "stub",
6383
+ "organization_id" => "stub"
6384
+ }
6385
+ model = WorkOS::UserApiKeyOwner.new(fixture.to_json)
6386
+ json = model.to_h
6387
+ assert_kind_of Hash, json
6388
+ assert_equal fixture["id"], json[:id]
6389
+ assert_equal fixture["organization_id"], json[:organization_id]
6390
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6391
+ end
6392
+
6212
6393
  def test_data_integrations_list_response_data_round_trip
6213
6394
  fixture = {
6214
6395
  "object" => "data_provider",
@@ -6295,12 +6476,24 @@ class ModelRoundTripTest < Minitest::Test
6295
6476
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6296
6477
  end
6297
6478
 
6298
- def test_api_key_with_value_owner_round_trip
6479
+ def test_organization_api_key_with_value_owner_round_trip
6299
6480
  fixture = {
6300
6481
  "type" => "organization",
6301
6482
  "id" => "stub"
6302
6483
  }
6303
- model = WorkOS::ApiKeyWithValueOwner.new(fixture.to_json)
6484
+ model = WorkOS::OrganizationApiKeyWithValueOwner.new(fixture.to_json)
6485
+ json = model.to_h
6486
+ assert_kind_of Hash, json
6487
+ assert_equal fixture["id"], json[:id]
6488
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6489
+ end
6490
+
6491
+ def test_organization_api_key_owner_round_trip
6492
+ fixture = {
6493
+ "type" => "organization",
6494
+ "id" => "stub"
6495
+ }
6496
+ model = WorkOS::OrganizationApiKeyOwner.new(fixture.to_json)
6304
6497
  json = model.to_h
6305
6498
  assert_kind_of Hash, json
6306
6499
  assert_equal fixture["id"], json[:id]
@@ -6358,6 +6551,32 @@ class ModelRoundTripTest < Minitest::Test
6358
6551
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6359
6552
  end
6360
6553
 
6554
+ def test_user_organization_membership_base_list_data_round_trip
6555
+ fixture = {
6556
+ "object" => "organization_membership",
6557
+ "id" => "stub",
6558
+ "user_id" => "stub",
6559
+ "organization_id" => "stub",
6560
+ "status" => "stub",
6561
+ "directory_managed" => true,
6562
+ "organization_name" => "stub",
6563
+ "custom_attributes" => {},
6564
+ "created_at" => "stub",
6565
+ "updated_at" => "stub",
6566
+ "user" => {}
6567
+ }
6568
+ model = WorkOS::UserOrganizationMembershipBaseListData.new(fixture.to_json)
6569
+ json = model.to_h
6570
+ assert_kind_of Hash, json
6571
+ assert_equal fixture["id"], json[:id]
6572
+ assert_equal fixture["user_id"], json[:user_id]
6573
+ assert_equal fixture["organization_id"], json[:organization_id]
6574
+ assert_equal fixture["directory_managed"], json[:directory_managed]
6575
+ assert_equal fixture["created_at"], json[:created_at]
6576
+ assert_equal fixture["updated_at"], json[:updated_at]
6577
+ fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6578
+ end
6579
+
6361
6580
  def test_directory_user_with_groups_email_round_trip
6362
6581
  fixture = {
6363
6582
  "primary" => true,
@@ -6407,38 +6626,13 @@ class ModelRoundTripTest < Minitest::Test
6407
6626
  fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6408
6627
  end
6409
6628
 
6410
- def test_user_organization_membership_base_list_data_round_trip
6411
- fixture = {
6412
- "object" => "organization_membership",
6413
- "id" => "stub",
6414
- "user_id" => "stub",
6415
- "organization_id" => "stub",
6416
- "status" => "stub",
6417
- "directory_managed" => true,
6418
- "organization_name" => "stub",
6419
- "custom_attributes" => {},
6420
- "created_at" => "stub",
6421
- "updated_at" => "stub"
6422
- }
6423
- model = WorkOS::UserOrganizationMembershipBaseListData.new(fixture.to_json)
6424
- json = model.to_h
6425
- assert_kind_of Hash, json
6426
- assert_equal fixture["id"], json[:id]
6427
- assert_equal fixture["user_id"], json[:user_id]
6428
- assert_equal fixture["organization_id"], json[:organization_id]
6429
- assert_equal fixture["directory_managed"], json[:directory_managed]
6430
- assert_equal fixture["created_at"], json[:created_at]
6431
- assert_equal fixture["updated_at"], json[:updated_at]
6432
- fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" }
6433
- end
6434
-
6435
- def test_role_assignment_resource_round_trip
6629
+ def test_user_role_assignment_resource_round_trip
6436
6630
  fixture = {
6437
6631
  "id" => "stub",
6438
6632
  "external_id" => "stub",
6439
6633
  "resource_type_slug" => "stub"
6440
6634
  }
6441
- model = WorkOS::RoleAssignmentResource.new(fixture.to_json)
6635
+ model = WorkOS::UserRoleAssignmentResource.new(fixture.to_json)
6442
6636
  json = model.to_h
6443
6637
  assert_kind_of Hash, json
6444
6638
  assert_equal fixture["id"], json[:id]
@@ -6990,7 +7184,8 @@ class ModelRoundTripTest < Minitest::Test
6990
7184
  "custom_attributes" => {},
6991
7185
  "created_at" => "stub",
6992
7186
  "updated_at" => "stub",
6993
- "role" => {}
7187
+ "role" => {},
7188
+ "user" => {}
6994
7189
  }
6995
7190
  model = WorkOS::OrganizationMembership.new(fixture.to_json)
6996
7191
  json = model.to_h
@@ -26,11 +26,27 @@ class SessionTest < Minitest::Test
26
26
 
27
27
  def test_unseal_with_wrong_key_raises
28
28
  sealed = @sm.seal_data({"x" => 1}, PASSWORD)
29
+ # Wrong key is the same length (>= 32 bytes) so the length guard doesn't
30
+ # short-circuit; we want to assert the underlying cipher rejection.
29
31
  assert_raises(OpenSSL::Cipher::CipherError) do
30
- @sm.unseal_data(sealed, "wrong-password")
32
+ @sm.unseal_data(sealed, "wrong-cookie-password-32-bytes--")
31
33
  end
32
34
  end
33
35
 
36
+ def test_unseal_with_short_key_raises_argument_error
37
+ sealed = @sm.seal_data({"x" => 1}, PASSWORD)
38
+ assert_raises(ArgumentError) { @sm.unseal_data(sealed, "too-short") }
39
+ end
40
+
41
+ def test_seal_with_short_key_raises_argument_error
42
+ assert_raises(ArgumentError) { @sm.seal_data({"x" => 1}, "too-short") }
43
+ end
44
+
45
+ def test_session_load_requires_min_length_cookie_password
46
+ short = "x" * 31
47
+ assert_raises(ArgumentError) { @sm.load(seal_data: "x", cookie_password: short) }
48
+ end
49
+
34
50
  def test_unseal_rejects_short_payload
35
51
  assert_raises(ArgumentError) do
36
52
  @sm.unseal_data(Base64.strict_encode64("short"), PASSWORD)
@@ -334,6 +350,19 @@ class SessionTest < Minitest::Test
334
350
  assert_equal WorkOS::SessionManager::INVALID_SESSION_COOKIE, result.reason
335
351
  end
336
352
 
353
+ def test_refresh_raises_argument_error_for_short_cookie_password_override
354
+ sealed = @sm.seal_data({"access_token" => "at", "refresh_token" => "rt"}, PASSWORD)
355
+ session = @sm.load(seal_data: sealed, cookie_password: PASSWORD)
356
+ err = assert_raises(ArgumentError) { session.refresh(cookie_password: "x" * 31) }
357
+ assert_match(/at least 32 bytes/, err.message)
358
+ end
359
+
360
+ def test_refresh_raises_argument_error_for_empty_cookie_password_override
361
+ sealed = @sm.seal_data({"access_token" => "at", "refresh_token" => "rt"}, PASSWORD)
362
+ session = @sm.load(seal_data: sealed, cookie_password: PASSWORD)
363
+ assert_raises(ArgumentError) { session.refresh(cookie_password: "") }
364
+ end
365
+
337
366
  def test_refresh_returns_error_when_no_refresh_token
338
367
  sealed = @sm.seal_data({"access_token" => "at_only"}, PASSWORD)
339
368
  result = @sm.refresh(seal_data: sealed, cookie_password: PASSWORD)
@@ -361,7 +390,7 @@ class SessionTest < Minitest::Test
361
390
  assert_requested(stub)
362
391
  end
363
392
 
364
- def test_refresh_returns_error_on_malformed_access_token_without_mutating_state
393
+ def test_refresh_persists_seal_data_even_when_access_token_decode_fails
365
394
  rsa, pub = signing_key_pair
366
395
  old_access = make_jwt({"sid" => "session_old", "exp" => Time.now.to_i - 60}, rsa)
367
396
  sealed = @sm.seal_data({"access_token" => old_access, "refresh_token" => "rt_old", "user" => {"id" => "u_1"}}, PASSWORD)
@@ -383,8 +412,18 @@ class SessionTest < Minitest::Test
383
412
  assert_kind_of WorkOS::SessionManager::RefreshError, result
384
413
  refute result.authenticated
385
414
 
386
- # Session state should not have been mutated
387
- assert_equal sealed, session.seal_data
415
+ # Session state IS updated to the freshly-sealed cookie before decode runs,
416
+ # so a transient JWT/JWKS failure leaves a usable seal the caller can
417
+ # re-#authenticate against rather than half-updated state pinned to the
418
+ # stale (already-rotated) refresh token.
419
+ refute_equal sealed, session.seal_data
420
+ refute_nil session.seal_data
421
+
422
+ # The rotated cookie is also reachable through the RefreshError result, so a
423
+ # caller that doesn't retain the Session object across requests (typical in
424
+ # a Rails request cycle) can still write the new cookie back to the browser
425
+ # rather than re-sending the now-revoked refresh token on the next request.
426
+ assert_equal session.seal_data, result.sealed_session
388
427
  end
389
428
 
390
429
  # --- Session constructor validation ---------------------------------------
@@ -345,6 +345,13 @@ class UserManagementTest < Minitest::Test
345
345
  refute_nil result
346
346
  end
347
347
 
348
+ def test_list_jwt_template_returns_expected_result
349
+ stub_request(:get, %r{\Ahttps://api\.workos\.com/user_management/jwt_template(\?|\z)})
350
+ .to_return(body: "{}", status: 200)
351
+ result = @client.user_management.list_jwt_template
352
+ refute_nil result
353
+ end
354
+
348
355
  def test_update_jwt_template_returns_expected_result
349
356
  stub_request(:put, %r{\Ahttps://api\.workos\.com/user_management/jwt_template(\?|\z)})
350
357
  .to_return(body: "{}", status: 200)
@@ -454,6 +461,20 @@ class UserManagementTest < Minitest::Test
454
461
  assert_nil result
455
462
  end
456
463
 
464
+ def test_list_user_api_keys_returns_expected_result
465
+ stub_request(:get, %r{\Ahttps://api\.workos\.com/user_management/users/stub/api_keys(\?|\z)})
466
+ .to_return(body: '{"data": [], "list_metadata": {}}', status: 200)
467
+ result = @client.user_management.list_user_api_keys(user_id: "stub")
468
+ assert_kind_of WorkOS::Types::ListStruct, result
469
+ end
470
+
471
+ def test_create_user_api_key_returns_expected_result
472
+ stub_request(:post, %r{\Ahttps://api\.workos\.com/user_management/users/stub/api_keys(\?|\z)})
473
+ .to_return(body: "{}", status: 200)
474
+ result = @client.user_management.create_user_api_key(user_id: "stub", name: "stub", organization_id: "stub")
475
+ refute_nil result
476
+ end
477
+
457
478
  # Parameterized authentication error tests (one per endpoint).
458
479
  [
459
480
  {name: :get_jwks, verb: :get, url: %r{\Ahttps://api\.workos\.com/sso/jwks/stub(\?|\z)}, args: {client_id: "stub"}},
@@ -484,6 +505,7 @@ class UserManagementTest < Minitest::Test
484
505
  {name: :accept_invitation, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/invitations/stub/accept(\?|\z)}, args: {id: "stub"}},
485
506
  {name: :resend_invitation, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/invitations/stub/resend(\?|\z)}, args: {id: "stub"}},
486
507
  {name: :revoke_invitation, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/invitations/stub/revoke(\?|\z)}, args: {id: "stub"}},
508
+ {name: :list_jwt_template, verb: :get, url: %r{\Ahttps://api\.workos\.com/user_management/jwt_template(\?|\z)}},
487
509
  {name: :update_jwt_template, verb: :put, url: %r{\Ahttps://api\.workos\.com/user_management/jwt_template(\?|\z)}, args: {content: "stub"}},
488
510
  {name: :create_magic_auth, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/magic_auth(\?|\z)}, args: {email: "stub"}},
489
511
  {name: :get_magic_auth, verb: :get, url: %r{\Ahttps://api\.workos\.com/user_management/magic_auth/stub(\?|\z)}, args: {id: "stub"}},
@@ -496,7 +518,9 @@ class UserManagementTest < Minitest::Test
496
518
  {name: :reactivate_organization_membership, verb: :put, url: %r{\Ahttps://api\.workos\.com/user_management/organization_memberships/stub/reactivate(\?|\z)}, args: {id: "stub"}},
497
519
  {name: :create_redirect_uri, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/redirect_uris(\?|\z)}, args: {uri: "stub"}},
498
520
  {name: :list_user_authorized_applications, verb: :get, url: %r{\Ahttps://api\.workos\.com/user_management/users/stub/authorized_applications(\?|\z)}, args: {user_id: "stub"}},
499
- {name: :delete_user_authorized_application, verb: :delete, url: %r{\Ahttps://api\.workos\.com/user_management/users/stub/authorized_applications/stub(\?|\z)}, args: {application_id: "stub", user_id: "stub"}}
521
+ {name: :delete_user_authorized_application, verb: :delete, url: %r{\Ahttps://api\.workos\.com/user_management/users/stub/authorized_applications/stub(\?|\z)}, args: {application_id: "stub", user_id: "stub"}},
522
+ {name: :list_user_api_keys, verb: :get, url: %r{\Ahttps://api\.workos\.com/user_management/users/stub/api_keys(\?|\z)}, args: {user_id: "stub"}},
523
+ {name: :create_user_api_key, verb: :post, url: %r{\Ahttps://api\.workos\.com/user_management/users/stub/api_keys(\?|\z)}, args: {user_id: "stub", name: "stub", organization_id: "stub"}}
500
524
  ].each do |spec|
501
525
  define_method("test_#{spec[:name]}_raises_authentication_error_on_401") do
502
526
  stub_request(spec[:verb], spec[:url])