workos 2.0.0 → 2.2.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/.semaphore/semaphore.yml +13 -39
- data/Gemfile.lock +2 -2
- data/README.md +4 -0
- data/lib/workos/challenge.rb +54 -0
- data/lib/workos/client.rb +2 -0
- data/lib/workos/directory_sync.rb +1 -0
- data/lib/workos/errors.rb +3 -1
- data/lib/workos/factor.rb +58 -0
- data/lib/workos/mfa.rb +165 -0
- data/lib/workos/sso.rb +38 -15
- data/lib/workos/types/challenge_struct.rb +18 -0
- data/lib/workos/types/factor_struct.rb +19 -0
- data/lib/workos/types/verify_factor_struct.rb +15 -0
- data/lib/workos/types.rb +3 -0
- data/lib/workos/verify_factor.rb +39 -0
- data/lib/workos/version.rb +1 -1
- data/lib/workos/webhooks.rb +9 -7
- data/lib/workos.rb +5 -0
- data/spec/lib/workos/mfa_spec.rb +232 -0
- data/spec/lib/workos/sso_spec.rb +140 -4
- data/spec/lib/workos/webhooks_spec.rb +1 -1
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_expired.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_invalid.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid.yml +82 -0
- metadata +36 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 983d578de3e27144af8a7947eebfb770ad7ee640954511586617505c520ee657
|
|
4
|
+
data.tar.gz: 92cb0b75234f56a1e18c47d9cb339b2f389e17463798141bc7a3a2977f5f9372
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1143a28ee95755c80fe36aa5fba02e069143ebdb96e67f909d566bbf091928176ac29f23ccfa7764da163a248268f7a882616e0db7bd73612eda060c78cf8515
|
|
7
|
+
data.tar.gz: a2e279f2f2427dd8089eddcc692e677d21978fdd16f3918ffe162822d116b7904f1dbc6826d151f583ba1c60cd5c0e8fbe8b825fb78212f772d7a1aa11faa6da
|
data/.semaphore/semaphore.yml
CHANGED
|
@@ -31,45 +31,19 @@ blocks:
|
|
|
31
31
|
- name: codecov-workos-ruby
|
|
32
32
|
jobs:
|
|
33
33
|
- name: Ruby 1.9.3
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- checkout
|
|
48
|
-
- sem-version ruby 2.3.4
|
|
49
|
-
- bundle install
|
|
50
|
-
- bundle exec rspec
|
|
51
|
-
- name: Ruby 2.5.7
|
|
52
|
-
commands:
|
|
53
|
-
- checkout
|
|
54
|
-
- sem-version ruby 2.5.7
|
|
55
|
-
- bundle install
|
|
56
|
-
- bundle exec rspec
|
|
57
|
-
- name: Ruby 2.6.5
|
|
58
|
-
commands:
|
|
59
|
-
- checkout
|
|
60
|
-
- sem-version ruby 2.6.5
|
|
61
|
-
- bundle install
|
|
62
|
-
- bundle exec rspec
|
|
63
|
-
- name: Ruby 2.7.3
|
|
64
|
-
commands:
|
|
65
|
-
- checkout
|
|
66
|
-
- sem-version ruby 2.7.3
|
|
67
|
-
- bundle install
|
|
68
|
-
- bundle exec rspec
|
|
69
|
-
- name: Ruby 3.0.2
|
|
70
|
-
commands:
|
|
71
|
-
- checkout
|
|
72
|
-
- sem-version ruby 3.0.2
|
|
34
|
+
matrix:
|
|
35
|
+
- env_var: RUBY_VERSION
|
|
36
|
+
values:
|
|
37
|
+
- 1.9.3-p551
|
|
38
|
+
- 2.0.0-p648
|
|
39
|
+
- 2.3.4
|
|
40
|
+
- 2.5.7
|
|
41
|
+
- 2.6.5
|
|
42
|
+
- 2.7.3
|
|
43
|
+
- 3.0.2
|
|
44
|
+
commands:
|
|
45
|
+
- checkout
|
|
46
|
+
- sem-version ruby $RUBY_VERSION
|
|
73
47
|
- bundle install
|
|
74
48
|
- bundle exec rspec
|
|
75
49
|
promotions:
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -38,6 +38,10 @@ Or, you may set the key yourself, such as in an initializer in your application
|
|
|
38
38
|
WorkOS.key = '[your api key]'
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## SDK Versioning
|
|
42
|
+
|
|
43
|
+
For our SDKs WorkOS follows a Semantic Versioning ([SemVer](https://semver.org/)) process where all releases will have a version X.Y.Z (like 1.0.0) pattern wherein Z would be a bug fix (e.g., 1.0.1), Y would be a minor release (1.1.0) and X would be a major release (2.0.0). We permit any breaking changes to only be released in major versions and strongly recommend reading changelogs before making any major version upgrades.
|
|
44
|
+
|
|
41
45
|
## More Information
|
|
42
46
|
|
|
43
47
|
* [Single Sign-On Guide](https://workos.com/docs/sso/guide)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: false
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
# The Challnge class provides a lightweight wrapper around
|
|
6
|
+
# a WorkOS DirectoryUser resource. This class is not meant to be instantiated
|
|
7
|
+
# in DirectoryUser space, and is instantiated internally but exposed.
|
|
8
|
+
class Challenge
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
attr_accessor :id, :object, :expires_at, :code, :authentication_factor_id, :updated_at, :created_at
|
|
12
|
+
|
|
13
|
+
sig { params(json: String).void }
|
|
14
|
+
def initialize(json)
|
|
15
|
+
raw = parse_json(json)
|
|
16
|
+
@id = T.let(raw.id, String)
|
|
17
|
+
@object = T.let(raw.object, String)
|
|
18
|
+
@expires_at = raw.expires_at
|
|
19
|
+
@code = raw.code
|
|
20
|
+
@authentication_factor_id = T.let(raw.authentication_factor_id, String)
|
|
21
|
+
@created_at = T.let(raw.created_at, String)
|
|
22
|
+
@updated_at = T.let(raw.updated_at, String)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_json(*)
|
|
26
|
+
{
|
|
27
|
+
id: id,
|
|
28
|
+
object: object,
|
|
29
|
+
expires_at: expires_at,
|
|
30
|
+
code: code,
|
|
31
|
+
authentication_factor_id: authentication_factor_id,
|
|
32
|
+
created_at: created_at,
|
|
33
|
+
updated_at: updated_at,
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
sig { params(json_string: String).returns(WorkOS::Types::ChallengeStruct) }
|
|
40
|
+
def parse_json(json_string)
|
|
41
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
|
42
|
+
|
|
43
|
+
WorkOS::Types::ChallengeStruct.new(
|
|
44
|
+
id: hash[:id],
|
|
45
|
+
object: hash[:object],
|
|
46
|
+
expires_at: hash[:expires_at],
|
|
47
|
+
code: hash[:code],
|
|
48
|
+
authentication_factor_id: hash[:authentication_factor_id],
|
|
49
|
+
created_at: hash[:created_at],
|
|
50
|
+
updated_at: hash[:updated_at],
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/workos/client.rb
CHANGED
|
@@ -144,6 +144,7 @@ module WorkOS
|
|
|
144
144
|
)
|
|
145
145
|
when 422
|
|
146
146
|
message = json['message']
|
|
147
|
+
code = json['code']
|
|
147
148
|
errors = extract_error(json['errors']) if json['errors']
|
|
148
149
|
message += " (#{errors})" if errors
|
|
149
150
|
|
|
@@ -151,6 +152,7 @@ module WorkOS
|
|
|
151
152
|
message: message,
|
|
152
153
|
http_status: http_status,
|
|
153
154
|
request_id: response['x-request-id'],
|
|
155
|
+
code: code,
|
|
154
156
|
)
|
|
155
157
|
end
|
|
156
158
|
end
|
|
@@ -26,6 +26,7 @@ module WorkOS
|
|
|
26
26
|
# before a provided Directory ID.
|
|
27
27
|
# @option options [String] after Pagination cursor to receive records
|
|
28
28
|
# before a provided Directory ID.
|
|
29
|
+
# @option options [String] organization_id The ID for an Organization configured on WorkOS.
|
|
29
30
|
#
|
|
30
31
|
# @return [Hash]
|
|
31
32
|
sig do
|
data/lib/workos/errors.rb
CHANGED
|
@@ -17,14 +17,16 @@ module WorkOS
|
|
|
17
17
|
error_description: T.nilable(String),
|
|
18
18
|
http_status: T.nilable(Integer),
|
|
19
19
|
request_id: T.nilable(String),
|
|
20
|
+
code: T.nilable(String),
|
|
20
21
|
).void
|
|
21
22
|
end
|
|
22
|
-
def initialize(message: nil, error: nil, error_description: nil, http_status: nil, request_id: nil)
|
|
23
|
+
def initialize(message: nil, error: nil, error_description: nil, http_status: nil, request_id: nil, code: nil)
|
|
23
24
|
@message = message
|
|
24
25
|
@error = error
|
|
25
26
|
@error_description = error_description
|
|
26
27
|
@http_status = http_status
|
|
27
28
|
@request_id = request_id
|
|
29
|
+
@code = code
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
sig { returns(String) }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: false
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
# The Factor class provides a lightweight wrapper around
|
|
6
|
+
# a WorkOS DirectoryUser resource. This class is not meant to be instantiated
|
|
7
|
+
# in DirectoryUser space, and is instantiated internally but exposed.
|
|
8
|
+
class Factor
|
|
9
|
+
# rubocop:disable Metrics/AbcSize
|
|
10
|
+
extend T::Sig
|
|
11
|
+
attr_accessor :id, :environment_id, :object, :type, :sms, :totp, :updated_at, :created_at
|
|
12
|
+
|
|
13
|
+
sig { params(json: String).void }
|
|
14
|
+
def initialize(json)
|
|
15
|
+
raw = parse_json(json)
|
|
16
|
+
@id = T.let(raw.id, String)
|
|
17
|
+
@environment_id = T.let(raw.environment_id, String)
|
|
18
|
+
@object = T.let(raw.object, String)
|
|
19
|
+
@type = T.let(raw.type, String)
|
|
20
|
+
@created_at = T.let(raw.created_at, String)
|
|
21
|
+
@updated_at = T.let(raw.updated_at, String)
|
|
22
|
+
@totp = raw.totp
|
|
23
|
+
@sms = raw.sms
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_json(*)
|
|
27
|
+
{
|
|
28
|
+
id: id,
|
|
29
|
+
environment_id: environment_id,
|
|
30
|
+
object: object,
|
|
31
|
+
type: type,
|
|
32
|
+
totp: totp,
|
|
33
|
+
sms: sms,
|
|
34
|
+
created_at: created_at,
|
|
35
|
+
updated_at: updated_at,
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
sig { params(json_string: String).returns(WorkOS::Types::FactorStruct) }
|
|
42
|
+
def parse_json(json_string)
|
|
43
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
|
44
|
+
|
|
45
|
+
WorkOS::Types::FactorStruct.new(
|
|
46
|
+
id: hash[:id],
|
|
47
|
+
environment_id: hash[:environment_id],
|
|
48
|
+
object: hash[:object],
|
|
49
|
+
type: hash[:type],
|
|
50
|
+
totp: hash[:totp],
|
|
51
|
+
sms: hash[:sms],
|
|
52
|
+
created_at: hash[:created_at],
|
|
53
|
+
updated_at: hash[:updated_at],
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
# rubocop:enable Metrics/AbcSize
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/workos/mfa.rb
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
require 'net/http'
|
|
6
|
+
require 'uri'
|
|
7
|
+
|
|
8
|
+
module WorkOS
|
|
9
|
+
# The MFA module provides convenience methods for working with the WorkOS
|
|
10
|
+
# MFA platform. You'll need a valid API key
|
|
11
|
+
module MFA
|
|
12
|
+
class << self
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include Base
|
|
15
|
+
include Client
|
|
16
|
+
sig { params(id: String).returns(T::Boolean) }
|
|
17
|
+
def delete_factor(id:)
|
|
18
|
+
response = execute_request(
|
|
19
|
+
request: delete_request(
|
|
20
|
+
path: "/auth/factors/#{id}",
|
|
21
|
+
auth: true,
|
|
22
|
+
),
|
|
23
|
+
)
|
|
24
|
+
response.is_a? Net::HTTPSuccess
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sig do
|
|
28
|
+
params(id: String).returns(WorkOS::Factor)
|
|
29
|
+
end
|
|
30
|
+
def get_factor(
|
|
31
|
+
id:
|
|
32
|
+
)
|
|
33
|
+
response = execute_request(
|
|
34
|
+
request: get_request(
|
|
35
|
+
path: "/auth/factors/#{id}",
|
|
36
|
+
auth: true,
|
|
37
|
+
),
|
|
38
|
+
)
|
|
39
|
+
WorkOS::Factor.new(response.body)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
sig do
|
|
43
|
+
params(
|
|
44
|
+
type: String,
|
|
45
|
+
totp_issuer: T.nilable(String),
|
|
46
|
+
totp_user: T.nilable(String),
|
|
47
|
+
phone_number: T.nilable(String),
|
|
48
|
+
).void
|
|
49
|
+
end
|
|
50
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
51
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
52
|
+
|
|
53
|
+
def validate_args(
|
|
54
|
+
type:,
|
|
55
|
+
totp_issuer: nil,
|
|
56
|
+
totp_user: nil,
|
|
57
|
+
phone_number: nil
|
|
58
|
+
)
|
|
59
|
+
if type != 'sms' && type != 'totp' && type != 'generic_otp'
|
|
60
|
+
raise ArgumentError, "Type argument must be either 'sms' or 'totp'"
|
|
61
|
+
end
|
|
62
|
+
if (type == 'totp' && totp_issuer.nil?) || (type == 'totp' && totp_user.nil?)
|
|
63
|
+
raise ArgumentError, 'Incomplete arguments. Need to specify both totp_issuer and totp_user when type is totp'
|
|
64
|
+
end
|
|
65
|
+
return unless type == 'sms' && phone_number.nil?
|
|
66
|
+
|
|
67
|
+
raise ArgumentError, 'Incomplete arguments. Need to specify phone_number when type is sms'
|
|
68
|
+
end
|
|
69
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
70
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
71
|
+
|
|
72
|
+
sig do
|
|
73
|
+
params(
|
|
74
|
+
type: String,
|
|
75
|
+
totp_issuer: T.nilable(String),
|
|
76
|
+
totp_user: T.nilable(String),
|
|
77
|
+
phone_number: T.nilable(String),
|
|
78
|
+
).returns(WorkOS::Factor)
|
|
79
|
+
end
|
|
80
|
+
# rubocop:disable Metrics/MethodLength
|
|
81
|
+
def enroll_factor(
|
|
82
|
+
type:,
|
|
83
|
+
totp_issuer: nil,
|
|
84
|
+
totp_user: nil,
|
|
85
|
+
phone_number: nil
|
|
86
|
+
)
|
|
87
|
+
validate_args(
|
|
88
|
+
type: type,
|
|
89
|
+
totp_issuer: totp_issuer,
|
|
90
|
+
totp_user: totp_user,
|
|
91
|
+
phone_number: phone_number,
|
|
92
|
+
)
|
|
93
|
+
response = execute_request(request: post_request(
|
|
94
|
+
auth: true,
|
|
95
|
+
body: {
|
|
96
|
+
type: type,
|
|
97
|
+
totp_issuer: totp_issuer,
|
|
98
|
+
totp_user: totp_user,
|
|
99
|
+
phone_number: phone_number,
|
|
100
|
+
},
|
|
101
|
+
path: '/auth/factors/enroll',
|
|
102
|
+
))
|
|
103
|
+
WorkOS::Factor.new(response.body)
|
|
104
|
+
end
|
|
105
|
+
# rubocop:enable Metrics/MethodLength
|
|
106
|
+
|
|
107
|
+
sig do
|
|
108
|
+
params(
|
|
109
|
+
authentication_factor_id: T.nilable(String),
|
|
110
|
+
sms_template: T.nilable(String),
|
|
111
|
+
).returns(WorkOS::Challenge)
|
|
112
|
+
end
|
|
113
|
+
def challenge_factor(
|
|
114
|
+
authentication_factor_id: nil,
|
|
115
|
+
sms_template: nil
|
|
116
|
+
)
|
|
117
|
+
if authentication_factor_id.nil?
|
|
118
|
+
raise ArgumentError, "Incomplete arguments: 'authentication_factor_id' is a required argument"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
request = post_request(
|
|
122
|
+
auth: true,
|
|
123
|
+
body: {
|
|
124
|
+
sms_template: sms_template,
|
|
125
|
+
authentication_factor_id: authentication_factor_id,
|
|
126
|
+
},
|
|
127
|
+
path: '/auth/factors/challenge',
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
response = execute_request(request: request)
|
|
131
|
+
WorkOS::Challenge.new(response.body)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
sig do
|
|
135
|
+
params(
|
|
136
|
+
authentication_challenge_id: T.nilable(String),
|
|
137
|
+
code: T.nilable(String),
|
|
138
|
+
).returns(WorkOS::VerifyFactor)
|
|
139
|
+
end
|
|
140
|
+
def verify_factor(
|
|
141
|
+
authentication_challenge_id: nil,
|
|
142
|
+
code: nil
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if authentication_challenge_id.nil? || code.nil?
|
|
146
|
+
raise ArgumentError, "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
options = {
|
|
150
|
+
"authentication_challenge_id": authentication_challenge_id,
|
|
151
|
+
"code": code,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
response = execute_request(
|
|
155
|
+
request: post_request(
|
|
156
|
+
path: '/auth/factors/verify',
|
|
157
|
+
auth: true,
|
|
158
|
+
body: options,
|
|
159
|
+
),
|
|
160
|
+
)
|
|
161
|
+
WorkOS::VerifyFactor.new(response.body)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
data/lib/workos/sso.rb
CHANGED
|
@@ -21,23 +21,27 @@ module WorkOS
|
|
|
21
21
|
# Generate an Oauth2 authorization URL where your users will
|
|
22
22
|
# authenticate using the configured SSO Identity Provider.
|
|
23
23
|
#
|
|
24
|
+
# @param [String] redirect_uri The URI where users are directed
|
|
25
|
+
# after completing the authentication step. Must match a
|
|
26
|
+
# configured redirect URI on your WorkOS dashboard.
|
|
27
|
+
# @param [String] client_id The WorkOS client ID for the environment
|
|
28
|
+
# where you've configured your SSO connection.
|
|
24
29
|
# @param [String] domain The domain for the relevant SSO Connection
|
|
25
|
-
# configured on your WorkOS dashboard. One of provider
|
|
26
|
-
# required
|
|
30
|
+
# configured on your WorkOS dashboard. One of provider, domain,
|
|
31
|
+
# connection, or organization is required.
|
|
32
|
+
# The domain is deprecated.
|
|
27
33
|
# @param [String] provider A provider name for an Identity Provider
|
|
28
|
-
# configured on your WorkOS dashboard. Only '
|
|
34
|
+
# configured on your WorkOS dashboard. Only 'GoogleOAuth' and
|
|
35
|
+
# 'MicrosoftOAuth' are supported.
|
|
29
36
|
# @param [String] connection The ID for a Connection configured on
|
|
30
37
|
# WorkOS.
|
|
31
|
-
# @param [String]
|
|
32
|
-
#
|
|
33
|
-
# @param [String]
|
|
34
|
-
# after completing the authentication step. Must match a
|
|
35
|
-
# configured redirect URI on your WorkOS dashboard.
|
|
36
|
-
# @param [String] state An aribtrary state object
|
|
38
|
+
# @param [String] organization The ID for an Organization configured
|
|
39
|
+
# on WorkOS.
|
|
40
|
+
# @param [String] state An arbitrary state object
|
|
37
41
|
# that is preserved and available to the client in the response.
|
|
38
42
|
# @example
|
|
39
43
|
# WorkOS::SSO.authorization_url(
|
|
40
|
-
#
|
|
44
|
+
# connection: 'conn_123',
|
|
41
45
|
# client_id: 'project_01DG5TGK363GRVXP3ZS40WNGEZ',
|
|
42
46
|
# redirect_uri: 'https://workos.com/callback',
|
|
43
47
|
# state: {
|
|
@@ -45,19 +49,23 @@ module WorkOS
|
|
|
45
49
|
# }.to_s
|
|
46
50
|
# )
|
|
47
51
|
#
|
|
48
|
-
# => "https://api.workos.com/sso/authorize?
|
|
52
|
+
# => "https://api.workos.com/sso/authorize?connection=conn_123" \
|
|
49
53
|
# "&client_id=project_01DG5TGK363GRVXP3ZS40WNGEZ" \
|
|
50
54
|
# "&redirect_uri=https%3A%2F%2Fworkos.com%2Fcallback&" \
|
|
51
55
|
# "response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdocs%22%7D"
|
|
52
56
|
#
|
|
53
57
|
# @return [String]
|
|
58
|
+
# rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
54
59
|
sig do
|
|
55
60
|
params(
|
|
56
61
|
redirect_uri: String,
|
|
57
62
|
client_id: T.nilable(String),
|
|
58
63
|
domain: T.nilable(String),
|
|
64
|
+
domain_hint: T.nilable(String),
|
|
65
|
+
login_hint: T.nilable(String),
|
|
59
66
|
provider: T.nilable(String),
|
|
60
67
|
connection: T.nilable(String),
|
|
68
|
+
organization: T.nilable(String),
|
|
61
69
|
state: T.nilable(String),
|
|
62
70
|
).returns(String)
|
|
63
71
|
end
|
|
@@ -65,14 +73,23 @@ module WorkOS
|
|
|
65
73
|
redirect_uri:,
|
|
66
74
|
client_id: nil,
|
|
67
75
|
domain: nil,
|
|
76
|
+
domain_hint: nil,
|
|
77
|
+
login_hint: nil,
|
|
68
78
|
provider: nil,
|
|
69
79
|
connection: nil,
|
|
80
|
+
organization: nil,
|
|
70
81
|
state: ''
|
|
71
82
|
)
|
|
83
|
+
if domain
|
|
84
|
+
warn '[DEPRECATION] `domain` is deprecated.
|
|
85
|
+
Please use `organization` instead.'
|
|
86
|
+
end
|
|
87
|
+
|
|
72
88
|
validate_authorization_url_arguments(
|
|
73
89
|
provider: provider,
|
|
74
90
|
domain: domain,
|
|
75
91
|
connection: connection,
|
|
92
|
+
organization: organization,
|
|
76
93
|
)
|
|
77
94
|
|
|
78
95
|
query = URI.encode_www_form({
|
|
@@ -81,12 +98,16 @@ module WorkOS
|
|
|
81
98
|
response_type: 'code',
|
|
82
99
|
state: state,
|
|
83
100
|
domain: domain,
|
|
101
|
+
domain_hint: domain_hint,
|
|
102
|
+
login_hint: login_hint,
|
|
84
103
|
provider: provider,
|
|
85
104
|
connection: connection,
|
|
105
|
+
organization: organization,
|
|
86
106
|
}.compact)
|
|
87
107
|
|
|
88
108
|
"https://#{WorkOS::API_HOSTNAME}/sso/authorize?#{query}"
|
|
89
109
|
end
|
|
110
|
+
# rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
|
|
90
111
|
|
|
91
112
|
sig do
|
|
92
113
|
params(
|
|
@@ -229,16 +250,18 @@ module WorkOS
|
|
|
229
250
|
domain: T.nilable(String),
|
|
230
251
|
provider: T.nilable(String),
|
|
231
252
|
connection: T.nilable(String),
|
|
253
|
+
organization: T.nilable(String),
|
|
232
254
|
).void
|
|
233
255
|
end
|
|
234
256
|
def validate_authorization_url_arguments(
|
|
235
257
|
domain:,
|
|
236
258
|
provider:,
|
|
237
|
-
connection
|
|
259
|
+
connection:,
|
|
260
|
+
organization:
|
|
238
261
|
)
|
|
239
|
-
if [domain, provider, connection].all?(&:nil?)
|
|
240
|
-
raise ArgumentError, 'Either connection, domain,
|
|
241
|
-
'provider is required.'
|
|
262
|
+
if [domain, provider, connection, organization].all?(&:nil?)
|
|
263
|
+
raise ArgumentError, 'Either connection, domain, ' \
|
|
264
|
+
'provider, or organization is required.'
|
|
242
265
|
end
|
|
243
266
|
|
|
244
267
|
return unless provider && !PROVIDERS.include?(provider)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
module Types
|
|
6
|
+
# This ChallgengeStruct acts as a typed interface
|
|
7
|
+
# for the Factor class
|
|
8
|
+
class ChallengeStruct < T::Struct
|
|
9
|
+
const :id, String
|
|
10
|
+
const :object, String
|
|
11
|
+
const :expires_at, T.nilable(String)
|
|
12
|
+
const :code, T.nilable(String)
|
|
13
|
+
const :authentication_factor_id, String
|
|
14
|
+
const :created_at, String
|
|
15
|
+
const :updated_at, String
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
module Types
|
|
6
|
+
# This FactorStruct acts as a typed interface
|
|
7
|
+
# for the Factor class
|
|
8
|
+
class FactorStruct < T::Struct
|
|
9
|
+
const :id, String
|
|
10
|
+
const :environment_id, String
|
|
11
|
+
const :object, String
|
|
12
|
+
const :type, String
|
|
13
|
+
const :totp, T.nilable(T::Hash[Symbol, Object])
|
|
14
|
+
const :sms, T.nilable(T::Hash[Symbol, Object])
|
|
15
|
+
const :created_at, String
|
|
16
|
+
const :updated_at, String
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
module Types
|
|
6
|
+
# This VerifyFactorStruct acts as a typed interface
|
|
7
|
+
# for the Factor class
|
|
8
|
+
class VerifyFactorStruct < T::Struct
|
|
9
|
+
const :challenge, T.nilable(T::Hash[Symbol, Object])
|
|
10
|
+
const :valid, T.nilable(TrueClass)
|
|
11
|
+
const :code, T.nilable(String)
|
|
12
|
+
const :message, T.nilable(String)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/workos/types.rb
CHANGED
|
@@ -16,5 +16,8 @@ module WorkOS
|
|
|
16
16
|
require_relative 'types/provider_enum'
|
|
17
17
|
require_relative 'types/directory_user_struct'
|
|
18
18
|
require_relative 'types/webhook_struct'
|
|
19
|
+
require_relative 'types/factor_struct'
|
|
20
|
+
require_relative 'types/challenge_struct'
|
|
21
|
+
require_relative 'types/verify_factor_struct'
|
|
19
22
|
end
|
|
20
23
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: false
|
|
3
|
+
|
|
4
|
+
module WorkOS
|
|
5
|
+
# The VerifyFactor class provides a lightweight wrapper around
|
|
6
|
+
# a WorkOS DirectoryUser resource. This class is not meant to be instantiated
|
|
7
|
+
# in DirectoryUser space, and is instantiated internally but exposed.
|
|
8
|
+
class VerifyFactor
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
attr_accessor :challenge, :valid
|
|
12
|
+
|
|
13
|
+
sig { params(json: String).void }
|
|
14
|
+
def initialize(json)
|
|
15
|
+
raw = parse_json(json)
|
|
16
|
+
@challenge = T.let(raw.challenge, Hash)
|
|
17
|
+
@valid = raw.valid
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_json(*)
|
|
21
|
+
{
|
|
22
|
+
challenge: challenge,
|
|
23
|
+
valid: valid,
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
sig { params(json_string: String).returns(WorkOS::Types::VerifyFactorStruct) }
|
|
30
|
+
def parse_json(json_string)
|
|
31
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
|
32
|
+
|
|
33
|
+
WorkOS::Types::VerifyFactorStruct.new(
|
|
34
|
+
challenge: hash[:challenge],
|
|
35
|
+
valid: hash[:valid],
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/workos/version.rb
CHANGED