kinde_sdk 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +103 -19
  3. data/kinde_api/README.md +58 -23
  4. data/kinde_api/docs/AddOrganizationUsersRequest.md +1 -1
  5. data/kinde_api/docs/AddOrganizationUsersRequestUsersInner.md +22 -0
  6. data/kinde_api/docs/{AddOrganizationUsers200Response.md → AddOrganizationUsersResponse.md} +2 -2
  7. data/kinde_api/docs/Application.md +20 -0
  8. data/kinde_api/docs/CallbacksApi.md +219 -0
  9. data/kinde_api/docs/ConnectedAppsApi.md +9 -9
  10. data/kinde_api/docs/CreateOrganizationRequest.md +11 -1
  11. data/kinde_api/docs/CreateOrganizationResponse.md +22 -0
  12. data/kinde_api/docs/CreateOrganizationResponseOrganization.md +18 -0
  13. data/kinde_api/docs/CreateOrganizationUserRoleRequest.md +18 -0
  14. data/kinde_api/docs/CreatePermissionRequest.md +22 -0
  15. data/kinde_api/docs/CreateRoleRequest.md +24 -0
  16. data/kinde_api/docs/CreateSubscriberSuccessResponse.md +18 -0
  17. data/kinde_api/docs/CreateSubscriberSuccessResponseSubscriber.md +18 -0
  18. data/kinde_api/docs/{CreateUser200Response.md → CreateUserResponse.md} +2 -2
  19. data/kinde_api/docs/EnvironmentsApi.md +71 -4
  20. data/kinde_api/docs/FeatureFlagsApi.md +9 -11
  21. data/kinde_api/docs/GetApplicationsResponse.md +24 -0
  22. data/kinde_api/docs/GetEnvironmentFeatureFlagsResponse.md +24 -0
  23. data/kinde_api/docs/GetOrganizationFeatureFlagsResponse.md +22 -0
  24. data/kinde_api/docs/GetOrganizationFeatureFlagsResponseFeatureFlagsValue.md +20 -0
  25. data/kinde_api/docs/{GetOrganizations200Response.md → GetOrganizationsResponse.md} +2 -2
  26. data/kinde_api/docs/GetOrganizationsUserRolesResponse.md +24 -0
  27. data/kinde_api/docs/{GetOrganizationUsers200Response.md → GetOrganizationsUsersResponse.md} +2 -2
  28. data/kinde_api/docs/GetRedirectCallbackUrlsResponse.md +18 -0
  29. data/kinde_api/docs/OrganizationUser.md +3 -1
  30. data/kinde_api/docs/OrganizationUserRole.md +22 -0
  31. data/kinde_api/docs/OrganizationsApi.md +494 -59
  32. data/kinde_api/docs/Permissions.md +22 -0
  33. data/kinde_api/docs/PermissionsApi.md +229 -0
  34. data/kinde_api/docs/RedirectCallbackUrls.md +18 -0
  35. data/kinde_api/docs/Roles.md +22 -0
  36. data/kinde_api/docs/RolesApi.md +229 -0
  37. data/kinde_api/docs/SubscribersApi.md +229 -0
  38. data/kinde_api/docs/UpdateOrganizationRequest.md +28 -0
  39. data/kinde_api/docs/UpdateOrganizationUsersRequest.md +18 -0
  40. data/kinde_api/docs/UpdateOrganizationUsersRequestUsersInner.md +24 -0
  41. data/kinde_api/docs/UpdateOrganizationUsersResponse.md +24 -0
  42. data/kinde_api/docs/UpdateUserRequest.md +3 -1
  43. data/kinde_api/docs/User.md +15 -1
  44. data/kinde_api/docs/UserIdentityResult.md +1 -3
  45. data/kinde_api/docs/UserProfile.md +3 -1
  46. data/kinde_api/docs/UserProfileV2.md +6 -2
  47. data/kinde_api/docs/UsersApi.md +31 -259
  48. data/kinde_api/docs/{GetUsers200Response.md → UsersResponse.md} +2 -2
  49. data/kinde_api/lib/kinde_api/api/callbacks_api.rb +221 -0
  50. data/kinde_api/lib/kinde_api/api/connected_apps_api.rb +8 -8
  51. data/kinde_api/lib/kinde_api/api/environments_api.rb +61 -4
  52. data/kinde_api/lib/kinde_api/api/feature_flags_api.rb +8 -15
  53. data/kinde_api/lib/kinde_api/api/organizations_api.rb +492 -57
  54. data/kinde_api/lib/kinde_api/api/permissions_api.rb +226 -0
  55. data/kinde_api/lib/kinde_api/api/roles_api.rb +226 -0
  56. data/kinde_api/lib/kinde_api/api/subscribers_api.rb +228 -0
  57. data/kinde_api/lib/kinde_api/api/users_api.rb +30 -233
  58. data/kinde_api/lib/kinde_api/api_client.rb +1 -13
  59. data/kinde_api/lib/kinde_api/configuration.rb +3 -77
  60. data/kinde_api/lib/kinde_api/models/add_organization_users_request.rb +2 -2
  61. data/kinde_api/lib/kinde_api/models/add_organization_users_request_users_inner.rb +242 -0
  62. data/kinde_api/lib/kinde_api/models/{add_organization_users200_response.rb → add_organization_users_response.rb} +3 -3
  63. data/kinde_api/lib/kinde_api/models/application.rb +226 -0
  64. data/kinde_api/lib/kinde_api/models/create_organization_request.rb +54 -4
  65. data/kinde_api/lib/kinde_api/models/{remove_organization_users200_response.rb → create_organization_response.rb} +19 -12
  66. data/kinde_api/lib/kinde_api/models/{create_organization201_response.rb → create_organization_response_organization.rb} +8 -18
  67. data/kinde_api/lib/kinde_api/models/create_organization_user_role_request.rb +218 -0
  68. data/kinde_api/lib/kinde_api/models/create_permission_request.rb +238 -0
  69. data/kinde_api/lib/kinde_api/models/create_role_request.rb +248 -0
  70. data/kinde_api/lib/kinde_api/models/create_subscriber_success_response.rb +217 -0
  71. data/kinde_api/lib/kinde_api/models/create_subscriber_success_response_subscriber.rb +218 -0
  72. data/kinde_api/lib/kinde_api/models/create_user_request_identities_inner.rb +34 -0
  73. data/kinde_api/lib/kinde_api/models/{create_user200_response.rb → create_user_response.rb} +3 -3
  74. data/kinde_api/lib/kinde_api/models/get_applications_response.rb +249 -0
  75. data/kinde_api/lib/kinde_api/models/get_environment_feature_flags_response.rb +250 -0
  76. data/kinde_api/lib/kinde_api/models/get_organization_feature_flags_response.rb +240 -0
  77. data/kinde_api/lib/kinde_api/models/get_organization_feature_flags_response_feature_flags_value.rb +260 -0
  78. data/kinde_api/lib/kinde_api/models/{get_organizations200_response.rb → get_organizations_response.rb} +3 -3
  79. data/kinde_api/lib/kinde_api/models/get_organizations_user_roles_response.rb +249 -0
  80. data/kinde_api/lib/kinde_api/models/{get_organization_users200_response.rb → get_organizations_users_response.rb} +3 -3
  81. data/kinde_api/lib/kinde_api/models/get_redirect_callback_urls_response.rb +220 -0
  82. data/kinde_api/lib/kinde_api/models/organization_user.rb +15 -4
  83. data/kinde_api/lib/kinde_api/models/organization_user_role.rb +235 -0
  84. data/kinde_api/lib/kinde_api/models/permissions.rb +238 -0
  85. data/kinde_api/lib/kinde_api/models/redirect_callback_urls.rb +220 -0
  86. data/kinde_api/lib/kinde_api/models/roles.rb +238 -0
  87. data/kinde_api/lib/kinde_api/models/update_organization_request.rb +268 -0
  88. data/kinde_api/lib/kinde_api/models/{remove_organization_users_request.rb → update_organization_users_request.rb} +5 -5
  89. data/kinde_api/lib/kinde_api/models/update_organization_users_request_users_inner.rb +252 -0
  90. data/kinde_api/lib/kinde_api/models/update_organization_users_response.rb +250 -0
  91. data/kinde_api/lib/kinde_api/models/update_user_request.rb +14 -4
  92. data/kinde_api/lib/kinde_api/models/user.rb +79 -5
  93. data/kinde_api/lib/kinde_api/models/user_identity_result.rb +4 -14
  94. data/kinde_api/lib/kinde_api/models/user_profile.rb +14 -4
  95. data/kinde_api/lib/kinde_api/models/user_profile_v2.rb +25 -5
  96. data/kinde_api/lib/kinde_api/models/{get_users200_response.rb → users_response.rb} +3 -3
  97. data/kinde_api/lib/kinde_api.rb +32 -8
  98. data/kinde_api/spec/api/callbacks_api_spec.rb +73 -0
  99. data/kinde_api/spec/api/connected_apps_api_spec.rb +1 -1
  100. data/kinde_api/spec/api/environments_api_spec.rb +11 -0
  101. data/kinde_api/spec/api/feature_flags_api_spec.rb +1 -2
  102. data/kinde_api/spec/api/organizations_api_spec.rb +93 -14
  103. data/kinde_api/spec/api/permissions_api_spec.rb +74 -0
  104. data/kinde_api/spec/api/roles_api_spec.rb +74 -0
  105. data/kinde_api/spec/api/subscribers_api_spec.rb +76 -0
  106. data/kinde_api/spec/api/users_api_spec.rb +6 -47
  107. data/kinde_api/spec/api_client_spec.rb +0 -12
  108. data/kinde_api/spec/models/add_organization_users_request_users_inner_spec.rb +46 -0
  109. data/kinde_api/spec/models/{add_organization_users200_response_spec.rb → add_organization_users_response_spec.rb} +6 -6
  110. data/kinde_api/spec/models/{remove_organization_users200_response_spec.rb → application_spec.rb} +8 -8
  111. data/kinde_api/spec/models/create_organization_request_spec.rb +30 -0
  112. data/kinde_api/spec/models/create_organization_response_organization_spec.rb +34 -0
  113. data/kinde_api/spec/models/{create_organization201_response_spec.rb → create_organization_response_spec.rb} +13 -7
  114. data/kinde_api/spec/models/create_organization_user_role_request_spec.rb +34 -0
  115. data/kinde_api/spec/models/create_permission_request_spec.rb +46 -0
  116. data/kinde_api/spec/models/create_role_request_spec.rb +52 -0
  117. data/kinde_api/spec/models/create_subscriber_success_response_spec.rb +34 -0
  118. data/kinde_api/spec/models/create_subscriber_success_response_subscriber_spec.rb +34 -0
  119. data/kinde_api/spec/models/create_user_request_identities_inner_spec.rb +4 -0
  120. data/kinde_api/spec/models/{create_user200_response_spec.rb → create_user_response_spec.rb} +6 -6
  121. data/kinde_api/spec/models/get_applications_response_spec.rb +52 -0
  122. data/kinde_api/spec/models/get_environment_feature_flags_response_spec.rb +52 -0
  123. data/kinde_api/spec/models/get_organization_feature_flags_response_feature_flags_value_spec.rb +44 -0
  124. data/kinde_api/spec/models/get_organization_feature_flags_response_spec.rb +46 -0
  125. data/kinde_api/spec/models/{get_organizations200_response_spec.rb → get_organizations_response_spec.rb} +6 -6
  126. data/kinde_api/spec/models/get_organizations_user_roles_response_spec.rb +52 -0
  127. data/kinde_api/spec/models/{get_organization_users200_response_spec.rb → get_organizations_users_response_spec.rb} +6 -6
  128. data/kinde_api/spec/models/get_redirect_callback_urls_response_spec.rb +34 -0
  129. data/kinde_api/spec/models/organization_user_role_spec.rb +46 -0
  130. data/kinde_api/spec/models/organization_user_spec.rb +6 -0
  131. data/kinde_api/spec/models/permissions_spec.rb +46 -0
  132. data/kinde_api/spec/models/redirect_callback_urls_spec.rb +34 -0
  133. data/kinde_api/spec/models/roles_spec.rb +46 -0
  134. data/kinde_api/spec/models/update_organization_request_spec.rb +64 -0
  135. data/kinde_api/spec/models/{remove_organization_users_request_spec.rb → update_organization_users_request_spec.rb} +6 -6
  136. data/kinde_api/spec/models/update_organization_users_request_users_inner_spec.rb +52 -0
  137. data/kinde_api/spec/models/update_organization_users_response_spec.rb +52 -0
  138. data/kinde_api/spec/models/update_user_request_spec.rb +6 -0
  139. data/kinde_api/spec/models/user_identity_result_spec.rb +0 -6
  140. data/kinde_api/spec/models/user_profile_spec.rb +6 -0
  141. data/kinde_api/spec/models/user_profile_v2_spec.rb +12 -0
  142. data/kinde_api/spec/models/user_spec.rb +42 -0
  143. data/kinde_api/spec/models/{get_users200_response_spec.rb → users_response_spec.rb} +6 -6
  144. data/kinde_sdk.gemspec +1 -1
  145. data/lib/kinde_sdk/client/feature_flags.rb +64 -0
  146. data/lib/kinde_sdk/client/permissions.rb +20 -0
  147. data/lib/kinde_sdk/client.rb +33 -18
  148. data/lib/kinde_sdk/configuration.rb +0 -2
  149. data/lib/kinde_sdk/version.rb +1 -1
  150. data/lib/kinde_sdk.rb +27 -12
  151. data/spec/kinde_sdk_spec.rb +131 -5
  152. data/spec/spec_helper.rb +2 -0
  153. metadata +134 -36
  154. data/kinde_api/docs/CreateOrganization201Response.md +0 -20
  155. data/kinde_api/docs/RemoveOrganizationUsers200Response.md +0 -20
  156. data/kinde_api/docs/RemoveOrganizationUsersRequest.md +0 -18
