stytch 10.36.0 → 10.37.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 +4 -4
- data/lib/stytch/b2b_client.rb +7 -4
- data/lib/stytch/b2b_idp.rb +3 -14
- data/lib/stytch/b2b_sessions.rb +3 -14
- data/lib/stytch/client.rb +7 -4
- data/lib/stytch/idp.rb +3 -14
- data/lib/stytch/jwks_cache.rb +52 -0
- data/lib/stytch/m2m.rb +3 -14
- data/lib/stytch/sessions.rb +3 -14
- data/lib/stytch/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2636f56ed7d78577fb1ff81133a92fc1c0fb2500696f7921dcff85d6e79d7995
|
4
|
+
data.tar.gz: 932c0aa9dcef45bfb75a82516508bceac612f89a4b4a55e1555103017f80ba55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 988ed498a5b30318230b13dd477125149ce76ca35bedab317843ce4b77f9ed0857d375f165e0268eb5d0877ae9ddda12f2fca221f2d82d95d14bb7dcf9f7e8e8
|
7
|
+
data.tar.gz: fa274f938a19f3f8241288467d7724e1a63a5c43695fdce8ea7626ce38e005ce76b71a7af799028356660728f8510abfb41d46ec31d3f999049adeea9354b852
|
data/lib/stytch/b2b_client.rb
CHANGED
@@ -23,6 +23,7 @@ require_relative 'b2b_totps'
|
|
23
23
|
require_relative 'connected_apps'
|
24
24
|
require_relative 'debug'
|
25
25
|
require_relative 'fraud'
|
26
|
+
require_relative 'jwks_cache'
|
26
27
|
require_relative 'm2m'
|
27
28
|
require_relative 'project'
|
28
29
|
require_relative 'rbac_local'
|
@@ -33,7 +34,7 @@ module StytchB2B
|
|
33
34
|
|
34
35
|
attr_reader :connected_app, :debug, :discovery, :fraud, :idp, :impersonation, :m2m, :magic_links, :oauth, :otps, :organizations, :passwords, :project, :rbac, :recovery_codes, :scim, :sso, :sessions, :totps
|
35
36
|
|
36
|
-
def initialize(project_id:, secret:, env: nil, fraud_env: nil, timeout: nil, &block)
|
37
|
+
def initialize(project_id:, secret:, env: nil, fraud_env: nil, timeout: nil, jwks: nil, &block)
|
37
38
|
@api_host = api_host(env, project_id)
|
38
39
|
@fraud_api_host = fraud_api_host(fraud_env)
|
39
40
|
@project_id = project_id
|
@@ -43,6 +44,8 @@ module StytchB2B
|
|
43
44
|
|
44
45
|
create_connection(&block)
|
45
46
|
|
47
|
+
@jwks_cache = Stytch::JWKSCache.new(@connection, @project_id, jwks)
|
48
|
+
|
46
49
|
rbac = StytchB2B::RBAC.new(@connection)
|
47
50
|
@policy_cache = Stytch::PolicyCache.new(rbac_client: rbac)
|
48
51
|
|
@@ -50,9 +53,9 @@ module StytchB2B
|
|
50
53
|
@debug = Stytch::Debug.new(@connection)
|
51
54
|
@discovery = StytchB2B::Discovery.new(@connection)
|
52
55
|
@fraud = Stytch::Fraud.new(@fraud_connection)
|
53
|
-
@idp = StytchB2B::IDP.new(@connection, @project_id, @policy_cache)
|
56
|
+
@idp = StytchB2B::IDP.new(@connection, @project_id, @jwks_cache, @policy_cache)
|
54
57
|
@impersonation = StytchB2B::Impersonation.new(@connection)
|
55
|
-
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client)
|
58
|
+
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client, @jwks_cache)
|
56
59
|
@magic_links = StytchB2B::MagicLinks.new(@connection)
|
57
60
|
@oauth = StytchB2B::OAuth.new(@connection)
|
58
61
|
@otps = StytchB2B::OTPs.new(@connection)
|
@@ -63,7 +66,7 @@ module StytchB2B
|
|
63
66
|
@recovery_codes = StytchB2B::RecoveryCodes.new(@connection)
|
64
67
|
@scim = StytchB2B::SCIM.new(@connection)
|
65
68
|
@sso = StytchB2B::SSO.new(@connection)
|
66
|
-
@sessions = StytchB2B::Sessions.new(@connection, @project_id, @policy_cache)
|
69
|
+
@sessions = StytchB2B::Sessions.new(@connection, @project_id, @jwks_cache, @policy_cache)
|
67
70
|
@totps = StytchB2B::TOTPs.new(@connection)
|
68
71
|
end
|
69
72
|
|
data/lib/stytch/b2b_idp.rb
CHANGED
@@ -16,24 +16,13 @@ module StytchB2B
|
|
16
16
|
include Stytch::RequestHelper
|
17
17
|
attr_reader :oauth
|
18
18
|
|
19
|
-
def initialize(connection, project_id, policy_cache)
|
19
|
+
def initialize(connection, project_id, jwks_cache, policy_cache)
|
20
20
|
@connection = connection
|
21
21
|
|
22
22
|
@oauth = StytchB2B::IDP::OAuth.new(@connection)
|
23
23
|
@policy_cache = policy_cache
|
24
24
|
@project_id = project_id
|
25
|
-
@
|
26
|
-
@jwks_loader = lambda do |options|
|
27
|
-
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
|
28
|
-
@cached_keys ||= begin
|
29
|
-
@cache_last_update = Time.now.to_i
|
30
|
-
keys = []
|
31
|
-
get_jwks(project_id: @project_id)['keys'].each do |r|
|
32
|
-
keys << r
|
33
|
-
end
|
34
|
-
{ keys: keys }
|
35
|
-
end
|
36
|
-
end
|
25
|
+
@jwks_cache = jwks_cache
|
37
26
|
end
|
38
27
|
|
39
28
|
# MANUAL(IDP::introspect_token_network)(SERVICE_METHOD)
|
@@ -199,7 +188,7 @@ module StytchB2B
|
|
199
188
|
true,
|
200
189
|
{
|
201
190
|
algorithms: ['RS256'],
|
202
|
-
jwks: @
|
191
|
+
jwks: @jwks_cache.loader,
|
203
192
|
iss: ["stytch.com/#{@project_id}", @connection.url_prefix],
|
204
193
|
aud: @project_id
|
205
194
|
}
|
data/lib/stytch/b2b_sessions.rb
CHANGED
@@ -34,23 +34,12 @@ module StytchB2B
|
|
34
34
|
|
35
35
|
include Stytch::RequestHelper
|
36
36
|
|
37
|
-
def initialize(connection, project_id, policy_cache)
|
37
|
+
def initialize(connection, project_id, jwks_cache, policy_cache)
|
38
38
|
@connection = connection
|
39
39
|
|
40
40
|
@policy_cache = policy_cache
|
41
41
|
@project_id = project_id
|
42
|
-
@
|
43
|
-
@jwks_loader = lambda do |options|
|
44
|
-
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
|
45
|
-
@cached_keys ||= begin
|
46
|
-
@cache_last_update = Time.now.to_i
|
47
|
-
keys = []
|
48
|
-
get_jwks(project_id: @project_id)['keys'].each do |r|
|
49
|
-
keys << r
|
50
|
-
end
|
51
|
-
{ keys: keys }
|
52
|
-
end
|
53
|
-
end
|
42
|
+
@jwks_cache = jwks_cache
|
54
43
|
end
|
55
44
|
|
56
45
|
# Retrieves all active Sessions for a Member.
|
@@ -706,7 +695,7 @@ module StytchB2B
|
|
706
695
|
|
707
696
|
begin
|
708
697
|
decoded_token = JWT.decode session_jwt, nil, true,
|
709
|
-
{ jwks: @
|
698
|
+
{ jwks: @jwks_cache.loader, iss: valid_issuers, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
710
699
|
|
711
700
|
session = decoded_token[0]
|
712
701
|
iat_time = Time.at(session['iat']).to_datetime
|
data/lib/stytch/client.rb
CHANGED
@@ -12,6 +12,7 @@ require_relative 'debug'
|
|
12
12
|
require_relative 'fraud'
|
13
13
|
require_relative 'idp'
|
14
14
|
require_relative 'impersonation'
|
15
|
+
require_relative 'jwks_cache'
|
15
16
|
require_relative 'm2m'
|
16
17
|
require_relative 'magic_links'
|
17
18
|
require_relative 'oauth'
|
@@ -31,7 +32,7 @@ module Stytch
|
|
31
32
|
|
32
33
|
attr_reader :connected_app, :crypto_wallets, :debug, :fraud, :idp, :impersonation, :m2m, :magic_links, :oauth, :otps, :passwords, :project, :rbac, :sessions, :totps, :users, :webauthn
|
33
34
|
|
34
|
-
def initialize(project_id:, secret:, env: nil, fraud_env: nil, timeout: nil, &block)
|
35
|
+
def initialize(project_id:, secret:, env: nil, fraud_env: nil, timeout: nil, jwks: nil, &block)
|
35
36
|
@api_host = api_host(env, project_id)
|
36
37
|
@fraud_api_host = fraud_api_host(fraud_env)
|
37
38
|
@project_id = project_id
|
@@ -41,6 +42,8 @@ module Stytch
|
|
41
42
|
|
42
43
|
create_connection(&block)
|
43
44
|
|
45
|
+
@jwks_cache = Stytch::JWKSCache.new(@connection, @project_id, jwks)
|
46
|
+
|
44
47
|
rbac = Stytch::RBAC.new(@connection)
|
45
48
|
@policy_cache = Stytch::PolicyCache.new(rbac_client: rbac)
|
46
49
|
|
@@ -48,16 +51,16 @@ module Stytch
|
|
48
51
|
@crypto_wallets = Stytch::CryptoWallets.new(@connection)
|
49
52
|
@debug = Stytch::Debug.new(@connection)
|
50
53
|
@fraud = Stytch::Fraud.new(@fraud_connection)
|
51
|
-
@idp = Stytch::IDP.new(@connection, @project_id, @policy_cache)
|
54
|
+
@idp = Stytch::IDP.new(@connection, @project_id, @jwks_cache, @policy_cache)
|
52
55
|
@impersonation = Stytch::Impersonation.new(@connection)
|
53
|
-
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client)
|
56
|
+
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client, @jwks_cache)
|
54
57
|
@magic_links = Stytch::MagicLinks.new(@connection)
|
55
58
|
@oauth = Stytch::OAuth.new(@connection)
|
56
59
|
@otps = Stytch::OTPs.new(@connection)
|
57
60
|
@passwords = Stytch::Passwords.new(@connection)
|
58
61
|
@project = Stytch::Project.new(@connection)
|
59
62
|
@rbac = Stytch::RBAC.new(@connection)
|
60
|
-
@sessions = Stytch::Sessions.new(@connection, @project_id, @policy_cache)
|
63
|
+
@sessions = Stytch::Sessions.new(@connection, @project_id, @jwks_cache, @policy_cache)
|
61
64
|
@totps = Stytch::TOTPs.new(@connection)
|
62
65
|
@users = Stytch::Users.new(@connection)
|
63
66
|
@webauthn = Stytch::WebAuthn.new(@connection)
|
data/lib/stytch/idp.rb
CHANGED
@@ -16,24 +16,13 @@ module Stytch
|
|
16
16
|
include Stytch::RequestHelper
|
17
17
|
attr_reader :oauth
|
18
18
|
|
19
|
-
def initialize(connection, project_id, policy_cache)
|
19
|
+
def initialize(connection, project_id, jwks_cache, policy_cache)
|
20
20
|
@connection = connection
|
21
21
|
|
22
22
|
@oauth = Stytch::IDP::OAuth.new(@connection)
|
23
23
|
@policy_cache = policy_cache
|
24
24
|
@project_id = project_id
|
25
|
-
@
|
26
|
-
@jwks_loader = lambda do |options|
|
27
|
-
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
|
28
|
-
@cached_keys ||= begin
|
29
|
-
@cache_last_update = Time.now.to_i
|
30
|
-
keys = []
|
31
|
-
get_jwks(project_id: @project_id)['keys'].each do |r|
|
32
|
-
keys << r
|
33
|
-
end
|
34
|
-
{ keys: keys }
|
35
|
-
end
|
36
|
-
end
|
25
|
+
@jwks_cache = jwks_cache
|
37
26
|
end
|
38
27
|
|
39
28
|
# MANUAL(IDP::introspect_token_network)(SERVICE_METHOD)
|
@@ -188,7 +177,7 @@ module Stytch
|
|
188
177
|
true,
|
189
178
|
{
|
190
179
|
algorithms: ['RS256'],
|
191
|
-
jwks: @
|
180
|
+
jwks: @jwks_cache.loader,
|
192
181
|
iss: ["stytch.com/#{@project_id}", @connection.url_prefix],
|
193
182
|
aud: @project_id
|
194
183
|
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'request_helper'
|
4
|
+
|
5
|
+
module Stytch
|
6
|
+
# JWKSCache handles caching and refreshing of JSON Web Key Sets (JWKS)
|
7
|
+
# for JWT signature verification. It can be initialized with pre-cached
|
8
|
+
# keys or will fetch them on-demand from the Stytch API.
|
9
|
+
class JWKSCache
|
10
|
+
include Stytch::RequestHelper
|
11
|
+
|
12
|
+
CACHE_EXPIRY_SECONDS = 300 # 5 minutes
|
13
|
+
|
14
|
+
def initialize(connection, project_id, jwks = nil)
|
15
|
+
@connection = connection
|
16
|
+
@project_id = project_id
|
17
|
+
@cache_last_update = 0
|
18
|
+
|
19
|
+
# If jwks are provided during initialization, use them directly
|
20
|
+
return unless jwks
|
21
|
+
|
22
|
+
@cached_keys = { keys: jwks }
|
23
|
+
@cache_last_update = Time.now.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a lambda suitable for use with JWT.decode
|
27
|
+
def loader
|
28
|
+
lambda do |options|
|
29
|
+
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - CACHE_EXPIRY_SECONDS
|
30
|
+
@cached_keys ||= begin
|
31
|
+
@cache_last_update = Time.now.to_i
|
32
|
+
keys = []
|
33
|
+
get_jwks(project_id: @project_id)['keys'].each do |r|
|
34
|
+
keys << r
|
35
|
+
end
|
36
|
+
{ keys: keys }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fetches JWKS from the Stytch API
|
42
|
+
def get_jwks(project_id:)
|
43
|
+
request_with_query_params(
|
44
|
+
@connection,
|
45
|
+
'/v1/sessions/jwks/%<project_id>s',
|
46
|
+
{
|
47
|
+
project_id: project_id
|
48
|
+
}
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/stytch/m2m.rb
CHANGED
@@ -13,24 +13,13 @@ module Stytch
|
|
13
13
|
include Stytch::RequestHelper
|
14
14
|
attr_reader :clients
|
15
15
|
|
16
|
-
def initialize(connection, project_id, is_b2b_client)
|
16
|
+
def initialize(connection, project_id, is_b2b_client, jwks_cache)
|
17
17
|
@connection = connection
|
18
18
|
|
19
19
|
@clients = Stytch::M2M::Clients.new(@connection)
|
20
20
|
@project_id = project_id
|
21
|
-
@
|
21
|
+
@jwks_cache = jwks_cache
|
22
22
|
@is_b2b_client = is_b2b_client
|
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
23
|
end
|
35
24
|
|
36
25
|
# MANUAL(M2M::get_jwks)(SERVICE_METHOD)
|
@@ -190,7 +179,7 @@ module Stytch
|
|
190
179
|
|
191
180
|
begin
|
192
181
|
decoded_token = JWT.decode jwt, nil, true,
|
193
|
-
{ jwks: @
|
182
|
+
{ jwks: @jwks_cache.loader, iss: valid_issuers, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
194
183
|
decoded_token[0]
|
195
184
|
rescue JWT::InvalidIssuerError
|
196
185
|
raise JWTInvalidIssuerError
|
data/lib/stytch/sessions.rb
CHANGED
@@ -15,23 +15,12 @@ module Stytch
|
|
15
15
|
class Sessions
|
16
16
|
include Stytch::RequestHelper
|
17
17
|
|
18
|
-
def initialize(connection, project_id, policy_cache)
|
18
|
+
def initialize(connection, project_id, jwks_cache, policy_cache)
|
19
19
|
@connection = connection
|
20
20
|
|
21
21
|
@policy_cache = policy_cache
|
22
22
|
@project_id = project_id
|
23
|
-
@
|
24
|
-
@jwks_loader = lambda do |options|
|
25
|
-
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
|
26
|
-
@cached_keys ||= begin
|
27
|
-
@cache_last_update = Time.now.to_i
|
28
|
-
keys = []
|
29
|
-
get_jwks(project_id: @project_id)['keys'].each do |r|
|
30
|
-
keys << r
|
31
|
-
end
|
32
|
-
{ keys: keys }
|
33
|
-
end
|
34
|
-
end
|
23
|
+
@jwks_cache = jwks_cache
|
35
24
|
end
|
36
25
|
|
37
26
|
# List all active Sessions for a given `user_id`. All timestamps are formatted according to the RFC 3339 standard and are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
|
@@ -514,7 +503,7 @@ module Stytch
|
|
514
503
|
|
515
504
|
begin
|
516
505
|
decoded_token = JWT.decode session_jwt, nil, true,
|
517
|
-
{ jwks: @
|
506
|
+
{ jwks: @jwks_cache.loader, iss: valid_issuers, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
518
507
|
|
519
508
|
session = decoded_token[0]
|
520
509
|
iat_time = Time.at(session['iat']).to_datetime
|
data/lib/stytch/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stytch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.
|
4
|
+
version: 10.37.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stytch
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/stytch/fraud.rb
|
148
148
|
- lib/stytch/idp.rb
|
149
149
|
- lib/stytch/impersonation.rb
|
150
|
+
- lib/stytch/jwks_cache.rb
|
150
151
|
- lib/stytch/m2m.rb
|
151
152
|
- lib/stytch/magic_links.rb
|
152
153
|
- lib/stytch/method_options.rb
|