stytch 10.24.0 → 10.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb709fad85473f219b4bf2d15da9c8381b117ba31a3f9dd3393a338ec1583323
4
- data.tar.gz: 1d59d330089fe207f936e80950a00ab0f1152d3f08c2a62db2df864fe4972408
3
+ metadata.gz: 0a905e33f9cc2881ad04adabc476f64db1cfc8836b1e012dd6692bd411ff32cd
4
+ data.tar.gz: bfa6c0c4d4858a8f7154bb85b359bd311b0ea17becf11fb89373bb721fe74d0f
5
5
  SHA512:
6
- metadata.gz: 015bffaf59b053a43f58d5ab48f245bc24f7ba623ae498a6bcca502ed6023d278e03023154ddb4eb1d269386488831ccc03d30f0ed028817fe7b355e4df006ab
7
- data.tar.gz: c5c4bd35f7da7a88da844c470238c6ec3c26dcc3e4ce3abfe874a9e936066b617cee4685019745b71a5ce969be35ab21a287245c1b9f93fcaa0602986980e15d
6
+ metadata.gz: acb3ded234b14fd6fbff16c1e15942a6a7b30bf30e4d3c763b0645e2e61c9bb7aab86f3b8583b1e5aa338bba49b36fd70f80887aed449dfcf854defac6bf0ede
7
+ data.tar.gz: 00cc8b6ad8d878561322055da00b0fed3a2265dbb7171ab46f89594fe0ba43636b8f86cd0c04c0f0b57c3ec89f0114f82667ef46d021697066bf0fb0a66d726b
@@ -1,6 +1,13 @@
1
+ # !!!
2
+ # WARNING: This file is autogenerated
3
+ # Only modify code within MANUAL() sections
4
+ # or your changes may be overwritten later!
5
+ # !!!
6
+
1
7
  # frozen_string_literal: true
2
8
 
3
9
  require_relative 'b2b_discovery'
10
+ require_relative 'b2b_idp'
4
11
  require_relative 'b2b_impersonation'
5
12
  require_relative 'b2b_magic_links'
6
13
  require_relative 'b2b_oauth'
@@ -23,7 +30,7 @@ module StytchB2B
23
30
  class Client
24
31
  ENVIRONMENTS = %i[live test].freeze
25
32
 
26
- attr_reader :connected_app, :discovery, :fraud, :impersonation, :m2m, :magic_links, :oauth, :otps, :organizations, :passwords, :project, :rbac, :recovery_codes, :scim, :sso, :sessions, :totps
33
+ attr_reader :connected_app, :discovery, :fraud, :impersonation, :m2m, :magic_links, :oauth, :otps, :organizations, :passwords, :project, :rbac, :recovery_codes, :scim, :sso, :sessions, :totps, :idp
27
34
 
28
35
  def initialize(project_id:, secret:, env: nil, fraud_env: nil, &block)
29
36
  @api_host = api_host(env, project_id)
@@ -35,7 +42,8 @@ module StytchB2B
35
42
  create_connection(&block)
36
43
 
37
44
  rbac = StytchB2B::RBAC.new(@connection)
38
- @policy_cache = StytchB2B::PolicyCache.new(rbac_client: rbac)
45
+ @policy_cache = Stytch::PolicyCache.new(rbac_client: rbac)
46
+ @idp = StytchB2B::IDP.new(@connection, @project_id, @policy_cache)
39
47
 
40
48
  @connected_app = Stytch::ConnectedApp.new(@connection)
41
49
  @discovery = StytchB2B::Discovery.new(@connection)
@@ -29,7 +29,7 @@ module StytchB2B
29
29
 
30
30
  # Exchange an Intermediate Session for a fully realized [Member Session](https://stytch.com/docs/b2b/api/session-object) for the [Organization](https://stytch.com/docs/b2b/api/organization-object) that the user wishes to log into.
31
31
  #
32
- # This endpoint can be used to accept invites and into a new Organization on the basis of the user's email domain or OAuth tenant.
32
+ # This endpoint can be used to accept invites and JIT Provision into a new Organization on the basis of the user's email domain or OAuth tenant.
33
33
  #
