workos 2.16.0 → 3.0.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile.lock +5 -14
  4. data/lib/workos/authentication_factor_and_challenge.rb +31 -0
  5. data/lib/workos/authentication_response.rb +27 -0
  6. data/lib/workos/client.rb +1 -1
  7. data/lib/workos/configuration.rb +1 -1
  8. data/lib/workos/invitation.rb +68 -0
  9. data/lib/workos/organization_membership.rb +50 -0
  10. data/lib/workos/sso.rb +1 -1
  11. data/lib/workos/types/invitation_struct.rb +20 -0
  12. data/lib/workos/types/magic_auth_challenge_struct.rb +12 -0
  13. data/lib/workos/types/organization_membership_struct.rb +15 -0
  14. data/lib/workos/types/provider_enum.rb +1 -0
  15. data/lib/workos/types/user_struct.rb +17 -0
  16. data/lib/workos/types.rb +9 -5
  17. data/lib/workos/user.rb +57 -0
  18. data/lib/workos/user_and_token.rb +29 -0
  19. data/lib/workos/user_management.rb +1008 -0
  20. data/lib/workos/user_response.rb +25 -0
  21. data/lib/workos/version.rb +1 -1
  22. data/lib/workos.rb +35 -28
  23. data/spec/lib/workos/sso_spec.rb +8 -8
  24. data/spec/lib/workos/user_management_spec.rb +1092 -0
  25. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/invalid.yml +84 -0
  26. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid.yml +82 -0
  27. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/invalid.yml +83 -0
  28. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/valid.yml +81 -0
  29. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/invalid.yml +82 -0
  30. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/valid.yml +82 -0
  31. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_organization_selection/invalid.yml +81 -0
  32. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_organization_selection/valid.yml +82 -0
  33. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/invalid.yml +82 -0
  34. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/valid.yml +82 -0
  35. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_totp/invalid.yml +83 -0
  36. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_totp/valid.yml +81 -0
  37. data/spec/support/fixtures/vcr_cassettes/user_management/confirm_password_reset/invalid.yml +82 -0
  38. data/spec/support/fixtures/vcr_cassettes/user_management/confirm_password_reset/valid.yml +82 -0
  39. data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/invalid.yml +83 -0
  40. data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/valid.yml +82 -0
  41. data/spec/support/fixtures/vcr_cassettes/user_management/create_user_invalid.yml +83 -0
  42. data/spec/support/fixtures/vcr_cassettes/user_management/create_user_valid.yml +82 -0
  43. data/spec/support/fixtures/vcr_cassettes/user_management/delete_organization_membership/invalid.yml +82 -0
  44. data/spec/support/fixtures/vcr_cassettes/user_management/delete_organization_membership/valid.yml +78 -0
  45. data/spec/support/fixtures/vcr_cassettes/user_management/delete_user/invalid.yml +82 -0
  46. data/spec/support/fixtures/vcr_cassettes/user_management/delete_user/valid.yml +78 -0
  47. data/spec/support/fixtures/vcr_cassettes/user_management/enroll_auth_factor/invalid.yml +82 -0
  48. data/spec/support/fixtures/vcr_cassettes/user_management/enroll_auth_factor/valid.yml +82 -0
  49. data/spec/support/fixtures/vcr_cassettes/user_management/get_invitation/invalid.yml +82 -0
  50. data/spec/support/fixtures/vcr_cassettes/user_management/get_invitation/valid.yml +82 -0
  51. data/spec/support/fixtures/vcr_cassettes/user_management/get_organization_membership.yml +82 -0
  52. data/spec/support/fixtures/vcr_cassettes/user_management/get_user.yml +82 -0
  53. data/spec/support/fixtures/vcr_cassettes/user_management/list_auth_factors/invalid.yml +82 -0
  54. data/spec/support/fixtures/vcr_cassettes/user_management/list_auth_factors/valid.yml +82 -0
  55. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_after.yml +83 -0
  56. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_before.yml +83 -0
  57. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_limit.yml +83 -0
  58. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_no_options.yml +83 -0
  59. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_organization_id.yml +83 -0
  60. data/spec/support/fixtures/vcr_cassettes/user_management/list_organization_memberships/no_options.yml +82 -0
  61. data/spec/support/fixtures/vcr_cassettes/user_management/list_organization_memberships/with_options.yml +82 -0
  62. data/spec/support/fixtures/vcr_cassettes/user_management/list_users/no_options.yml +82 -0
  63. data/spec/support/fixtures/vcr_cassettes/user_management/list_users/with_options.yml +82 -0
  64. data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/invalid.yml +82 -0
  65. data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/valid.yml +82 -0
  66. data/spec/support/fixtures/vcr_cassettes/user_management/revoke_invitation/invalid.yml +82 -0
  67. data/spec/support/fixtures/vcr_cassettes/user_management/revoke_invitation/valid.yml +82 -0
  68. data/spec/support/fixtures/vcr_cassettes/user_management/send_invitation/invalid.yml +82 -0
  69. data/spec/support/fixtures/vcr_cassettes/user_management/send_invitation/valid.yml +82 -0
  70. data/spec/support/fixtures/vcr_cassettes/user_management/send_magic_auth_code/valid.yml +82 -0
  71. data/spec/support/fixtures/vcr_cassettes/user_management/send_password_reset_email/invalid.yml +83 -0
  72. data/spec/support/fixtures/vcr_cassettes/user_management/send_password_reset_email/valid.yml +82 -0
  73. data/spec/support/fixtures/vcr_cassettes/user_management/send_verification_email/invalid.yml +82 -0
  74. data/spec/support/fixtures/vcr_cassettes/user_management/send_verification_email/valid.yml +82 -0
  75. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/invalid.yml +82 -0
  76. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/valid.yml +82 -0
  77. data/spec/support/fixtures/vcr_cassettes/user_management/update_user_password/invalid.yml +82 -0
  78. data/spec/support/fixtures/vcr_cassettes/user_management/update_user_password/valid.yml +82 -0
  79. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/invalid_code.yml +83 -0
  80. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/invalid_magic_auth_challenge.yml +82 -0
  81. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/valid.yml +82 -0
  82. data/workos.gemspec +0 -2
  83. metadata +132 -55
  84. data/bin/docs +0 -5
  85. data/docs/WorkOS/APIError.html +0 -160
  86. data/docs/WorkOS/AuditLog.html +0 -235
  87. data/docs/WorkOS/AuditTrail.html +0 -235
  88. data/docs/WorkOS/AuthenticationError.html +0 -160
  89. data/docs/WorkOS/Base.html +0 -287
  90. data/docs/WorkOS/Client.html +0 -504
  91. data/docs/WorkOS/InvalidRequestError.html +0 -160
  92. data/docs/WorkOS/Profile.html +0 -788
  93. data/docs/WorkOS/RequestError.html +0 -135
  94. data/docs/WorkOS/SSO.html +0 -691
  95. data/docs/WorkOS/Types/ProfileStruct.html +0 -135
  96. data/docs/WorkOS/Types/Provider.html +0 -135
  97. data/docs/WorkOS/Types.html +0 -128
  98. data/docs/WorkOS/WorkOSError.html +0 -447
  99. data/docs/WorkOS.html +0 -324
  100. data/docs/class_list.html +0 -51
  101. data/docs/css/common.css +0 -1
  102. data/docs/css/full_list.css +0 -58
  103. data/docs/css/style.css +0 -496
  104. data/docs/file.README.html +0 -252
  105. data/docs/file_list.html +0 -56
  106. data/docs/frames.html +0 -17
  107. data/docs/index.html +0 -250
  108. data/docs/js/app.js +0 -314
  109. data/docs/js/full_list.js +0 -216
  110. data/docs/js/jquery.js +0 -4
  111. data/docs/method_list.html +0 -267
  112. data/docs/top-level-namespace.html +0 -110
  113. data/lib/workos/audit_trail.rb +0 -111
  114. data/spec/lib/workos/audit_trail_spec.rb +0 -146
