workos 2.17.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) 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/invitation.rb +68 -0
  7. data/lib/workos/organization_membership.rb +50 -0
  8. data/lib/workos/types/invitation_struct.rb +20 -0
  9. data/lib/workos/types/magic_auth_challenge_struct.rb +12 -0
  10. data/lib/workos/types/organization_membership_struct.rb +15 -0
  11. data/lib/workos/types/user_struct.rb +18 -0
  12. data/lib/workos/types.rb +9 -5
  13. data/lib/workos/user.rb +60 -0
  14. data/lib/workos/user_and_token.rb +29 -0
  15. data/lib/workos/user_management.rb +1008 -0
  16. data/lib/workos/user_response.rb +25 -0
  17. data/lib/workos/version.rb +1 -1
  18. data/lib/workos.rb +17 -12
  19. data/spec/lib/workos/user_management_spec.rb +1092 -0
  20. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/invalid.yml +84 -0
  21. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid.yml +82 -0
  22. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/invalid.yml +83 -0
  23. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/valid.yml +81 -0
  24. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/invalid.yml +82 -0
  25. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/valid.yml +82 -0
  26. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_organization_selection/invalid.yml +81 -0
  27. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_organization_selection/valid.yml +82 -0
  28. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/invalid.yml +82 -0
  29. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/valid.yml +82 -0
  30. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_totp/invalid.yml +83 -0
  31. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_totp/valid.yml +81 -0
  32. data/spec/support/fixtures/vcr_cassettes/user_management/confirm_password_reset/invalid.yml +82 -0
  33. data/spec/support/fixtures/vcr_cassettes/user_management/confirm_password_reset/valid.yml +82 -0
  34. data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/invalid.yml +83 -0
  35. data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/valid.yml +82 -0
  36. data/spec/support/fixtures/vcr_cassettes/user_management/create_user_invalid.yml +83 -0
  37. data/spec/support/fixtures/vcr_cassettes/user_management/create_user_valid.yml +82 -0
  38. data/spec/support/fixtures/vcr_cassettes/user_management/delete_organization_membership/invalid.yml +82 -0
  39. data/spec/support/fixtures/vcr_cassettes/user_management/delete_organization_membership/valid.yml +78 -0
  40. data/spec/support/fixtures/vcr_cassettes/user_management/delete_user/invalid.yml +82 -0
  41. data/spec/support/fixtures/vcr_cassettes/user_management/delete_user/valid.yml +78 -0
  42. data/spec/support/fixtures/vcr_cassettes/user_management/enroll_auth_factor/invalid.yml +82 -0
  43. data/spec/support/fixtures/vcr_cassettes/user_management/enroll_auth_factor/valid.yml +82 -0
  44. data/spec/support/fixtures/vcr_cassettes/user_management/get_invitation/invalid.yml +82 -0
  45. data/spec/support/fixtures/vcr_cassettes/user_management/get_invitation/valid.yml +82 -0
  46. data/spec/support/fixtures/vcr_cassettes/user_management/get_organization_membership.yml +82 -0
  47. data/spec/support/fixtures/vcr_cassettes/user_management/get_user.yml +82 -0
  48. data/spec/support/fixtures/vcr_cassettes/user_management/list_auth_factors/invalid.yml +82 -0
  49. data/spec/support/fixtures/vcr_cassettes/user_management/list_auth_factors/valid.yml +82 -0
  50. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_after.yml +83 -0
  51. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_before.yml +83 -0
  52. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_limit.yml +83 -0
  53. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_no_options.yml +83 -0
  54. data/spec/support/fixtures/vcr_cassettes/user_management/list_invitations/with_organization_id.yml +83 -0
  55. data/spec/support/fixtures/vcr_cassettes/user_management/list_organization_memberships/no_options.yml +82 -0
  56. data/spec/support/fixtures/vcr_cassettes/user_management/list_organization_memberships/with_options.yml +82 -0
  57. data/spec/support/fixtures/vcr_cassettes/user_management/list_users/no_options.yml +82 -0
  58. data/spec/support/fixtures/vcr_cassettes/user_management/list_users/with_options.yml +82 -0
  59. data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/invalid.yml +82 -0
  60. data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/valid.yml +82 -0
  61. data/spec/support/fixtures/vcr_cassettes/user_management/revoke_invitation/invalid.yml +82 -0
  62. data/spec/support/fixtures/vcr_cassettes/user_management/revoke_invitation/valid.yml +82 -0
  63. data/spec/support/fixtures/vcr_cassettes/user_management/send_invitation/invalid.yml +82 -0
  64. data/spec/support/fixtures/vcr_cassettes/user_management/send_invitation/valid.yml +82 -0
  65. data/spec/support/fixtures/vcr_cassettes/user_management/send_magic_auth_code/valid.yml +82 -0
  66. data/spec/support/fixtures/vcr_cassettes/user_management/send_password_reset_email/invalid.yml +83 -0
  67. data/spec/support/fixtures/vcr_cassettes/user_management/send_password_reset_email/valid.yml +82 -0
  68. data/spec/support/fixtures/vcr_cassettes/user_management/send_verification_email/invalid.yml +82 -0
  69. data/spec/support/fixtures/vcr_cassettes/user_management/send_verification_email/valid.yml +82 -0
  70. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/invalid.yml +82 -0
  71. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/valid.yml +82 -0
  72. data/spec/support/fixtures/vcr_cassettes/user_management/update_user_password/invalid.yml +82 -0
  73. data/spec/support/fixtures/vcr_cassettes/user_management/update_user_password/valid.yml +82 -0
  74. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/invalid_code.yml +83 -0
  75. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/invalid_magic_auth_challenge.yml +82 -0
  76. data/spec/support/fixtures/vcr_cassettes/user_management/verify_email/valid.yml +82 -0
  77. data/workos.gemspec +0 -1
  78. metadata +131 -49
  79. data/bin/docs +0 -5
  80. data/docs/WorkOS/APIError.html +0 -160
  81. data/docs/WorkOS/AuditLog.html +0 -235
  82. data/docs/WorkOS/AuditTrail.html +0 -235
  83. data/docs/WorkOS/AuthenticationError.html +0 -160
  84. data/docs/WorkOS/Base.html +0 -287
  85. data/docs/WorkOS/Client.html +0 -504
  86. data/docs/WorkOS/InvalidRequestError.html +0 -160
  87. data/docs/WorkOS/Profile.html +0 -788
  88. data/docs/WorkOS/RequestError.html +0 -135
  89. data/docs/WorkOS/SSO.html +0 -691
  90. data/docs/WorkOS/Types/ProfileStruct.html +0 -135
  91. data/docs/WorkOS/Types/Provider.html +0 -135
  92. data/docs/WorkOS/Types.html +0 -128
  93. data/docs/WorkOS/WorkOSError.html +0 -447
  94. data/docs/WorkOS.html +0 -324
  95. data/docs/class_list.html +0 -51
  96. data/docs/css/common.css +0 -1
  97. data/docs/css/full_list.css +0 -58
  98. data/docs/css/style.css +0 -496
  99. data/docs/file.README.html +0 -252
  100. data/docs/file_list.html +0 -56
  101. data/docs/frames.html +0 -17
  102. data/docs/index.html +0 -250
  103. data/docs/js/app.js +0 -314
  104. data/docs/js/full_list.js +0 -216
  105. data/docs/js/jquery.js +0 -4
  106. data/docs/method_list.html +0 -267
  107. data/docs/top-level-namespace.html +0 -110
  108. data/lib/workos/audit_trail.rb +0 -111
  109. 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