34
34
  # If the user **has** already satisfied the authentication requirements of the Organization they are trying to exchange into and logged in with a method that verifies their email address, this API will return `member_authenticated: true` and a `session_token` and `session_jwt`.
35
35
  #
@@ -69,7 +69,7 @@ module StytchB2B
69
69
  # Total custom claims size cannot exceed four kilobytes.
70
70
  # The type of this field is nilable +object+.
71
71
  # locale::
72
- # If the needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
72
+ # If the Member needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
73
73
  #
74
74
  # Parameter is a [IETF BCP 47 language tag](https://www.w3.org/International/articles/language-tags/), e.g. `"en"`.
75
75
  #
@@ -144,7 +144,7 @@ module StytchB2B
144
144
  @connection = connection
145
145
  end
146
146
 
147
- # This endpoint allows you to exchange the `intermediate_session_token` returned when the user successfully completes a authentication flow to create a new
147
+ # This endpoint allows you to exchange the `intermediate_session_token` returned when the user successfully completes a Discovery authentication flow to create a new
148
148
  # [Organization](https://stytch.com/docs/b2b/api/organization-object) and [Member](https://stytch.com/docs/b2b/api/member-object) and log the user in. If the user wants to log into an existing Organization, use the [Exchange Intermediate Session endpoint](https://stytch.com/docs/b2b/api/exchange-intermediate-session) instead.
149
149
  #
150
150
  # Stytch **requires that users verify their email address** prior to creating a new Organization in order to prevent Account Takeover (ATO) attacks and phishing.
@@ -197,7 +197,7 @@ module StytchB2B
197
197
  # sso_jit_provisioning::
198
198
  # The authentication setting that controls the JIT provisioning of Members when authenticating via SSO. The accepted values are:
199
199
  #
200
- # `ALL_ALLOWED` – new Members will be automatically provisioned upon successful authentication via any of the Organization's `sso_active_connections`.
200
+ # `ALL_ALLOWED` – the default setting, new Members will be automatically provisioned upon successful authentication via any of the Organization's `sso_active_connections`.
201
201
  #
202
202
  # `RESTRICTED` – only new Members with SSO logins that comply with `sso_jit_provisioning_allowed_connections` can be provisioned upon authentication.
203
203
  #
@@ -215,7 +215,7 @@ module StytchB2B
215
215
  #
216
216
  # `RESTRICTED` – only new Members with verified emails that comply with `email_allowed_domains` can be provisioned upon authentication via Email Magic Link or OAuth.
217
217
  #
218
- # `NOT_ALLOWED` – disable JIT provisioning via Email Magic Link and OAuth.
218
+ # `NOT_ALLOWED` – the default setting, disables JIT provisioning via Email Magic Link and OAuth.
219
219
  #
220
220
  # The type of this field is nilable +String+.
221
221
  # email_invites::
@@ -273,7 +273,7 @@ module StytchB2B
273
273
  #
274
274
  # `RESTRICTED` – only new Members with tenants in `allowed_oauth_tenants` can JIT provision via tenant.
275
275
  #
276
- # `NOT_ALLOWED` – disable JIT provisioning by OAuth Tenant.
276
+ # `NOT_ALLOWED` – the default setting, disables JIT provisioning by OAuth Tenant.
277
277
  #
278
278
  # The type of this field is nilable +String+.
279
279
  # allowed_oauth_tenants::
@@ -282,7 +282,7 @@ module StytchB2B
282
282
  # first_party_connected_apps_allowed_type::
283
283
  # The authentication setting that sets the Organization's policy towards first party Connected Apps. The accepted values are:
284
284
  #
285
- # `ALL_ALLOWED` – any first party Connected App in the Project is permitted for use by Members.
285
+ # `ALL_ALLOWED` – the default setting, any first party Connected App in the Project is permitted for use by Members.
286
286
  #
287
287
  # `RESTRICTED` – only first party Connected Apps with IDs in `allowed_first_party_connected_apps` can be used by Members.
288
288
  #
@@ -295,7 +295,7 @@ module StytchB2B
295
295
  # third_party_connected_apps_allowed_type::
296
296
  # The authentication setting that sets the Organization's policy towards third party Connected Apps. The accepted values are:
