workos 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +4 -1
  4. data/lib/workos/audit_trail.rb +0 -1
  5. data/lib/workos/client.rb +14 -5
  6. data/lib/workos/configuration.rb +17 -0
  7. data/lib/workos/directory_sync.rb +0 -1
  8. data/lib/workos/errors.rb +3 -0
  9. data/lib/workos/mfa.rb +22 -7
  10. data/lib/workos/organizations.rb +0 -1
  11. data/lib/workos/passwordless.rb +0 -1
  12. data/lib/workos/portal.rb +0 -1
  13. data/lib/workos/sso.rb +1 -2
  14. data/lib/workos/types/{verify_factor_struct.rb → verify_challenge_struct.rb} +3 -3
  15. data/lib/workos/types.rb +1 -1
  16. data/lib/workos/{verify_factor.rb → verify_challenge.rb} +5 -6
  17. data/lib/workos/version.rb +1 -1
  18. data/lib/workos.rb +17 -7
  19. data/spec/lib/workos/configuration_spec.rb +61 -0
  20. data/spec/lib/workos/mfa_spec.rb +93 -74
  21. data/spec/lib/workos/sso_spec.rb +1 -1
  22. data/spec/spec_helper.rb +2 -2
  23. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +2 -2
  24. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +2 -2
  25. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +2 -2
  26. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_expired.yml → verify_challenge_generic_expired.yml} +2 -2
  27. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_invalid.yml → verify_challenge_generic_invalid.yml} +2 -2
  28. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_valid.yml → verify_challenge_generic_valid.yml} +2 -2
  29. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_valid_is_false.yml → verify_challenge_generic_valid_is_false.yml} +2 -2
  30. metadata +15 -15
  31. data/lib/workos/base.rb +0 -18
  32. data/spec/lib/workos/base_spec.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b8ce6f7bddb9f3bbee9713d7ec1674c487f1c9f963e7e57ee8e6b99b26e183a
4
- data.tar.gz: de86e65fad32c780bc23ba9a2e2e7e611af89c2025f768d96ca51a59b5c23218
3
+ metadata.gz: 014f85386dcfba661f0a74ae427127257b953a2791b4667c72d9b1961237a93b
4
+ data.tar.gz: 7290ad0b22df3751f1183f5465d35f56828c4fd1b0e519c29c208138b67db3fe
5
5
  SHA512:
6
- metadata.gz: 82b37f71d2b099ccfde1f6d47f5a43392f275e093d130156796079be0f2ada5f8e787143991aa9b2d65878c5cd4ab052b5c81f60fe43e46e59619714c17b08c4
7
- data.tar.gz: f02fbd38fedce2ac51834fb10196b6c79a1ed29013afb7f681ec9329df0e571035330f2a6f52bdb0c963bb0be5ade92b389962609f2d87cba8fd83bbca471a60
6
+ metadata.gz: 766ef6dfba39dc072dab56a7fbfbcaa4484e39bbd444dc3c9148894e791b232689e7210a13f178442e595a67ac3c74aed64ee377ddad342f6105b2103513bbec
7
+ data.tar.gz: 759b73ee9afe91742acb8ee818d03bc397a6760d44f88dbfa3989439e4e396cacc2b71dd866ab90495bb7c1e2b430709987f09335a20b4a08b123aedfa1003d8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- workos (2.4.0)
4
+ workos (2.5.0)
5
5
  sorbet-runtime (~> 0.5)
6
6
 
7
7
  GEM
@@ -60,7 +60,7 @@ GEM
60
60
  simplecov_json_formatter (0.1.2)
61
61
  sorbet (0.5.6388)
62
62
  sorbet-static (= 0.5.6388)
63
- sorbet-runtime (0.5.10090)
63
+ sorbet-runtime (0.5.10207)
64
64
  sorbet-static (0.5.6388-universal-darwin-14)
65
65
  sorbet-static (0.5.6388-universal-darwin-15)
66
66
  sorbet-static (0.5.6388-universal-darwin-16)
data/README.md CHANGED
@@ -35,7 +35,10 @@ Or, you may set the key yourself, such as in an initializer in your application
35
35
  ```ruby
36
36
  # /config/initializers/workos.rb
37
37
 
38
- WorkOS.key = '[your api key]'
38
+ WorkOS.configure do |config|
39
+ config.key = '[your api key]'
40
+ config.timeout = 120
41
+ end
39
42
  ```
40
43
 
41
44
  ## SDK Versioning
@@ -12,7 +12,6 @@ module WorkOS
12
12
  module AuditTrail
13
13
  class << self
14
14
  extend T::Sig
