workos 2.4.0 → 2.5.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.
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