stytch 6.0.0 → 6.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.
@@ -160,6 +160,14 @@ module StytchB2B
160
160
  #
161
161
  # To create a new member via domain matching, use the [Exchange Intermediate Session](https://stytch.com/docs/b2b/api/exchange-intermediate-session) flow instead.
162
162
  #
163
+ # Only Email Magic Link, OAuth, and SMS OTP factors can be transferred between sessions. Other authentication factors, such as password factors, will not be transferred to the new session.
164
+ # SMS OTP factors can be used to fulfill MFA requirements for the target Organization if both the original and target Member have the same phone number and the phone number is verified for both Members.
165
+ #
166
+ # (Coming Soon) 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.
167
+ # 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.
168
+ # 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.
169
+ # The `session_duration_minutes` and `session_custom_claims` parameters will be ignored.
170
+ #
163
171
  # == Parameters:
164
172
  # organization_id::
165
173
  # Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
@@ -188,6 +196,16 @@ module StytchB2B
188
196
  # delete a key, supply a null value. Custom claims made with reserved claims (`iss`, `sub`, `aud`, `exp`, `nbf`, `iat`, `jti`) will be ignored.
189
197
  # Total custom claims size cannot exceed four kilobytes.
190
198
  # The type of this field is nilable +object+.
199
+ # locale::
200
+ # (Coming Soon) 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.
201
+ #
202
+ # Parameter is a [IETF BCP 47 language tag](https://www.w3.org/International/articles/language-tags/), e.g. `"en"`.
203
+ #
204
+ # Currently supported languages are English (`"en"`), Spanish (`"es"`), and Brazilian Portuguese (`"pt-br"`); if no value is provided, the copy defaults to English.
205
+ #
206
+ # Request support for additional languages [here](https://docs.google.com/forms/d/e/1FAIpQLScZSpAu_m2AmLXRT3F3kap-s_mcV6UTBitYn6CdyWP0-o7YjQ/viewform?usp=sf_link")!
207
+ #
208
+ # The type of this field is nilable +ExchangeRequestLocale+ (string enum).
191
209
  #
192
210
  # == Returns:
193
211
  # An object with the following fields:
@@ -212,15 +230,28 @@ module StytchB2B
212
230
  # organization::
213
231
  # The [Organization object](https://stytch.com/docs/b2b/api/organization-object).
214
232
  # The type of this field is +Organization+ (+object+).
233
+ # member_authenticated::
234
+ # Indicates whether the Member is fully authenticated. If false, the Member needs to complete an MFA step to log in to the Organization.
235
+ # The type of this field is +Boolean+.
236
+ # intermediate_session_token::
237
+ # The returned Intermediate Session Token contains any Email Magic Link or OAuth factors from the original member session that are valid for the target Organization.
238
+ # The token can be used with the [OTP SMS Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-otp-sms) to complete the MFA flow and log in to the target Organization.
239
+ # It can also be used with the [Exchange Intermediate Session endpoint](https://stytch.com/docs/b2b/api/exchange-intermediate-session) to join a different existing Organization,
240
+ # or the [Create Organization via Discovery endpoint](https://stytch.com/docs/b2b/api/create-organization-via-discovery) to create a new Organization.
241
+ # The type of this field is +String+.
215
242
  # status_code::
216
243
  # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
217
244
  # The type of this field is +Integer+.
245
+ # mfa_required::
246
+ # (Coming Soon) Information about the MFA requirements of the Organization and the Member's options for fulfilling MFA.
247
+ # The type of this field is nilable +MfaRequired+ (+object+).
218
248
  def exchange(
219
249
  organization_id:,
220
250
  session_token: nil,
221
251
  session_jwt: nil,
222
252
  session_duration_minutes: nil,
223
- session_custom_claims: nil
253
+ session_custom_claims: nil,
254
+ locale: nil
224
255
  )
