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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.semaphore/semaphore.yml +13 -39
  3. data/Gemfile.lock +2 -2
  4. data/README.md +4 -0
  5. data/lib/workos/challenge.rb +54 -0
  6. data/lib/workos/client.rb +2 -0
  7. data/lib/workos/directory_sync.rb +1 -0
  8. data/lib/workos/errors.rb +3 -1
  9. data/lib/workos/factor.rb +58 -0
  10. data/lib/workos/mfa.rb +165 -0
  11. data/lib/workos/sso.rb +38 -15
  12. data/lib/workos/types/challenge_struct.rb +18 -0
  13. data/lib/workos/types/factor_struct.rb +19 -0
  14. data/lib/workos/types/verify_factor_struct.rb +15 -0
  15. data/lib/workos/types.rb +3 -0
  16. data/lib/workos/verify_factor.rb +39 -0
  17. data/lib/workos/version.rb +1 -1
  18. data/lib/workos/webhooks.rb +9 -7
  19. data/lib/workos.rb +5 -0
  20. data/spec/lib/workos/mfa_spec.rb +232 -0
  21. data/spec/lib/workos/sso_spec.rb +140 -4
  22. data/spec/lib/workos/webhooks_spec.rb +1 -1
  23. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
  24. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
  25. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
  26. data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
  27. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
  28. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
  29. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
  30. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
  31. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
  32. data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_expired.yml +84 -0
  33. data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_invalid.yml +84 -0
  34. data/spec/support/fixtures/vcr_cassettes/mfa/verify_factor_generic_valid.yml +82 -0
  35. metadata +36 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 739e4734f5caa4b4c8180e125a206106242fea489c1dccc19f1bc45ad514bc7e
4
- data.tar.gz: '029c0a8ef19f9b9b933a73eec53a9770851ea2a338a81060c040b72a06e39189'
3
+ metadata.gz: 983d578de3e27144af8a7947eebfb770ad7ee640954511586617505c520ee657
4
+ data.tar.gz: 92cb0b75234f56a1e18c47d9cb339b2f389e17463798141bc7a3a2977f5f9372
5
5
  SHA512:
6
- metadata.gz: 18631e0e0cdc5033b7df32d3ff95e2eeadcd7babd6c3b11063e174006ed3e8abd7769bfe4b0c828967e79b724ce0d8a79243960b5f2922eeb242051b56395b41
7
- data.tar.gz: 2a2b2d48b1410ad0fc86943a168d584234fd5c01ca5ee3e3b4b3117f9924ddc4199d55d10d338b1f07daa193edc0144312ec6271a68c65b89ec8fa2243064aa0
6
+ metadata.gz: 1143a28ee95755c80fe36aa5fba02e069143ebdb96e67f909d566bbf091928176ac29f23ccfa7764da163a248268f7a882616e0db7bd73612eda060c78cf8515
7
+ data.tar.gz: a2e279f2f2427dd8089eddcc692e677d21978fdd16f3918ffe162822d116b7904f1dbc6826d151f583ba1c60cd5c0e8fbe8b825fb78212f772d7a1aa11faa6da
@@ -31,45 +31,19 @@ blocks:
31
31
  - name: codecov-workos-ruby
32
32
  jobs:
33
33
  - name: Ruby 1.9.3
34
- commands:
35
- - checkout
36
- - sem-version ruby 1.9.3-p551
37
- - bundle install
38
- - bundle exec rspec
39
- - name: Ruby 2.0.0
40
- commands:
41
- - checkout
42
- - sem-version ruby 2.0.0-p648
43
- - bundle install
44
- - bundle exec rspec
45
- - name: Ruby 2.3.4
46
- commands:
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- workos (2.0.0)
4
+ workos (2.2.0)
5
5
  sorbet-runtime (~> 0.5)
6
6
 
7
7
  GEM
@@ -93,4 +93,4 @@ DEPENDENCIES
93
93
  yard
94
94
 
95
95
  BUNDLED WITH
96
- 2.2.22
96
+ 2.2.33
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 or domain is
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 'Google' is supported.
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] client_id The WorkOS client ID for the environment
32
- # where you've configured your SSO connection.
33
- # @param [String] redirect_uri The URI where users are directed
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
- # domain: 'acme.com',
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?domain=acme.com" \
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, or ' \
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
@@ -2,5 +2,5 @@
2
2
  # typed: strong
3
3
 
4
4
  module WorkOS
5
- VERSION = '2.0.0'
5
+ VERSION = '2.2.0'
6
6
  end