297
297
  #
298
- # `ALL_ALLOWED` – any third party Connected App in the Project is permitted for use by Members.
298
+ # `ALL_ALLOWED` – the default setting, any third party Connected App in the Project is permitted for use by Members.
299
299
  #
300
300
  # `RESTRICTED` – only third party Connected Apps with IDs in `allowed_first_party_connected_apps` can be used by Members.
301
301
  #
@@ -0,0 +1,266 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+ require 'json/jwt'
5
+ require_relative 'errors'
6
+ require_relative 'request_helper'
7
+ require_relative 'rbac_local'
8
+
9
+ module StytchB2B
10
+ class IDP
11
+ include Stytch::RequestHelper
12
+
13
+ def initialize(connection, project_id, policy_cache)
14
+ @connection = connection
15
+ @project_id = project_id
16
+ @policy_cache = policy_cache
17
+ @non_custom_claim_keys = [
18
+ 'aud',
19
+ 'exp',
20
+ 'iat',
21
+ 'iss',
22
+ 'jti',
23
+ 'nbf',
24
+ 'sub',
25
+ 'active',
26
+ 'client_id',
27
+ 'request_id',
28
+ 'scope',
29
+ 'status_code',
30
+ 'token_type',
31
+ 'https://stytch.com/organization'
32
+ ]
33
+ end
34
+
35
+ # Introspects a token JWT from an authorization code response.
36
+ # Access tokens are JWTs signed with the project's JWKs. Refresh tokens are opaque tokens.
37
+ # Access tokens contain a standard set of claims as well as any custom claims generated from templates.
38
+ #
39
+ # == Parameters:
40
+ # token::
41
+ # The access token (or refresh token) to introspect.
42
+ # The type of this field is +String+.
43
+ # client_id::
44
+ # The ID of the client.
45
+ # The type of this field is +String+.
46
+ # client_secret::
47
+ # The secret of the client.
48
+ # The type of this field is nilable +String+.
49
+ # token_type_hint::
50
+ # A hint on what the token contains. Valid fields are 'access_token' and 'refresh_token'.
51
+ # The type of this field is +String+.
52
+ # authorization_check::
53
+ # Optional authorization check object.
54
+ # The type of this field is nilable +Hash+.
55
+ #
56
+ # == Returns:
57
+ # An object with the following fields:
58
+ # subject::
59
+ # The subject of the token.
60
+ # The type of this field is +String+.
61
+ # scope::
62
+ # The scope of the token.
63
+ # The type of this field is +String+.
64
+ # audience::
65
+ # The audience of the token.
66
+ # The type of this field is +String+.
67
+ # expires_at::
68
+ # The expiration time of the token.
69
+ # The type of this field is +Integer+.
70
+ # issued_at::
71
+ # The issued at time of the token.
72
+ # The type of this field is +Integer+.
73
+ # issuer::
74
+ # The issuer of the token.
75
+ # The type of this field is +String+.
76
+ # not_before::
77
+ # The not before time of the token.
78
+ # The type of this field is +Integer+.
79
+ # token_type::
80
+ # The type of the token.
81
+ # The type of this field is +String+.
82
+ # custom_claims::
83
+ # Custom claims in the token.
84
+ # The type of this field is +Hash+.
85
+ # organization_claim::
86
+ # The organization claim in the token.
87
+ # The type of this field is +Hash+.
88
+ def introspect_token_network(
89
+ token:,
90
+ client_id:,
91
+ client_secret: nil,
92
+ token_type_hint: 'access_token',
93
+ authorization_check: nil
94
+ )
95
+ headers = {}
96
+ data = {
97
+ 'token' => token,
98
+ 'client_id' => client_id,
99
+ 'token_type_hint' => token_type_hint
100
+ }
101
+ data['client_secret'] = client_secret unless client_secret.nil?
102
+
103
+ url = @connection.url_prefix + '/v1/oauth2/introspect'
104
+ jwt_response = post_request(url, data, headers)
105
+
106
+ return nil unless jwt_response['active']
107
+
108
+ custom_claims = jwt_response.reject { |k, _| @non_custom_claim_keys.include?(k) }
109
+ organization_claim = jwt_response['https://stytch.com/organization']
110
+ organization_id = organization_claim['organization_id']
111
+ scope = jwt_response['scope']
112
+
113
+ if authorization_check
114
+ @policy_cache.perform_authorization_check(
115
+ subject_roles: scope.split,
116
+ authorization_check: authorization_check,
117
+ subject_org_id: organization_id
118
+ )
119
+ end
120
+
121
+ {
122
+ 'subject' => jwt_response['sub'],
123
+ 'scope' => jwt_response['scope'],
124
+ 'audience' => jwt_response['aud'],
125
+ 'expires_at' => jwt_response['exp'],
126
+ 'issued_at' => jwt_response['iat'],
127
+ 'issuer' => jwt_response['iss'],
128
+ 'not_before' => jwt_response['nbf'],
129
+ 'token_type' => jwt_response['token_type'],
130
+ 'custom_claims' => custom_claims,
131
+ 'organization_claim' => organization_claim
132
+ }
133
+ end
134
+
135
+ # Introspects a token JWT from an authorization code response.
136
+ # Access tokens are JWTs signed with the project's JWKs. Refresh tokens are opaque tokens.
137
+ # Access tokens contain a standard set of claims as well as any custom claims generated from templates.
138
+ #
139
+ # == Parameters:
140
+ # access_token::
141
+ # The access token (or refresh token) to introspect.
142
+ # The type of this field is +String+.
143
+ # authorization_check::
144
+ # Optional authorization check object.
145
+ # The type of this field is nilable +Hash+.
146
+ #
147
+ # == Returns:
148
+ # An object with the following fields:
149
+ # subject::
150
+ # The subject of the token.
151
+ # The type of this field is +String+.
152
+ # scope::
153
+ # The scope of the token.
154
+ # The type of this field is +String+.
155
+ # audience::
156
+ # The audience of the token.
157
+ # The type of this field is +String+.
158
+ # expires_at::
159
+ # The expiration time of the token.
160
+ # The type of this field is +Integer+.
161
+ # issued_at::
162
+ # The issued at time of the token.
163
+ # The type of this field is +Integer+.
164
+ # issuer::
165
+ # The issuer of the token.
166
+ # The type of this field is +String+.
167
+ # not_before::
168
+ # The not before time of the token.
169
+ # The type of this field is +Integer+.
170
+ # token_type::
171
+ # The type of the token.
172
+ # The type of this field is +String+.
173
+ # custom_claims::
174
+ # Custom claims in the token.
175
+ # The type of this field is +Hash+.
176
+ # organization_claim::
177
+ # The organization claim in the token.
178
+ # The type of this field is +Hash+.
179
+ def introspect_access_token_local(
180
+ access_token:,
181
+ authorization_check: nil
182
+ )
183
+ scope_claim = 'scope'
184
+ organization_claim = 'https://stytch.com/organization'
185
+
186
+ # Create a JWKS loader similar to other classes in the codebase
187
+ @cache_last_update = 0
188
+ jwks_loader = lambda do |options|
189
+ @cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
190
+ if @cached_keys.nil?
191
+ @cached_keys = get_jwks(project_id: @project_id)
192
+ @cache_last_update = Time.now.to_i
193
+ end
194
+ @cached_keys
195
+ end
196
+
197
+ begin
198
+ decoded_jwt = JWT.decode(
199
+ access_token,
200
+ nil,
201
+ true,
202
+ {
203
+ algorithms: ['RS256'],
204
+ jwks: jwks_loader,
205
+ iss: ["stytch.com/#{@project_id}", @connection.url_prefix],
206
+ aud: @project_id
207
+ }
208
+ )[0]
209
+
210
+ generic_claims = decoded_jwt
211
+ custom_claims = generic_claims.reject { |k, _| @non_custom_claim_keys.include?(k) }
212
+ organization_claim_data = generic_claims[organization_claim]
213
+ organization_id = organization_claim_data['organization_id']
214
+ scope = generic_claims[scope_claim]
215
+
216
+ if authorization_check
217
+ @policy_cache.perform_authorization_check(
218
+ subject_roles: scope.split,
219
+ authorization_check: authorization_check,
220
+ subject_org_id: organization_id
221
+ )
222
+ end
223
+
224
+ {
225
+ 'subject' => generic_claims['sub'],
226
+ 'scope' => generic_claims[scope_claim],
227
+ 'audience' => generic_claims['aud'],
228
+ 'expires_at' => generic_claims['exp'],
229
+ 'issued_at' => generic_claims['iat'],
230
+ 'issuer' => generic_claims['iss'],
231
+ 'not_before' => generic_claims['nbf'],
232
+ 'token_type' => 'access_token',
233
+ 'custom_claims' => custom_claims,
234
+ 'organization_claim' => organization_claim_data
235
+ }
236
+ rescue JWT::InvalidIssuerError
237
+ raise Stytch::JWTInvalidIssuerError
238
+ rescue JWT::InvalidAudError
239
+ raise Stytch::JWTInvalidAudienceError
240
+ rescue JWT::ExpiredSignature
241
+ raise Stytch::JWTExpiredSignatureError
242
+ rescue JWT::IncorrectAlgorithm
243
+ raise Stytch::JWTIncorrectAlgorithmError
244
+ rescue JWT::DecodeError
245
+ nil
246
+ end
247
+ end
248
+
249
+ # Gets the JWKS for the project.
250
+ #
251
+ # == Parameters:
252
+ # project_id::
253
+ # The ID of the project.
254
+ # The type of this field is +String+.
255
+ #
256
+ # == Returns:
257
+ # The JWKS for the project.
258
+ # The type of this field is +Hash+.
259
+ def get_jwks(project_id:)
260
+ headers = {}
261
+ query_params = {}
262
+ request = request_with_query_params("/v1/b2b/sessions/jwks/#{project_id}", query_params)
263
+ get_request(request, headers)
264
+ end
265
+ end
266
+ end
@@ -16,14 +16,14 @@ module StytchB2B
16
16
  @connection = connection