@@ -0,0 +1,1008 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module WorkOS
8
+ # The UserManagement module provides convenience methods for working with the
9
+ # WorkOS User platform. You'll need a valid API key.
10
+
11
+ # rubocop:disable Metrics/ModuleLength
12
+ module UserManagement
13
+ module Types
14
+ # The ProviderEnum is type-safe declaration of a
15
+ # fixed set of values for User Management Providers.
16
+ class Provider < T::Enum
17
+ enums do
18
+ GitHub = new('GitHubOAuth')
19
+ Google = new('GoogleOAuth')
20
+ Microsoft = new('MicrosoftOAuth')
21
+ AuthKit = new('authkit')
22
+ end
23
+ end
24
+
25
+ # The AuthFactorType is type-safe declaration of a
26
+ # fixed set of factor values to enroll
27
+ class AuthFactorType < T::Enum
28
+ enums do
29
+ Totp = new('totp')
30
+ end
31
+ end
32
+ end
33
+
34
+ class << self
35
+ extend T::Sig
36
+ include Client
37
+
38
+ PROVIDERS = WorkOS::UserManagement::Types::Provider.values.map(&:serialize).freeze
39
+ AUTH_FACTOR_TYPES = WorkOS::UserManagement::Types::AuthFactorType.values.map(&:serialize).freeze
40
+
41
+ # Generate an OAuth 2.0 authorization URL that automatically directs a user
42
+ # to their Identity Provider.
43
+ #
44
+ # @param [String] redirect_uri The URI where users are directed
45
+ # after completing the authentication step. Must match a
46
+ # configured redirect URI on your WorkOS dashboard.
47
+ # @param [String] client_id This value can be obtained from the API Keys page in the WorkOS dashboard.
48
+ # @param [String] provider A provider name is used to initiate SSO using an
49
+ # OAuth-compatible provider. Only 'authkit ,'GoogleOAuth' and 'MicrosoftOAuth' are supported.
50
+ # @param [String] connection_id The ID for a Connection configured on
51
+ # WorkOS.
52
+ # @param [String] organization_id The organization_id selector is used to
53
+ # initiate SSO for an Organization.
54
+ # @param [String] state An arbitrary state object
55
+ # that is preserved and available to the client in the response.
56
+ # @param [String] login_hint Can be used to pre-fill the username/email address
57
+ # field of the IdP sign-in page for the user, if you know their username ahead of time.
58
+ # @param [String] domain_hint Can be used to pre-fill the domain field when
59
+ # initiating authentication with Microsoft OAuth, or with a GoogleSAML connection type.
60
+ # @example
61
+ # WorkOS::UserManagement.authorization_url(
62
+ # connection_id: 'conn_123',
63
+ # client_id: 'project_01DG5TGK363GRVXP3ZS40WNGEZ',
64
+ # redirect_uri: 'https://your-app.com/callback',
65
+ # state: {
66
+ # next_page: '/docs'
67
+ # }.to_s
68
+ # )
69
+ #
70
+ # => "https://api.workos.com/user_management/authorize?connection_id=conn_123" \
71
+ # "&client_id=project_01DG5TGK363GRVXP3ZS40WNGEZ" \
72
+ # "&redirect_uri=https%3A%2F%2Fyour-app.com%2Fcallback&" \
73
+ # "response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdocs%22%7D"
74
+ #
75
+ # @return [String]
76
+ # rubocop:disable Metrics/ParameterLists
77
+ sig do
78
+ params(
79
+ redirect_uri: String,
80
+ client_id: T.nilable(String),
81
+ domain_hint: T.nilable(String),
82
+ login_hint: T.nilable(String),
83
+ provider: T.nilable(String),
84
+ connection_id: T.nilable(String),
85
+ organization_id: T.nilable(String),
86
+ state: T.nilable(String),
87
+ ).returns(String)
88
+ end
89
+ def authorization_url(
90
+ redirect_uri:,
91
+ client_id: nil,
92
+ domain_hint: nil,
93
+ login_hint: nil,
94
+ provider: nil,
95
+ connection_id: nil,
96
+ organization_id: nil,
97
+ state: ''
98
+ )
99
+
100
+ validate_authorization_url_arguments(
101
+ provider: provider,
102
+ connection_id: connection_id,
103
+ organization_id: organization_id,
104
+ )
105
+
106
+ query = URI.encode_www_form({
107
+ client_id: client_id,
108
+ redirect_uri: redirect_uri,
109
+ response_type: 'code',
110
+ state: state,
111
+ domain_hint: domain_hint,
112
+ login_hint: login_hint,
113
+ provider: provider,
114
+ connection_id: connection_id,
115
+ organization_id: organization_id,
116
+ }.compact)
117
+
118
+ "https://#{WorkOS.config.api_hostname}/user_management/authorize?#{query}"
119
+ end
120
+ # rubocop:enable Metrics/ParameterLists
121
+
122
+ # Get a User
123
+ #
124
+ # @param [String] id The unique ID of the User.
125
+ #
126
+ # @return WorkOS::User
127
+ sig do
128
+ params(id: String).returns(WorkOS::User)
129
+ end
130
+ def get_user(id:)
131
+ response = execute_request(
132
+ request: get_request(
133
+ path: "/user_management/users/#{id}",
134
+ auth: true,
135
+ ),
136
+ )
137
+
138
+ WorkOS::User.new(response.body)
139
+ end
140
+
141
+ # Retrieve a list of users.
142
+ #
143
+ # @param [Hash] options
144
+ # @option options [String] email Filter Users by their email.
145
+ # @option options [String] organization_id Filter Users by the organization they are members of.
146
+ # @option options [String] limit Maximum number of records to return.
147
+ # @option options [String] order The order in which to paginate records
148
+ # @option options [String] before Pagination cursor to receive records
149
+ # before a provided User ID.
150
+ # @option options [String] after Pagination cursor to receive records
151
+ # before a provided User ID.
152
+ #
153
+ # @return [WorkOS::User]
154
+ sig do
155
+ params(
156
+ options: T::Hash[Symbol, String],
157
+ ).returns(WorkOS::Types::ListStruct)
158
+ end
159
+ def list_users(options = {})
160
+ response = execute_request(
161
+ request: get_request(
162
+ path: '/user_management/users',
163
+ auth: true,
164
+ params: options,
165
+ ),
166
+ )
167
+
168
+ parsed_response = JSON.parse(response.body)
169
+
170
+ users = parsed_response['data'].map do |user|
171
+ ::WorkOS::User.new(user.to_json)
172
+ end
173
+
174
+ WorkOS::Types::ListStruct.new(
175
+ data: users,
176
+ list_metadata: parsed_response['list_metadata'],
177
+ )
178
+ end
179
+
180
+ # Create a user
181
+ #
182
+ # @param [String] email The email address of the user.
183
+ # @param [String] password The password to set for the user.
184
+ # @param [String] first_name The user's first name.
185
+ # @param [String] last_name The user's last name.
186
+ # @param [Boolean] email_verified Whether the user's email address was previously verified.
187
+ #
188
+ # @return [WorkOS::User]
189
+ sig do
190
+ params(
191
+ email: String,
192
+ password: T.nilable(String),
193
+ first_name: T.nilable(String),
194
+ last_name: T.nilable(String),
195
+ email_verified: T.nilable(T::Boolean),
196
+ ).returns(WorkOS::User)
197
+ end
198
+ def create_user(email:, password: nil, first_name: nil, last_name: nil, email_verified: nil)
199
+ request = post_request(
200
+ path: '/user_management/users',
201
+ body: {
202
+ email: email,
203
+ password: password,
204
+ first_name: first_name,
205
+ last_name: last_name,
206
+ email_verified: email_verified,
207
+ },
208
+ auth: true,
209
+ )
210
+
211
+ response = execute_request(request: request)
212
+
213
+ WorkOS::User.new(response.body)
214
+ end
215
+
216
+ # Update a user
217
+ #
218
+ # @param [String] id of the user.
219
+ # @param [String] first_name The user's first name.
220
+ # @param [String] last_name The user's last name.
221
+ # @param [Boolean] email_verified Whether the user's email address was previously verified.
222
+ # @param [String] password The user's password.
223
+ # @param [String] password_hash The user's hashed password.
224
+ # @option [String] password_hash_type The algorithm originally used to hash the password.
225
+ # Valid values are bcrypt.
226
+ #
227
+ # @return [WorkOS::User]
228
+ # rubocop:disable Metrics/ParameterLists
229
+ sig do
230
+ params(
231
+ id: String,
232
+ first_name: T.nilable(String),
233
+ last_name: T.nilable(String),
234
+ email_verified: T.nilable(T::Boolean),
235
+ password: T.nilable(String),
236
+ password_hash: T.nilable(String),
237
+ password_hash_type: T.nilable(String),
238
+ ).returns(WorkOS::User)
239
+ end
240
+ def update_user(
241
+ id:,
242
+ first_name: nil,
243
+ last_name: nil,
244
+ email_verified: nil,
245
+ password: nil,
246
+ password_hash: nil,
247
+ password_hash_type: nil
248
+ )
249
+ request = put_request(
250
+ path: "/user_management/users/#{id}",
251
+ body: {
252
+ first_name: first_name,
253
+ last_name: last_name,
254
+ email_verified: email_verified,
255
+ password: password,
256
+ password_hash: password_hash,
257
+ password_hash_type: password_hash_type,
258
+ },
259
+ auth: true,
260
+ )
261
+
262
+ response = execute_request(request: request)
263
+
264
+ WorkOS::User.new(response.body)
265
+ end
266
+ # rubocop:enable Metrics/ParameterLists
267
+
268
+ # Delete a User
269
+ #
270
+ # @param [String] id The unique ID of the User.
271
+ #
272
+ # @return [Bool] - returns `true` if successful
273
+ sig do
274
+ params(
275
+ id: String,
276
+ ).returns(T::Boolean)
277
+ end
278
+ def delete_user(id:)
279
+ response = execute_request(
280
+ request: delete_request(
281
+ path: "/user_management/users/#{id}",
282
+ auth: true,
283
+ ),
284
+ )
285
+
286
+ response.is_a? Net::HTTPSuccess
287
+ end
288
+
289
+ # Authenticates user by email and password.
290
+ #
291
+ # @param [String] email The email address of the user.
292
+ # @param [String] password The password for the user.
293
+ # @param [String] client_id The WorkOS client ID for the environment
294
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
295
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
296
+ #
297
+ # @return WorkOS::AuthenticationResponse
298
+
299
+ sig do
300
+ params(
301
+ email: String,
302
+ password: String,
303
+ client_id: String,
304
+ ip_address: T.nilable(String),
305
+ user_agent: T.nilable(String),
306
+ ).returns(WorkOS::AuthenticationResponse)
307
+ end
308
+ def authenticate_with_password(email:, password:, client_id:, ip_address: nil, user_agent: nil)
309
+ response = execute_request(
310
+ request: post_request(
311
+ path: '/user_management/authenticate',
312
+ body: {
313
+ client_id: client_id,
314
+ client_secret: WorkOS.config.key!,
315
+ email: email,
316
+ password: password,
317
+ ip_address: ip_address,
318
+ user_agent: user_agent,
319
+ grant_type: 'password',
320
+ },
321
+ ),
322
+ )
323
+
324
+ WorkOS::AuthenticationResponse.new(response.body)
325
+ end
326
+
327
+ # Authenticate a user using OAuth or an organization's SSO connection.
328
+ #
329
+ # @param [String] code The authorization value which was passed back as a
330
+ # query parameter in the callback to the Redirect URI.
331
+ # @param [String] client_id The WorkOS client ID for the environment
332
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
333
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
334
+ #
335
+ # @return WorkOS::AuthenticationResponse
336
+
337
+ sig do
338
+ params(
339
+ code: String,
340
+ client_id: String,
341
+ ip_address: T.nilable(String),
342
+ user_agent: T.nilable(String),
343
+ ).returns(WorkOS::AuthenticationResponse)
344
+ end
345
+ def authenticate_with_code(
346
+ code:,
347
+ client_id:,
348
+ ip_address: nil,
349
+ user_agent: nil
350
+ )
351
+ response = execute_request(
352
+ request: post_request(
353
+ path: '/user_management/authenticate',
354
+ body: {
355
+ code: code,
356
+ client_id: client_id,
357
+ client_secret: WorkOS.config.key!,
358
+ ip_address: ip_address,
359
+ user_agent: user_agent,
360
+ grant_type: 'authorization_code',
361
+ },
362
+ ),
363
+ )
364
+
365
+ WorkOS::AuthenticationResponse.new(response.body)
366
+ end
367
+
368
+ # Authenticate user by Magic Auth Code.
369
+ #
370
+ # @param [String] code The one-time code that was emailed to the user.
371
+ # @param [String] email The email address of the user.
372
+ # @param [String] client_id The WorkOS client ID for the environment.
373
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
374
+ # @param [String] link_authorization_code Used to link an OAuth profile to an existing user,
375
+ # after having completed a Magic Code challenge.
376
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
377
+ #
378
+ # @return WorkOS::AuthenticationResponse
379
+
380
+ sig do
381
+ params(
382
+ code: String,
383
+ email: String,
384
+ client_id: String,
385
+ ip_address: T.nilable(String),
386
+ user_agent: T.nilable(String),
387
+ link_authorization_code: T.nilable(String),
388
+ ).returns(WorkOS::AuthenticationResponse)
389
+ end
390
+ def authenticate_with_magic_auth(
391
+ code:,
392
+ email:,
393
+ client_id:,
394
+ ip_address: nil,
395
+ user_agent: nil,
396
+ link_authorization_code: nil
397
+ )
398
+ response = execute_request(
399
+ request: post_request(
400
+ path: '/user_management/authenticate',
401
+ body: {
402
+ code: code,
403
+ email: email,
404
+ client_id: client_id,
405
+ client_secret: WorkOS.config.key!,
406
+ ip_address: ip_address,
407
+ user_agent: user_agent,
408
+ grant_type: 'urn:workos:oauth:grant-type:magic-auth:code',
409
+ link_authorization_code: link_authorization_code,
410
+ },
411
+ ),
412
+ )
413
+
414
+ WorkOS::AuthenticationResponse.new(response.body)
415
+ end
416
+
417
+
418
+ # Authenticate a user into an organization they are a member of.
419
+ #
420
+ # @param [String] client_id The WorkOS client ID for the environment.
421
+ # @param [String] organization_id The organization ID the user selected to sign in to.
422
+ # @param [String] pending_authentication_token The pending authentication token
423
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
424
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
425
+ #
426
+ # @return WorkOS::AuthenticationResponse
427
+ sig do
428
+ params(
429
+ client_id: String,
430
+ organization_id: String,
431
+ pending_authentication_token: String,
432
+ ip_address: T.nilable(String),
433
+ user_agent: T.nilable(String),
434
+ ).returns(WorkOS::AuthenticationResponse)
435
+ end
436
+ def authenticate_with_organization_selection(
437
+ client_id:,
438
+ organization_id:,
439
+ pending_authentication_token:,
440
+ ip_address: nil,
441
+ user_agent: nil
442
+ )
443
+ response = execute_request(
444
+ request: post_request(
445
+ path: '/user_management/authenticate',
446
+ body: {
447
+ client_id: client_id,
448
+ client_secret: WorkOS.config.key!,
449
+ ip_address: ip_address,
450
+ user_agent: user_agent,
451
+ grant_type: 'urn:workos:oauth:grant-type:organization-selection',
452
+ organization_id: organization_id,
453
+ pending_authentication_token: pending_authentication_token,
454
+ },
455
+ ),
456
+ )
457
+
458
+ WorkOS::AuthenticationResponse.new(response.body)
459
+ end
460
+
461
+ # Authenticate a user using TOTP.
462
+ #
463
+ # @param [String] code The one-time code that was emailed to the user.
464
+ # @param [String] client_id The WorkOS client ID for the environment
465
+ # @param [String] pending_authentication_token The pending authentication token
466
+ # from the initial authentication request.
467
+ # @param [String] authentication_challenge_id The authentication challenge ID for the
468
+ # authentication request.
469
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
470
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
471
+ #
472
+ # @return WorkOS::AuthenticationResponse
473
+
474
+ sig do
475
+ params(
476
+ code: String,
477
+ client_id: String,
478
+ pending_authentication_token: String,
479
+ authentication_challenge_id: String,
480
+ ip_address: T.nilable(String),
481
+ user_agent: T.nilable(String),
482
+ ).returns(WorkOS::AuthenticationResponse)
483
+ end
484
+ def authenticate_with_totp(
485
+ code:,
486
+ client_id:,
487
+ pending_authentication_token:,
488
+ authentication_challenge_id:,
489
+ ip_address: nil,
490
+ user_agent: nil
491
+ )
492
+ response = execute_request(
493
+ request: post_request(
494
+ path: '/user_management/authenticate',
495
+ body: {
496
+ code: code,
497
+ client_id: client_id,
498
+ client_secret: WorkOS.config.key!,
499
+ pending_authentication_token: pending_authentication_token,
500
+ grant_type: 'urn:workos:oauth:grant-type:mfa-totp',
501
+ authentication_challenge_id: authentication_challenge_id,
502
+ ip_address: ip_address,
503
+ user_agent: user_agent,
504
+ },
505
+ ),
506
+ )
507
+
508
+ WorkOS::AuthenticationResponse.new(response.body)
509
+ end
510
+
511
+ # Authenticate a user using Email Verification Code.
512
+ #
513
+ # @param [String] code The one-time code that was emailed to the user.
514
+ # @param [String] client_id The WorkOS client ID for the environment
515
+ # @param [String] pending_authentication_token The token returned from a failed email/password or OAuth
516
+ # authentication attempt due to an unverified email address.
517
+ # @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
518
+ # @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
519
+ #
520
+ # @return WorkOS::AuthenticationResponse
521
+
522
+ sig do
523
+ params(
524
+ code: String,
525
+ client_id: String,
526
+ pending_authentication_token: String,
527
+ ip_address: T.nilable(String),
528
+ user_agent: T.nilable(String),
529
+ ).returns(WorkOS::AuthenticationResponse)
530
+ end
531
+ def authenticate_with_email_verification(
532
+ code:,
533
+ client_id:,
534
+ pending_authentication_token:,
535
+ ip_address: nil,
536
+ user_agent: nil
537
+ )
538
+ response = execute_request(
539
+ request: post_request(
540
+ path: '/user_management/authenticate',
541
+ body: {
542
+ code: code,
543
+ client_id: client_id,
544
+ pending_authentication_token: pending_authentication_token,
545
+ client_secret: WorkOS.config.key!,
546
+ grant_type: 'urn:workos:oauth:grant-type:email-verification:code',
547
+ ip_address: ip_address,
548
+ user_agent: user_agent,
549
+ },
550
+ ),
551
+ )
552
+
553
+ WorkOS::AuthenticationResponse.new(response.body)
554
+ end
555
+
556
+ # Create a one-time Magic Auth code and emails it to the user.
557
+ #
558
+ # @param [String] email The email address the one-time code will be sent to.
559
+ #
560
+ # @return Boolean
561
+ sig do
562
+ params(
563
+ email: String,
564
+ ).returns(T::Boolean)
565
+ end
566
+ def send_magic_auth_code(email:)
567
+ response = execute_request(
568
+ request: post_request(
569
+ path: '/user_management/magic_auth/send',
570
+ body: {
571
+ email: email,
572
+ },
573
+ auth: true,
574
+ ),
575
+ )
576
+
577
+ response.is_a? Net::HTTPSuccess
578
+ end
579
+
580
+ # Enroll a user into an authentication factor.
581
+ #
582
+ # @param [String] user_id The id for the user.
583
+ # @param [String] type The type of the factor to enroll. Only option available is totp.
584
+ # @param [String] totp_issuer For totp factors. Typically your application
585
+ # or company name, this helps users distinguish between factors in authenticator apps.
586
+ # @param [String] totp_user For totp factors. Used as the account name in authenticator apps.
587
+ #
588
+ # @return WorkOS::AuthenticationFactorAndChallenge
589
+ sig do
590
+ params(
591
+ user_id: String,
592
+ type: String,
593
+ totp_issuer: T.nilable(String),
594
+ totp_user: T.nilable(String),
595
+ ).returns(WorkOS::AuthenticationFactorAndChallenge)
596
+ end
597
+ def enroll_auth_factor(user_id:, type:, totp_issuer: nil, totp_user: nil)
598
+ validate_auth_factor_type(
599
+ type: type,
600
+ )
601
+
602
+ response = execute_request(
603
+ request: post_request(
604
+ path: "/user_management/users/#{user_id}/auth_factors",
605
+ body: {
606
+ type: type,
607
+ totp_issuer: totp_issuer,
608
+ totp_user: totp_user,
609
+ },
610
+ auth: true,
611
+ ),
612
+ )
613
+
614
+ WorkOS::AuthenticationFactorAndChallenge.new(response.body)
615
+ end
616
+
617
+ # Get all auth factors for a user
618
+ #
619
+ # @param [String] user_id The id for the user.
620
+ #
621
+ # @return WorkOS::ListStruct
622
+ sig do
623
+ params(
624
+ user_id: String,
625
+ ).returns(WorkOS::Types::ListStruct)
626
+ end
627
+ def list_auth_factors(user_id:)
628
+ response = execute_request(
629
+ request: get_request(
630
+ path: "/user_management/users/#{user_id}/auth_factors",
631
+ auth: true,
632
+ ),
633
+ )
634
+
635
+ parsed_response = JSON.parse(response.body)
636
+
637
+ auth_factors = parsed_response['data'].map do |auth_factor|
638
+ ::WorkOS::Factor.new(auth_factor.to_json)
639
+ end
640
+
641
+ WorkOS::Types::ListStruct.new(
642
+ data: auth_factors,
643
+ list_metadata: parsed_response['list_metadata'],
644
+ )
645
+ end
646
+
647
+ # Sends a verification email to the provided user.
648
+ #
649
+ # @param [String] user_id The unique ID of the User whose email address will be verified.
650
+ #
651
+ # @return WorkOS::UserResponse
652
+ sig do
653
+ params(
654
+ user_id: String,
655
+ ).returns(WorkOS::UserResponse)
656
+ end
657
+ def send_verification_email(user_id:)
658
+ response = execute_request(
659
+ request: post_request(
660
+ path: "/user_management/users/#{user_id}/email_verification/send",
661
+ auth: true,
662
+ ),
663
+ )
664
+
665
+ WorkOS::UserResponse.new(response.body)
666
+ end
667
+
668
+ # Verifiy user email using one-time code that was sent to the user.
669
+ #
670
+ # @param [String] user_id The unique ID of the User whose email address will be verified.
671
+ # @param [String] code The one-time code emailed to the user.
672
+ #
673
+ # @return WorkOS::UserResponse
674
+ sig do
675
+ params(
676
+ user_id: String,
677
+ code: String,
678
+ ).returns(WorkOS::UserResponse)
679
+ end
680
+ def verify_email(user_id:, code:)
681
+ response = execute_request(
682
+ request: post_request(
683
+ path: "/user_management/users/#{user_id}/email_verification/confirm",
684
+ body: {
685
+ code: code,
686
+ },
687
+ auth: true,
688
+ ),
689
+ )
690
+
691
+ WorkOS::UserResponse.new(response.body)
692
+ end
693
+
694
+ # Create a password reset challenge and emails a password reset link to a user.
695
+ #
696
+ # @param [String] email The email of the user that wishes to reset their password.
697
+ # @param [String] password_reset_url The URL that will be linked to in the email.
698
+ #
699
+ # @return [Bool] - returns `true` if successful
700
+ sig do
701
+ params(
702
+ email: String,
703
+ password_reset_url: String,
704
+ ).returns(T::Boolean)
705
+ end
706
+ def send_password_reset_email(email:, password_reset_url:)
707
+ request = post_request(
708
+ path: '/user_management/password_reset/send',
709
+ body: {
710
+ email: email,
711
+ password_reset_url: password_reset_url,
712
+ },
713
+ auth: true,
714
+ )
715
+
716
+ response = execute_request(request: request)
717
+
718
+ response.is_a? Net::HTTPSuccess
719
+ end
720
+
721
+ # Reset user password using token that was sent to the user.
722
+ #
723
+ # @param [String] token The token that was sent to the user.
724
+ # @param [String] new_password The new password to set for the user.
725
+ #
726
+ # @return WorkOS::User
727
+ sig do
728
+ params(
729
+ token: String,
730
+ new_password: String,
731
+ ).returns(WorkOS::User)
732
+ end
733
+ def reset_password(token:, new_password:)
734
+ response = execute_request(
735
+ request: post_request(
736
+ path: '/user_management/password_reset/confirm',
737
+ body: {
738
+ token: token,
739
+ new_password: new_password,
740
+ },
741
+ auth: true,
742
+ ),
743
+ )
744
+
745
+ WorkOS::User.new(response.body)
746
+ end
747
+
748
+ # Get an Organization Membership
749
+ #
750
+ # @param [String] id The unique ID of the Organization Membership.
751
+ #
752
+ # @return WorkOS::OrganizationMembership
753
+ sig do
754
+ params(id: String).returns(WorkOS::OrganizationMembership)
755
+ end
756
+ def get_organization_membership(id:)
757
+ response = execute_request(
758
+ request: get_request(
759
+ path: "/user_management/organization_memberships/#{id}",
760
+ auth: true,
761
+ ),
762
+ )
763
+
764
+ WorkOS::OrganizationMembership.new(response.body)
765
+ end
766
+
767
+ # Retrieve a list of Organization Memberships.
768
+ #
769
+ # @param [Hash] options
770
+ # @option options [String] user_id The ID of the User.
771
+ # @option options [String] organization_id Filter Users by the organization they are members of.
772
+ # @option options [String] limit Maximum number of records to return.
773
+ # @option options [String] order The order in which to paginate records
774
+ # @option options [String] before Pagination cursor to receive records
775
+ # before a provided User ID.
776
+ # @option options [String] after Pagination cursor to receive records
777
+ # before a provided User ID.
778
+ #
779
+ # @return [WorkOS::OrganizationMembership]
780
+ sig do
781
+ params(
782
+ options: T::Hash[Symbol, String],
783
+ ).returns(WorkOS::Types::ListStruct)
784
+ end
785
+ def list_organization_memberships(options = {})
786
+ response = execute_request(
787
+ request: get_request(
788
+ path: '/user_management/organization_memberships',
789
+ auth: true,
790
+ params: options,
791
+ ),
792
+ )
793
+
794
+ parsed_response = JSON.parse(response.body)
795
+
796
+ organization_memberships = parsed_response['data'].map do |organization_membership|
797
+ ::WorkOS::OrganizationMembership.new(organization_membership.to_json)
798
+ end
799
+
800
+ WorkOS::Types::ListStruct.new(
801
+ data: organization_memberships,
802
+ list_metadata: parsed_response['list_metadata'],
803
+ )
804
+ end
805
+
806
+ # Create an Organization Membership
807
+ #
808
+ # @param [String] user_id The ID of the User.
809
+ # @param [String] organization_id The ID of the Organization to which the user belongs to.
810
+ #
811
+ # @return [WorkOS::OrganizationMembership]
812
+ sig do
813
+ params(
814
+ user_id: String,
815
+ organization_id: String,
816
+ ).returns(WorkOS::OrganizationMembership)
817
+ end
818
+ def create_organization_membership(user_id:, organization_id:)
819
+ request = post_request(
820
+ path: '/user_management/organization_memberships',
821
+ body: {
822
+ user_id: user_id,
823
+ organization_id: organization_id,
824
+ },
825
+ auth: true,
826
+ )
827
+
828
+ response = execute_request(request: request)
829
+
830
+ WorkOS::OrganizationMembership.new(response.body)
831
+ end
832
+
833
+ # Delete an Organization Membership
834
+ #
835
+ # @param [String] id The unique ID of the Organization Membership.
836
+ #
837
+ # @return [Bool] - returns `true` if successful
838
+ sig do
839
+ params(
840
+ id: String,
841
+ ).returns(T::Boolean)
842
+ end
843
+ def delete_organization_membership(id:)
844
+ response = execute_request(
845
+ request: delete_request(
846
+ path: "/user_management/organization_memberships/#{id}",
847
+ auth: true,
848
+ ),
849
+ )
850
+
851
+ response.is_a? Net::HTTPSuccess
852
+ end
853
+
854
+ # Gets an Invitation
855
+ #
856
+ # @param [String] id The unique ID of the Invitation.
857
+ #
858
+ # @return WorkOS::Invitation
859
+ sig do
860
+ params(id: String).returns(WorkOS::Invitation)
861
+ end
862
+ def get_invitation(id:)
863
+ response = execute_request(
864
+ request: get_request(
865
+ path: "/user_management/invitations/#{id}",
866
+ auth: true,
867
+ ),
868
+ )
869
+
870
+ WorkOS::Invitation.new(response.body)
871
+ end
872
+
873
+ # Retrieve a list of invitations.
874
+ #
875
+ # @param [Hash] options
876
+ # @option options [String] email The email address of a recipient.
877
+ # @option options [String] organization_id The ID of the Organization that the recipient was invited to join.
878
+ # @option options [String] limit Maximum number of records to return.
879
+ # @option options [String] order The order in which to paginate records
880
+ # @option options [String] before Pagination cursor to receive records
881
+ # before a provided User ID.
882
+ # @option options [String] after Pagination cursor to receive records
883
+ # before a provided User ID.
884
+ #
885
+ # @return [WorkOS::Invitation]
886
+ sig do
887
+ params(
888
+ options: T::Hash[Symbol, String],
889
+ ).returns(WorkOS::Types::ListStruct)
890
+ end
891
+ def list_invitations(options = {})
892
+ response = execute_request(
893
+ request: get_request(
894
+ path: '/user_management/invitations',
895
+ auth: true,
896
+ params: options,
897
+ ),
898
+ )
899
+
900
+ parsed_response = JSON.parse(response.body)
901
+
902
+ invitations = parsed_response['data'].map do |invitation|
903
+ ::WorkOS::Invitation.new(invitation.to_json)
904
+ end
905
+
906
+ WorkOS::Types::ListStruct.new(
907
+ data: invitations,
908
+ list_metadata: parsed_response['list_metadata'],
909
+ )
910
+ end
911
+
912
+ # Sends an Invitation to a recipient.
913
+ #
914
+ # @param [String] email The email address of the recipient.
915
+ # @param [String] organization_id The ID of the Organization to which the recipient is being invited.
916
+ # @param [Integer] expires_in_days The number of days the invitations will be valid for.
917
+ # Must be between 1 and 30, defaults to 7 if not specified.
918
+ # @param [String] inviter_user_id The ID of the User sending the invitation.
919
+ #
920
+ # @return WorkOS::Invitation
921
+ sig do
922
+ params(
923
+ email: String,
924
+ organization_id: T.nilable(String),
925
+ expires_in_days: T.nilable(Integer),
926
+ inviter_user_id: T.nilable(String),
927
+ ).returns(WorkOS::Invitation)
928
+ end
929
+ def send_invitation(email:, organization_id: nil, expires_in_days: nil, inviter_user_id: nil)
930
+ response = execute_request(
931
+ request: post_request(
932
+ path: '/user_management/invitations',
933
+ body: {
934
+ email: email,
935
+ organization_id: organization_id,
936
+ expires_in_days: expires_in_days,
937
+ inviter_user_id: inviter_user_id,
938
+ },
939
+ auth: true,
940
+ ),
941
+ )
942
+
943
+ WorkOS::Invitation.new(response.body)
944
+ end
945
+
946
+ # Revokes an existing Invitation.
947
+ #
948
+ # @param [String] id The unique ID of the Invitation.
949
+ #
950
+ # @return WorkOS::Invitation
951
+ sig do
952
+ params(id: String).returns(WorkOS::Invitation)
953
+ end
954
+ def revoke_invitation(id:)
955
+ request = post_request(
956
+ path: "/user_management/invitations/#{id}/revoke",
957
+ auth: true,
958
+ )
959
+
960
+ response = execute_request(request: request)
961
+
962
+ WorkOS::Invitation.new(response.body)
963
+ end
964
+
965
+ private
966
+
967
+ sig do
968
+ params(
969
+ provider: T.nilable(String),
970
+ connection_id: T.nilable(String),
971
+ organization_id: T.nilable(String),
972
+ ).void
973
+ end
974
+
975
+ def validate_authorization_url_arguments(
976
+ provider:,
977
+ connection_id:,
978
+ organization_id:
979
+ )
980
+ if [provider, connection_id, organization_id].all?(&:nil?)
981
+ raise ArgumentError, 'Either connection ID, organization ID,' \
982
+ ' or provider is required.'
983
+ end
984
+
985
+ return unless provider && !PROVIDERS.include?(provider)
986
+
987
+ raise ArgumentError, "#{provider} is not a valid value." \
988
+ " `provider` must be in #{PROVIDERS}"
989
+ end
990
+
991
+ sig do
992
+ params(
993
+ type: String,
994
+ ).void
995
+ end
996
+
997
+ def validate_auth_factor_type(
998
+ type:
999
+ )
1000
+ return if AUTH_FACTOR_TYPES.include?(type)
1001
+
1002
+ raise ArgumentError, "#{type} is not a valid value." \
1003
+ " `type` must be in #{AUTH_FACTOR_TYPES}"
1004
+ end
1005
+ end
1006
+ end
1007
+ # rubocop:enable Metrics/ModuleLength
1008
+ end