kinde_sdk 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +117 -25
- data/kinde_api/README.md +58 -23
- data/kinde_api/docs/AddOrganizationUsersRequest.md +1 -1
- data/kinde_api/docs/AddOrganizationUsersRequestUsersInner.md +22 -0
- data/kinde_api/docs/{AddOrganizationUsers200Response.md → AddOrganizationUsersResponse.md} +2 -2
- data/kinde_api/docs/Application.md +20 -0
- data/kinde_api/docs/CallbacksApi.md +219 -0
- data/kinde_api/docs/ConnectedAppsApi.md +9 -9
- data/kinde_api/docs/CreateOrganizationRequest.md +11 -1
- data/kinde_api/docs/CreateOrganizationResponse.md +22 -0
- data/kinde_api/docs/CreateOrganizationResponseOrganization.md +18 -0
- data/kinde_api/docs/CreateOrganizationUserRoleRequest.md +18 -0
- data/kinde_api/docs/CreatePermissionRequest.md +22 -0
- data/kinde_api/docs/CreateRoleRequest.md +24 -0
- data/kinde_api/docs/CreateSubscriberSuccessResponse.md +18 -0
- data/kinde_api/docs/CreateSubscriberSuccessResponseSubscriber.md +18 -0
- data/kinde_api/docs/{CreateUser200Response.md → CreateUserResponse.md} +2 -2
- data/kinde_api/docs/EnvironmentsApi.md +71 -4
- data/kinde_api/docs/FeatureFlagsApi.md +9 -11
- data/kinde_api/docs/GetApplicationsResponse.md +24 -0
- data/kinde_api/docs/GetEnvironmentFeatureFlagsResponse.md +24 -0
- data/kinde_api/docs/GetOrganizationFeatureFlagsResponse.md +22 -0
- data/kinde_api/docs/GetOrganizationFeatureFlagsResponseFeatureFlagsValue.md +20 -0
- data/kinde_api/docs/{GetOrganizations200Response.md → GetOrganizationsResponse.md} +2 -2
- data/kinde_api/docs/GetOrganizationsUserRolesResponse.md +24 -0
- data/kinde_api/docs/{GetOrganizationUsers200Response.md → GetOrganizationsUsersResponse.md} +2 -2
- data/kinde_api/docs/GetRedirectCallbackUrlsResponse.md +18 -0
- data/kinde_api/docs/OrganizationUser.md +3 -1
- data/kinde_api/docs/OrganizationUserRole.md +22 -0
- data/kinde_api/docs/OrganizationsApi.md +494 -59
- data/kinde_api/docs/Permissions.md +22 -0
- data/kinde_api/docs/PermissionsApi.md +229 -0
- data/kinde_api/docs/RedirectCallbackUrls.md +18 -0
- data/kinde_api/docs/Roles.md +22 -0
- data/kinde_api/docs/RolesApi.md +229 -0
- data/kinde_api/docs/SubscribersApi.md +229 -0
- data/kinde_api/docs/UpdateOrganizationRequest.md +28 -0
- data/kinde_api/docs/UpdateOrganizationUsersRequest.md +18 -0
- data/kinde_api/docs/UpdateOrganizationUsersRequestUsersInner.md +24 -0
- data/kinde_api/docs/UpdateOrganizationUsersResponse.md +24 -0
- data/kinde_api/docs/UpdateUserRequest.md +3 -1
- data/kinde_api/docs/User.md +15 -1
- data/kinde_api/docs/UserIdentityResult.md +1 -3
- data/kinde_api/docs/UserProfile.md +3 -1
- data/kinde_api/docs/UserProfileV2.md +6 -2
- data/kinde_api/docs/UsersApi.md +31 -259
- data/kinde_api/docs/{GetUsers200Response.md → UsersResponse.md} +2 -2
- data/kinde_api/lib/kinde_api/api/callbacks_api.rb +221 -0
- data/kinde_api/lib/kinde_api/api/connected_apps_api.rb +8 -8
- data/kinde_api/lib/kinde_api/api/environments_api.rb +61 -4
- data/kinde_api/lib/kinde_api/api/feature_flags_api.rb +8 -15
- data/kinde_api/lib/kinde_api/api/organizations_api.rb +492 -57
- data/kinde_api/lib/kinde_api/api/permissions_api.rb +226 -0
- data/kinde_api/lib/kinde_api/api/roles_api.rb +226 -0
- data/kinde_api/lib/kinde_api/api/subscribers_api.rb +228 -0
- data/kinde_api/lib/kinde_api/api/users_api.rb +30 -233
- data/kinde_api/lib/kinde_api/api_client.rb +1 -13
- data/kinde_api/lib/kinde_api/configuration.rb +3 -77
- data/kinde_api/lib/kinde_api/models/add_organization_users_request.rb +2 -2
- data/kinde_api/lib/kinde_api/models/add_organization_users_request_users_inner.rb +242 -0
- data/kinde_api/lib/kinde_api/models/{add_organization_users200_response.rb → add_organization_users_response.rb} +3 -3
- data/kinde_api/lib/kinde_api/models/application.rb +226 -0
- data/kinde_api/lib/kinde_api/models/create_organization_request.rb +54 -4
- data/kinde_api/lib/kinde_api/models/{remove_organization_users200_response.rb → create_organization_response.rb} +19 -12
- data/kinde_api/lib/kinde_api/models/{create_organization201_response.rb → create_organization_response_organization.rb} +8 -18
- data/kinde_api/lib/kinde_api/models/create_organization_user_role_request.rb +218 -0
- data/kinde_api/lib/kinde_api/models/create_permission_request.rb +238 -0
- data/kinde_api/lib/kinde_api/models/create_role_request.rb +248 -0
- data/kinde_api/lib/kinde_api/models/create_subscriber_success_response.rb +217 -0
- data/kinde_api/lib/kinde_api/models/create_subscriber_success_response_subscriber.rb +218 -0
- data/kinde_api/lib/kinde_api/models/create_user_request_identities_inner.rb +34 -0
- data/kinde_api/lib/kinde_api/models/{create_user200_response.rb → create_user_response.rb} +3 -3
- data/kinde_api/lib/kinde_api/models/get_applications_response.rb +249 -0
- data/kinde_api/lib/kinde_api/models/get_environment_feature_flags_response.rb +250 -0
- data/kinde_api/lib/kinde_api/models/get_organization_feature_flags_response.rb +240 -0
- data/kinde_api/lib/kinde_api/models/get_organization_feature_flags_response_feature_flags_value.rb +260 -0
- data/kinde_api/lib/kinde_api/models/{get_organizations200_response.rb → get_organizations_response.rb} +3 -3
- data/kinde_api/lib/kinde_api/models/get_organizations_user_roles_response.rb +249 -0
- data/kinde_api/lib/kinde_api/models/{get_organization_users200_response.rb → get_organizations_users_response.rb} +3 -3
- data/kinde_api/lib/kinde_api/models/get_redirect_callback_urls_response.rb +220 -0
- data/kinde_api/lib/kinde_api/models/organization_user.rb +15 -4
- data/kinde_api/lib/kinde_api/models/organization_user_role.rb +235 -0
- data/kinde_api/lib/kinde_api/models/permissions.rb +238 -0
- data/kinde_api/lib/kinde_api/models/redirect_callback_urls.rb +220 -0
- data/kinde_api/lib/kinde_api/models/roles.rb +238 -0
- data/kinde_api/lib/kinde_api/models/update_organization_request.rb +268 -0
- data/kinde_api/lib/kinde_api/models/{remove_organization_users_request.rb → update_organization_users_request.rb} +5 -5
- data/kinde_api/lib/kinde_api/models/update_organization_users_request_users_inner.rb +252 -0
- data/kinde_api/lib/kinde_api/models/update_organization_users_response.rb +250 -0
- data/kinde_api/lib/kinde_api/models/update_user_request.rb +14 -4
- data/kinde_api/lib/kinde_api/models/user.rb +79 -5
- data/kinde_api/lib/kinde_api/models/user_identity_result.rb +4 -14
- data/kinde_api/lib/kinde_api/models/user_profile.rb +14 -4
- data/kinde_api/lib/kinde_api/models/user_profile_v2.rb +25 -5
- data/kinde_api/lib/kinde_api/models/{get_users200_response.rb → users_response.rb} +3 -3
- data/kinde_api/lib/kinde_api.rb +32 -8
- data/kinde_api/spec/api/callbacks_api_spec.rb +73 -0
- data/kinde_api/spec/api/connected_apps_api_spec.rb +1 -1
- data/kinde_api/spec/api/environments_api_spec.rb +11 -0
- data/kinde_api/spec/api/feature_flags_api_spec.rb +1 -2
- data/kinde_api/spec/api/organizations_api_spec.rb +93 -14
- data/kinde_api/spec/api/permissions_api_spec.rb +74 -0
- data/kinde_api/spec/api/roles_api_spec.rb +74 -0
- data/kinde_api/spec/api/subscribers_api_spec.rb +76 -0
- data/kinde_api/spec/api/users_api_spec.rb +6 -47
- data/kinde_api/spec/api_client_spec.rb +0 -12
- data/kinde_api/spec/models/add_organization_users_request_users_inner_spec.rb +46 -0
- data/kinde_api/spec/models/{add_organization_users200_response_spec.rb → add_organization_users_response_spec.rb} +6 -6
- data/kinde_api/spec/models/{remove_organization_users200_response_spec.rb → application_spec.rb} +8 -8
- data/kinde_api/spec/models/create_organization_request_spec.rb +30 -0
- data/kinde_api/spec/models/create_organization_response_organization_spec.rb +34 -0
- data/kinde_api/spec/models/{create_organization201_response_spec.rb → create_organization_response_spec.rb} +13 -7
- data/kinde_api/spec/models/create_organization_user_role_request_spec.rb +34 -0
- data/kinde_api/spec/models/create_permission_request_spec.rb +46 -0
- data/kinde_api/spec/models/create_role_request_spec.rb +52 -0
- data/kinde_api/spec/models/create_subscriber_success_response_spec.rb +34 -0
- data/kinde_api/spec/models/create_subscriber_success_response_subscriber_spec.rb +34 -0
- data/kinde_api/spec/models/create_user_request_identities_inner_spec.rb +4 -0
- data/kinde_api/spec/models/{create_user200_response_spec.rb → create_user_response_spec.rb} +6 -6
- data/kinde_api/spec/models/get_applications_response_spec.rb +52 -0
- data/kinde_api/spec/models/get_environment_feature_flags_response_spec.rb +52 -0
- data/kinde_api/spec/models/get_organization_feature_flags_response_feature_flags_value_spec.rb +44 -0
- data/kinde_api/spec/models/get_organization_feature_flags_response_spec.rb +46 -0
- data/kinde_api/spec/models/{get_organizations200_response_spec.rb → get_organizations_response_spec.rb} +6 -6
- data/kinde_api/spec/models/get_organizations_user_roles_response_spec.rb +52 -0
- data/kinde_api/spec/models/{get_organization_users200_response_spec.rb → get_organizations_users_response_spec.rb} +6 -6
- data/kinde_api/spec/models/get_redirect_callback_urls_response_spec.rb +34 -0
- data/kinde_api/spec/models/organization_user_role_spec.rb +46 -0
- data/kinde_api/spec/models/organization_user_spec.rb +6 -0
- data/kinde_api/spec/models/permissions_spec.rb +46 -0
- data/kinde_api/spec/models/redirect_callback_urls_spec.rb +34 -0
- data/kinde_api/spec/models/roles_spec.rb +46 -0
- data/kinde_api/spec/models/update_organization_request_spec.rb +64 -0
- data/kinde_api/spec/models/{remove_organization_users_request_spec.rb → update_organization_users_request_spec.rb} +6 -6
- data/kinde_api/spec/models/update_organization_users_request_users_inner_spec.rb +52 -0
- data/kinde_api/spec/models/update_organization_users_response_spec.rb +52 -0
- data/kinde_api/spec/models/update_user_request_spec.rb +6 -0
- data/kinde_api/spec/models/user_identity_result_spec.rb +0 -6
- data/kinde_api/spec/models/user_profile_spec.rb +6 -0
- data/kinde_api/spec/models/user_profile_v2_spec.rb +12 -0
- data/kinde_api/spec/models/user_spec.rb +42 -0
- data/kinde_api/spec/models/{get_users200_response_spec.rb → users_response_spec.rb} +6 -6
- data/kinde_sdk.gemspec +1 -1
- data/lib/kinde_sdk/client/feature_flags.rb +64 -0
- data/lib/kinde_sdk/client/permissions.rb +20 -0
- data/lib/kinde_sdk/client.rb +32 -21
- data/lib/kinde_sdk/configuration.rb +0 -2
- data/lib/kinde_sdk/version.rb +1 -1
- data/lib/kinde_sdk.rb +31 -19
- data/spec/kinde_sdk_spec.rb +156 -14
- data/spec/spec_helper.rb +2 -0
- metadata +134 -36
- data/kinde_api/docs/CreateOrganization201Response.md +0 -20
- data/kinde_api/docs/RemoveOrganizationUsers200Response.md +0 -20
- data/kinde_api/docs/RemoveOrganizationUsersRequest.md +0 -18
data/lib/kinde_sdk/client.rb
CHANGED
@@ -2,46 +2,57 @@ require "kinde_api"
|
|
2
2
|
|
3
3
|
module KindeSdk
|
4
4
|
class Client
|
5
|
-
|
6
|
-
|
5
|
+
include FeatureFlags
|
6
|
+
include Permissions
|
7
7
|
|
8
|
-
|
8
|
+
attr_accessor :kinde_api_client, :bearer_token, :tokens_hash, :expires_at
|
9
|
+
|
10
|
+
def initialize(sdk_api_client, tokens_hash)
|
9
11
|
@kinde_api_client = sdk_api_client
|
10
|
-
|
11
|
-
@decoded_token = JWT.decode(bearer_token, nil, false)
|
12
|
+
set_hash_related_data(tokens_hash)
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
|
15
|
+
def token_expired?
|
16
|
+
expires_at.to_i > 0 && (expires_at <= Time.now.to_i)
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
-
|
19
|
+
def refresh_token
|
20
|
+
new_tokens_hash = KindeSdk.refresh_token(tokens_hash)
|
21
|
+
set_hash_related_data(new_tokens_hash)
|
22
|
+
@kinde_api_client = KindeSdk.api_client(tokens_hash["access_token"])
|
23
|
+
new_tokens_hash
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
# token_type is one of: :access_token, :id_token
|
27
|
+
#
|
28
|
+
# @return [Hash]
|
29
|
+
# @example {name: "scp", value: ["openid", "offline"]}
|
30
|
+
def get_claim(claim, token_type = :access_token)
|
31
|
+
token = tokens_hash[token_type]
|
32
|
+
return unless token
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
34
|
+
value = JWT.decode(token, nil, false)[0][claim]
|
35
|
+
return unless value
|
32
36
|
|
33
|
-
|
34
|
-
KindeSdk.logout(bearer_token, kinde_api_client)
|
37
|
+
{ name: claim, value: value }
|
35
38
|
end
|
36
39
|
|
37
40
|
::KindeApi.constants.filter { |klass| klass.to_s.end_with?("Api") }.each do |klass|
|
38
41
|
api_klass = Kernel.const_get("KindeApi::#{klass}")
|
39
42
|
|
40
|
-
define_method(klass.to_s.downcase.split("
|
43
|
+
define_method(klass.to_s.gsub(/([a-z\d])([A-Z])/) { "#{$1}_#{$2}" }.downcase.split("_api")[0]) do
|
44
|
+
init_instance_api(api_klass)
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
48
|
private
|
44
49
|
|
50
|
+
def set_hash_related_data(tokens_hash)
|
51
|
+
@tokens_hash = tokens_hash.transform_keys(&:to_sym)
|
52
|
+
@bearer_token = tokens_hash[:access_token]
|
53
|
+
@expires_at = tokens_hash[:expires_at]
|
54
|
+
end
|
55
|
+
|
45
56
|
def init_instance_api(api_klass)
|
46
57
|
api_klass.new(kinde_api_client)
|
47
58
|
end
|
@@ -14,7 +14,6 @@ module KindeSdk
|
|
14
14
|
attr_accessor :debugging
|
15
15
|
attr_accessor :oauth_client
|
16
16
|
attr_accessor :pkce_enabled
|
17
|
-
attr_accessor :business_name
|
18
17
|
|
19
18
|
def initialize
|
20
19
|
@authorize_url = '/oauth2/auth'
|
@@ -23,7 +22,6 @@ module KindeSdk
|
|
23
22
|
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
24
23
|
@scope = 'openid offline email profile'
|
25
24
|
@pkce_enabled = true
|
26
|
-
@business_name = nil
|
27
25
|
|
28
26
|
yield(self) if block_given?
|
29
27
|
end
|
data/lib/kinde_sdk/version.rb
CHANGED
data/lib/kinde_sdk.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require "kinde_sdk/version"
|
2
2
|
require "kinde_sdk/configuration"
|
3
|
+
require "kinde_sdk/client/feature_flags"
|
4
|
+
require "kinde_sdk/client/permissions"
|
3
5
|
require "kinde_sdk/client"
|
4
6
|
|
5
7
|
require 'securerandom'
|
6
8
|
require 'oauth2'
|
7
9
|
require 'pkce_challenge'
|
8
10
|
require 'faraday/follow_redirects'
|
11
|
+
require 'uri'
|
9
12
|
|
10
13
|
module KindeSdk
|
11
14
|
class << self
|
@@ -24,9 +27,9 @@ module KindeSdk
|
|
24
27
|
# receive url for authorization in Kinde itself
|
25
28
|
#
|
26
29
|
# @return [Hash]
|
27
|
-
def auth_url(**kwargs)
|
30
|
+
def auth_url(redirect_uri: @config.callback_url, **kwargs)
|
28
31
|
params = {
|
29
|
-
redirect_uri:
|
32
|
+
redirect_uri: redirect_uri,
|
30
33
|
state: SecureRandom.hex,
|
31
34
|
scope: @config.scope
|
32
35
|
}.merge(**kwargs)
|
@@ -43,26 +46,34 @@ module KindeSdk
|
|
43
46
|
# when callback processor receives code, it needs to be used for fetching bearer token
|
44
47
|
#
|
45
48
|
# @return [Hash]
|
46
|
-
def fetch_tokens(params_or_code, code_verifier
|
49
|
+
def fetch_tokens(params_or_code, code_verifier: nil, redirect_uri: @config.callback_url)
|
47
50
|
code = params_or_code.kind_of?(Hash) ? params.fetch("code") : params_or_code
|
48
|
-
params = {
|
51
|
+
params = {
|
52
|
+
redirect_uri: redirect_uri,
|
53
|
+
headers: { 'User-Agent' => "Kinde-SDK: Ruby/#{KindeSdk::VERSION}" }
|
54
|
+
}
|
49
55
|
params[:code_verifier] = code_verifier if code_verifier
|
50
56
|
@config.oauth_client.auth_code.get_token(code.to_s, params).to_hash
|
51
57
|
end
|
52
58
|
|
59
|
+
# tokens_hash #=>
|
60
|
+
# {"access_token"=>"eyJhbGciOiJSUzI1NiIsIm...",
|
61
|
+
# "expires_in"=>86399,
|
62
|
+
# "id_token"=>"eyJhbGciOiJSUz",
|
63
|
+
# "refresh_token"=>"eyJhbGciOiJSUz",
|
64
|
+
# "scope"=>"openid offline email profile",
|
65
|
+
# "token_type"=>"bearer"}
|
66
|
+
#
|
53
67
|
# @return [KindeSdk::Client]
|
54
|
-
def client(
|
55
|
-
sdk_api_client = api_client(
|
56
|
-
KindeSdk::Client.new(sdk_api_client,
|
68
|
+
def client(tokens_hash)
|
69
|
+
sdk_api_client = api_client(tokens_hash["access_token"])
|
70
|
+
KindeSdk::Client.new(sdk_api_client, tokens_hash)
|
57
71
|
end
|
58
72
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
query_params: { 'redirect' => @config.logout_url },
|
64
|
-
header_params: { 'Authorization' => "Bearer #{bearer_token}" }
|
65
|
-
)
|
73
|
+
def logout_url
|
74
|
+
query = @config.logout_url ? URI.encode_www_form(redirect: @config.logout_url) : nil
|
75
|
+
host = URI::parse(@config.domain).host
|
76
|
+
URI::HTTP.build(host: host, path: '/logout', query: query).to_s
|
66
77
|
end
|
67
78
|
|
68
79
|
def client_credentials_access(
|
@@ -97,10 +108,10 @@ module KindeSdk
|
|
97
108
|
config = KindeApi::Configuration.default
|
98
109
|
config.configure do |c|
|
99
110
|
c.access_token = bearer_token
|
100
|
-
c.server_variables = { businessName: business_name }
|
101
111
|
c.host = @config.domain
|
102
112
|
c.debugging = @config.debugging
|
103
113
|
c.logger = @config.logger
|
114
|
+
c.scheme = url_scheme(c.scheme)
|
104
115
|
end
|
105
116
|
|
106
117
|
KindeApi::ApiClient.new(config)
|
@@ -108,10 +119,11 @@ module KindeSdk
|
|
108
119
|
|
109
120
|
private
|
110
121
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
122
|
+
def url_scheme(default_scheme)
|
123
|
+
parsed_url = URI.parse(@config.domain.to_s)
|
124
|
+
parsed_url.scheme || default_scheme
|
125
|
+
rescue URI::InvalidURIError
|
126
|
+
default_scheme
|
115
127
|
end
|
116
128
|
end
|
117
129
|
end
|
data/spec/kinde_sdk_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe KindeSdk do
|
|
5
5
|
let(:client_id) { "client_id" }
|
6
6
|
let(:client_secret) { "client_secret" }
|
7
7
|
let(:callback_url) { "http://localhost:3000/callback" }
|
8
|
+
let(:logout_url) { "http://localhost/logout-callback" }
|
8
9
|
|
9
10
|
before do
|
10
11
|
KindeSdk.configure do |c|
|
@@ -12,6 +13,7 @@ describe KindeSdk do
|
|
12
13
|
c.client_id = client_id
|
13
14
|
c.client_secret = client_secret
|
14
15
|
c.callback_url = callback_url
|
16
|
+
c.logout_url = logout_url
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
@@ -20,12 +22,71 @@ describe KindeSdk do
|
|
20
22
|
auth_obj = described_class.auth_url
|
21
23
|
expect(auth_obj[:code_verifier]).not_to be_nil
|
22
24
|
expect(auth_obj[:url]).to start_with("#{domain}/oauth2/auth?client_id=#{client_id}&")
|
25
|
+
expect(auth_obj[:url]).to match(/localhost%3A3000%2Fcallback/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows override callback url" do
|
29
|
+
auth_obj = described_class.auth_url(redirect_uri: "localhost:5000/another_callback")
|
30
|
+
expect(auth_obj[:url]).to match(/localhost%3A5000%2Fanother_callback/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#logout_url" do
|
35
|
+
it "returns logout url" do
|
36
|
+
expect(described_class.logout_url)
|
37
|
+
.to eq("http://example.com/logout?redirect=http%3A%2F%2Flocalhost%2Flogout-callback")
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when logout url not set" do
|
41
|
+
let(:logout_url) { nil }
|
42
|
+
it "returns logout url without redirect query" do
|
43
|
+
expect(described_class.logout_url).to eq("http://example.com/logout")
|
44
|
+
end
|
23
45
|
end
|
24
46
|
end
|
25
47
|
|
26
48
|
describe "#api_client" do
|
27
49
|
it "returns initialized api_client instance of KindeApi" do
|
28
|
-
expect(described_class.api_client("bearer-token"))
|
50
|
+
expect(described_class.api_client({ "access_token": "bearer-token" }))
|
51
|
+
.to be_instance_of(KindeApi::ApiClient)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#fetch_tokens" do
|
56
|
+
let(:code) { "some-code" }
|
57
|
+
before do
|
58
|
+
stub_request(:post, "#{domain}/oauth2/token")
|
59
|
+
.with(
|
60
|
+
body: {
|
61
|
+
"code" => code,
|
62
|
+
"grant_type" => "authorization_code",
|
63
|
+
"redirect_uri" => callback_url
|
64
|
+
},
|
65
|
+
headers: {
|
66
|
+
'Accept' => '*/*',
|
67
|
+
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
|
68
|
+
'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=',
|
69
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
70
|
+
'User-Agent' => "Kinde-SDK: Ruby/#{KindeSdk::VERSION}"
|
71
|
+
}
|
72
|
+
)
|
73
|
+
.to_return(
|
74
|
+
status: 200,
|
75
|
+
body: { "access_token": "eyJ", "expires_in": 86399, "scope": "", "token_type": "bearer" }.to_json,
|
76
|
+
headers: { "content-type" => "application/json;charset=UTF-8" }
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "calls /token url with proper body and headers" do
|
81
|
+
expect(described_class.fetch_tokens(code).keys).to eq(%w[scope token_type access_token refresh_token expires_at])
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with redefined callback_url" do
|
85
|
+
let(:callback_url) { "another-callback" }
|
86
|
+
|
87
|
+
it "calls /token url with proper body and headers" do
|
88
|
+
expect(described_class.fetch_tokens(code).keys.size).to eq(5)
|
89
|
+
end
|
29
90
|
end
|
30
91
|
end
|
31
92
|
|
@@ -59,22 +120,89 @@ describe KindeSdk do
|
|
59
120
|
describe "client" do
|
60
121
|
let(:hash_to_encode) do
|
61
122
|
{ "aud" => [],
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
123
|
+
"azp" => "19ebb687cd2f405c9f2daf645a8db895",
|
124
|
+
"exp" => 1679600554,
|
125
|
+
"feature_flags" => {
|
126
|
+
"asd" => { "t" => "b", "v" => true },
|
127
|
+
"eeeeee" => { "t" => "i", "v" => 111 },
|
128
|
+
"qqq" => { "t" => "s", "v" => "aa" }
|
129
|
+
},
|
130
|
+
"iat" => 1679514154,
|
131
|
+
"iss" => "https://example.kinde.com",
|
132
|
+
"jti" => "22c48b2c-da46-4661-a7ff-425c23eceab5",
|
133
|
+
"org_code" => "org_cb4544175bc",
|
134
|
+
"permissions" => ["read:todos", "create:todos"],
|
135
|
+
"scp" => ["openid", "offline"],
|
136
|
+
"sub" => "kp:b17adf719f7d4b87b611d1a88a09fd15" }
|
72
137
|
end
|
73
138
|
let(:token) { JWT.encode(hash_to_encode, nil, "none") }
|
74
|
-
let(:
|
139
|
+
let(:expires_at) { Time.now.to_i + 10000000 }
|
140
|
+
let(:client) { described_class.client({ "access_token": token, "expires_at": expires_at }) }
|
141
|
+
|
142
|
+
context "with feature flags" do
|
143
|
+
it "returns existing flags", :aggregate_failures do
|
144
|
+
expect(client.get_flag("asd")).to eq({ code: "asd", is_default: false, type: "boolean", value: true })
|
145
|
+
expect(client.get_flag("eeeeee")).to eq({ code: "eeeeee", is_default: false, type: "integer", value: 111 })
|
146
|
+
expect(client.get_flag("qqq")).to eq({ code: "qqq", is_default: false, type: "string", value: "aa" })
|
147
|
+
|
148
|
+
expect { client.get_flag("undefined") }
|
149
|
+
.to raise_error(StandardError, "This flag was not found, and no default value has been provided")
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns fallbacks if no flag present", :aggregate_failures do
|
153
|
+
expect(client.get_flag("undefined", { default_value: true }))
|
154
|
+
.to eq({ code: "undefined", is_default: true, value: true })
|
155
|
+
|
156
|
+
expect(client.get_flag("undefined", { default_value: true }, "b")[:value]).to eq(true)
|
157
|
+
expect(client.get_flag("undefined", { default_value: "true" }, "s")[:value]).to eq("true")
|
158
|
+
expect(client.get_flag("undefined", { default_value: 111 }, "i")[:value]).to eq(111)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "raises argument error when no value type match", :aggregate_failures do
|
162
|
+
expect { client.get_flag("undefined", { default_value: true }, "s") }
|
163
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
164
|
+
|
165
|
+
expect { client.get_flag("undefined", { default_value: true }, "i") }
|
166
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
167
|
+
|
168
|
+
expect { client.get_flag("undefined", { default_value: "true" }, "b") }
|
169
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
170
|
+
end
|
171
|
+
|
172
|
+
it "behaves the same way for boolean flag wrapper getter", :aggregate_failures do
|
173
|
+
expect { client.get_boolean_flag("eeeeee") }
|
174
|
+
.to raise_error(ArgumentError, "Flag eeeeee value type is different from requested type")
|
175
|
+
expect(client.get_boolean_flag("asd")).to eq(true)
|
176
|
+
expect(client.get_boolean_flag("undefined", false)).to eq(false)
|
177
|
+
|
178
|
+
expect { client.get_boolean_flag("undefined", "true") }
|
179
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
180
|
+
end
|
181
|
+
|
182
|
+
it "behaves the same way for integer flag wrapper getter", :aggregate_failures do
|
183
|
+
expect { client.get_integer_flag("asd") }
|
184
|
+
.to raise_error(ArgumentError, "Flag asd value type is different from requested type")
|
185
|
+
expect(client.get_integer_flag("eeeeee")).to eq(111)
|
186
|
+
expect(client.get_integer_flag("undefined", 111)).to eq(111)
|
187
|
+
|
188
|
+
expect { client.get_integer_flag("undefined", "true") }
|
189
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
190
|
+
end
|
191
|
+
|
192
|
+
it "behaves the same way for string flag wrapper getter", :aggregate_failures do
|
193
|
+
expect { client.get_string_flag("asd") }
|
194
|
+
.to raise_error(ArgumentError, "Flag asd value type is different from requested type")
|
195
|
+
expect(client.get_string_flag("qqq")).to eq("aa")
|
196
|
+
expect(client.get_string_flag("undefined", "111")).to eq("111")
|
197
|
+
|
198
|
+
expect { client.get_string_flag("undefined", true) }
|
199
|
+
.to raise_error(ArgumentError, "Flag undefined value type is different from requested type")
|
200
|
+
end
|
201
|
+
end
|
75
202
|
|
76
203
|
it "returns requested claim from bearer", :aggregate_failures do
|
77
|
-
expect(client.get_claim("scp")).to eq(hash_to_encode["scp"])
|
204
|
+
expect(client.get_claim("scp")).to eq({ name: "scp", value: hash_to_encode["scp"] })
|
205
|
+
expect(client.get_claim("scp", :id_token)).to be_nil
|
78
206
|
expect(client.get_claim("aaa")).to be_nil
|
79
207
|
end
|
80
208
|
|
@@ -88,8 +216,18 @@ describe KindeSdk do
|
|
88
216
|
expect(client.permission_granted?("asd")).to be(false)
|
89
217
|
end
|
90
218
|
|
219
|
+
context "with expiration check" do
|
220
|
+
it { expect(client.token_expired?).to be(false) }
|
221
|
+
|
222
|
+
context "when token expired" do
|
223
|
+
let(:expires_at) { Time.now.to_i - 1 }
|
224
|
+
|
225
|
+
it { expect(client.token_expired?).to be(true) }
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
91
229
|
describe "api instances" do
|
92
|
-
it 'initializes client by passing the
|
230
|
+
it 'initializes client by passing the tokens_hash' do
|
93
231
|
expect(client).to be_instance_of(KindeSdk::Client)
|
94
232
|
end
|
95
233
|
|
@@ -100,6 +238,10 @@ describe KindeSdk do
|
|
100
238
|
it "initializes users instance api" do
|
101
239
|
expect(client.users).to be_instance_of(KindeApi::UsersApi)
|
102
240
|
end
|
241
|
+
|
242
|
+
it "initializes feature flags instance api" do
|
243
|
+
expect(client.feature_flags).to be_instance_of(KindeApi::FeatureFlagsApi)
|
244
|
+
end
|
103
245
|
end
|
104
246
|
end
|
105
247
|
end
|
data/spec/spec_helper.rb
CHANGED