@@ -2,42 +2,57 @@ require "kinde_api"
2
2
 
3
3
  module KindeSdk
4
4
  class Client
5
- attr_accessor :kinde_api_client
6
- attr_accessor :bearer_token
5
+ include FeatureFlags
6
+ include Permissions
7
7
 
8
- def initialize(sdk_api_client, bearer_token)
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
- @bearer_token = bearer_token
11
- @decoded_token = JWT.decode(bearer_token, nil, false)
12
+ set_hash_related_data(tokens_hash)
12
13
  end
13
14
 
14
- def get_claim(*args)
15
- @decoded_token[0].dig(*args)
15
+ def token_expired?
16
+ expires_at.to_i > 0 && (expires_at <= Time.now.to_i)
16
17
  end
17
18
 
18
- def get_permissions
19
- get_claim("permissions")
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
- def get_permission(permission)
23
- {
24
- org_code: get_claim("org_code"),
25
- is_granted: permission_granted?(permission)
26
- }
27
- end
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
33
+
34
+ value = JWT.decode(token, nil, false)[0][claim]
35
+ return unless value
28
36
 
29
- def permission_granted?(permission)
30
- get_claim("permissions").include?(permission)
37
+ { name: claim, value: value }
31
38
  end
32
39
 
33
40
  ::KindeApi.constants.filter { |klass| klass.to_s.end_with?("Api") }.each do |klass|