17
17
  end
18
18
 
19
- # Authenticate an impersonation token to impersonate a. This endpoint requires an impersonation token that is not expired or previously used.
19
+ # Authenticate an impersonation token to impersonate a Member. This endpoint requires an impersonation token that is not expired or previously used.
20
20
  # A Stytch session will be created for the impersonated member with a 60 minute duration. Impersonated sessions cannot be extended.
21
21
  #
22
22
  # Prior to this step, you can generate an impersonation token by visiting the Stytch Dashboard, viewing a member, and clicking the `Impersonate Member` button.
23
23
  #
24
24
  # == Parameters:
25
25
  # impersonation_token::
26
- # The User Impersonation token to authenticate.
26
+ # The Member Impersonation token to authenticate. Expires in 5 minutes by default.
27
27
  # The type of this field is +String+.
28
28
  #
29
29
  # == Returns:
@@ -20,10 +20,10 @@ module StytchB2B
20
20
  @discovery = StytchB2B::MagicLinks::Discovery.new(@connection)
21
21
  end
22
22
 
23
- # Authenticate a with a Magic Link. This endpoint requires a Magic Link token that is not expired or previously used. If the Member’s status is `pending` or `invited`, they will be updated to `active`.
23
+ # Authenticate a Member with a Magic Link. This endpoint requires a Magic Link token that is not expired or previously used. If the Member’s status is `pending` or `invited`, they will be updated to `active`.
24
24
  # Provide the `session_duration_minutes` parameter to set the lifetime of the session. If the `session_duration_minutes` parameter is not specified, a Stytch session will be created with a 60 minute duration.
