workosv2 2.15.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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +5 -0
  3. data/.github/pull_request_template.md +11 -0
  4. data/.github/renovate.json +5 -0
  5. data/.gitignore +49 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +24 -0
  8. data/.ruby-version +1 -0
  9. data/.semaphore/rubygems.yml +24 -0
  10. data/.semaphore/semaphore.yml +51 -0
  11. data/Gemfile +5 -0
  12. data/Gemfile.lock +126 -0
  13. data/Gemfile.lock.old +127 -0
  14. data/LICENSE +21 -0
  15. data/README.md +53 -0
  16. data/bin/build +3 -0
  17. data/bin/console +3 -0
  18. data/bin/docs +5 -0
  19. data/bin/publish +3 -0
  20. data/bin/tapioca +29 -0
  21. data/codecov.yml +12 -0
  22. data/docs/WorkOS/APIError.html +160 -0
  23. data/docs/WorkOS/AuditLog.html +235 -0
  24. data/docs/WorkOS/AuditTrail.html +235 -0
  25. data/docs/WorkOS/AuthenticationError.html +160 -0
  26. data/docs/WorkOS/Base.html +287 -0
  27. data/docs/WorkOS/Client.html +504 -0
  28. data/docs/WorkOS/InvalidRequestError.html +160 -0
  29. data/docs/WorkOS/Profile.html +788 -0
  30. data/docs/WorkOS/RequestError.html +135 -0
  31. data/docs/WorkOS/SSO.html +691 -0
  32. data/docs/WorkOS/Types/ProfileStruct.html +135 -0
  33. data/docs/WorkOS/Types/Provider.html +135 -0
  34. data/docs/WorkOS/Types.html +128 -0
  35. data/docs/WorkOS/WorkOSError.html +447 -0
  36. data/docs/WorkOS.html +324 -0
  37. data/docs/class_list.html +51 -0
  38. data/docs/css/common.css +1 -0
  39. data/docs/css/full_list.css +58 -0
  40. data/docs/css/style.css +496 -0
  41. data/docs/file.README.html +252 -0
  42. data/docs/file_list.html +56 -0
  43. data/docs/frames.html +17 -0
  44. data/docs/index.html +250 -0
  45. data/docs/js/app.js +314 -0
  46. data/docs/js/full_list.js +216 -0
  47. data/docs/js/jquery.js +4 -0
  48. data/docs/method_list.html +267 -0
  49. data/docs/top-level-namespace.html +110 -0
  50. data/lib/workosv2/audit_log_export.rb +55 -0
  51. data/lib/workosv2/audit_logs.rb +114 -0
  52. data/lib/workosv2/audit_trail.rb +111 -0
  53. data/lib/workosv2/challenge.rb +55 -0
  54. data/lib/workosv2/client.rb +186 -0
  55. data/lib/workosv2/configuration.rb +17 -0
  56. data/lib/workosv2/connection.rb +66 -0
  57. data/lib/workosv2/deprecated_hash_wrapper.rb +76 -0
  58. data/lib/workosv2/directory.rb +65 -0
  59. data/lib/workosv2/directory_group.rb +68 -0
  60. data/lib/workosv2/directory_sync.rb +218 -0
  61. data/lib/workosv2/directory_user.rb +97 -0
  62. data/lib/workosv2/errors.rb +81 -0
  63. data/lib/workosv2/event.rb +51 -0
  64. data/lib/workosv2/events.rb +52 -0
  65. data/lib/workosv2/factor.rb +54 -0
  66. data/lib/workosv2/hash_provider.rb +19 -0
  67. data/lib/workosv2/mfa.rb +178 -0
  68. data/lib/workosv2/organization.rb +57 -0
  69. data/lib/workosv2/organizations.rb +188 -0
  70. data/lib/workosv2/passwordless.rb +85 -0
  71. data/lib/workosv2/portal.rb +66 -0
  72. data/lib/workosv2/profile.rb +76 -0
  73. data/lib/workosv2/profile_and_token.rb +29 -0
  74. data/lib/workosv2/sso.rb +297 -0
  75. data/lib/workosv2/types/audit_log_export_struct.rb +17 -0
  76. data/lib/workosv2/types/challenge_struct.rb +18 -0
  77. data/lib/workosv2/types/connection_struct.rb +20 -0
  78. data/lib/workosv2/types/directory_group_struct.rb +19 -0
  79. data/lib/workosv2/types/directory_struct.rb +19 -0
  80. data/lib/workosv2/types/directory_user_struct.rb +26 -0
  81. data/lib/workosv2/types/event_struct.rb +15 -0
  82. data/lib/workosv2/types/factor_struct.rb +18 -0
  83. data/lib/workosv2/types/intent_enum.rb +17 -0
  84. data/lib/workosv2/types/list_struct.rb +13 -0
  85. data/lib/workosv2/types/organization_struct.rb +17 -0
  86. data/lib/workosv2/types/passwordless_session_struct.rb +17 -0
  87. data/lib/workosv2/types/profile_struct.rb +21 -0
  88. data/lib/workosv2/types/provider_enum.rb +15 -0
  89. data/lib/workosv2/types/verify_challenge_struct.rb +13 -0
  90. data/lib/workosv2/types/webhook_struct.rb +15 -0
  91. data/lib/workosv2/types.rb +25 -0
  92. data/lib/workosv2/verify_challenge.rb +39 -0
  93. data/lib/workosv2/version.rb +6 -0
  94. data/lib/workosv2/webhook.rb +51 -0
  95. data/lib/workosv2/webhooks.rb +217 -0
  96. data/lib/workosv2.rb +79 -0
  97. data/sorbet/config +2 -0
  98. data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
  99. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  100. data/sorbet/rbi/gems/codecov@0.2.12.rbi +55 -0
  101. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  102. data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
  103. data/sorbet/rbi/gems/diff-lcs@1.4.4.rbi +185 -0
  104. data/sorbet/rbi/gems/docile@1.3.5.rbi +54 -0
  105. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
  106. data/sorbet/rbi/gems/json@2.5.1.rbi +109 -0
  107. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  108. data/sorbet/rbi/gems/parallel@1.20.1.rbi +113 -0
  109. data/sorbet/rbi/gems/parser@3.0.1.0.rbi +1187 -0
  110. data/sorbet/rbi/gems/pry@0.14.2.rbi +8 -0
  111. data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +146 -0
  112. data/sorbet/rbi/gems/rainbow@3.0.0.rbi +153 -0
  113. data/sorbet/rbi/gems/rake@13.0.3.rbi +807 -0
  114. data/sorbet/rbi/gems/rbi@0.0.16.rbi +2118 -0
  115. data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +1117 -0
  116. data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
  117. data/sorbet/rbi/gems/rspec-core@3.9.3.rbi +2467 -0
  118. data/sorbet/rbi/gems/rspec-expectations@3.9.4.rbi +1569 -0
  119. data/sorbet/rbi/gems/rspec-mocks@3.9.1.rbi +1493 -0
  120. data/sorbet/rbi/gems/rspec-support@3.9.4.rbi +511 -0
  121. data/sorbet/rbi/gems/rspec@3.9.0.rbi +38 -0
  122. data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +1881 -0
  123. data/sorbet/rbi/gems/rubocop@0.93.1.rbi +11497 -0
  124. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
  125. data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
  126. data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
  127. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.2.rbi +8 -0
  128. data/sorbet/rbi/gems/spoom@1.1.15.rbi +1549 -0
  129. data/sorbet/rbi/gems/tapioca@0.7.3.rbi +1718 -0
  130. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  131. data/sorbet/rbi/gems/unicode-display_width@1.7.0.rbi +22 -0
  132. data/sorbet/rbi/gems/unparser@0.6.2.rbi +8 -0
  133. data/sorbet/rbi/gems/vcr@5.0.0.rbi +699 -0
  134. data/sorbet/rbi/gems/webmock@3.12.2.rbi +662 -0
  135. data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +268 -0
  136. data/sorbet/rbi/gems/yard@0.9.26.rbi +4048 -0
  137. data/sorbet/tapioca/config.yml +13 -0
  138. data/sorbet/tapioca/require.rb +4 -0
  139. data/spec/lib/workos/audit_logs_spec.rb +151 -0
  140. data/spec/lib/workos/audit_trail_spec.rb +146 -0
  141. data/spec/lib/workos/configuration_spec.rb +61 -0
  142. data/spec/lib/workos/directory_sync_spec.rb +492 -0
  143. data/spec/lib/workos/directory_user_spec.rb +36 -0
  144. data/spec/lib/workos/event_spec.rb +88 -0
  145. data/spec/lib/workos/mfa_spec.rb +281 -0
  146. data/spec/lib/workos/organizations_spec.rb +257 -0
  147. data/spec/lib/workos/passwordless_spec.rb +77 -0
  148. data/spec/lib/workos/portal_spec.rb +87 -0
  149. data/spec/lib/workos/sso_spec.rb +650 -0
  150. data/spec/lib/workos/webhooks_spec.rb +236 -0
  151. data/spec/spec_helper.rb +56 -0
  152. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event.yml +59 -0
  153. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_custom_idempotency_key.yml +60 -0
  154. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_invalid.yml +59 -0
  155. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export.yml +76 -0
  156. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export_with_filters.yml +77 -0
  157. data/spec/support/fixtures/vcr_cassettes/audit_logs/get_export.yml +73 -0
  158. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml +65 -0
  159. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_custom_idempotency_key.yml +67 -0
  160. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml +68 -0
  161. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml +131 -0
  162. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml +134 -0
  163. data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +61 -0
  164. data/spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml +66 -0
  165. data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
  166. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_invalid_id.yml +83 -0
  167. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_valid_id.yml +84 -0
  168. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml +80 -0
  169. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml +62 -0
  170. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +83 -0
  171. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user_with_invalid_id.yml +62 -0
  172. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_after.yml +87 -0
  173. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_before.yml +89 -0
  174. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_domain.yml +84 -0
  175. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_limit.yml +85 -0
  176. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_no_options.yml +93 -0
  177. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +85 -0
  178. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +90 -0
  179. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +90 -0
  180. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +90 -0
  181. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +84 -0
  182. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_no_options.yml +84 -0
  183. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +82 -0
  184. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +186 -0
  185. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +88 -0
  186. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +194 -0
  187. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +186 -0
  188. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +189 -0
  189. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_no_options.yml +74 -0
  190. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_after.yml +80 -0
  191. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_event.yml +80 -0
  192. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_no_options.yml +80 -0
  193. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_range.yml +80 -0
  194. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
  195. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
  196. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
  197. data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
  198. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
  199. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
  200. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
  201. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
  202. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
  203. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml +84 -0
  204. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml +84 -0
  205. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml +82 -0
  206. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml +82 -0
  207. data/spec/support/fixtures/vcr_cassettes/organization/create.yml +84 -0
  208. data/spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml +72 -0
  209. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_different_payload.yml +155 -0
  210. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_payload.yml +154 -0
  211. data/spec/support/fixtures/vcr_cassettes/organization/create_with_idempotency_key.yml +79 -0
  212. data/spec/support/fixtures/vcr_cassettes/organization/delete.yml +72 -0
  213. data/spec/support/fixtures/vcr_cassettes/organization/delete_invalid.yml +72 -0
  214. data/spec/support/fixtures/vcr_cassettes/organization/get.yml +84 -0
  215. data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
  216. data/spec/support/fixtures/vcr_cassettes/organization/list.yml +87 -0
  217. data/spec/support/fixtures/vcr_cassettes/organization/update.yml +84 -0
  218. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml +72 -0
  219. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml +73 -0
  220. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session.yml +72 -0
  221. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session_invalid.yml +73 -0
  222. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_audit_logs.yml +72 -0
  223. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
  224. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml +72 -0
  225. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_sso.yml +72 -0
  226. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
  227. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
  228. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
  229. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +86 -0
  230. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +83 -0
  231. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +86 -0
  232. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +90 -0
  233. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_domain.yml +86 -0
  234. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +83 -0
  235. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +89 -0
  236. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_organization_id.yml +86 -0
  237. data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +74 -0
  238. data/spec/support/profile.txt +1 -0
  239. data/spec/support/shared_examples/client_spec.rb +30 -0
  240. data/spec/support/webhook_payload.txt +1 -0
  241. data/workosv2.gemspec +38 -0
  242. metadata +531 -0