15
- include Base
16
15
  include Client
17
16
 
18
17
  # Create an Audit Trail event.
data/lib/workos/client.rb CHANGED
@@ -11,6 +11,9 @@ module WorkOS
11
11
  def client
12
12
  Net::HTTP.new(WorkOS::API_HOSTNAME, 443).tap do |http_client|
13
13
  http_client.use_ssl = true
14
+ http_client.open_timeout = WorkOS.config.timeout
15
+ http_client.read_timeout = WorkOS.config.timeout
16
+ http_client.write_timeout = WorkOS.config.timeout
14
17
  end
15
18
  end
16
19
 
@@ -20,7 +23,13 @@ module WorkOS
20
23
  ).returns(::T.untyped)
21
24
  end
22
25
  def execute_request(request:)
23
- response = client.request(request)
26
+ begin
27
+ response = client.request(request)
28
+ rescue Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout
29
+ raise TimeoutError.new(
30
+ message: 'API Timeout Error',
31
+ )
32
+ end
24
33
 
25
34
  http_status = response.code.to_i
26
35
  handle_error_response(response: response) if http_status >= 400
@@ -45,7 +54,7 @@ module WorkOS
45
54
  'Content-Type' => 'application/json',
46
55
  )
47
56
 
48
- request['Authorization'] = "Bearer #{access_token || WorkOS.key!}" if auth
57
+ request['Authorization'] = "Bearer #{access_token || WorkOS.config.key!}" if auth
49
58
  request['User-Agent'] = user_agent
50
59
  request
51
60
  end
@@ -61,7 +70,7 @@ module WorkOS
61
70
  def post_request(path:, auth: false, idempotency_key: nil, body: nil)
62
71
  request = Net::HTTP::Post.new(path, 'Content-Type' => 'application/json')
63
72
  request.body = body.to_json if body
64
- request['Authorization'] = "Bearer #{WorkOS.key!}" if auth
73
+ request['Authorization'] = "Bearer #{WorkOS.config.key!}" if auth
65
74
  request['Idempotency-Key'] = idempotency_key if idempotency_key
66
75
  request['User-Agent'] = user_agent
67
76
  request
@@ -83,7 +92,7 @@ module WorkOS
83
92
  'Content-Type' => 'application/json',
84
93
  )
85
94
 
86
- request['Authorization'] = "Bearer #{WorkOS.key!}" if auth
95
+ request['Authorization'] = "Bearer #{WorkOS.config.key!}" if auth
87
96
  request['User-Agent'] = user_agent
88
97
  request
89
98
  end
@@ -99,7 +108,7 @@ module WorkOS
99
108
  def put_request(path:, auth: false, idempotency_key: nil, body: nil)
100
109
  request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
101
110
  request.body = body.to_json if body
102
- request['Authorization'] = "Bearer #{WorkOS.key!}" if auth
111
+ request['Authorization'] = "Bearer #{WorkOS.config.key!}" if auth
103
112
  request['Idempotency-Key'] = idempotency_key if idempotency_key
104
113
  request['User-Agent'] = user_agent
105
114
  request
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOS
5
+ # Configuration class sets config initializer
6
+ class Configuration
7
+ attr_accessor :timeout, :key
8
+
9
+ def initialize
10
+ @timeout = 60
11
+ end
12
+
13
+ def key!
14
+ key or raise '`WorkOS.config.key` not set'
15
+ end
16
+ end
17
+ end
@@ -12,7 +12,6 @@ module WorkOS
12
12
  module DirectorySync
13
13
  class << self
14
14
  extend T::Sig
15
- include Base
16
15
  include Client
17
16
 
18
17
  # Retrieve directories.
data/lib/workos/errors.rb CHANGED
@@ -61,4 +61,7 @@ module WorkOS
61
61
  # SignatureVerificationError is raised when the signature verification for a
62
62
  # webhook fails
63
63
  class SignatureVerificationError < WorkOSError; end
64
+
65
+ # TimeoutError is raised when the HTTP request to the API times out
66
+ class TimeoutError < WorkOSError; end
64
67
  end
data/lib/workos/mfa.rb CHANGED
@@ -11,7 +11,6 @@ module WorkOS
11
11
  module MFA
12
12
  class << self
13
13
  extend T::Sig
14
- include Base
15
14
  include Client
16
15
  sig { params(id: String).returns(T::Boolean) }
17
16
  def delete_factor(id:)
@@ -122,9 +121,8 @@ module WorkOS
122
121
  auth: true,
123
122
  body: {
124
123
  sms_template: sms_template,
125
- authentication_factor_id: authentication_factor_id,
126
124
  },