34
41
  api_klass = Kernel.const_get("KindeApi::#{klass}")
35
42
 
36
- define_method(klass.to_s.downcase.split("api")[0]) { init_instance_api(api_klass) }
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
37
46
  end
38
47
 
39
48
  private
40
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
+
41
56
  def init_instance_api(api_klass)
42
57
  api_klass.new(kinde_api_client)
43
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
@@ -1,3 +1,3 @@
1
1
  module KindeSdk
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
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: @config.callback_url,
32
+ redirect_uri: redirect_uri,
30
33
  state: SecureRandom.hex,
31
34
  scope: @config.scope
32
35
  }.merge(**kwargs)
@@ -43,17 +46,28 @@ 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 = nil)
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 = { redirect_uri: @config.callback_url }
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(bearer_token)
55
- sdk_api_client = api_client(bearer_token)
56
- KindeSdk::Client.new(sdk_api_client, bearer_token)
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
73
  def logout_url
@@ -94,10 +108,10 @@ module KindeSdk
94
108
  config = KindeApi::Configuration.default
95
109
  config.configure do |c|
96
110
  c.access_token = bearer_token
97
- c.server_variables = { businessName: business_name }
98
111
  c.host = @config.domain
99
112
  c.debugging = @config.debugging
100
113
  c.logger = @config.logger