225
256
  request = {
226
257
  organization_id: organization_id
@@ -229,6 +260,7 @@ module StytchB2B
229
260
  request[:session_jwt] = session_jwt unless session_jwt.nil?
230
261
  request[:session_duration_minutes] = session_duration_minutes unless session_duration_minutes.nil?
231
262
  request[:session_custom_claims] = session_custom_claims unless session_custom_claims.nil?
263
+ request[:locale] = locale unless locale.nil?
232
264
 
233
265
  post_request('/v1/b2b/sessions/exchange', request)
234
266
  end
@@ -83,6 +83,12 @@ module StytchB2B
83
83
  # If the `session_duration_minutes` parameter is not specified, a Stytch session will be created with a 60 minute duration.
84
84
  # To link this authentication event to an existing Stytch session, include either the `session_token` or `session_jwt` param.
85
85
  #
86
+ # (Coming Soon) 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.
87
+ # 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.
88
+ # The `session_duration_minutes` and `session_custom_claims` parameters will be ignored.
89
+ #
90
+ # If a valid `session_token` or `session_jwt` is passed in, the Member will not be required to complete an MFA step.
91
+ #
86
92
  # == Parameters:
87
93
  # sso_token::
88
94
  # The token to authenticate.
@@ -114,6 +120,16 @@ module StytchB2B
114
120
  # delete a key, supply a null value. Custom claims made with reserved claims (`iss`, `sub`, `aud`, `exp`, `nbf`, `iat`, `jti`) will be ignored.
115
121
  # Total custom claims size cannot exceed four kilobytes.
116
122
  # The type of this field is nilable +object+.
123
+ # locale::
124
+ # (Coming Soon) 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.
125
+ #
126
+ # Parameter is a [IETF BCP 47 language tag](https://www.w3.org/International/articles/language-tags/), e.g. `"en"`.
127
+ #
128
+ # Currently supported languages are English (`"en"`), Spanish (`"es"`), and Brazilian Portuguese (`"pt-br"`); if no value is provided, the copy defaults to English.
129
+ #
130
+ # Request support for additional languages [here](https://docs.google.com/forms/d/e/1FAIpQLScZSpAu_m2AmLXRT3F3kap-s_mcV6UTBitYn6CdyWP0-o7YjQ/viewform?usp=sf_link")!
131
+ #
132
+ # The type of this field is nilable +AuthenticateRequestLocale+ (string enum).
117
133
  #
118
134
  # == Returns:
119
135
  # An object with the following fields:
@@ -142,19 +158,31 @@ module StytchB2B
142
158
  # organization::
143
159
  # The [Organization object](https://stytch.com/docs/b2b/api/organization-object).
144
160
  # The type of this field is +Organization+ (+object+).
161
+ # intermediate_session_token::
162
+ # The returned Intermediate Session Token contains an SSO factor associated with the Member.
163
+ # The token can be used with the [OTP SMS Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-otp-sms) to complete the MFA flow and log in to the Organization.
164
+ # SSO factors are not transferable between Organizations, so the intermediate session token is not valid for use with discovery endpoints.
165
+ # The type of this field is +String+.
166
+ # member_authenticated::
167
+ # Indicates whether the Member is fully authenticated. If false, the Member needs to complete an MFA step to log in to the Organization.
168
+ # The type of this field is +Boolean+.
145
169
  # status_code::
146
170
  # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
147
171
  # The type of this field is +Integer+.
148
172
  # member_session::
149
173
  # The [Session object](https://stytch.com/docs/b2b/api/session-object).
150
174
  # The type of this field is nilable +MemberSession+ (+object+).
175
+ # mfa_required::
176
+ # (Coming Soon) Information about the MFA requirements of the Organization and the Member's options for fulfilling MFA.
177
+ # The type of this field is nilable +MfaRequired+ (+object+).
151
178
  def authenticate(
152
179
  sso_token:,
153
180
  pkce_code_verifier: nil,
154
181
  session_token: nil,
155
182
  session_jwt: nil,
156
183
  session_duration_minutes: nil,
157
- session_custom_claims: nil
184
+ session_custom_claims: nil,
185
+ locale: nil
158
186
  )
159
187
  request = {
160
188
  sso_token: sso_token
@@ -164,6 +192,7 @@ module StytchB2B
164
192
  request[:session_jwt] = session_jwt unless session_jwt.nil?
165
193
  request[:session_duration_minutes] = session_duration_minutes unless session_duration_minutes.nil?
166
194
  request[:session_custom_claims] = session_custom_claims unless session_custom_claims.nil?
195
+ request[:locale] = locale unless locale.nil?
167
196
 
168
197
  post_request('/v1/b2b/sso/authenticate', request)
169
198
  end
data/lib/stytch/client.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'crypto_wallets'
4
+ require_relative 'm2m'
4
5
  require_relative 'magic_links'
5
6
  require_relative 'oauth'
6
7
  require_relative 'otps'
@@ -14,7 +15,7 @@ module Stytch
14
15
  class Client
15
16
  ENVIRONMENTS = %i[live test].freeze
16
17
 
17
- attr_reader :crypto_wallets, :magic_links, :oauth, :otps, :passwords, :sessions, :totps, :users, :webauthn
18
+ attr_reader :crypto_wallets, :m2m, :magic_links, :oauth, :otps, :passwords, :sessions, :totps, :users, :webauthn
18
19
 
19
20
  def initialize(project_id:, secret:, env: nil, &block)
20
21
  @api_host = api_host(env, project_id)
@@ -24,6 +25,7 @@ module Stytch
24
25
  create_connection(&block)
25
26
 
26
27
  @crypto_wallets = Stytch::CryptoWallets.new(@connection)
28
+ @m2m = Stytch::M2M.new(@connection, project_id)
27
29
  @magic_links = Stytch::MagicLinks.new(@connection)
28
30
  @oauth = Stytch::OAuth.new(@connection)
29
31
  @otps = Stytch::OTPs.new(@connection)
data/lib/stytch/m2m.rb ADDED
@@ -0,0 +1,482 @@
1
+ # frozen_string_literal: true
2
+
3
+ # !!!
4
+ # WARNING: This file is autogenerated
5
+ # Only modify code within MANUAL() sections
6
+ # or your changes may be overwritten later!
7
+ # !!!
8
+
9
+ require_relative 'request_helper'
10
+
11
+ module Stytch
12
+ class M2M
13
+ include Stytch::RequestHelper
14
+ attr_reader :clients
15
+
16
+ def initialize(connection, project_id)
17
+ @connection = connection
18
+
19
+ @clients = Stytch::M2M::Clients.new(@connection)
20
+
21
+ @project_id = project_id
22
+ @cache_last_update = 0
23
+ @jwks_loader = lambda do |options|
24
+ @cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
25
+ @cached_keys ||= begin
26
+ @cache_last_update = Time.now.to_i
27
+ keys = []
28
+ get_jwks(project_id: @project_id)['keys'].each do |r|
29
+ keys << r
30
+ end
31
+ { keys: keys }
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ # MANUAL(M2M::get_jwks)(SERVICE_METHOD)
38
+ # This is a helper so we can retrieve the JWKS for a project for decoding M2M access tokens
39
+ def get_jwks(
40
+ project_id:
41
+ )
42
+ query_params = {}
43
+ request = request_with_query_params("/v1/sessions/jwks/#{project_id}", query_params)
44
+ get_request(request)
45
+ end
46
+ # ENDMANUAL(M2M::get_jwks)
47
+
48
+ # MANUAL(M2M::token)(SERVICE_METHOD)
49
+ # +token+ retrieves an access token for the given M2M Client.
50
+ # Access tokens are JWTs signed with the project's JWKs, and are valid for one hour after issuance.
51
+ # M2M Access tokens contain a standard set of claims as well as any custom claims generated from templates.
52
+ #
53
+ # == Parameters:
54
+ # client_id::
55
+ # The ID of the client.
56
+ # The type of this field is +String+.
57
+ # client_secret::
58
+ # The secret of the client.
59
+ # The type of this field is +String+.
60
+ # scopes::
61
+ # An array scopes requested. If omitted, all scopes assigned to the client will be returned.
62
+ # The type of this field is nilable list of +String+.
63
+ #
64
+ # == Returns:
65
+ # An object with the following fields:
66
+ # access_token::
67
+ # The access token granted to the client. Access tokens are JWTs signed with the project's JWKs.
68
+ # The type of this field is +String+.
69
+ # expires_in::
70
+ # The lifetime in seconds of the access token.
71
+ # For example, the value 3600 denotes that the access token will expire in one hour from the time the response was generated.
72
+ # The type of this field is +Integer+.
73
+ # token_type::
74
+ # The type of the returned access token. Today, this value will always be equal to "bearer"
75
+ # The type of this field is +String+.
76
+ def token(client_id:, client_secret:, scopes: nil)
77
+ request = {
78
+ grant_type: 'client_credentials',
79
+ client_id: client_id,
80
+ client_secret: client_secret
81
+ }
82
+ request[:scope] = scopes.join(' ') unless scopes.nil?
83
+
84
+ JSON.parse(post_request("/v1/public/#{@project_id}/oauth2/token", request), {:symbolize_names => true})
85
+ end
86
+ # ENDMANUAL(M2M::token)
87
+
88
+ # MANUAL(M2M::authenticate_token)(SERVICE_METHOD)
89
+ # +authenticate_token+ validates a M2M JWT locally.
90
+ #
91
+ # == Parameters:
92
+ # access_token::
93
+ # The access token granted to the client. Access tokens are JWTs signed with the project's JWKs.
94
+ # The type of this field is +String+.
95
+ # required_scopes::
96
+ # A list of scopes the token must have to be valid.
97
+ # The type of this field is nilable list of +String+.
98
+ # max_token_age::
99
+ # The maximum possible lifetime in seconds for the token to be valid.
100
+ # The type of this field is nilable +Integer+.
101
+ # == Returns:
102
+ # +nil+ if the token could not be validated, or an object with the following fields:
103
+ # scopes::
104
+ # An array of scopes granted to the token holder.
105
+ # The type of this field is list of +String+.
106
+ # client_id::
107
+ # The ID of the client that was issued the token
108
+ # The type of this field is +String+.
109
+ # custom_claims::
110
+ # A map of custom claims present in the token.
111
+ # The type of this field is +object+.
112
+ def authenticate_token(access_token:, required_scopes: nil, max_token_age: nil)
113
+ begin
114
+ decoded_jwt = authenticate_token_local(access_token)
115
+ rescue StandardError
116
+ # Could not authenticate locally
117
+ return nil
118
+ end
119
+
120
+ iat_time = Time.at(decoded_jwt['iat']).to_datetime
121
+
122
+ # Token too old
123
+ unless max_token_age.nil?
124
+ return nil if iat_time + max_token_age < Time.now
125
+ end
126
+
127
+ resp = marshal_jwt_into_response(decoded_jwt)
128
+
129
+ unless required_scopes.nil?
130
+ for scope in required_scopes
131
+ unless resp['scopes'].include?(scope)
132
+ # Token missing a required scope
133
+ return nil
134
+ end
135
+ end
136
+ end
137
+
138
+ resp
139
+ end
140
+
141
+ # Parse a M2M token and verify the signature locally (without calling /authenticate in the API)
142
+ def authenticate_token_local(jwt)
143
+ issuer = 'stytch.com/' + @project_id
144
+ begin
145
+ decoded_token = JWT.decode jwt, nil, true,
146
+ { jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'] }
147
+ decoded_token[0]
148
+ rescue JWT::InvalidIssuerError
149
+ raise JWTInvalidIssuerError
150
+ rescue JWT::InvalidAudError
151
+ raise JWTInvalidAudienceError
152
+ rescue JWT::ExpiredSignature
153
+ raise JWTExpiredSignatureError
154
+ rescue JWT::IncorrectAlgorithm
155
+ raise JWTIncorrectAlgorithmError
156
+ end
157
+ end
158
+
159
+ def marshal_jwt_into_response(jwt)
160
+ # The custom claim set is all the claims in the payload except for the standard claims.
161
+ # The cleanest way to collect those seems to be naming what we want
162
+ # to omit and filtering the rest to collect the custom claims.
163
+ reserved_claims = %w[aud exp iat iss jti nbf sub]
164
+ custom_claims = jwt.reject { |key, _| reserved_claims.include?(key) }
165
+ {
166
+ 'scopes' => jwt['scope'].split(' '),
167
+ 'client_id' => jwt['sub'],
168
+ 'custom_claims' => custom_claims
169
+ }
170
+ end
171
+ # ENDMANUAL(M2M::authenticate_token)
172
+
173
+ class Clients
174
+ include Stytch::RequestHelper
175
+ attr_reader :secrets
176
+
177
+ def initialize(connection)
178
+ @connection = connection
179
+
180
+ @secrets = Stytch::M2M::Clients::Secrets.new(@connection)
181
+ end
182
+
183
+ # Gets information about an existing M2M Client.
184
+ #
185
+ # == Parameters:
186
+ # client_id::
187
+ # The ID of the client.
188
+ # The type of this field is +String+.
189
+ #
190
+ # == Returns:
191
+ # An object with the following fields:
192
+ # request_id::
193
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
194
+ # The type of this field is +String+.
195
+ # status_code::
196
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
197
+ # The type of this field is +Integer+.
198
+ # m2m_client::
199
+ # The M2M Client affected by this operation.
200
+ # The type of this field is nilable +M2MClient+ (+object+).
201
+ def get(
202
+ client_id:
203
+ )
204
+ query_params = {}
205
+ request = request_with_query_params("/v1/m2m/clients/#{client_id}", query_params)
206
+ get_request(request)
207
+ end
208
+
209
+ # Search for M2M Clients within your Stytch Project. Submit an empty `query` in the request to return all M2M Clients.
210
+ #
211
+ # The following search filters are supported today:
212
+ # - `client_id`: Pass in a list of client IDs to get many clients in a single request
213
+ # - `client_name`: Search for clients by exact match on client name
214
+ # - `scopes`: Search for clients assigned a specific scope
215
+ #
216
+ # == Parameters:
217
+ # cursor::
218
+ # The `cursor` field allows you to paginate through your results. Each result array is limited to 1000 results. If your query returns more than 1000 results, you will need to paginate the responses using the `cursor`. If you receive a response that includes a non-null `next_cursor` in the `results_metadata` object, repeat the search call with the `next_cursor` value set to the `cursor` field to retrieve the next page of results. Continue to make search calls until the `next_cursor` in the response is null.
219
+ # The type of this field is nilable +String+.
220
+ # limit::
221
+ # The number of search results to return per page. The default limit is 100. A maximum of 1000 results can be returned by a single search request. If the total size of your result set is greater than one page size, you must paginate the response. See the `cursor` field.
222
+ # The type of this field is nilable +Integer+.
223
+ # query::
224
+ # The optional query object contains the operator, i.e. `AND` or `OR`, and the operands that will filter your results. Only an operator is required. If you include no operands, no filtering will be applied. If you include no query object, it will return all results with no filtering applied.
225
+ # The type of this field is nilable +M2MSearchQuery+ (+object+).
226
+ #
227
+ # == Returns:
228
+ # An object with the following fields:
229
+ # request_id::
230
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
231
+ # The type of this field is +String+.
232
+ # m2m_clients::
233
+ # An array of M2M Clients that match your search query.
234
+ # The type of this field is list of +M2MClient+ (+object+).
235
+ # results_metadata::
236
+ # The search `results_metadata` object contains metadata relevant to your specific query like total and `next_cursor`.
237
+ # The type of this field is +ResultsMetadata+ (+object+).
238
+ # status_code::
239
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
240
+ # The type of this field is +Integer+.
241
+ def search(
242
+ cursor: nil,
243
+ limit: nil,
244
+ query: nil
245
+ )
246
+ request = {}
247
+ request[:cursor] = cursor unless cursor.nil?
248
+ request[:limit] = limit unless limit.nil?
249
+ request[:query] = query unless query.nil?
250
+
251
+ post_request('/v1/m2m/clients/search', request)
252
+ end
253
+
254
+ # Updates an existing M2M Client. You can use this endpoint to activate or deactivate a M2M Client by changing its `status`. A deactivated M2M Client will not be allowed to perform future token exchange flows until it is reactivated.
255
+ #
256
+ # **Important:** Deactivating a M2M Client will not invalidate any existing JWTs issued to the client, only prevent it from receiving new ones.
257
+ # To protect more-sensitive routes, pass a lower `max_token_age` value when[authenticating the token](https://stytch.com/docs/b2b/api/authenticate-m2m-token)[authenticating the token](https://stytch.com/docs/api/authenticate-m2m-token).
258
+ #
259
+ # == Parameters:
260
+ # client_id::
261
+ # The ID of the client.
262
+ # The type of this field is +String+.
263
+ # client_name::
264
+ # A human-readable name for the client.
265
+ # The type of this field is nilable +String+.
266
+ # client_description::
267
+ # A human-readable description for the client.
268
+ # The type of this field is nilable +String+.
269
+ # status::
270
+ # The status of the client - either `active` or `inactive`.
271
+ # The type of this field is nilable +UpdateRequestStatus+ (string enum).
272
+ # scopes::
273
+ # An array of scopes assigned to the client.
274
+ # The type of this field is nilable list of +String+.
275
+ # trusted_metadata::
276
+ # The `trusted_metadata` field contains an arbitrary JSON object of application-specific data. See the [Metadata](https://stytch.com/docs/api/metadata) reference for complete field behavior details.
277
+ # The type of this field is nilable +object+.
278
+ #
279
+ # == Returns:
280
+ # An object with the following fields:
281
+ # request_id::
282
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
283
+ # The type of this field is +String+.
284
+ # status_code::
285
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
286
+ # The type of this field is +Integer+.
287
+ # m2m_client::
288
+ # The M2M Client affected by this operation.
289
+ # The type of this field is nilable +M2MClient+ (+object+).
290
+ def update(
291
+ client_id:,
292
+ client_name: nil,
293
+ client_description: nil,
294
+ status: nil,
295
+ scopes: nil,
296
+ trusted_metadata: nil
297
+ )
298
+ request = {}
299
+ request[:client_name] = client_name unless client_name.nil?
300
+ request[:client_description] = client_description unless client_description.nil?
301
+ request[:status] = status unless status.nil?
302
+ request[:scopes] = scopes unless scopes.nil?
303
+ request[:trusted_metadata] = trusted_metadata unless trusted_metadata.nil?
304
+
305
+ put_request("/v1/m2m/clients/#{client_id}", request)
306
+ end
307
+
308
+ # Deletes the M2M Client.
309
+ #
310
+ # **Important:** Deleting a M2M Client will not invalidate any existing JWTs issued to the client, only prevent it from receiving new ones.
311
+ # To protect more-sensitive routes, pass a lower `max_token_age` value when[authenticating the token](https://stytch.com/docs/b2b/api/authenticate-m2m-token)[authenticating the token](https://stytch.com/docs/api/authenticate-m2m-token).
312
+ #
313
+ # == Parameters:
314
+ # client_id::
315
+ # The ID of the client.
316
+ # The type of this field is +String+.
317
+ #
318
+ # == Returns:
319
+ # An object with the following fields:
320
+ # request_id::
321
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
322
+ # The type of this field is +String+.
323
+ # client_id::
324
+ # The ID of the client.
325
+ # The type of this field is +String+.
326
+ # status_code::
327
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
328
+ # The type of this field is +Integer+.
329
+ def delete(
330
+ client_id:
331
+ )
332
+ delete_request("/v1/m2m/clients/#{client_id}")
333
+ end
334
+
335
+ # Creates a new M2M Client. On initial client creation, you may pass in a custom `client_id` or `client_secret` to import an existing M2M client. If you do not pass in a custom `client_id` or `client_secret`, one will be generated automatically. The `client_id` must be unique among all clients in your project.
336
+ #
337
+ # **Important:** This is the only time you will be able to view the generated `client_secret` in the API response. Stytch stores a hash of the `client_secret` and cannot recover the value if lost. Be sure to persist the `client_secret` in a secure location. If the `client_secret` is lost, you will need to trigger a secret rotation flow to receive another one.
338
+ #
339
+ # == Parameters:
340
+ # scopes::
341
+ # An array of scopes assigned to the client.
342
+ # The type of this field is list of +String+.
343
+ # client_id::
344
+ # If provided, the ID of the client to create. If not provided, Stytch will generate this value for you. The `client_id` must be unique within your project.
345
+ # The type of this field is nilable +String+.
346
+ # client_secret::
347
+ # If provided, the stored secret of the client to create. If not provided, Stytch will generate this value for you. If provided, the `client_secret` must be at least 8 characters long and pass entropy requirements.
348
+ # The type of this field is nilable +String+.
349
+ # client_name::
350
+ # A human-readable name for the client.
351
+ # The type of this field is nilable +String+.
352
+ # client_description::
353
+ # A human-readable description for the client.
354
+ # The type of this field is nilable +String+.
355
+ # trusted_metadata::
356
+ # The `trusted_metadata` field contains an arbitrary JSON object of application-specific data. See the [Metadata](https://stytch.com/docs/api/metadata) reference for complete field behavior details.
357
+ # The type of this field is nilable +object+.
358
+ #
359
+ # == Returns:
360
+ # An object with the following fields:
361
+ # request_id::
362
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
363
+ # The type of this field is +String+.
364
+ # status_code::
365
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
366
+ # The type of this field is +Integer+.
367
+ # m2m_client::
368
+ # The M2M Client created by this API call.
369
+ # The type of this field is nilable +M2MClientWithClientSecret+ (+object+).
370
+ def create(
371
+ scopes:,
372
+ client_id: nil,
373
+ client_secret: nil,
374
+ client_name: nil,
375
+ client_description: nil,
376
+ trusted_metadata: nil
377
+ )
378
+ request = {
379
+ scopes: scopes
380
+ }
381
+ request[:client_id] = client_id unless client_id.nil?
382
+ request[:client_secret] = client_secret unless client_secret.nil?
383
+ request[:client_name] = client_name unless client_name.nil?
384
+ request[:client_description] = client_description unless client_description.nil?
385
+ request[:trusted_metadata] = trusted_metadata unless trusted_metadata.nil?
386
+
387
+ post_request('/v1/m2m/clients', request)
388
+ end
389
+
390
+ class Secrets
391
+ include Stytch::RequestHelper
392
+
393
+ def initialize(connection)
394
+ @connection = connection
395
+ end
396
+
397
+ # Initiate the rotation of an M2M client secret. After this endpoint is called, both the client's `client_secret` and `next_client_secret` will be valid. To complete the secret rotation flow, update all usages of `client_secret` to `next_client_secret` and call the[Rotate Secret Endpoint](https://stytch.com/docs/b2b/api/m2m-rotate-secret)[Rotate Secret Endpoint](https://stytch.com/docs/api/m2m-rotate-secret) to complete the flow.
398
+ # Secret rotation can be cancelled using the[Rotate Cancel Endpoint](https://stytch.com/docs/b2b/api/m2m-rotate-secret-cancel)[Rotate Cancel Endpoint](https://stytch.com/docs/api/m2m-rotate-secret-cancel).
399
+ #
400
+ # **Important:** This is the only time you will be able to view the generated `next_client_secret` in the API response. Stytch stores a hash of the `next_client_secret` and cannot recover the value if lost. Be sure to persist the `next_client_secret` in a secure location. If the `next_client_secret` is lost, you will need to trigger a secret rotation flow to receive another one.
401
+ #
402
+ # == Parameters:
403
+ # client_id::
404
+ # The ID of the client.
405
+ # The type of this field is +String+.
406
+ #
407
+ # == Returns:
408
+ # An object with the following fields:
409
+ # request_id::
410
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
411
+ # The type of this field is +String+.
412
+ # status_code::
413
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
414
+ # The type of this field is +Integer+.
415
+ # m2m_client::
416
+ # The M2M Client affected by this operation.
417
+ # The type of this field is nilable +M2MClientWithNextClientSecret+ (+object+).
418
+ def rotate_start(
419
+ client_id:
420
+ )
421
+ request = {}
422
+
423
+ post_request("/v1/m2m/clients/#{client_id}/secrets/rotate/start", request)
424
+ end
425
+
426
+ # Cancel the rotation of an M2M client secret started with the[Start Secret Rotation Endpoint](https://stytch.com/docs/b2b/api/m2m-rotate-secret-start)[Start Secret Rotation Endpoint](https://stytch.com/docs/api/m2m-rotate-secret-start).
427
+ # After this endpoint is called, the client's `next_client_secret` is discarded and only the original `client_secret` will be valid.
428
+ #
429
+ # == Parameters:
430
+ # client_id::
431
+ # The ID of the client.
432
+ # The type of this field is +String+.
433
+ #
434
+ # == Returns:
435
+ # An object with the following fields:
436
+ # request_id::
437
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
438
+ # The type of this field is +String+.
439
+ # status_code::
440
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
441
+ # The type of this field is +Integer+.
442
+ # m2m_client::
443
+ # The M2M Client affected by this operation.
444
+ # The type of this field is nilable +M2MClient+ (+object+).
445
+ def rotate_cancel(
446
+ client_id:
447
+ )
448
+ request = {}
449
+
450
+ post_request("/v1/m2m/clients/#{client_id}/secrets/rotate/cancel", request)
451
+ end
452
+
453
+ # Complete the rotation of an M2M client secret started with the[Start Secret Rotation Endpoint](https://stytch.com/docs/b2b/api/m2m-rotate-secret-start)[Start Secret Rotation Endpoint](https://stytch.com/docs/api/m2m-rotate-secret-start).
454
+ # After this endpoint is called, the client's `next_client_secret` becomes its `client_secret` and the previous `client_secret` will no longer be valid.
455
+ #
456
+ # == Parameters:
457
+ # client_id::
458
+ # The ID of the client.
459
+ # The type of this field is +String+.
460
+ #
461
+ # == Returns:
462
+ # An object with the following fields:
463
+ # request_id::
464
+ # Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
465
+ # The type of this field is +String+.
466
+ # status_code::
467
+ # The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
468
+ # The type of this field is +Integer+.
469
+ # m2m_client::
470
+ # The M2M Client affected by this operation.
471
+ # The type of this field is nilable +M2MClient+ (+object+).
472
+ def rotate(
473
+ client_id:
474
+ )
475
+ request = {}
476
+
477
+ post_request("/v1/m2m/clients/#{client_id}/secrets/rotate", request)
478
+ end
479
+ end
480
+ end
481
+ end
482
+ end