127
- path: '/auth/factors/challenge',
125
+ path: "/auth/factors/#{authentication_factor_id}/challenge",
128
126
  )
129
127
 
130
128
  response = execute_request(request: request)
@@ -135,30 +133,47 @@ module WorkOS
135
133
  params(
136
134
  authentication_challenge_id: T.nilable(String),
137
135
  code: T.nilable(String),
138
- ).returns(WorkOS::VerifyFactor)
136
+ ).returns(WorkOS::VerifyChallenge)
139
137
  end
140
138
  def verify_factor(
141
139
  authentication_challenge_id: nil,
142
140
  code: nil
143
141
  )
142
+ warn '[DEPRECATION] `verify_factor` is deprecated. Please use `verify_challenge` instead.'
143
+
144
+ verify_challenge(
145
+ authentication_challenge_id: authentication_challenge_id,
146
+ code: code,
147
+ )
148
+ end
149
+
150
+ sig do
151
+ params(
152
+ authentication_challenge_id: T.nilable(String),
153
+ code: T.nilable(String),
154
+ ).returns(WorkOS::VerifyChallenge)
155
+ end
156
+ def verify_challenge(
157
+ authentication_challenge_id: nil,
158
+ code: nil
159
+ )
144
160
 
145
161
  if authentication_challenge_id.nil? || code.nil?
146
162
  raise ArgumentError, "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments"
147
163
  end
148
164
 
149
165
  options = {
150
- "authentication_challenge_id": authentication_challenge_id,
151
166
  "code": code,
152
167
  }
153
168
 
154
169
  response = execute_request(
155
170
  request: post_request(
156
- path: '/auth/factors/verify',
171
+ path: "/auth/challenges/#{authentication_challenge_id}/verify",
157
172
  auth: true,
158
173
  body: options,
159
174
  ),
160
175
  )
161
- WorkOS::VerifyFactor.new(response.body)
176
+ WorkOS::VerifyChallenge.new(response.body)
162
177
  end
163
178
  end
164
179
  end
@@ -8,7 +8,6 @@ module WorkOS
8
8
  module Organizations
9
9
  class << self
10
10
  extend T::Sig
11
- include Base
12
11
  include Client
13
12
 
14
13
  # Retrieve a list of organizations that have connections configured
@@ -12,7 +12,6 @@ module WorkOS
12
12
  module Passwordless
13
13
  class << self
14
14
  extend T::Sig
15
- include Base
16
15
  include Client
17
16
 
18
17
  # Create a Passwordless Session.
data/lib/workos/portal.rb CHANGED
@@ -9,7 +9,6 @@ module WorkOS
9
9
  module Portal
10
10
  class << self
11
11
  extend T::Sig
12
- include Base
13
12
  include Client
14
13
 
15
14
  GENERATE_LINK_INTENTS = WorkOS::Types::Intent.values.map(&:serialize).
data/lib/workos/sso.rb CHANGED
@@ -13,7 +13,6 @@ module WorkOS
13
13
  module SSO
14
14
  class << self
15
15
  extend T::Sig
16
- include Base
17
16
  include Client
18
17
 
19
18
  PROVIDERS = WorkOS::Types::Provider.values.map(&:serialize).freeze
@@ -142,7 +141,7 @@ module WorkOS
142
141
  def profile_and_token(code:, client_id: nil)
143
142
  body = {
144
143
  client_id: client_id,
145
- client_secret: WorkOS.key!,
144
+ client_secret: WorkOS.config.key!,
146
145
  grant_type: 'authorization_code',
147
146
  code: code,
148
147
  }
@@ -3,9 +3,9 @@
3
3
 
4
4
  module WorkOS
5
5
  module Types
6
- # This VerifyFactorStruct acts as a typed interface
7
- # for the Factor class
8
- class VerifyFactorStruct < T::Struct
6
+ # This VerifyChallengeStruct acts as a typed interface
7
+ # for the VerifyChallenge class
8
+ class VerifyChallengeStruct < T::Struct
9
9
  const :challenge, T.nilable(T::Hash[Symbol, Object])
10
10
  const :valid, T::Boolean
11
11
  end
data/lib/workos/types.rb CHANGED
@@ -18,6 +18,6 @@ module WorkOS
18
18
  require_relative 'types/webhook_struct'
19
19
  require_relative 'types/factor_struct'
20
20
  require_relative 'types/challenge_struct'
21
- require_relative 'types/verify_factor_struct'
21
+ require_relative 'types/verify_challenge_struct'
22
22
  end
23
23
  end
@@ -2,10 +2,9 @@
2
2
  # typed: false
