workos 5.19.0 → 5.20.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/Gemfile.lock +1 -1
- data/lib/workos/authentication_response.rb +4 -1
- data/lib/workos/oauth_tokens.rb +29 -0
- data/lib/workos/user_management.rb +4 -1
- data/lib/workos/version.rb +1 -1
- data/lib/workos.rb +1 -0
- data/spec/lib/workos/user_management_spec.rb +60 -0
- data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_oauth_tokens.yml +82 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc1f97c76fdf489cb3be51bd9026dc515195c34aaf9810379bfe4773029aafc1
|
4
|
+
data.tar.gz: 2176f6680ae6a7c46ca77824c7dcf2fbe91ca244986a05f7039a1d40265db881
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bda209314485831a8237e381566472c5815dea3b727db277e2a06c3db1c06191da54dc59292ec37bd4415291ca78c7593ae4a78cad82775ce6ffb8eae6d0931
|
7
|
+
data.tar.gz: fd199d57bd3e29e0bea6b21840597ae255db869c9815b6a06348a90c3d70532606732c999c8bef3caa2ba2900914c20b222b526c7e1a9b61c836f30f5e55d694
|
data/Gemfile.lock
CHANGED
@@ -12,7 +12,8 @@ module WorkOS
|
|
12
12
|
:access_token,
|
13
13
|
:refresh_token,
|
14
14
|
:authentication_method,
|
15
|
-
:sealed_session
|
15
|
+
:sealed_session,
|
16
|
+
:oauth_tokens
|
16
17
|
|
17
18
|
# rubocop:disable Metrics/AbcSize
|
18
19
|
def initialize(authentication_response_json, session = nil)
|
@@ -27,6 +28,7 @@ module WorkOS
|
|
27
28
|
reason: impersonator_json[:reason],)
|
28
29
|
end
|
29
30
|
@authentication_method = json[:authentication_method]
|
31
|
+
@oauth_tokens = json[:oauth_tokens] ? WorkOS::OAuthTokens.new(json[:oauth_tokens].to_json) : nil
|
30
32
|
@sealed_session =
|
31
33
|
if session && session[:seal_session]
|
32
34
|
WorkOS::Session.seal_data({
|
@@ -49,6 +51,7 @@ module WorkOS
|
|
49
51
|
refresh_token: refresh_token,
|
50
52
|
authentication_method: authentication_method,
|
51
53
|
sealed_session: sealed_session,
|
54
|
+
oauth_tokens: oauth_tokens&.to_json,
|
52
55
|
}
|
53
56
|
end
|
54
57
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WorkOS
|
4
|
+
# The OAuthTokens class represents the third party provider OAuth tokens returned in the authentication response.
|
5
|
+
# This class is not meant to be instantiated in user space, and is instantiated internally but exposed.
|
6
|
+
class OAuthTokens
|
7
|
+
include HashProvider
|
8
|
+
|
9
|
+
attr_accessor :access_token, :refresh_token, :scopes, :expires_at
|
10
|
+
|
11
|
+
def initialize(json)
|
12
|
+
hash = JSON.parse(json, symbolize_names: true)
|
13
|
+
|
14
|
+
@access_token = hash[:access_token]
|
15
|
+
@refresh_token = hash[:refresh_token]
|
16
|
+
@scopes = hash[:scopes]
|
17
|
+
@expires_at = hash[:expires_at]
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_json(*)
|
21
|
+
{
|
22
|
+
access_token: access_token,
|
23
|
+
refresh_token: refresh_token,
|
24
|
+
scopes: scopes,
|
25
|
+
expires_at: expires_at,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -71,6 +71,7 @@ module WorkOS
|
|
71
71
|
# field of the IdP sign-in page for the user, if you know their username ahead of time.
|
72
72
|
# @param [String] domain_hint Can be used to pre-fill the domain field when
|
73
73
|
# initiating authentication with Microsoft OAuth, or with a GoogleSAML connection type.
|
74
|
+
# @param [Array<String>] provider_scopes An array of additional OAuth scopes to request from the provider.
|
74
75
|
# @example
|
75
76
|
# WorkOS::UserManagement.authorization_url(
|
76
77
|
# connection_id: 'conn_123',
|
@@ -96,7 +97,8 @@ module WorkOS
|
|
96
97
|
provider: nil,
|
97
98
|
connection_id: nil,
|
98
99
|
organization_id: nil,
|
99
|
-
state: ''
|
100
|
+
state: '',
|
101
|
+
provider_scopes: nil
|
100
102
|
)
|
101
103
|
|
102
104
|
validate_authorization_url_arguments(
|
@@ -115,6 +117,7 @@ module WorkOS
|
|
115
117
|
provider: provider,
|
116
118
|
connection_id: connection_id,
|
117
119
|
organization_id: organization_id,
|
120
|
+
provider_scopes: provider_scopes,
|
118
121
|
}.compact)
|
119
122
|
|
120
123
|
"https://#{WorkOS.config.api_hostname}/user_management/authorize?#{query}"
|
data/lib/workos/version.rb
CHANGED
data/lib/workos.rb
CHANGED
@@ -63,6 +63,7 @@ module WorkOS
|
|
63
63
|
autoload :Invitation, 'workos/invitation'
|
64
64
|
autoload :MagicAuth, 'workos/magic_auth'
|
65
65
|
autoload :MFA, 'workos/mfa'
|
66
|
+
autoload :OAuthTokens, 'workos/oauth_tokens'
|
66
67
|
autoload :Organization, 'workos/organization'
|
67
68
|
autoload :Organizations, 'workos/organizations'
|
68
69
|
autoload :OrganizationMembership, 'workos/organization_membership'
|
@@ -36,6 +36,32 @@ describe WorkOS::UserManagement do
|
|
36
36
|
'edit%22%7D&provider=authkit',
|
37
37
|
)
|
38
38
|
end
|
39
|
+
|
40
|
+
context 'with provider_scopes' do
|
41
|
+
it 'returns a valid authorization URL that includes provider_scopes' do
|
42
|
+
url = WorkOS::UserManagement.authorization_url(
|
43
|
+
provider: 'GoogleOAuth',
|
44
|
+
provider_scopes: %w[custom-scope-1 custom-scope-2],
|
45
|
+
client_id: 'workos-proj-123',
|
46
|
+
redirect_uri: 'foo.com/auth/callback',
|
47
|
+
state: {
|
48
|
+
next_page: '/dashboard/edit',
|
49
|
+
}.to_s,
|
50
|
+
)
|
51
|
+
|
52
|
+
expect(url).to eq(
|
53
|
+
'https://api.workos.com/user_management/authorize?' \
|
54
|
+
'client_id=workos-proj-123' \
|
55
|
+
'&redirect_uri=foo.com%2Fauth%2Fcallback' \
|
56
|
+
'&response_type=code' \
|
57
|
+
'&state=%7B%3Anext_page%3D%3E%22%2Fdashboard%2F' \
|
58
|
+
'edit%22%7D' \
|
59
|
+
'&provider=GoogleOAuth' \
|
60
|
+
'&provider_scopes=custom-scope-1' \
|
61
|
+
'&provider_scopes=custom-scope-2',
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
39
65
|
end
|
40
66
|
|
41
67
|
context 'with a connection selector' do
|
@@ -453,6 +479,40 @@ describe WorkOS::UserManagement do
|
|
453
479
|
end
|
454
480
|
end
|
455
481
|
|
482
|
+
context 'when oauth_tokens is present in the api response' do
|
483
|
+
it 'returns an oauth_tokens object' do
|
484
|
+
VCR.use_cassette('user_management/authenticate_with_code/valid_with_oauth_tokens') do
|
485
|
+
authentication_response = WorkOS::UserManagement.authenticate_with_code(
|
486
|
+
code: '01H93ZZHA0JBHFJH9RR11S83YN',
|
487
|
+
client_id: 'client_123',
|
488
|
+
ip_address: '200.240.210.16',
|
489
|
+
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/108.0.0.0 Safari/537.36',
|
490
|
+
)
|
491
|
+
|
492
|
+
expect(authentication_response.oauth_tokens).to be_a(WorkOS::OAuthTokens)
|
493
|
+
expect(authentication_response.oauth_tokens.access_token).to eq('oauth_access_token')
|
494
|
+
expect(authentication_response.oauth_tokens.refresh_token).to eq('oauth_refresh_token')
|
495
|
+
expect(authentication_response.oauth_tokens.scopes).to eq(%w[read write])
|
496
|
+
expect(authentication_response.oauth_tokens.expires_at).to eq(1_234_567_890)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
context 'when oauth_tokens is not present in the api response' do
|
502
|
+
it 'returns nil oauth_tokens' do
|
503
|
+
VCR.use_cassette('user_management/authenticate_with_code/valid') do
|
504
|
+
authentication_response = WorkOS::UserManagement.authenticate_with_code(
|
505
|
+
code: '01H93ZZHA0JBHFJH9RR11S83YN',
|
506
|
+
client_id: 'client_123',
|
507
|
+
ip_address: '200.240.210.16',
|
508
|
+
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/108.0.0.0 Safari/537.36',
|
509
|
+
)
|
510
|
+
|
511
|
+
expect(authentication_response.oauth_tokens).to be_nil
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
456
516
|
context 'when the user is being impersonated' do
|
457
517
|
it 'contains the impersonator metadata' do
|
458
518
|
VCR.use_cassette('user_management/authenticate_with_code/valid_with_impersonator') do
|
@@ -0,0 +1,82 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.workos.com/user_management/authenticate
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string:
|
9
|
+
'{"code":"01H93ZZHA0JBHFJH9RR11S83YN","client_id":"client_123","client_secret":"<API_KEY>","ip_address":"200.240.210.16","user_agent":"Mozilla/5.0
|
10
|
+
(Macintosh; Intel Mac OS X 10_15_7) Chrome/108.0.0.0 Safari/537.36","grant_type":"authorization_code"}'
|
11
|
+
headers:
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
User-Agent:
|
19
|
+
- WorkOS; ruby/3.0.2; arm64-darwin21; v2.16.0
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Date:
|
26
|
+
- Wed, 30 Aug 2023 19:51:51 GMT
|
27
|
+
Content-Type:
|
28
|
+
- application/json; charset=utf-8
|
29
|
+
Transfer-Encoding:
|
30
|
+
- chunked
|
31
|
+
Connection:
|
32
|
+
- keep-alive
|
33
|
+
Cf-Ray:
|
34
|
+
- 7fef921deeca091f-SEA
|
35
|
+
Cf-Cache-Status:
|
36
|
+
- DYNAMIC
|
37
|
+
Etag:
|
38
|
+
- W/"13b-pHataL1lHEvsW5EO4vq5QgAdcWw"
|
39
|
+
Strict-Transport-Security:
|
40
|
+
- max-age=15552000; includeSubDomains
|
41
|
+
Vary:
|
42
|
+
- Origin, Accept-Encoding
|
43
|
+
Via:
|
44
|
+
- 1.1 spaces-router (devel)
|
45
|
+
Access-Control-Allow-Credentials:
|
46
|
+
- "true"
|
47
|
+
Content-Security-Policy:
|
48
|
+
- "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self'
|
49
|
+
https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src
|
50
|
+
'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests"
|
51
|
+
Expect-Ct:
|
52
|
+
- max-age=0
|
53
|
+
Referrer-Policy:
|
54
|
+
- no-referrer
|
55
|
+
X-Content-Type-Options:
|
56
|
+
- nosniff
|
57
|
+
X-Dns-Prefetch-Control:
|
58
|
+
- "off"
|
59
|
+
X-Download-Options:
|
60
|
+
- noopen
|
61
|
+
X-Frame-Options:
|
62
|
+
- SAMEORIGIN
|
63
|
+
X-Permitted-Cross-Domain-Policies:
|
64
|
+
- none
|
65
|
+
X-Request-Id:
|
66
|
+
- 630bec5a-5a13-4311-a0b7-958889a3bbb2
|
67
|
+
X-Xss-Protection:
|
68
|
+
- "0"
|
69
|
+
Set-Cookie:
|
70
|
+
- __cf_bm=o5KBdIAUFZp0azSQnnd1GlQcIlcPCz95uFg6hFNnKM8-1693425111-0-ARSauqdojZdKD6Z7vp12JBrxCp6wE1s0JzEhaN0XE2DqME76OnJiDJugj2TsbNGXtqWaH3By7XHUXVZDf+AdFxU=;
|
71
|
+
path=/; expires=Wed, 30-Aug-23 20:21:51 GMT; domain=.workos.com; HttpOnly;
|
72
|
+
Secure; SameSite=None
|
73
|
+
- __cfruid=3e9a5d359ba92753e7626245fef8b2f1ee096477-1693425111; path=/; domain=.workos.com;
|
74
|
+
HttpOnly; Secure; SameSite=None
|
75
|
+
Server:
|
76
|
+
- cloudflare
|
77
|
+
body:
|
78
|
+
encoding: ASCII-8BIT
|
79
|
+
string: '{"user":{"object":"user","id":"user_01H93ZY4F80YZRRS6N59Z2HFVS","email":"test@workos.app","email_verified":false,"first_name":"Lucille","last_name":"Bluth","created_at":"2023-08-30T19:50:13.214Z","updated_at":"2023-08-30T19:50:13.214Z","user_type":"managed","sso_profile_id":"prof_01H93ZTVWYPAT4RKDSPFPPXH0J"},"access_token":"<ACCESS_TOKEN>","refresh_token":"<REFRESH_TOKEN>","oauth_tokens":{"access_token":"oauth_access_token","refresh_token":"oauth_refresh_token","scopes":["read","write"],"expires_at":1234567890}}'
|
80
|
+
http_version:
|
81
|
+
recorded_at: Wed, 30 Aug 2023 19:51:51 GMT
|
82
|
+
recorded_with: VCR 5.0.0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: workos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WorkOS
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: encryptor
|
@@ -158,6 +158,7 @@ files:
|
|
158
158
|
- lib/workos/invitation.rb
|
159
159
|
- lib/workos/magic_auth.rb
|
160
160
|
- lib/workos/mfa.rb
|
161
|
+
- lib/workos/oauth_tokens.rb
|
161
162
|
- lib/workos/organization.rb
|
162
163
|
- lib/workos/organization_membership.rb
|
163
164
|
- lib/workos/organizations.rb
|
@@ -300,6 +301,7 @@ files:
|
|
300
301
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/invalid.yml
|
301
302
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid.yml
|
302
303
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_impersonator.yml
|
304
|
+
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_oauth_tokens.yml
|
303
305
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/invalid.yml
|
304
306
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/valid.yml
|
305
307
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/invalid.yml
|
@@ -523,6 +525,7 @@ test_files:
|
|
523
525
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/invalid.yml
|
524
526
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid.yml
|
525
527
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_impersonator.yml
|
528
|
+
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_oauth_tokens.yml
|
526
529
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/invalid.yml
|
527
530
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_email_verification/valid.yml
|
528
531
|
- spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_magic_auth/invalid.yml
|