114
+ c.scheme = url_scheme(c.scheme)
101
115
  end
102
116
 
103
117
  KindeApi::ApiClient.new(config)
@@ -105,10 +119,11 @@ module KindeSdk
105
119
 
106
120
  private
107
121
 
108
- def business_name
109
- # from https://example.kinde.com fetches `example`
110
- # from https://example-chamois.au.kinde.com fetches `example-chamois.au`
111
- @config.business_name || @config.domain.split("//")[1].split(".")[0..-3].join(".")
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
112
127
  end
113
128
  end
114
129
  end
@@ -22,6 +22,12 @@ describe KindeSdk do
22
22
  auth_obj = described_class.auth_url
23
23
  expect(auth_obj[:code_verifier]).not_to be_nil
24
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/)
25
31
  end
26
32
  end
27
33
 
@@ -41,7 +47,46 @@ describe KindeSdk do
41
47
 
42
48
  describe "#api_client" do
43
49
  it "returns initialized api_client instance of KindeApi" do
44
- expect(described_class.api_client("bearer-token")).to be_instance_of(KindeApi::ApiClient)
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
45
90
  end
46
91
  end
47
92
 
@@ -77,7 +122,11 @@ describe KindeSdk do
77
122
  { "aud" => [],
78
123
  "azp" => "19ebb687cd2f405c9f2daf645a8db895",
79
124
  "exp" => 1679600554,
80
- "feature_flags" => nil,
125
+ "feature_flags" => {
126
+ "asd" => { "t" => "b", "v" => true },
127
+ "eeeeee" => { "t" => "i", "v" => 111 },
128
+ "qqq" => { "t" => "s", "v" => "aa" }
129
+ },
81
130
  "iat" => 1679514154,
82
131
  "iss" => "https://example.kinde.com",
83
132
  "jti" => "22c48b2c-da46-4661-a7ff-425c23eceab5",
@@ -87,10 +136,73 @@ describe KindeSdk do
87
136
  "sub" => "kp:b17adf719f7d4b87b611d1a88a09fd15" }