3
3
 
4
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
5
+ # The VerifyChallenge class provides a lightweight wrapper around
6
+ # a WorkOS Authentication Challenge resource.
7
+ class VerifyChallenge
9
8
  include HashProvider
10
9
  extend T::Sig
11
10
 
@@ -27,11 +26,11 @@ module WorkOS
27
26
 
28
27
  private
29
28
 
30
- sig { params(json_string: String).returns(WorkOS::Types::VerifyFactorStruct) }
29
+ sig { params(json_string: String).returns(WorkOS::Types::VerifyChallengeStruct) }
31
30
  def parse_json(json_string)
32
31
  hash = JSON.parse(json_string, symbolize_names: true)
33
32
 
34
- WorkOS::Types::VerifyFactorStruct.new(
33
+ WorkOS::Types::VerifyChallengeStruct.new(
35
34
  challenge: hash[:challenge],
36
35
  valid: hash[:valid],
37
36
  )
@@ -2,5 +2,5 @@
2
2
  # typed: strong
3
3
 
4
4
  module WorkOS
5
- VERSION = '2.4.0'
5
+ VERSION = '2.5.0'
6
6
  end
data/lib/workos.rb CHANGED
@@ -5,6 +5,7 @@ require 'workos/version'
5
5
  require 'sorbet-runtime'
6
6
  require 'json'
7
7
  require 'workos/hash_provider'
8
+ require 'workos/configuration'
8
9
 
9
10
  # Use the WorkOS module to authenticate your
10
11
  # requests to the WorkOS API. The gem will read
@@ -16,20 +17,28 @@ module WorkOS
16
17
  API_HOSTNAME = ENV['WORKOS_API_HOSTNAME'] || 'api.workos.com'
17
18
 
18
19
  def self.key=(value)
19
- Base.key = value
20
+ warn '`WorkOS.key=` is deprecated. Use `WorkOS.configure` instead.'
21
+
22
+ config.key = value
20
23
  end
21
24
 
22
25
  def self.key
23
- Base.key
26
+ warn '`WorkOS.key` is deprecated. Use `WorkOS.configure` instead.'
27
+
28
+ config.key
29
+ end
30
+
31
+ def self.config
32
+ @config ||= Configuration.new
24
33
  end
25
34
 
26
- def self.key!
27
- key || raise('WorkOS.key not set')
35
+ def self.configure
36
+ yield(config)
28
37
  end
29
38
 
30
39
  autoload :Types, 'workos/types'
31
- autoload :Base, 'workos/base'
32
40
  autoload :Client, 'workos/client'
41
+ autoload :Configuration, 'workos/configuration'
33
42
  autoload :AuditTrail, 'workos/audit_trail'
34
43
  autoload :Connection, 'workos/connection'
35
44
  autoload :DirectorySync, 'workos/directory_sync'
@@ -48,7 +57,7 @@ module WorkOS
48
57
  autoload :MFA, 'workos/mfa'
49
58
  autoload :Factor, 'workos/factor'
50
59
  autoload :Challenge, 'workos/challenge'
51
- autoload :VerifyFactor, 'workos/verify_factor'
60
+ autoload :VerifyChallenge, 'workos/verify_challenge'
52
61
  autoload :DeprecatedHashWrapper, 'workos/deprecated_hash_wrapper'
53
62
 
54
63
 
@@ -57,9 +66,10 @@ module WorkOS
57
66
  autoload :AuthenticationError, 'workos/errors'
58
67
  autoload :InvalidRequestError, 'workos/errors'
59
68
  autoload :SignatureVerificationError, 'workos/errors'
69
+ autoload :TimeoutError, 'workos/errors'
60
70
 
61
71
  # Remove WORKOS_KEY at some point in the future. Keeping it here now for
62
72
  # backwards compatibility.
63
73
  key = ENV['WORKOS_API_KEY'] || ENV['WORKOS_KEY']
64
- WorkOS.key = key unless key.nil?
74
+ config.key = key unless key.nil?
65
75
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ describe WorkOS do
5
+ describe '.configure' do
6
+ context 'with key and no timeout' do
7
+ before do
8
+ WorkOS.configure do |config|
9
+ config.key = 'example_api_key'
10
+ end
11
+ end
12
+
13
+ it 'sets the key and default timeout configuration' do
14
+ expect(WorkOS.config.key).to eq('example_api_key')
15
+ expect(WorkOS.config.timeout).to eq(60)
16
+ end
17
+ end
18
+
19
+ context 'with key and timeout' do
20
+ before do
21
+ WorkOS.configure do |config|
22
+ config.key = 'example_api_key'
23
+ config.timeout = 120
24
+ end
25
+ end
26
+
27
+ it 'sets the key and timeout configuration' do
28
+ expect(WorkOS.config.key).to eq('example_api_key')
29
+ expect(WorkOS.config.timeout).to eq(120)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ describe WorkOS::Configuration do
36
+ describe '.key!' do
37
+ context 'with key set' do
38
+ before do
39
+ WorkOS.config.key = 'example_api_key'
40
+ end
41
+
42
+ it 'returns the key' do
43
+ expect(WorkOS.config.key!).to eq('example_api_key')
44
+ end
45
+ end
46
+
47
+ context 'with key not set' do
48
+ before do
49
+ WorkOS.config.key = nil
50
+ end
51
+
52
+ it 'throws an error' do
53
+ expect do
54
+ WorkOS.config.key!
55
+ end.to raise_error(
56
+ '`WorkOS.config.key` not set',
57
+ )
58
+ end
59
+ end
60
+ end
61
+ end
@@ -4,8 +4,8 @@
4
4
  describe WorkOS::MFA do
5
5
  it_behaves_like 'client'
6
6
 
7
- describe 'enroll_factor valid requests' do
8
- context 'enroll factor using valid generic argument' do
7
+ describe '.enroll_factor' do
8
+ context 'with valid generic argument' do
9
9
  it 'returns a valid factor object' do
10
10
  VCR.use_cassette 'mfa/enroll_factor_generic_valid' do
11
11
  factor = described_class.enroll_factor(
@@ -16,7 +16,7 @@ describe WorkOS::MFA do
16
16
  end
17
17
  end
18
18
 
19
- context 'enroll factor using valid totp arguments' do
19
+ context 'with valid totp arguments' do
20
20
  it 'returns a valid factor object' do
21
21
  VCR.use_cassette 'mfa/enroll_factor_totp_valid' do
22
22
  factor = described_class.enroll_factor(
@@ -29,7 +29,7 @@ describe WorkOS::MFA do
29
29
  end
30
30
  end
31
31
 
32
- context 'enroll factor using valid sms arguments' do
32
+ context 'with valid sms arguments' do
33
33
  it 'returns a valid factor object' do
34
34
  VCR.use_cassette 'mfa/enroll_factor_sms_valid' do
35
35
  factor = described_class.enroll_factor(
@@ -40,10 +40,8 @@ describe WorkOS::MFA do
40
40
  end
41
41
  end
42
42
  end
43
- end
44
43
 
45
- describe 'enroll_factor invalid responses' do
46
- context 'enroll factor throws error if type is not sms or totp' do
44
+ context 'when type is not sms or totp' do
47
45
  it 'returns an error' do
48
46
  expect do
49
47
  described_class.enroll_factor(
@@ -57,7 +55,7 @@ describe WorkOS::MFA do
57
55
  end
58
56
  end
59
57
 
60
- context 'enroll factor throws error if type is not sms or totp' do
58
+ context 'when type is totp but missing arguments' do
61
59
  it 'returns an error' do
62
60
  expect do
63
61
  described_class.enroll_factor(
@@ -70,7 +68,7 @@ describe WorkOS::MFA do
70
68
  )
71
69
  end
72
70
  end
73
- context 'enroll factor throws error if type sms and phone number is nil' do
71
+ context 'when type is sms and phone number is nil' do
74
72
  it 'returns an error' do
75
73
  expect do
76
74
  described_class.enroll_factor(
@@ -84,7 +82,7 @@ describe WorkOS::MFA do
84
82
  end
85
83
  end
86
84
 
87
- describe 'challenge factor with valid request arguments' do
85
+ describe '.challenge_factor' do
88
86
  context 'challenge with totp' do
89
87
  it 'returns challenge factor object for totp' do
90
88
  VCR.use_cassette 'mfa/challenge_factor_totp_valid' do
@@ -118,9 +116,7 @@ describe WorkOS::MFA do
118
116
  end
119
117
  end
120
118
  end
121
- end
122
119
 
123
- describe 'challenge factor with invalid arguments' do
124
120
  context 'challenge with totp mssing authentication_factor_id' do
125
121
  it 'returns argument error' do
126
122
  expect do
@@ -133,48 +129,58 @@ describe WorkOS::MFA do
133
129
  end
134
130
  end
135
131
 
136
- describe 'challenge factor with valid requests' do
137
- context 'verify generic otp' do
138
- it 'returns a true boolean if the challenge has not been verifed yet' do
139
- VCR.use_cassette 'mfa/verify_factor_generic_valid' do
140
- verify_factor = described_class.verify_factor(
132
+ describe '.verify_factor' do
133
+ it 'throws a warning' do
134
+ expect do
135
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
136
+ described_class.verify_factor(
141
137
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
142
138
  code: '897792',
143
139
  )
144
- expect(verify_factor.valid == 'true')
145
140
  end
146
- end
141
+ end.to output("[DEPRECATION] `verify_factor` is deprecated. Please use `verify_challenge` instead.\n").to_stderr
147
142
  end
148
143
 
149
- context 'verify generic otp invalid response' do
150
- it 'returns a true boolean if the challenge has not been verifed yet' do
151
- VCR.use_cassette 'mfa/verify_factor_generic_valid_is_false' do
152
- verify_factor = described_class.verify_factor(
153
- authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
154
- code: '897792',
155
- )
156
- expect(verify_factor.valid == 'false')
157
- end
144
+ it 'calls verify_challenge' do
145
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
146
+ verify_factor = described_class.verify_factor(
147
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
148
+ code: '897792',
149
+ )
150
+ expect(verify_factor.valid == 'true')
158
151
  end
159
152
  end
153
+ end
160
154
 
161
- context 'verify generic otp' do
162
- it 'returns error that the challenge has already been verfied' do
163
- VCR.use_cassette 'mfa/verify_factor_generic_invalid' do
164
- expect do
165
- described_class.verify_factor(
155
+ describe '.verify_challenge' do
156
+ context 'with generic otp' do
157
+ context 'and the challenge has not been verified' do
158
+ it 'returns true if the code is correct' do
159
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
160
+ verify_challenge = described_class.verify_challenge(
166
161
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
167
162
  code: '897792',
168
163
  )
169
- end.to raise_error(WorkOS::InvalidRequestError)
164
+ expect(verify_challenge.valid == 'true')
165
+ end
166
+ end
167
+
168
+ it 'returns false if the code is incorrect' do
169
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid_is_false' do
170
+ verify_challenge = described_class.verify_challenge(
171
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
172
+ code: '897792',
173
+ )
174
+ expect(verify_challenge.valid == 'false')
175
+ end
170
176
  end
171
177
  end
172
178
 
173
- context 'verify generic otp' do
174
- it 'returns error that the challenge has expired' do
175
- VCR.use_cassette 'mfa/verify_factor_generic_expired' do
179
+ context 'and the challenge has already been verified' do
180
+ it 'returns an error' do
181
+ VCR.use_cassette 'mfa/verify_challenge_generic_invalid' do
176
182
  expect do
177
- described_class.verify_factor(
183
+ described_class.verify_challenge(
178
184
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
179
185
  code: '897792',
180
186
  )
@@ -182,51 +188,62 @@ describe WorkOS::MFA do
182
188
  end
183
189
  end
184
190
  end
185
- end
186
- end
187
191
 
188
- describe 'verify_factor with invalid argument' do
189
- context 'missing code argument' do
190
- it 'returns argument error' do
191
- expect do
192
- described_class.verify_factor(
193
- authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
192
+ context 'and the challenge has expired' do
193
+ it 'returns an error' do
194
+ VCR.use_cassette 'mfa/verify_challenge_generic_expired' do
195
+ expect do
196
+ described_class.verify_challenge(
197
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
198
+ code: '897792',
199
+ )
200
+ end.to raise_error(WorkOS::InvalidRequestError)
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'with missing code argument' do
206
+ it 'returns an argument error' do
207
+ expect do
208
+ described_class.verify_challenge(
209
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
210
+ )
211
+ end.to raise_error(
212
+ ArgumentError,
213
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
194
214
  )
195
- end.to raise_error(
196
- ArgumentError,
197
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
198
- )
215
+ end
199
216
  end
200
- end
201
217
 
202
- context 'missing authentication_challenge_id argument' do
203
- it 'returns and error' do
204
- expect do
205
- described_class.verify_factor(
206
- code: '897792',
218
+ context 'with missing authentication_challenge_id argument' do
219
+ it 'returns an error' do
220
+ expect do
221
+ described_class.verify_challenge(
222
+ code: '897792',
223
+ )
224
+ end.to raise_error(
225
+ ArgumentError,
226
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
207
227
  )
208
- end.to raise_error(
209
- ArgumentError,
210
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
211
- )
228
+ end
212
229
  end
213
- end
214
230
 
215
- context 'missing code and authentication_challenge_id arguments' do
216
- it 'returns argument error' do
217
- expect do
218
- described_class.verify_factor
219
- end.to raise_error(
220
- ArgumentError,
221
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
222
- )
231
+ context 'with missing code and authentication_challenge_id arguments' do
232
+ it 'returns an argument error' do
233
+ expect do
234
+ described_class.verify_challenge
235
+ end.to raise_error(
236
+ ArgumentError,
237
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
238
+ )
239
+ end
223
240
  end
224
241
  end
225
242
  end
226
243
 
227
- describe 'tests returning and deleting a factor' do
228
- context 'returns a factor' do
229
- it 'uses get_factor to return factor' do
244
+ describe '.get_factor' do
245
+ context 'with a valid id' do
246
+ it 'returns a factor' do
230
247
  VCR.use_cassette 'mfa/get_factor_valid' do
231
248
  factor = described_class.get_factor(
232
249
  id: 'auth_factor_01FZ4WMXXA09XF6NK1XMKNWB3M',
@@ -236,8 +253,8 @@ describe WorkOS::MFA do
236
253
  end
237
254
  end
238
255
 
239
- context 'invalid factor request' do
240
- it 'uses get_factor and throws error if id is wrong' do
256
+ context 'with an invalid id' do
257
+ it 'returns an error' do
241
258
  VCR.use_cassette 'mfa/get_factor_invalid' do
242
259
  expect do
243
260
  described_class.get_factor(
@@ -247,7 +264,9 @@ describe WorkOS::MFA do
247
264
  end
248
265
  end
249
266
  end
267
+ end
250
268
 
269
+ describe '.delete_factor' do
251
270
  context 'deletes facotr' do
252
271
  it 'uses delete_factor to delete factor' do
253
272
  VCR.use_cassette 'mfa/delete_factor' do
@@ -330,7 +330,7 @@ describe WorkOS::SSO do
330
330
  let(:request_body) do
331
331
  {
332
332
  client_id: args[:client_id],
333
- client_secret: WorkOS.key,
333
+ client_secret: WorkOS.config.key,
334
334
  code: args[:code],
335
335
  grant_type: 'authorization_code',
336
336
  }
data/spec/spec_helper.rb CHANGED
@@ -25,7 +25,7 @@ SPEC_ROOT = File.dirname __FILE__
25
25
 
26
26
  VCR.configure do |config|
27
27
  config.cassette_library_dir = 'spec/support/fixtures/vcr_cassettes'
28
- config.filter_sensitive_data('<API_KEY>') { WorkOS.key }
28
+ config.filter_sensitive_data('<API_KEY>') { WorkOS.config.key }
29
29
  config.hook_into :webmock
30
30
  end
31
31
 
@@ -51,6 +51,6 @@ RSpec.configure do |config|
51
51
  end
52
52
  end)
53
53
 
54
- config.before(:all) { WorkOS.key ||= '' }
54
+ config.before(:all) { WorkOS.config.key ||= '' }
55
55
  config.before(:each) { VCR.turn_on! }
56
56
  end
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/challenge
5
+ uri: https://api.workos.com/auth/factors/auth_factor_01FZ4WMXXA09XF6NK1XMKNWB3M/challenge
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"sms_template":null,"authentication_factor_id":"auth_factor_01FZ4WMXXA09XF6NK1XMKNWB3M"}'
8
+ string: '{"sms_template":null}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/challenge
5
+ uri: https://api.workos.com/auth/factors/auth_factor_01FZ4TS14D1PHFNZ9GF6YD8M1F/challenge
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"sms_template":"Your code is {{code}}","authentication_factor_id":"auth_factor_01FZ4TS14D1PHFNZ9GF6YD8M1F"}'
8
+ string: '{"sms_template":"Your code is {{code}}"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/challenge
5
+ uri: https://api.workos.com/auth/factors/auth_factor_01FZ4TS0MWPZR7GATS7KCXANQZ/challenge
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"sms_template":null,"authentication_factor_id":"auth_factor_01FZ4TS0MWPZR7GATS7KCXANQZ"}'
8
+ string: '{"sms_template":null}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/verify
5
+ uri: https://api.workos.com/auth/challenges/auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J/verify
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"authentication_challenge_id":"auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J","code":"897792"}'
8
+ string: '{"code":"897792"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/verify
5
+ uri: https://api.workos.com/auth/challenges/auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J/verify
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"authentication_challenge_id":"auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J","code":"897792"}'
8
+ string: '{"code":"897792"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/verify
5
+ uri: https://api.workos.com/auth/challenges/auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J/verify
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"authentication_challenge_id":"auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J","code":"897792"}'
8
+ string: '{"code":"897792"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -2,10 +2,10 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: https://api.workos.com/auth/factors/verify
5
+ uri: https://api.workos.com/auth/challenges/auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J/verify
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"authentication_challenge_id":"auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J","code":"897792"}'
8
+ string: '{"code":"897792"}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
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: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - WorkOS
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-14 00:00:00.000000000 Z
11
+ date: 2022-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -208,9 +208,9 @@ files:
208
208
  - docs/top-level-namespace.html
209
209
  - lib/workos.rb
210
210
  - lib/workos/audit_trail.rb
211
- - lib/workos/base.rb
212
211
  - lib/workos/challenge.rb
213
212
  - lib/workos/client.rb
213
+ - lib/workos/configuration.rb
214
214
  - lib/workos/connection.rb
215
215
  - lib/workos/deprecated_hash_wrapper.rb
216
216
  - lib/workos/directory.rb
@@ -241,9 +241,9 @@ files:
241
241
  - lib/workos/types/passwordless_session_struct.rb
242
242
  - lib/workos/types/profile_struct.rb
243
243
  - lib/workos/types/provider_enum.rb
244
- - lib/workos/types/verify_factor_struct.rb
244
+ - lib/workos/types/verify_challenge_struct.rb
245
245
  - lib/workos/types/webhook_struct.rb
246
- - lib/workos/verify_factor.rb
246
+ - lib/workos/verify_challenge.rb
247
247
  - lib/workos/version.rb
248
248
  - lib/workos/webhook.rb
249
249
  - lib/workos/webhooks.rb
@@ -282,7 +282,7 @@ files:
282
282
  - sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi
283
283
  - sorbet/rbi/todo.rbi
284
284
  - spec/lib/workos/audit_trail_spec.rb
285
- - spec/lib/workos/base_spec.rb
285
+ - spec/lib/workos/configuration_spec.rb
286
286
  - spec/lib/workos/directory_sync_spec.rb
287
287
  - spec/lib/workos/directory_user_spec.rb
288
288
  - spec/lib/workos/mfa_spec.rb
@@ -333,10 +333,10 @@ files:
333
333
  - spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml
334
334
  - spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml
335
335
  - spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml
336
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_expired.yml
337
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_invalid.yml
338
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid.yml
339
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid_is_false.yml
336
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml
337
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml
338
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml
339
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml
340
340
  - spec/support/fixtures/vcr_cassettes/organization/create.yml
341
341
  - spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml
342
342
  - spec/support/fixtures/vcr_cassettes/organization/delete.yml
@@ -394,7 +394,7 @@ specification_version: 4
394
394
  summary: API client for WorkOS
395
395
  test_files:
396
396
  - spec/lib/workos/audit_trail_spec.rb
397
- - spec/lib/workos/base_spec.rb
397
+ - spec/lib/workos/configuration_spec.rb
398
398
  - spec/lib/workos/directory_sync_spec.rb
399
399
  - spec/lib/workos/directory_user_spec.rb
400
400
  - spec/lib/workos/mfa_spec.rb
@@ -445,10 +445,10 @@ test_files:
445
445
  - spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml
446
446
  - spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml
447
447
  - spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml
448
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_expired.yml
449
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_invalid.yml
450
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid.yml
451
- - spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid_is_false.yml
448
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml
449
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml
450
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml
451
+ - spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml
452
452
  - spec/support/fixtures/vcr_cassettes/organization/create.yml
453
453
  - spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml
454
454
  - spec/support/fixtures/vcr_cassettes/organization/delete.yml
data/lib/workos/base.rb DELETED
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
- # typed: true
3
-
4
-
5
- module WorkOS
6
- ## The Base class handles setting and reading the WorkOS
7
- ## API Key for authentication
8
- module Base
9
- attr_accessor :key
10
-
11
- class << self
12
- extend T::Sig
13
-
14
- attr_writer :key
15
- attr_reader :key
16
- end
17
- end
18
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
- # typed: false
3
-
4
- module WorkOS
5
- module Test
6
- class << self
7
- include Base
8
- include Client
9
-
10
- def request
11
- execute_request(request: post_request(path: '/events', body: {}))
12
- end
13
- end
14
- end
15
- end
16
-
17
- describe WorkOS::Base do
18
- describe '.execute_request' do
19
- context 'when unauthenticated' do
20
- it 'raises an error' do
21
- VCR.use_cassette('base/execute_request_unauthenticated') do
22
- expect { WorkOS::Test.request }.to raise_error(
23
- WorkOS::AuthenticationError,
24
- /Status 401, Unauthorized/,
25
- )
26
- end
27
- end
28
- end
29
- end
30
- end