kinde_sdk 1.5.0 → 1.6.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/kinde_api/spec/spec_helper.rb +1 -0
- data/lib/kinde_sdk/client.rb +1 -1
- data/lib/kinde_sdk/engine.rb +5 -0
- data/lib/kinde_sdk/version.rb +1 -1
- data/lib/kinde_sdk.rb +5 -1
- data/spec/spec_helper.rb +3 -0
- metadata +35 -21
- data/lib/kinde_sdk/controllers/auth_controller.rb +0 -152
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83f3ec0e5e4b6f61d409b0a6c6314459917c94fa6109440fda5634e7d2e747f6
|
4
|
+
data.tar.gz: 35dd34872266b28076bf0a9a89f5bb624d6a314d4067fc359a49f901403ef7a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58130b81b2d67b3c2ef8c4f34b6d87157016270b08af9d19d77bb67cfae9b27b32937bbd8b90891f0590b9ad7a7d4cdb0443cf4a2281983567c1960415f60bb8
|
7
|
+
data.tar.gz: fa2f18f0219dbe76661f9a6809deeb0a1e5fcfde13ea300533d3be8c342c97902143392e1c9991e3b94ad5bfda319eefb042f21de27405e091d7b6fbb2d34c75
|
data/lib/kinde_sdk/client.rb
CHANGED
data/lib/kinde_sdk/version.rb
CHANGED
data/lib/kinde_sdk.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "logger"
|
2
|
+
require "rails"
|
2
3
|
require "kinde_sdk/version"
|
3
4
|
require "kinde_sdk/configuration"
|
4
5
|
require "kinde_sdk/client/feature_flags"
|
5
6
|
require "kinde_sdk/client/permissions"
|
6
|
-
require "kinde_sdk/controllers/auth_controller"
|
7
7
|
require "kinde_sdk/client"
|
8
8
|
require 'securerandom'
|
9
9
|
require 'oauth2'
|
@@ -19,6 +19,10 @@ module KindeSdk
|
|
19
19
|
class << self
|
20
20
|
attr_accessor :config
|
21
21
|
|
22
|
+
if defined?(Rails)
|
23
|
+
require "kinde_sdk/engine"
|
24
|
+
end
|
25
|
+
|
22
26
|
def configure
|
23
27
|
if block_given?
|
24
28
|
yield(Configuration.default)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kinde_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kinde Australia Pty Ltd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|
@@ -45,61 +45,75 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '2.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: pkce_challenge
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0
|
53
|
+
version: '0'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0
|
60
|
+
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
62
|
+
name: faraday-follow_redirects
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '0'
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
76
|
+
name: rails
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
81
|
+
version: 7.0.4
|
82
82
|
type: :runtime
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version:
|
88
|
+
version: 7.0.4
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
90
|
+
name: httparty
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
95
|
+
version: 0.19.0
|
96
96
|
type: :runtime
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: 0.19.0
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: jwt
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '2.2'
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '2.2'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: rspec
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -450,7 +464,7 @@ files:
|
|
450
464
|
- lib/kinde_sdk/client/feature_flags.rb
|
451
465
|
- lib/kinde_sdk/client/permissions.rb
|
452
466
|
- lib/kinde_sdk/configuration.rb
|
453
|
-
- lib/kinde_sdk/
|
467
|
+
- lib/kinde_sdk/engine.rb
|
454
468
|
- lib/kinde_sdk/version.rb
|
455
469
|
- spec/kinde_sdk_spec.rb
|
456
470
|
- spec/spec_helper.rb
|
@@ -1,152 +0,0 @@
|
|
1
|
-
require 'action_controller'
|
2
|
-
require 'uri'
|
3
|
-
require 'cgi'
|
4
|
-
require 'net/http'
|
5
|
-
require 'json'
|
6
|
-
require 'jwt'
|
7
|
-
|
8
|
-
module KindeSdk
|
9
|
-
class AuthController < ActionController::Base
|
10
|
-
# Add before_action to validate nonce in callback
|
11
|
-
before_action :validate_state, only: :callback
|
12
|
-
|
13
|
-
def auth
|
14
|
-
# Generate a secure random nonce
|
15
|
-
nonce = SecureRandom.urlsafe_base64(16)
|
16
|
-
|
17
|
-
# Call KindeSdk.auth_url with nonce
|
18
|
-
auth_data = KindeSdk.auth_url(nonce: nonce)
|
19
|
-
|
20
|
-
# Store in session
|
21
|
-
session[:code_verifier] = auth_data[:code_verifier] if auth_data[:code_verifier].present?
|
22
|
-
session[:auth_nonce] = nonce
|
23
|
-
session[:auth_state] = {
|
24
|
-
requested_at: Time.current.to_i,
|
25
|
-
redirect_url: auth_data[:url]
|
26
|
-
}
|
27
|
-
|
28
|
-
redirect_to auth_data[:url], allow_other_host: true
|
29
|
-
end
|
30
|
-
|
31
|
-
def callback
|
32
|
-
tokens = KindeSdk.fetch_tokens(
|
33
|
-
params[:code],
|
34
|
-
code_verifier: KindeSdk.config.pkce_enabled ? session[:code_verifier] : nil
|
35
|
-
).slice(:access_token, :id_token, :refresh_token, :expires_at)
|
36
|
-
|
37
|
-
|
38
|
-
# Validate nonce in ID token
|
39
|
-
id_token = tokens[:id_token]
|
40
|
-
issuer = KindeSdk.config.domain
|
41
|
-
client_id = KindeSdk.config.client_id
|
42
|
-
original_nonce = session[:auth_nonce]
|
43
|
-
unless validate_nonce(id_token, original_nonce, issuer, client_id)
|
44
|
-
Rails.logger.warn("Nonce validation failed")
|
45
|
-
redirect_to "/", alert: "Invalid authentication nonce"
|
46
|
-
return
|
47
|
-
end
|
48
|
-
|
49
|
-
# Store tokens and user in session
|
50
|
-
session[:kinde_auth] = OAuth2::AccessToken.from_hash(KindeSdk.config.oauth_client, tokens).to_hash
|
51
|
-
.slice(:access_token, :refresh_token, :expires_at)
|
52
|
-
session[:kinde_user] = KindeSdk.client(tokens).oauth.get_user.to_hash
|
53
|
-
|
54
|
-
# Clear nonce and state after successful authentication
|
55
|
-
session.delete(:auth_nonce)
|
56
|
-
session.delete(:auth_state)
|
57
|
-
session.delete(:code_verifier)
|
58
|
-
redirect_to "/"
|
59
|
-
rescue StandardError => e
|
60
|
-
Rails.logger.error("Authentication callback failed: #{e.message}")
|
61
|
-
redirect_to "/", alert: "Authentication failed"
|
62
|
-
end
|
63
|
-
|
64
|
-
def client_credentials_auth
|
65
|
-
result = KindeSdk.client_credentials_access(
|
66
|
-
client_id: ENV["KINDE_MANAGEMENT_CLIENT_ID"],
|
67
|
-
client_secret: ENV["KINDE_MANAGEMENT_CLIENT_SECRET"]
|
68
|
-
)
|
69
|
-
|
70
|
-
if result["error"].present?
|
71
|
-
Rails.logger.error("Client credentials auth failed: #{result['error']}")
|
72
|
-
raise result["error"]
|
73
|
-
end
|
74
|
-
|
75
|
-
$redis.set("kinde_m2m_token", result["access_token"], ex: result["expires_in"].to_i)
|
76
|
-
redirect_to mgmt_path
|
77
|
-
end
|
78
|
-
|
79
|
-
def logout
|
80
|
-
redirect_to KindeSdk.logout_url, allow_other_host: true
|
81
|
-
end
|
82
|
-
|
83
|
-
def logout_callback
|
84
|
-
reset_session
|
85
|
-
redirect_to "/"
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def validate_state
|
91
|
-
# Check if nonce and state exist in session
|
92
|
-
unless session[:auth_nonce] && session[:auth_state]
|
93
|
-
Rails.logger.warn("Missing session state or nonce [#{session[:auth_nonce]}] [#{session[:auth_state]}]")
|
94
|
-
redirect_to "/", alert: "Invalid authentication state"
|
95
|
-
return
|
96
|
-
end
|
97
|
-
|
98
|
-
# Verify nonce returned matches stored nonce
|
99
|
-
returned_state = params[:state]
|
100
|
-
stored_state = session[:auth_state]
|
101
|
-
stored_url = stored_state["redirect_url"]
|
102
|
-
|
103
|
-
# Extract the state from the stored redirect_url
|
104
|
-
parsed_url = URI.parse(stored_url)
|
105
|
-
query_params = CGI.parse(parsed_url.query || "")
|
106
|
-
stored_state_from_url = query_params["state"]&.first
|
107
|
-
|
108
|
-
# Verify returned state matches the state extracted from the redirect_url
|
109
|
-
unless returned_state.present? && returned_state == stored_state_from_url
|
110
|
-
Rails.logger.warn("State validation failed: returned=#{returned_state}, expected=#{stored_state_from_url}")
|
111
|
-
redirect_to "/", alert: "Invalid authentication state"
|
112
|
-
return
|
113
|
-
end
|
114
|
-
|
115
|
-
# Optional: Check state age (e.g., expires after 15 minutes)
|
116
|
-
if Time.current.to_i - stored_state["requested_at"] > 900
|
117
|
-
Rails.logger.warn("Authentication state expired")
|
118
|
-
redirect_to "/", alert: "Authentication session expired"
|
119
|
-
return
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
|
124
|
-
def validate_nonce(id_token, original_nonce, issuer, client_id)
|
125
|
-
jwks_uri = URI.parse("#{issuer}/.well-known/jwks.json")
|
126
|
-
jwks_response = Net::HTTP.get(jwks_uri)
|
127
|
-
jwks = JSON.parse(jwks_response)
|
128
|
-
|
129
|
-
decoded_token = JWT.decode(
|
130
|
-
id_token,
|
131
|
-
nil,
|
132
|
-
true,
|
133
|
-
algorithm: 'RS256',
|
134
|
-
iss: issuer,
|
135
|
-
aud: client_id,
|
136
|
-
verify_iss: true,
|
137
|
-
verify_aud: true,
|
138
|
-
jwks: { keys: jwks['keys'] }
|
139
|
-
)
|
140
|
-
|
141
|
-
payload = decoded_token[0]
|
142
|
-
nonce_from_token = payload['nonce']
|
143
|
-
|
144
|
-
nonce_from_token == original_nonce
|
145
|
-
rescue StandardError => e
|
146
|
-
Rails.logger.error("Nonce validation error: #{e.message}")
|
147
|
-
false
|
148
|
-
end
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
end
|