88
137
  end
89
138
  let(:token) { JWT.encode(hash_to_encode, nil, "none") }
90
- let(:client) { described_class.client(token) }
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
91
202
 
92
203
  it "returns requested claim from bearer", :aggregate_failures do
93
- 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
94
206
  expect(client.get_claim("aaa")).to be_nil
95
207
  end
96
208
 
@@ -104,8 +216,18 @@ describe KindeSdk do
104
216
  expect(client.permission_granted?("asd")).to be(false)
105
217
  end
106
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
+
107
229
  describe "api instances" do
108
- it 'initializes client by passing the bearer' do
230
+ it 'initializes client by passing the tokens_hash' do
109
231
  expect(client).to be_instance_of(KindeSdk::Client)
110
232
  end
111
233
 
@@ -116,6 +238,10 @@ describe KindeSdk do
116
238
  it "initializes users instance api" do
117
239
  expect(client.users).to be_instance_of(KindeApi::UsersApi)
118
240
  end
241
+
242
+ it "initializes feature flags instance api" do
243
+ expect(client.feature_flags).to be_instance_of(KindeApi::FeatureFlagsApi)
244
+ end
119
245
  end
120
246
  end
121
247
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "kinde_sdk"
2
2
  require "webmock/rspec"
3
3
 
4
+ WebMock.disable_net_connect!
5
+
4
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
7
  RSpec.configure do |config|
6
8
  # rspec-expectations config goes here. You can use an alternate