25
25
  #
26
- # If the Member is required to complete MFA to log in to the, the returned value of `member_authenticated` will be `false`, and an `intermediate_session_token` will be returned.
26
+ # If the Member is required to complete MFA to log in to the Organization, the returned value of `member_authenticated` will be `false`, and an `intermediate_session_token` will be returned.
27
27
  # The `intermediate_session_token` can be passed into the [OTP SMS Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-otp-sms), [TOTP Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-totp),
28
28
  # or [Recovery Codes Recover endpoint](https://stytch.com/docs/b2b/api/recovery-codes-recover) to complete the MFA step and acquire a full member session.
29
29
  # The `intermediate_session_token` can also be used with the [Exchange Intermediate Session endpoint](https://stytch.com/docs/b2b/api/exchange-intermediate-session) or the [Create Organization via Discovery endpoint](https://stytch.com/docs/b2b/api/create-organization-via-discovery) to join a different Organization or create a new one.
@@ -67,7 +67,7 @@ module StytchB2B
67
67
  # Total custom claims size cannot exceed four kilobytes.
68
68
  # The type of this field is nilable +object+.
69
69
  # locale::
70
- # If the needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
70
+ # If the Member needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
71
71
  #
72
72
  # Parameter is a [IETF BCP 47 language tag](https://www.w3.org/International/articles/language-tags/), e.g. `"en"`.
