workos 5.3.0 → 6.1.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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -1
- data/.github/workflows/ci.yml +2 -4
- data/.github/workflows/lint-pr-title.yml +20 -0
- data/.github/workflows/release-please.yml +25 -0
- data/.github/workflows/release.yml +22 -25
- data/.gitignore +1 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +11 -8
- data/.rubocop_todo.yml +94 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +32 -18
- data/Rakefile +8 -0
- data/context7.json +4 -0
- data/lib/workos/authentication_response.rb +32 -4
- data/lib/workos/cache.rb +94 -0
- data/lib/workos/client.rb +9 -1
- data/lib/workos/directory_sync.rb +1 -1
- data/lib/workos/directory_user.rb +31 -3
- data/lib/workos/encryptors/aes_gcm.rb +49 -0
- data/lib/workos/encryptors.rb +9 -0
- data/lib/workos/errors.rb +4 -0
- data/lib/workos/feature_flag.rb +34 -0
- data/lib/workos/mfa.rb +0 -1
- data/lib/workos/oauth_tokens.rb +29 -0
- data/lib/workos/organization.rb +14 -1
- data/lib/workos/organization_membership.rb +5 -1
- data/lib/workos/organizations.rb +87 -3
- data/lib/workos/profile.rb +10 -2
- data/lib/workos/refresh_authentication_response.rb +29 -2
- data/lib/workos/role.rb +38 -0
- data/lib/workos/session.rb +187 -0
- data/lib/workos/sso.rb +3 -24
- data/lib/workos/types/intent.rb +3 -1
- data/lib/workos/types/provider.rb +1 -1
- data/lib/workos/types/widget_scope.rb +15 -0
- data/lib/workos/types.rb +1 -0
- data/lib/workos/user.rb +7 -1
- data/lib/workos/user_management/session.rb +57 -0
- data/lib/workos/user_management.rb +213 -45
- data/lib/workos/version.rb +1 -1
- data/lib/workos/widgets.rb +46 -0
- data/lib/workos.rb +8 -0
- data/release-please-config.json +12 -0
- data/spec/lib/workos/cache_spec.rb +94 -0
- data/spec/lib/workos/directory_user_spec.rb +13 -3
- data/spec/lib/workos/encryptors/aes_gcm_spec.rb +41 -0
- data/spec/lib/workos/organizations_spec.rb +258 -1
- data/spec/lib/workos/portal_spec.rb +30 -0
- data/spec/lib/workos/role_spec.rb +142 -0
- data/spec/lib/workos/session_spec.rb +475 -0
- data/spec/lib/workos/sso_spec.rb +106 -5
- data/spec/lib/workos/user_management_spec.rb +496 -1
- data/spec/lib/workos/widgets_spec.rb +73 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/organization/create_with_external_id.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/organization/list_organization_feature_flags.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update_with_external_id.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update_with_external_id_null.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update_with_stripe_customer_id.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update_without_name.yml +85 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_certificate_renewal.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_domain_verification.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_oauth_tokens.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/unverified.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_refresh_token/valid.yml +79 -78
- data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/valid_multiple_roles.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/create_user_with_external_id.yml +77 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/get_user.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/user_management/list_sessions/valid.yml +38 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/accepted.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/expired.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/invalid.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/revoked.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/valid.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/valid.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/user_management/update_organization_membership/valid_multiple_roles.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/update_user/email.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/update_user/locale.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/update_user/valid.yml +2 -2
- data/spec/support/fixtures/vcr_cassettes/user_management/update_user_external_id_null.yml +77 -0
- data/spec/support/fixtures/vcr_cassettes/widgets/get_token.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/widgets/get_token_invalid_organization_id.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/widgets/get_token_invalid_user_id.yml +74 -0
- data/spec/support/profile.txt +1 -1
- data/workos.gemspec +7 -3
- metadata +132 -10
|
@@ -6,9 +6,9 @@ require 'uri'
|
|
|
6
6
|
module WorkOS
|
|
7
7
|
# The UserManagement module provides convenience methods for working with the
|
|
8
8
|
# WorkOS User platform. You'll need a valid API key.
|
|
9
|
-
|
|
10
|
-
# rubocop:disable Metrics/ModuleLength
|
|
11
9
|
module UserManagement
|
|
10
|
+
autoload :Session, 'workos/user_management/session'
|
|
11
|
+
|
|
12
12
|
module Types
|
|
13
13
|
# The ProviderEnum is a declaration of a
|
|
14
14
|
# fixed set of values for User Management Providers.
|
|
@@ -19,7 +19,7 @@ module WorkOS
|
|
|
19
19
|
Microsoft = 'MicrosoftOAuth'
|
|
20
20
|
AuthKit = 'authkit'
|
|
21
21
|
|
|
22
|
-
ALL = [GitHub, Google, Microsoft, AuthKit].freeze
|
|
22
|
+
ALL = [Apple, GitHub, Google, Microsoft, AuthKit].freeze
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
# The AuthFactorType is a declaration of a
|
|
@@ -37,6 +37,24 @@ module WorkOS
|
|
|
37
37
|
PROVIDERS = WorkOS::UserManagement::Types::Provider::ALL
|
|
38
38
|
AUTH_FACTOR_TYPES = WorkOS::UserManagement::Types::AuthFactorType::ALL
|
|
39
39
|
|
|
40
|
+
# Load a sealed session
|
|
41
|
+
#
|
|
42
|
+
# @param [String] client_id The WorkOS client ID for the environment
|
|
43
|
+
# @param [String] session_data The sealed session data
|
|
44
|
+
# @param [String] cookie_password The password used to seal the session
|
|
45
|
+
# @param [Object] encryptor Optional custom encryptor that responds to #seal and #unseal
|
|
46
|
+
#
|
|
47
|
+
# @return WorkOS::Session
|
|
48
|
+
def load_sealed_session(client_id:, session_data:, cookie_password:, encryptor: nil)
|
|
49
|
+
WorkOS::Session.new(
|
|
50
|
+
user_management: self,
|
|
51
|
+
client_id: client_id,
|
|
52
|
+
session_data: session_data,
|
|
53
|
+
cookie_password: cookie_password,
|
|
54
|
+
encryptor: encryptor,
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
# Generate an OAuth 2.0 authorization URL that automatically directs a user
|
|
41
59
|
# to their Identity Provider.
|
|
42
60
|
#
|
|
@@ -55,8 +73,11 @@ module WorkOS
|
|
|
55
73
|
# that is preserved and available to the client in the response.
|
|
56
74
|
# @param [String] login_hint Can be used to pre-fill the username/email address
|
|
57
75
|
# field of the IdP sign-in page for the user, if you know their username ahead of time.
|
|
76
|
+
# @param [String] screen_hint Specify which AuthKit screen users should land on upon redirection
|
|
77
|
+
# (Only applicable when provider is 'authkit').
|
|
58
78
|
# @param [String] domain_hint Can be used to pre-fill the domain field when
|
|
59
79
|
# initiating authentication with Microsoft OAuth, or with a GoogleSAML connection type.
|
|
80
|
+
# @param [Array<String>] provider_scopes An array of additional OAuth scopes to request from the provider.
|
|
60
81
|
# @example
|
|
61
82
|
# WorkOS::UserManagement.authorization_url(
|
|
62
83
|
# connection_id: 'conn_123',
|
|
@@ -79,10 +100,12 @@ module WorkOS
|
|
|
79
100
|
client_id: nil,
|
|
80
101
|
domain_hint: nil,
|
|
81
102
|
login_hint: nil,
|
|
103
|
+
screen_hint: nil,
|
|
82
104
|
provider: nil,
|
|
83
105
|
connection_id: nil,
|
|
84
106
|
organization_id: nil,
|
|
85
|
-
state: ''
|
|
107
|
+
state: '',
|
|
108
|
+
provider_scopes: nil
|
|
86
109
|
)
|
|
87
110
|
|
|
88
111
|
validate_authorization_url_arguments(
|
|
@@ -98,9 +121,11 @@ module WorkOS
|
|
|
98
121
|
state: state,
|
|
99
122
|
domain_hint: domain_hint,
|
|
100
123
|
login_hint: login_hint,
|
|
124
|
+
screen_hint: screen_hint,
|
|
101
125
|
provider: provider,
|
|
102
126
|
connection_id: connection_id,
|
|
103
127
|
organization_id: organization_id,
|
|
128
|
+
provider_scopes: provider_scopes,
|
|
104
129
|
}.compact)
|
|
105
130
|
|
|
106
131
|
"https://#{WorkOS.config.api_hostname}/user_management/authorize?#{query}"
|
|
@@ -165,6 +190,7 @@ module WorkOS
|
|
|
165
190
|
# @param [String] first_name The user's first name.
|
|
166
191
|
# @param [String] last_name The user's last name.
|
|
167
192
|
# @param [Boolean] email_verified Whether the user's email address was previously verified.
|
|
193
|
+
# @param [String] external_id The user's external ID.
|
|
168
194
|
# @param [String] password_hash The user's hashed password.
|
|
169
195
|
# @option [String] password_hash_type The algorithm originally used to hash the password.
|
|
170
196
|
#
|
|
@@ -176,6 +202,7 @@ module WorkOS
|
|
|
176
202
|
first_name: nil,
|
|
177
203
|
last_name: nil,
|
|
178
204
|
email_verified: nil,
|
|
205
|
+
external_id: nil,
|
|
179
206
|
password_hash: nil,
|
|
180
207
|
password_hash_type: nil
|
|
181
208
|
)
|
|
@@ -187,9 +214,10 @@ module WorkOS
|
|
|
187
214
|
first_name: first_name,
|
|
188
215
|
last_name: last_name,
|
|
189
216
|
email_verified: email_verified,
|
|
217
|
+
external_id: external_id,
|
|
190
218
|
password_hash: password_hash,
|
|
191
219
|
password_hash_type: password_hash_type,
|
|
192
|
-
},
|
|
220
|
+
}.compact,
|
|
193
221
|
auth: true,
|
|
194
222
|
)
|
|
195
223
|
|
|
@@ -201,9 +229,12 @@ module WorkOS
|
|
|
201
229
|
# Update a user
|
|
202
230
|
#
|
|
203
231
|
# @param [String] id of the user.
|
|
232
|
+
# @param [String] email of the user.
|
|
204
233
|
# @param [String] first_name The user's first name.
|
|
205
234
|
# @param [String] last_name The user's last name.
|
|
206
235
|
# @param [Boolean] email_verified Whether the user's email address was previously verified.
|
|
236
|
+
# @param [String] external_id The users's external ID
|
|
237
|
+
# @param [String] locale The user's locale.
|
|
207
238
|
# @param [String] password The user's password.
|
|
208
239
|
# @param [String] password_hash The user's hashed password.
|
|
209
240
|
# @option [String] password_hash_type The algorithm originally used to hash the password.
|
|
@@ -212,23 +243,29 @@ module WorkOS
|
|
|
212
243
|
# @return [WorkOS::User]
|
|
213
244
|
def update_user(
|
|
214
245
|
id:,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
246
|
+
email: :not_set,
|
|
247
|
+
first_name: :not_set,
|
|
248
|
+
last_name: :not_set,
|
|
249
|
+
email_verified: :not_set,
|
|
250
|
+
external_id: :not_set,
|
|
251
|
+
locale: :not_set,
|
|
252
|
+
password: :not_set,
|
|
253
|
+
password_hash: :not_set,
|
|
254
|
+
password_hash_type: :not_set
|
|
221
255
|
)
|
|
222
256
|
request = put_request(
|
|
223
257
|
path: "/user_management/users/#{id}",
|
|
224
258
|
body: {
|
|
259
|
+
email: email,
|
|
225
260
|
first_name: first_name,
|
|
226
261
|
last_name: last_name,
|
|
227
262
|
email_verified: email_verified,
|
|
263
|
+
external_id: external_id,
|
|
264
|
+
locale: locale,
|
|
228
265
|
password: password,
|
|
229
266
|
password_hash: password_hash,
|
|
230
267
|
password_hash_type: password_hash_type,
|
|
231
|
-
},
|
|
268
|
+
}.reject { |_, v| v == :not_set },
|
|
232
269
|
auth: true,
|
|
233
270
|
)
|
|
234
271
|
|
|
@@ -261,9 +298,23 @@ module WorkOS
|
|
|
261
298
|
# @param [String] client_id The WorkOS client ID for the environment
|
|
262
299
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
263
300
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
301
|
+
# @param [String] invitation_token The token of an Invitation, if required.
|
|
302
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
303
|
+
# the optional cookie password.
|
|
264
304
|
#
|
|
265
305
|
# @return WorkOS::AuthenticationResponse
|
|
266
|
-
|
|
306
|
+
# rubocop:disable Metrics/ParameterLists
|
|
307
|
+
def authenticate_with_password(
|
|
308
|
+
email:,
|
|
309
|
+
password:,
|
|
310
|
+
client_id:,
|
|
311
|
+
ip_address: nil,
|
|
312
|
+
user_agent: nil,
|
|
313
|
+
invitation_token: nil,
|
|
314
|
+
session: nil
|
|
315
|
+
)
|
|
316
|
+
validate_session(session)
|
|
317
|
+
|
|
267
318
|
response = execute_request(
|
|
268
319
|
request: post_request(
|
|
269
320
|
path: '/user_management/authenticate',
|
|
@@ -274,13 +325,15 @@ module WorkOS
|
|
|
274
325
|
password: password,
|
|
275
326
|
ip_address: ip_address,
|
|
276
327
|
user_agent: user_agent,
|
|
328
|
+
invitation_token: invitation_token,
|
|
277
329
|
grant_type: 'password',
|
|
278
330
|
},
|
|
279
331
|
),
|
|
280
332
|
)
|
|
281
333
|
|
|
282
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
334
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
283
335
|
end
|
|
336
|
+
# rubocop:enable Metrics/ParameterLists
|
|
284
337
|
|
|
285
338
|
# Authenticate a user using OAuth or an organization's SSO connection.
|
|
286
339
|
#
|
|
@@ -289,14 +342,21 @@ module WorkOS
|
|
|
289
342
|
# @param [String] client_id The WorkOS client ID for the environment
|
|
290
343
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
291
344
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
345
|
+
# @param [String] invitation_token The token of an Invitation, if required.
|
|
346
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
347
|
+
# the optional cookie password.
|
|
292
348
|
#
|
|
293
349
|
# @return WorkOS::AuthenticationResponse
|
|
294
350
|
def authenticate_with_code(
|
|
295
351
|
code:,
|
|
296
352
|
client_id:,
|
|
297
353
|
ip_address: nil,
|
|
298
|
-
user_agent: nil
|
|
354
|
+
user_agent: nil,
|
|
355
|
+
invitation_token: nil,
|
|
356
|
+
session: nil
|
|
299
357
|
)
|
|
358
|
+
validate_session(session)
|
|
359
|
+
|
|
300
360
|
response = execute_request(
|
|
301
361
|
request: post_request(
|
|
302
362
|
path: '/user_management/authenticate',
|
|
@@ -306,28 +366,36 @@ module WorkOS
|
|
|
306
366
|
client_secret: WorkOS.config.key!,
|
|
307
367
|
ip_address: ip_address,
|
|
308
368
|
user_agent: user_agent,
|
|
369
|
+
invitation_token: invitation_token,
|
|
309
370
|
grant_type: 'authorization_code',
|
|
310
371
|
},
|
|
311
372
|
),
|
|
312
373
|
)
|
|
313
374
|
|
|
314
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
375
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
315
376
|
end
|
|
316
377
|
|
|
317
378
|
# Authenticate a user using a refresh token.
|
|
318
379
|
#
|
|
319
380
|
# @param [String] refresh_token The refresh token previously obtained from a successful authentication call
|
|
320
381
|
# @param [String] client_id The WorkOS client ID for the environment
|
|
382
|
+
# @param [String] organization_id The organization to issue the new access token for. (Optional)
|
|
321
383
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
322
384
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
385
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
386
|
+
# the optional cookie password.
|
|
323
387
|
#
|
|
324
388
|
# @return WorkOS::RefreshAuthenticationResponse
|
|
325
389
|
def authenticate_with_refresh_token(
|
|
326
390
|
refresh_token:,
|
|
327
391
|
client_id:,
|
|
392
|
+
organization_id: nil,
|
|
328
393
|
ip_address: nil,
|
|
329
|
-
user_agent: nil
|
|
394
|
+
user_agent: nil,
|
|
395
|
+
session: nil
|
|
330
396
|
)
|
|
397
|
+
validate_session(session)
|
|
398
|
+
|
|
331
399
|
response = execute_request(
|
|
332
400
|
request: post_request(
|
|
333
401
|
path: '/user_management/authenticate',
|
|
@@ -338,11 +406,12 @@ module WorkOS
|
|
|
338
406
|
ip_address: ip_address,
|
|
339
407
|
user_agent: user_agent,
|
|
340
408
|
grant_type: 'refresh_token',
|
|
409
|
+
organization_id: organization_id,
|
|
341
410
|
},
|
|
342
411
|
),
|
|
343
412
|
)
|
|
344
413
|
|
|
345
|
-
WorkOS::RefreshAuthenticationResponse.new(response.body)
|
|
414
|
+
WorkOS::RefreshAuthenticationResponse.new(response.body, session)
|
|
346
415
|
end
|
|
347
416
|
|
|
348
417
|
# Authenticate user by Magic Auth Code.
|
|
@@ -354,16 +423,24 @@ module WorkOS
|
|
|
354
423
|
# @param [String] link_authorization_code Used to link an OAuth profile to an existing user,
|
|
355
424
|
# after having completed a Magic Code challenge.
|
|
356
425
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
426
|
+
# @param [String] invitation_token The token of an Invitation, if required.
|
|
427
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
428
|
+
# the optional cookie password.
|
|
357
429
|
#
|
|
358
430
|
# @return WorkOS::AuthenticationResponse
|
|
431
|
+
# rubocop:disable Metrics/ParameterLists
|
|
359
432
|
def authenticate_with_magic_auth(
|
|
360
433
|
code:,
|
|
361
434
|
email:,
|
|
362
435
|
client_id:,
|
|
363
436
|
ip_address: nil,
|
|
364
437
|
user_agent: nil,
|
|
365
|
-
link_authorization_code: nil
|
|
438
|
+
link_authorization_code: nil,
|
|
439
|
+
invitation_token: nil,
|
|
440
|
+
session: nil
|
|
366
441
|
)
|
|
442
|
+
validate_session(session)
|
|
443
|
+
|
|
367
444
|
response = execute_request(
|
|
368
445
|
request: post_request(
|
|
369
446
|
path: '/user_management/authenticate',
|
|
@@ -376,12 +453,14 @@ module WorkOS
|
|
|
376
453
|
user_agent: user_agent,
|
|
377
454
|
grant_type: 'urn:workos:oauth:grant-type:magic-auth:code',
|
|
378
455
|
link_authorization_code: link_authorization_code,
|
|
456
|
+
invitation_token: invitation_token,
|
|
379
457
|
},
|
|
380
458
|
),
|
|
381
459
|
)
|
|
382
460
|
|
|
383
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
461
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
384
462
|
end
|
|
463
|
+
# rubocop:enable Metrics/ParameterLists
|
|
385
464
|
|
|
386
465
|
# Authenticate a user into an organization they are a member of.
|
|
387
466
|
#
|
|
@@ -390,6 +469,8 @@ module WorkOS
|
|
|
390
469
|
# @param [String] pending_authentication_token The pending authentication token
|
|
391
470
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
392
471
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
472
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
473
|
+
# the optional cookie password.
|
|
393
474
|
#
|
|
394
475
|
# @return WorkOS::AuthenticationResponse
|
|
395
476
|
def authenticate_with_organization_selection(
|
|
@@ -397,8 +478,11 @@ module WorkOS
|
|
|
397
478
|
organization_id:,
|
|
398
479
|
pending_authentication_token:,
|
|
399
480
|
ip_address: nil,
|
|
400
|
-
user_agent: nil
|
|
481
|
+
user_agent: nil,
|
|
482
|
+
session: nil
|
|
401
483
|
)
|
|
484
|
+
validate_session(session)
|
|
485
|
+
|
|
402
486
|
response = execute_request(
|
|
403
487
|
request: post_request(
|
|
404
488
|
path: '/user_management/authenticate',
|
|
@@ -414,7 +498,7 @@ module WorkOS
|
|
|
414
498
|
),
|
|
415
499
|
)
|
|
416
500
|
|
|
417
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
501
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
418
502
|
end
|
|
419
503
|
|
|
420
504
|
# Authenticate a user using TOTP.
|
|
@@ -427,16 +511,22 @@ module WorkOS
|
|
|
427
511
|
# authentication request.
|
|
428
512
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
429
513
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
514
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
515
|
+
# the optional cookie password.
|
|
430
516
|
#
|
|
431
517
|
# @return WorkOS::AuthenticationResponse
|
|
518
|
+
# rubocop:disable Metrics/ParameterLists
|
|
432
519
|
def authenticate_with_totp(
|
|
433
520
|
code:,
|
|
434
521
|
client_id:,
|
|
435
522
|
pending_authentication_token:,
|
|
436
523
|
authentication_challenge_id:,
|
|
437
524
|
ip_address: nil,
|
|
438
|
-
user_agent: nil
|
|
525
|
+
user_agent: nil,
|
|
526
|
+
session: nil
|
|
439
527
|
)
|
|
528
|
+
validate_session(session)
|
|
529
|
+
|
|
440
530
|
response = execute_request(
|
|
441
531
|
request: post_request(
|
|
442
532
|
path: '/user_management/authenticate',
|
|
@@ -453,8 +543,9 @@ module WorkOS
|
|
|
453
543
|
),
|
|
454
544
|
)
|
|
455
545
|
|
|
456
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
546
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
457
547
|
end
|
|
548
|
+
# rubocop:enable Metrics/ParameterLists
|
|
458
549
|
|
|
459
550
|
# Authenticate a user using Email Verification Code.
|
|
460
551
|
#
|
|
@@ -464,6 +555,8 @@ module WorkOS
|
|
|
464
555
|
# authentication attempt due to an unverified email address.
|
|
465
556
|
# @param [String] ip_address The IP address of the request from the user who is attempting to authenticate.
|
|
466
557
|
# @param [String] user_agent The user agent of the request from the user who is attempting to authenticate.
|
|
558
|
+
# @param [Hash] session An optional hash that determines whether the session should be sealed and
|
|
559
|
+
# the optional cookie password.
|
|
467
560
|
#
|
|
468
561
|
# @return WorkOS::AuthenticationResponse
|
|
469
562
|
def authenticate_with_email_verification(
|
|
@@ -471,8 +564,11 @@ module WorkOS
|
|
|
471
564
|
client_id:,
|
|
472
565
|
pending_authentication_token:,
|
|
473
566
|
ip_address: nil,
|
|
474
|
-
user_agent: nil
|
|
567
|
+
user_agent: nil,
|
|
568
|
+
session: nil
|
|
475
569
|
)
|
|
570
|
+
validate_session(session)
|
|
571
|
+
|
|
476
572
|
response = execute_request(
|
|
477
573
|
request: post_request(
|
|
478
574
|
path: '/user_management/authenticate',
|
|
@@ -488,7 +584,7 @@ module WorkOS
|
|
|
488
584
|
),
|
|
489
585
|
)
|
|
490
586
|
|
|
491
|
-
WorkOS::AuthenticationResponse.new(response.body)
|
|
587
|
+
WorkOS::AuthenticationResponse.new(response.body, session)
|
|
492
588
|
end
|
|
493
589
|
|
|
494
590
|
# Get the logout URL for a session
|
|
@@ -497,13 +593,17 @@ module WorkOS
|
|
|
497
593
|
#
|
|
498
594
|
# @param [String] session_id The session ID can be found in the `sid`
|
|
499
595
|
# claim of the access token
|
|
596
|
+
# @param [String] return_to The URL to redirect the user to after logging out
|
|
500
597
|
#
|
|
501
598
|
# @return String
|
|
502
|
-
def get_logout_url(session_id:)
|
|
599
|
+
def get_logout_url(session_id:, return_to: nil)
|
|
600
|
+
params = { session_id: session_id }
|
|
601
|
+
params[:return_to] = return_to if return_to
|
|
602
|
+
|
|
503
603
|
URI::HTTPS.build(
|
|
504
604
|
host: WorkOS.config.api_hostname,
|
|
505
605
|
path: '/user_management/sessions/logout',
|
|
506
|
-
query:
|
|
606
|
+
query: URI.encode_www_form(params),
|
|
507
607
|
).to_s
|
|
508
608
|
end
|
|
509
609
|
|
|
@@ -568,7 +668,7 @@ module WorkOS
|
|
|
568
668
|
body: {
|
|
569
669
|
email: email,
|
|
570
670
|
invitation_token: invitation_token,
|
|
571
|
-
},
|
|
671
|
+
}.compact,
|
|
572
672
|
auth: true,
|
|
573
673
|
),
|
|
574
674
|
)
|
|
@@ -622,7 +722,7 @@ module WorkOS
|
|
|
622
722
|
totp_issuer: totp_issuer,
|
|
623
723
|
totp_user: totp_user,
|
|
624
724
|
totp_secret: totp_secret,
|
|
625
|
-
},
|
|
725
|
+
}.compact,
|
|
626
726
|
auth: true,
|
|
627
727
|
),
|
|
628
728
|
)
|
|
@@ -655,6 +755,40 @@ module WorkOS
|
|
|
655
755
|
)
|
|
656
756
|
end
|
|
657
757
|
|
|
758
|
+
# Get all sessions for a user
|
|
759
|
+
#
|
|
760
|
+
# @param [String] user_id The id for the user.
|
|
761
|
+
# @param [Hash] options
|
|
762
|
+
# @option options [String] limit Maximum number of records to return.
|
|
763
|
+
# @option options [String] order The order in which to paginate records
|
|
764
|
+
# @option options [String] before Pagination cursor to receive records
|
|
765
|
+
# before a provided Session ID.
|
|
766
|
+
# @option options [String] after Pagination cursor to receive records
|
|
767
|
+
# after a provided Session ID.
|
|
768
|
+
#
|
|
769
|
+
# @return [WorkOS::Types::ListStruct<WorkOS::UserManagement::Session>]
|
|
770
|
+
def list_sessions(user_id:, options: {})
|
|
771
|
+
options[:order] ||= 'desc'
|
|
772
|
+
response = execute_request(
|
|
773
|
+
request: get_request(
|
|
774
|
+
path: "/user_management/users/#{user_id}/sessions",
|
|
775
|
+
auth: true,
|
|
776
|
+
params: options,
|
|
777
|
+
),
|
|
778
|
+
)
|
|
779
|
+
|
|
780
|
+
parsed_response = JSON.parse(response.body)
|
|
781
|
+
|
|
782
|
+
sessions = parsed_response['data'].map do |session|
|
|
783
|
+
::WorkOS::UserManagement::Session.new(session.to_json)
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
WorkOS::Types::ListStruct.new(
|
|
787
|
+
data: sessions,
|
|
788
|
+
list_metadata: parsed_response['list_metadata'],
|
|
789
|
+
)
|
|
790
|
+
end
|
|
791
|
+
|
|
658
792
|
# Gets an email verification object
|
|
659
793
|
#
|
|
660
794
|
# @param [String] id The unique ID of the EmailVerification object.
|
|
@@ -784,7 +918,7 @@ module WorkOS
|
|
|
784
918
|
),
|
|
785
919
|
)
|
|
786
920
|
|
|
787
|
-
WorkOS::
|
|
921
|
+
WorkOS::UserResponse.new(response.body).user
|
|
788
922
|
end
|
|
789
923
|
|
|
790
924
|
# Get an Organization Membership
|
|
@@ -844,16 +978,23 @@ module WorkOS
|
|
|
844
978
|
# @param [String] user_id The ID of the User.
|
|
845
979
|
# @param [String] organization_id The ID of the Organization to which the user belongs to.
|
|
846
980
|
# @param [String] role_slug The slug of the role to grant to this membership. (Optional)
|
|
981
|
+
# @param [Array<String>] role_slugs Array of role slugs to assign to this membership. (Optional)
|
|
847
982
|
#
|
|
848
983
|
# @return [WorkOS::OrganizationMembership]
|
|
849
|
-
def create_organization_membership(user_id:, organization_id:, role_slug: nil)
|
|
984
|
+
def create_organization_membership(user_id:, organization_id:, role_slug: nil, role_slugs: nil)
|
|
985
|
+
raise ArgumentError, 'Cannot specify both role_slug and role_slugs' if role_slug && role_slugs
|
|
986
|
+
|
|
987
|
+
body = {
|
|
988
|
+
user_id: user_id,
|
|
989
|
+
organization_id: organization_id,
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
body[:role_slugs] = role_slugs if role_slugs
|
|
993
|
+
body[:role_slug] = role_slug if role_slug
|
|
994
|
+
|
|
850
995
|
request = post_request(
|
|
851
996
|
path: '/user_management/organization_memberships',
|
|
852
|
-
body:
|
|
853
|
-
user_id: user_id,
|
|
854
|
-
organization_id: organization_id,
|
|
855
|
-
role_slug: role_slug,
|
|
856
|
-
},
|
|
997
|
+
body: body.compact,
|
|
857
998
|
auth: true,
|
|
858
999
|
)
|
|
859
1000
|
|
|
@@ -864,17 +1005,22 @@ module WorkOS
|
|
|
864
1005
|
|
|
865
1006
|
# Update an Organization Membership
|
|
866
1007
|
#
|
|
867
|
-
# @param [String]
|
|
868
|
-
# @param [String] role_slug The slug of the role to grant to this membership.
|
|
1008
|
+
# @param [String] id The ID of the Organization Membership.
|
|
1009
|
+
# @param [String] role_slug The slug of the role to grant to this membership. (Optional)
|
|
1010
|
+
# @param [Array<String>] role_slugs Array of role slugs to assign to this membership. (Optional)
|
|
869
1011
|
#
|
|
870
1012
|
# @return [WorkOS::OrganizationMembership]
|
|
871
|
-
def update_organization_membership(id:, role_slug:)
|
|
1013
|
+
def update_organization_membership(id:, role_slug: nil, role_slugs: nil)
|
|
1014
|
+
raise ArgumentError, 'Cannot specify both role_slug and role_slugs' if role_slug && role_slugs
|
|
1015
|
+
|
|
1016
|
+
body = { id: id }
|
|
1017
|
+
|
|
1018
|
+
body[:role_slugs] = role_slugs if role_slugs
|
|
1019
|
+
body[:role_slug] = role_slug if role_slug
|
|
1020
|
+
|
|
872
1021
|
request = put_request(
|
|
873
1022
|
path: "/user_management/organization_memberships/#{id}",
|
|
874
|
-
body:
|
|
875
|
-
id: id,
|
|
876
|
-
role_slug: role_slug,
|
|
877
|
-
},
|
|
1023
|
+
body: body.compact,
|
|
878
1024
|
auth: true,
|
|
879
1025
|
)
|
|
880
1026
|
|
|
@@ -1018,7 +1164,7 @@ module WorkOS
|
|
|
1018
1164
|
expires_in_days: expires_in_days,
|
|
1019
1165
|
inviter_user_id: inviter_user_id,
|
|
1020
1166
|
role_slug: role_slug,
|
|
1021
|
-
},
|
|
1167
|
+
}.compact,
|
|
1022
1168
|
auth: true,
|
|
1023
1169
|
),
|
|
1024
1170
|
)
|
|
@@ -1042,8 +1188,30 @@ module WorkOS
|
|
|
1042
1188
|
WorkOS::Invitation.new(response.body)
|
|
1043
1189
|
end
|
|
1044
1190
|
|
|
1191
|
+
# Resends an existing Invitation.
|
|
1192
|
+
#
|
|
1193
|
+
# @param [String] id The unique ID of the Invitation.
|
|
1194
|
+
#
|
|
1195
|
+
# @return WorkOS::Invitation
|
|
1196
|
+
def resend_invitation(id:)
|
|
1197
|
+
request = post_request(
|
|
1198
|
+
path: "/user_management/invitations/#{id}/resend",
|
|
1199
|
+
auth: true,
|
|
1200
|
+
)
|
|
1201
|
+
|
|
1202
|
+
response = execute_request(request: request)
|
|
1203
|
+
|
|
1204
|
+
WorkOS::Invitation.new(response.body)
|
|
1205
|
+
end
|
|
1206
|
+
|
|
1045
1207
|
private
|
|
1046
1208
|
|
|
1209
|
+
def validate_session(session)
|
|
1210
|
+
return unless session && (session[:seal_session] == true) && session[:cookie_password].nil?
|
|
1211
|
+
|
|
1212
|
+
raise ArgumentError, 'cookie_password is required when sealing session'
|
|
1213
|
+
end
|
|
1214
|
+
|
|
1047
1215
|
def validate_authorization_url_arguments(
|
|
1048
1216
|
provider:,
|
|
1049
1217
|
connection_id:,
|
data/lib/workos/version.rb
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
|
|
5
|
+
module WorkOS
|
|
6
|
+
# The Widgets module provides resource methods for working with the Widgets APIs
|
|
7
|
+
module Widgets
|
|
8
|
+
class << self
|
|
9
|
+
include Client
|
|
10
|
+
|
|
11
|
+
WIDGET_SCOPES = WorkOS::Types::WidgetScope::ALL
|
|
12
|
+
|
|
13
|
+
# Generate a widget token.
|
|
14
|
+
#
|
|
15
|
+
# @param [String] organization_id The ID of the organization to generate the token for.
|
|
16
|
+
# @param [String] user_id The ID of the user to generate the token for.
|
|
17
|
+
# @param [WidgetScope[]] The scopes to generate the token for.
|
|
18
|
+
def get_token(organization_id:, user_id:, scopes:)
|
|
19
|
+
validate_scopes(scopes)
|
|
20
|
+
|
|
21
|
+
request = post_request(
|
|
22
|
+
auth: true,
|
|
23
|
+
body: {
|
|
24
|
+
organization_id: organization_id,
|
|
25
|
+
user_id: user_id,
|
|
26
|
+
scopes: scopes,
|
|
27
|
+
},
|
|
28
|
+
path: '/widgets/token',
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
response = execute_request(request: request)
|
|
32
|
+
|
|
33
|
+
JSON.parse(response.body)['token']
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def validate_scopes(scopes)
|
|
39
|
+
return if scopes.all? { |scope| WIDGET_SCOPES.include?(scope) }
|
|
40
|
+
|
|
41
|
+
raise ArgumentError, 'scopes contains an invalid value.' \
|
|
42
|
+
" Every item in `scopes` must be in #{WIDGET_SCOPES}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/workos.rb
CHANGED
|
@@ -45,6 +45,7 @@ module WorkOS
|
|
|
45
45
|
autoload :AuthenticationFactorAndChallenge, 'workos/authentication_factor_and_challenge'
|
|
46
46
|
autoload :AuthenticationResponse, 'workos/authentication_response'
|
|
47
47
|
autoload :AuditLogs, 'workos/audit_logs'
|
|
48
|
+
autoload :Cache, 'workos/cache'
|
|
48
49
|
autoload :Challenge, 'workos/challenge'
|
|
49
50
|
autoload :Client, 'workos/client'
|
|
50
51
|
autoload :Connection, 'workos/connection'
|
|
@@ -55,13 +56,16 @@ module WorkOS
|
|
|
55
56
|
autoload :DirectorySync, 'workos/directory_sync'
|
|
56
57
|
autoload :DirectoryUser, 'workos/directory_user'
|
|
57
58
|
autoload :EmailVerification, 'workos/email_verification'
|
|
59
|
+
autoload :Encryptors, 'workos/encryptors'
|
|
58
60
|
autoload :Event, 'workos/event'
|
|
59
61
|
autoload :Events, 'workos/events'
|
|
60
62
|
autoload :Factor, 'workos/factor'
|
|
63
|
+
autoload :FeatureFlag, 'workos/feature_flag'
|
|
61
64
|
autoload :Impersonator, 'workos/impersonator'
|
|
62
65
|
autoload :Invitation, 'workos/invitation'
|
|
63
66
|
autoload :MagicAuth, 'workos/magic_auth'
|
|
64
67
|
autoload :MFA, 'workos/mfa'
|
|
68
|
+
autoload :OAuthTokens, 'workos/oauth_tokens'
|
|
65
69
|
autoload :Organization, 'workos/organization'
|
|
66
70
|
autoload :Organizations, 'workos/organizations'
|
|
67
71
|
autoload :OrganizationMembership, 'workos/organization_membership'
|
|
@@ -71,6 +75,8 @@ module WorkOS
|
|
|
71
75
|
autoload :Profile, 'workos/profile'
|
|
72
76
|
autoload :ProfileAndToken, 'workos/profile_and_token'
|
|
73
77
|
autoload :RefreshAuthenticationResponse, 'workos/refresh_authentication_response'
|
|
78
|
+
autoload :Role, 'workos/role'
|
|
79
|
+
autoload :Session, 'workos/session'
|
|
74
80
|
autoload :SSO, 'workos/sso'
|
|
75
81
|
autoload :Types, 'workos/types'
|
|
76
82
|
autoload :User, 'workos/user'
|
|
@@ -80,11 +86,13 @@ module WorkOS
|
|
|
80
86
|
autoload :VerifyChallenge, 'workos/verify_challenge'
|
|
81
87
|
autoload :Webhook, 'workos/webhook'
|
|
82
88
|
autoload :Webhooks, 'workos/webhooks'
|
|
89
|
+
autoload :Widgets, 'workos/widgets'
|
|
83
90
|
|
|
84
91
|
# Errors
|
|
85
92
|
autoload :APIError, 'workos/errors'
|
|
86
93
|
autoload :AuthenticationError, 'workos/errors'
|
|
87
94
|
autoload :InvalidRequestError, 'workos/errors'
|
|
95
|
+
autoload :ForbiddenRequestError, 'workos/errors'
|
|
88
96
|
autoload :SignatureVerificationError, 'workos/errors'
|
|
89
97
|
autoload :TimeoutError, 'workos/errors'
|
|
90
98
|
autoload :NotFoundError, 'workos/errors'
|