@@ -0,0 +1,297 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module WorkOSV2
8
+ # The SSO module provides convenience methods for working with the WorkOSV2
9
+ # SSO platform. You'll need a valid API key, a client ID, and to have
10
+ # created an SSO connection on your WorkOSV2 dashboard.
11
+ #
12
+ # @see https://docs.workos.com/sso/overview
13
+ module SSO
14
+ class << self
15
+ extend T::Sig
16
+ include Client
17
+
18
+ PROVIDERS = WorkOSV2::Types::Provider.values.map(&:serialize).freeze
19
+
20
+ # Generate an Oauth2 authorization URL where your users will
21
+ # authenticate using the configured SSO Identity Provider.
22
+ #
23
+ # @param [String] redirect_uri The URI where users are directed
24
+ # after completing the authentication step. Must match a
25
+ # configured redirect URI on your WorkOSV2 dashboard.
26
+ # @param [String] client_id The WorkOSV2 client ID for the environment
27
+ # where you've configured your SSO connection.
28
+ # @param [String] domain The domain for the relevant SSO Connection
29
+ # configured on your WorkOSV2 dashboard. One of provider, domain,
30
+ # connection, or organization is required.
31
+ # The domain is deprecated.
32
+ # @param [String] provider A provider name for an Identity Provider
33
+ # configured on your WorkOSV2 dashboard. Only 'GoogleOAuth' and
34
+ # 'MicrosoftOAuth' are supported.
35
+ # @param [String] connection The ID for a Connection configured on
36
+ # WorkOSV2.
37
+ # @param [String] organization The ID for an Organization configured
38
+ # on WorkOSV2.
39
+ # @param [String] state An arbitrary state object
40
+ # that is preserved and available to the client in the response.
41
+ # @example
42
+ # WorkOSV2::SSO.authorization_url(
43
+ # connection: 'conn_123',
44
+ # client_id: 'project_01DG5TGK363GRVXP3ZS40WNGEZ',
45
+ # redirect_uri: 'https://workos.com/callback',
46
+ # state: {
47
+ # next_page: '/docs'
48
+ # }.to_s
49
+ # )
50
+ #
51
+ # => "https://api.workos.com/sso/authorize?connection=conn_123" \
52
+ # "&client_id=project_01DG5TGK363GRVXP3ZS40WNGEZ" \
53
+ # "&redirect_uri=https%3A%2F%2Fworkos.com%2Fcallback&" \
54
+ # "response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdocs%22%7D"
55
+ #
56
+ # @return [String]
57
+ # rubocop:disable Metrics/ParameterLists
58
+ sig do
59
+ params(
60
+ redirect_uri: String,
61
+ client_id: T.nilable(String),
62
+ domain: T.nilable(String),
63
+ domain_hint: T.nilable(String),
64
+ login_hint: T.nilable(String),
65
+ provider: T.nilable(String),
66
+ connection: T.nilable(String),
67
+ organization: T.nilable(String),
68
+ state: T.nilable(String),
69
+ ).returns(String)
70
+ end
71
+ def authorization_url(
72
+ redirect_uri:,
73
+ client_id: nil,
74
+ domain: nil,
75
+ domain_hint: nil,
76
+ login_hint: nil,
77
+ provider: nil,
78
+ connection: nil,
79
+ organization: nil,
80
+ state: ''
81
+ )
82
+ if domain
83
+ warn '[DEPRECATION] `domain` is deprecated.
84
+ Please use `organization` instead.'
85
+ end
86
+
87
+ validate_authorization_url_arguments(
88
+ provider: provider,
89
+ domain: domain,
90
+ connection: connection,
91
+ organization: organization,
92
+ )
93
+
94
+ query = URI.encode_www_form({
95
+ client_id: client_id,
96
+ redirect_uri: redirect_uri,
97
+ response_type: 'code',
98
+ state: state,
99
+ domain: domain,
100
+ domain_hint: domain_hint,
101
+ login_hint: login_hint,
102
+ provider: provider,
103
+ connection: connection,
104
+ organization: organization,
105
+ }.compact)
106
+
107
+ "https://#{WorkOSV2::API_HOSTNAME}/sso/authorize?#{query}"
108
+ end
109
+ # rubocop:enable Metrics/ParameterLists
110
+
111
+ sig do
112
+ params(
113
+ access_token: String,
114
+ ).returns(WorkOSV2::Profile)
115
+ end
116
+ def get_profile(access_token:)
117
+ response = execute_request(
118
+ request: get_request(
119
+ path: '/sso/profile',
120
+ auth: true,
121
+ access_token: access_token,
122
+ ),
123
+ )
124
+
125
+ WorkOSV2::Profile.new(response.body)
126
+ end
127
+
128
+ # Fetch the profile details for the authenticated SSO user.
129
+ #
130
+ # @param [String] code The authorization code provided in the callback URL
131
+ # @param [String] client_id The WorkOSV2 client ID for the environment
132
+ # where you've configured your SSO connection
133
+ #
134
+ # @return [WorkOSV2::ProfileAndToken]
135
+ sig do
136
+ params(
137
+ code: String,
138
+ client_id: T.nilable(String),
139
+ ).returns(WorkOSV2::ProfileAndToken)
140
+ end
141
+ def profile_and_token(code:, client_id: nil)
142
+ body = {
143
+ client_id: client_id,
144
+ client_secret: WorkOSV2.config.key!,
145
+ grant_type: 'authorization_code',
146
+ code: code,
147
+ }
148
+
149
+ response = client.request(post_request(path: '/sso/token', body: body))
150
+ check_and_raise_profile_and_token_error(response: response)
151
+
152
+ WorkOSV2::ProfileAndToken.new(response.body)
153
+ end
154
+
155
+ # Retrieve connections.
156
+ #
157
+ # @param [Hash] options An options hash
158
+ # @option options [String] connection_type Authentication service
159
+ # provider descriptor.
160
+ # @option options [String] domain The domain of the connection to be
161
+ # retrieved.
162
+ # @option options [String] organization_id The id of the organization
163
+ # of the connections to be retrieved.
164
+ # @option options [String] limit Maximum number of records to return.
165
+ # @option options [String] order The order in which to paginate records
166
+ # @option options [String] before Pagination cursor to receive records
167
+ # before a provided Connection ID.
168
+ # @option options [String] after Pagination cursor to receive records
169
+ # before a provided Connection ID.
170
+ #
171
+ # @return [Hash]
172
+ sig do
173
+ params(
174
+ options: T::Hash[Symbol, String],
175
+ ).returns(WorkOSV2::Types::ListStruct)
176
+ end
177
+ def list_connections(options = {})
178
+ response = execute_request(
179
+ request: get_request(
180
+ path: '/connections',
181
+ auth: true,
182
+ params: options,
183
+ ),
184
+ )
185
+
186
+ parsed_response = JSON.parse(response.body)
187
+ connections = parsed_response['data'].map do |connection|
188
+ ::WorkOSV2::Connection.new(connection.to_json)
189
+ end
190
+
191
+ WorkOSV2::Types::ListStruct.new(
192
+ data: connections,
193
+ list_metadata: parsed_response['listMetadata'],
194
+ )
195
+ end
196
+
197
+ # Get a Connection
198
+ #
199
+ # @param [String] id Connection unique identifier
200
+ #
201
+ # @example
202
+ # WorkOSV2::SSO.get_connection(id: 'conn_02DRA1XNSJDZ19A31F183ECQW9')
203
+ # => #<WorkOSV2::Connection:0x00007fb6e4193d20
204
+ # @id="conn_02DRA1XNSJDZ19A31F183ECQW9",
205
+ # @name="Foo Corp",
206
+ # @connection_type="OktaSAML",
207
+ # @domains=
208
+ # [{:object=>"connection_domain",
209
+ # :id=>"domain_01E6PK9N3XMD8RHWF7S66380AR",
210
+ # :domain=>"example.com"}]>
211
+ #
212
+ # @return [WorkOSV2::Connection]
213
+ sig { params(id: String).returns(WorkOSV2::Connection) }
214
+ def get_connection(id:)
215
+ request = get_request(
216
+ auth: true,
217
+ path: "/connections/#{id}",
218
+ )
219
+
220
+ response = execute_request(request: request)
221
+
222
+ WorkOSV2::Connection.new(response.body)
223
+ end
224
+
225
+ # Delete a Connection
226
+ #
227
+ # @param [String] id Connection unique identifier
228
+ #
229
+ # @example
230
+ # WorkOSV2::SSO.delete_connection(id: 'conn_02DRA1XNSJDZ19A31F183ECQW9')
231
+ # => true
232
+ #
233
+ # @return [Bool] - returns `true` if successful
234
+ sig { params(id: String).returns(T::Boolean) }
235
+ def delete_connection(id:)
236
+ request = delete_request(
237
+ auth: true,
238
+ path: "/connections/#{id}",
239
+ )
240
+
241
+ response = execute_request(request: request)
242
+
243
+ response.is_a? Net::HTTPSuccess
244
+ end
245
+
246
+ private
247
+
248
+ sig do
249
+ params(
250
+ domain: T.nilable(String),
251
+ provider: T.nilable(String),
252
+ connection: T.nilable(String),
253
+ organization: T.nilable(String),
254
+ ).void
255
+ end
256
+ def validate_authorization_url_arguments(
257
+ domain:,
258
+ provider:,
259
+ connection:,
260
+ organization:
261
+ )
262
+ if [domain, provider, connection, organization].all?(&:nil?)
263
+ raise ArgumentError, 'Either connection, domain, ' \
264
+ 'provider, or organization is required.'
265
+ end
266
+
267
+ return unless provider && !PROVIDERS.include?(provider)
268
+
269
+ raise ArgumentError, "#{provider} is not a valid value." \
270
+ " `provider` must be in #{PROVIDERS}"
271
+ end
272
+
273
+ sig { params(response: Net::HTTPResponse).void }
274
+ def check_and_raise_profile_and_token_error(response:)
275
+ begin
276
+ body = JSON.parse(response.body)
277
+ return if body['access_token'] && body['profile']
278
+
279
+ message = body['message']
280
+ error = body['error']
281
+ error_description = body['error_description']
282
+ request_id = response['x-request-id']
283
+ rescue StandardError
284
+ message = 'Something went wrong'
285
+ end
286
+
287
+ raise APIError.new(
288
+ message: message,
289
+ error: error,
290
+ error_description: error_description,
291
+ http_status: nil,
292
+ request_id: request_id,
293
+ )
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This AuditLogExportStruct acts as a typed interface
7
+ # for the AuditLogExport class
8
+ class AuditLogExportStruct < T::Struct
9
+ const :object, String
10
+ const :id, String
11
+ const :state, String
12
+ const :url, T.nilable(String)
13
+ const :created_at, String
14
+ const :updated_at, String
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This ChallgengeStruct acts as a typed interface
7
+ # for the Factor class
8
+ class ChallengeStruct < T::Struct
9
+ const :id, String
10
+ const :object, String
11
+ const :expires_at, String
12
+ const :code, T.nilable(String)
13
+ const :authentication_factor_id, String
14
+ const :created_at, String
15
+ const :updated_at, String
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This ConnectionStruct acts as a typed interface
7
+ # for the Connection class
8
+ class ConnectionStruct < T::Struct
9
+ const :id, String
10
+ const :name, String
11
+ const :connection_type, String
12
+ const :domains, T::Array[T.untyped]
13
+ const :organization_id, T.nilable(String)
14
+ const :state, String
15
+ const :status, String
16
+ const :created_at, String
17
+ const :updated_at, String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This DirectoryGroupStruct acts as a typed interface
7
+ # for the DirectoryGroup class
8
+ class DirectoryGroupStruct < T::Struct
9
+ const :id, String
10
+ const :directory_id, String
11
+ const :organization_id, T.nilable(String)
12
+ const :idp_id, String
13
+ const :name, String
14
+ const :created_at, String
15
+ const :updated_at, String
16
+ const :raw_attributes, T::Hash[Symbol, Object]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This DirectoryStruct acts as a typed interface
7
+ # for the Directory class
8
+ class DirectoryStruct < T::Struct
9
+ const :id, String
10
+ const :name, String
11
+ const :domain, T.nilable(String)
12
+ const :type, String
13
+ const :state, String
14
+ const :organization_id, T.nilable(String)
15
+ const :created_at, String
16
+ const :updated_at, String
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # The DirectoryUserStruct acts as a typed interface
7
+ # for the DirectoryUser class
8
+ class DirectoryUserStruct < T::Struct
9
+ const :id, String
10
+ const :directory_id, String
11
+ const :organization_id, T.nilable(String)
12
+ const :idp_id, String
13
+ const :emails, T::Array[T.untyped]
14
+ const :first_name, T.nilable(String)
15
+ const :last_name, T.nilable(String)
16
+ const :job_title, T.nilable(String)
17
+ const :username, T.nilable(String)
18
+ const :state, T.nilable(String)
19
+ const :groups, T::Array[T.untyped]
20
+ const :custom_attributes, T::Hash[Symbol, T.untyped]
21
+ const :raw_attributes, T::Hash[Symbol, Object]
22
+ const :created_at, String
23
+ const :updated_at, String
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # The EventStruct acts as a typed interface
7
+ # for the Event class
8
+ class EventStruct < T::Struct
9
+ const :id, String
10
+ const :event, String
11
+ const :data, T::Hash[Symbol, Object]
12
+ const :created_at, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This FactorStruct acts as a typed interface
7
+ # for the Factor class
8
+ class FactorStruct < T::Struct
9
+ const :id, String
10
+ const :object, String
11
+ const :type, String
12
+ const :totp, T.nilable(T::Hash[Symbol, Object])
13
+ const :sms, T.nilable(T::Hash[Symbol, Object])
14
+ const :created_at, String
15
+ const :updated_at, String
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # The IntentEnum is type-safe declarations of a fixed set of values for
7
+ # intents while generating an Admin Portal link.
8
+ class Intent < T::Enum
9
+ enums do
10
+ AUDIT_LOGS = new('audit_logs')
11
+ DSYNC = new('dsync')
12
+ LOG_STREAMS = new('log_streams')
13
+ SSO = new('sso')
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # ListStruct acts as a typed interface to expose lists of data and related
7
+ # metadata
8
+ class ListStruct < T::Struct
9
+ const :data, T::Array[T.untyped]
10
+ const :list_metadata, T::Hash[String, T.nilable(String)]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This OrganizationStruct acts as a typed interface
7
+ # for the Organization class
8
+ class OrganizationStruct < T::Struct
9
+ const :id, String
10
+ const :name, String
11
+ const :allow_profiles_outside_organization, T::Boolean
12
+ const :domains, T::Array[T.untyped]
13
+ const :created_at, String
14
+ const :updated_at, String
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ require 'date'
5
+
6
+ module WorkOSV2
7
+ module Types
8
+ # This PasswordlessSessionStruct acts as a typed interface
9
+ # for the Passwordless class
10
+ class PasswordlessSessionStruct < T::Struct
11
+ const :id, String
12
+ const :email, String
13
+ const :expires_at, Date
14
+ const :link, String
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # The ProfileStruct acts as a typed interface
7
+ # for the Profile class
8
+ class ProfileStruct < T::Struct
9
+ const :id, String
10
+ const :email, String
11
+ const :first_name, T.nilable(String)
12
+ const :last_name, T.nilable(String)
13
+ const :groups, T.nilable(T::Array[String])
14
+ const :organization_id, T.nilable(String)
15
+ const :connection_id, String
16
+ const :connection_type, String
17
+ const :idp_id, T.nilable(String)
18
+ const :raw_attributes, T::Hash[Symbol, Object]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # The ProviderEnum is type-safe declarations of a
7
+ # fixed set of values for SSO Providers.
8
+ class Provider < T::Enum
9
+ enums do
10
+ Google = new('GoogleOAuth')
11
+ Microsoft = new('MicrosoftOAuth')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This VerifyChallengeStruct acts as a typed interface
7
+ # for the VerifyChallenge class
8
+ class VerifyChallengeStruct < T::Struct
9
+ const :challenge, T.nilable(T::Hash[Symbol, Object])
10
+ const :valid, T::Boolean
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module WorkOSV2
5
+ module Types
6
+ # This WebhookStruct acts as a typed interface
7
+ # for the Webhook class
8
+ class WebhookStruct < T::Struct
9
+ const :id, String
10
+ const :event, String
11
+ const :data, T::Hash[Symbol, Object]
12
+ const :created_at, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ # typed: strong
3
+
4
+ module WorkOSV2
5
+ # WorkOSV2 believes strongly in typed languages,
6
+ # so we're using Sorbet throughout this Ruby gem.
7
+ module Types
8
+ require_relative 'types/audit_log_export_struct'
9
+ require_relative 'types/connection_struct'
10
+ require_relative 'types/directory_struct'
11
+ require_relative 'types/directory_group_struct'
12
+ require_relative 'types/event_struct'
13
+ require_relative 'types/intent_enum'
14
+ require_relative 'types/list_struct'
15
+ require_relative 'types/organization_struct'
16
+ require_relative 'types/passwordless_session_struct'
17
+ require_relative 'types/profile_struct'
18
+ require_relative 'types/provider_enum'
19
+ require_relative 'types/directory_user_struct'
20
+ require_relative 'types/webhook_struct'
21
+ require_relative 'types/factor_struct'
22
+ require_relative 'types/challenge_struct'
23
+ require_relative 'types/verify_challenge_struct'
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ module WorkOSV2
5
+ # The VerifyChallenge class provides a lightweight wrapper around
6
+ # a WorkOSV2 Authentication Challenge resource.
7
+ class VerifyChallenge
8
+ include HashProvider
9
+ extend T::Sig
10
+
11
+ attr_accessor :challenge, :valid
12
+
13
+ sig { params(json: String).void }
14
+ def initialize(json)
15
+ raw = parse_json(json)
16
+ @challenge = T.let(raw.challenge, Hash)
17
+ @valid = raw.valid
18
+ end
19
+
20
+ def to_json(*)
21
+ {
22
+ challenge: challenge,
23
+ valid: valid,
24
+ }
25
+ end
26
+
27
+ private
28
+
29
+ sig { params(json_string: String).returns(WorkOSV2::Types::VerifyChallengeStruct) }
30
+ def parse_json(json_string)
31
+ hash = JSON.parse(json_string, symbolize_names: true)
32
+
33
+ WorkOSV2::Types::VerifyChallengeStruct.new(
34
+ challenge: hash[:challenge],
35
+ valid: hash[:valid],
36
+ )
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # typed: strong
3
+
4
+ module WorkOSV2
5
+ VERSION = '2.15.0'
6
+ end