73
73
  #
@@ -277,7 +277,7 @@ module StytchB2B
277
277
  post_request('/v1/b2b/magic_links/email/login_or_signup', request, headers)
278
278
  end
279
279
 
280
- # Send an invite email to a new to join an. The Member will be created with an `invited` status until they successfully authenticate. Sending invites to `pending` Members will update their status to `invited`. Sending invites to already `active` Members will return an error.
280
+ # Send an invite email to a new Member to join an Organization. The Member will be created with an `invited` status until they successfully authenticate. Sending invites to `pending` Members will update their status to `invited`. Sending invites to already `active` Members will return an error.
281
281
  #
282
282
  # The magic link invite will be valid for 1 week.
283
283
  #
@@ -19,9 +19,9 @@ module StytchB2B
19
19
  @discovery = StytchB2B::OAuth::Discovery.new(@connection)
20
20
  end
21
21
 
22
- # Authenticate a given a `token`. This endpoint verifies that the member completed the flow by verifying that the token is valid and hasn't expired. Provide the `session_duration_minutes` parameter to set the lifetime of the session. If the `session_duration_minutes` parameter is not specified, a Stytch session will be created with a 60 minute duration.
22
+ # Authenticate a Member given a `token`. This endpoint verifies that the member completed the OAuth flow by verifying that the token is valid and hasn't expired. Provide the `session_duration_minutes` parameter to set the lifetime of the session. If the `session_duration_minutes` parameter is not specified, a Stytch session will be created with a 60 minute duration.
23
23
  #
24
- # If the Member is required to complete MFA to log in to the, the returned value of `member_authenticated` will be `false`, and an `intermediate_session_token` will be returned.
24
+ # If the Member is required to complete MFA to log in to the Organization, the returned value of `member_authenticated` will be `false`, and an `intermediate_session_token` will be returned.
25
25
  # The `intermediate_session_token` can be passed into the [OTP SMS Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-otp-sms) to complete the MFA step and acquire a full member session.
26
26
  # The `intermediate_session_token` can also be used with the [Exchange Intermediate Session endpoint](https://stytch.com/docs/b2b/api/exchange-intermediate-session) or the [Create Organization via Discovery endpoint](https://stytch.com/docs/b2b/api/create-organization-via-discovery) to join a different Organization or create a new one.
27
27
  # The `session_duration_minutes` and `session_custom_claims` parameters will be ignored.
@@ -65,7 +65,7 @@ module StytchB2B
65
65
  # A base64url encoded one time secret used to validate that the request starts and ends on the same device.
66
66
  # The type of this field is nilable +String+.
67
67
  # locale::
68
- # If the needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
68
+ # If the Member needs to complete an MFA step, and the Member has a phone number, this endpoint will pre-emptively send a one-time passcode (OTP) to the Member's phone number. The locale argument will be used to determine which language to use when sending the passcode.
69
69
  #
70
70
  # Parameter is a [IETF BCP 47 language tag](https://www.w3.org/International/articles/language-tags/), e.g. `"en"`.
71
71
  #
@@ -165,7 +165,7 @@ module StytchB2B
165
165
  @connection = connection
166
166
  end
167
167
 
168
- # Authenticates the Discovery token and exchanges it for an Intermediate
168
+ # Authenticates the Discovery OAuth token and exchanges it for an Intermediate
169
169
  # Session Token. Intermediate Session Tokens can be used for various Discovery login flows and are valid for 10 minutes.
170
170
  #
171
171
  # == Parameters: