api_guard_grape 0.5.4 → 0.5.5
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/README.md +37 -37
- data/Rakefile +1 -1
- data/app/controllers/{api_guard_grape → api_guard}/application_controller.rb +1 -1
- data/app/controllers/{api_guard_grape → api_guard}/authentication_controller.rb +6 -6
- data/app/controllers/{api_guard_grape → api_guard}/passwords_controller.rb +4 -4
- data/app/controllers/{api_guard_grape → api_guard}/registration_controller.rb +4 -4
- data/app/controllers/{api_guard_grape → api_guard}/tokens_controller.rb +6 -6
- data/config/locales/en.yml +1 -1
- data/config/routes.rb +2 -2
- data/lib/{api_guard_grape.rb → api_guard.rb} +9 -9
- data/lib/{api_guard_grape → api_guard}/app_secret_key.rb +1 -1
- data/lib/{api_guard_grape → api_guard}/engine.rb +4 -4
- data/lib/{api_guard_grape → api_guard}/jwt_auth/authentication.rb +16 -16
- data/lib/{api_guard_grape → api_guard}/jwt_auth/blacklist_token.rb +1 -1
- data/lib/api_guard/jwt_auth/json_web_token.rb +143 -0
- data/lib/{api_guard_grape/jwt_auth/json_web_token.rb → api_guard/jwt_auth/refresh_jwt_token.rb} +10 -107
- data/lib/api_guard/models/concerns.rb +27 -0
- data/lib/api_guard/modules.rb +26 -0
- data/lib/{api_guard_grape → api_guard}/resource_mapper.rb +3 -3
- data/lib/{api_guard_grape → api_guard}/response_formatters/renderer.rb +3 -3
- data/lib/{api_guard_grape → api_guard}/route_mapper.rb +10 -10
- data/lib/api_guard/test/controller_helper.rb +13 -0
- data/lib/api_guard/version.rb +5 -0
- data/lib/generators/{api_guard_grape → api_guard}/controllers/USAGE +1 -1
- data/lib/generators/{api_guard_grape → api_guard}/controllers/controllers_generator.rb +1 -1
- data/lib/generators/{api_guard_grape → api_guard}/controllers/templates/authentication_controller.rb +5 -5
- data/lib/generators/{api_guard_grape → api_guard}/controllers/templates/passwords_controller.rb +3 -3
- data/lib/generators/{api_guard_grape → api_guard}/controllers/templates/registration_controller.rb +3 -3
- data/lib/generators/{api_guard_grape → api_guard}/controllers/templates/tokens_controller.rb +5 -5
- data/lib/generators/{api_guard_grape → api_guard}/initializer/USAGE +2 -2
- data/lib/generators/{api_guard_grape → api_guard}/initializer/initializer_generator.rb +2 -2
- data/lib/generators/{api_guard_grape → api_guard}/initializer/templates/initializer.rb +1 -1
- metadata +30 -30
- data/lib/api_guard_grape/jwt_auth/refresh_jwt_token.rb +0 -46
- data/lib/api_guard_grape/models/concerns.rb +0 -27
- data/lib/api_guard_grape/modules.rb +0 -26
- data/lib/api_guard_grape/test/controller_helper.rb +0 -13
- data/lib/api_guard_grape/version.rb +0 -5
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module ApiGuard
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
-
isolate_namespace
|
5
|
+
isolate_namespace ApiGuard
|
6
6
|
|
7
7
|
config.generators do |g|
|
8
8
|
g.test_framework :rspec
|
@@ -10,8 +10,8 @@ module ApiGuardGrape
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# Use 'secret_key_base' from Rails secrets if 'token_signing_secret' is not configured
|
13
|
-
initializer '
|
14
|
-
|
13
|
+
initializer 'ApiGuard.token_signing_secret' do |app|
|
14
|
+
ApiGuard.token_signing_secret ||= ApiGuard::AppSecretKey.new(app).detect
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module ApiGuard
|
4
4
|
module JwtAuth
|
5
5
|
# Common module for API authentication
|
6
6
|
module Authentication
|
7
7
|
# Handle authentication of the resource dynamically
|
8
|
-
def
|
8
|
+
def method_missing(name, *args)
|
9
9
|
method_name = name.to_s
|
10
10
|
|
11
11
|
if method_name.start_with?('authenticate_and_set_')
|
@@ -16,32 +16,32 @@ module ApiGuardGrape
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def respond_to_missing?(method_name, include_private = false)
|
20
20
|
method_name.to_s.start_with?('authenticate_and_set_') || super
|
21
21
|
end
|
22
22
|
|
23
23
|
# Authenticate the JWT token and set resource
|
24
|
-
def
|
24
|
+
def authenticate_and_set_resource(resource_name)
|
25
25
|
@resource_name = resource_name
|
26
26
|
|
27
27
|
@token = request.headers['Authorization']&.split('Bearer ')&.last
|
28
|
-
return render_error(401, message: I18n.t('
|
28
|
+
return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token
|
29
29
|
|
30
30
|
authenticate_token
|
31
31
|
|
32
32
|
# Render error response only if no resource found and no previous render happened
|
33
|
-
render_error(401, message: I18n.t('
|
33
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid')) if !current_resource && !performed?
|
34
34
|
rescue JWT::DecodeError => e
|
35
35
|
if e.message == 'Signature has expired'
|
36
|
-
render_error(401, message: I18n.t('
|
36
|
+
render_error(401, message: I18n.t('api_guard.access_token.expired'))
|
37
37
|
else
|
38
|
-
render_error(401, message: I18n.t('
|
38
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
# Decode the JWT token
|
43
43
|
# and don't verify token expiry for refresh token API request
|
44
|
-
def
|
44
|
+
def decode_token
|
45
45
|
# TODO: Set token refresh controller dynamic
|
46
46
|
verify_token = (controller_name != 'tokens' || action_name != 'create')
|
47
47
|
@decoded_token = decode(@token, verify_token)
|
@@ -49,15 +49,15 @@ module ApiGuardGrape
|
|
49
49
|
|
50
50
|
# Returns whether the JWT token is issued after the last password change
|
51
51
|
# Returns true if password hasn't changed by the user
|
52
|
-
def
|
53
|
-
return true unless
|
52
|
+
def valid_issued_at?(resource)
|
53
|
+
return true unless ApiGuard.invalidate_old_tokens_on_password_change
|
54
54
|
|
55
55
|
!resource.token_issued_at || @decoded_token[:iat] >= resource.token_issued_at.to_i
|
56
56
|
end
|
57
57
|
|
58
58
|
# Defines "current_{{resource_name}}" method and "@current_{{resource_name}}" instance variable
|
59
59
|
# that returns "resource" value
|
60
|
-
def
|
60
|
+
def define_current_resource_accessors(resource)
|
61
61
|
define_singleton_method("current_#{@resource_name}") do
|
62
62
|
instance_variable_get("@current_#{@resource_name}") ||
|
63
63
|
instance_variable_set("@current_#{@resource_name}", resource)
|
@@ -69,7 +69,7 @@ module ApiGuardGrape
|
|
69
69
|
#
|
70
70
|
# Also, set "current_{{resource_name}}" method and "@current_{{resource_name}}" instance variable
|
71
71
|
# for accessing the authenticated resource
|
72
|
-
def
|
72
|
+
def authenticate_token
|
73
73
|
return unless decode_token
|
74
74
|
|
75
75
|
resource = find_resource_from_token(@resource_name.classify.constantize)
|
@@ -77,18 +77,18 @@ module ApiGuardGrape
|
|
77
77
|
if resource && valid_issued_at?(resource) && !blacklisted?(resource)
|
78
78
|
define_current_resource_accessors(resource)
|
79
79
|
else
|
80
|
-
render_error(401, message: I18n.t('
|
80
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
84
|
+
def find_resource_from_token(resource_class)
|
85
85
|
resource_id = @decoded_token[:"#{@resource_name}_id"]
|
86
86
|
return if resource_id.blank?
|
87
87
|
|
88
88
|
resource_class.find_by(id: resource_id)
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
91
|
+
def current_resource
|
92
92
|
return unless respond_to?("current_#{@resource_name}")
|
93
93
|
|
94
94
|
public_send("current_#{@resource_name}")
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jwt'
|
4
|
+
require 'api_guard/jwt_auth/refresh_jwt_token'
|
5
|
+
module ApiGuard
|
6
|
+
module JwtAuth
|
7
|
+
# Common module for JWT operations
|
8
|
+
module JsonWebToken
|
9
|
+
|
10
|
+
def self.current_time
|
11
|
+
@current_time ||= Time.now.utc
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.token_expire_at
|
15
|
+
@token_expire_at ||= (current_time + ApiGuard.token_validity).to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.token_issued_at
|
19
|
+
@token_issued_at ||= current_time.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
# Encode the payload with the secret key and return the JWT token
|
23
|
+
def self.encode(payload)
|
24
|
+
JWT.encode(payload, ApiGuard.token_signing_secret)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Decode the JWT token and return the payload
|
28
|
+
def self.decode(token, verify = true)
|
29
|
+
HashWithIndifferentAccess.new(
|
30
|
+
JWT.decode(token, ApiGuard.token_signing_secret, verify, verify_iat: true)[0]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create a JWT token with resource detail in payload.
|
35
|
+
# Also, create refresh token if enabled for the resource.
|
36
|
+
#
|
37
|
+
# This creates expired JWT token if the argument 'expired_token' is true which can be used for testing.
|
38
|
+
def self.jwt_and_refresh_token(resource, resource_name, expired_token = false)
|
39
|
+
payload = {
|
40
|
+
"#{resource_name}_id": resource.id,
|
41
|
+
exp: expired_token ? token_issued_at : token_expire_at,
|
42
|
+
iat: token_issued_at
|
43
|
+
}
|
44
|
+
|
45
|
+
# Add custom data in the JWT token payload
|
46
|
+
payload.merge!(resource.jwt_token_payload) if resource.respond_to?(:jwt_token_payload)
|
47
|
+
[self.encode(payload), self.new_refresh_token(resource)]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create tokens and set response headers
|
51
|
+
def self.create_token_and_set_header(resource, resource_name)
|
52
|
+
access_token, refresh_token = jwt_and_refresh_token(resource, resource_name)
|
53
|
+
set_token_headers(access_token, refresh_token)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set token details in response headers
|
57
|
+
def self.set_token_headers(token, refresh_token = nil)
|
58
|
+
response.headers['Access-Token'] = token
|
59
|
+
response.headers['Refresh-Token'] = refresh_token if refresh_token
|
60
|
+
response.headers['Expire-At'] = token_expire_at.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set token issued at to current timestamp
|
64
|
+
# to restrict access to old access(JWT) tokens
|
65
|
+
def self.invalidate_old_jwt_tokens(resource)
|
66
|
+
return unless ApiGuard.invalidate_old_tokens_on_password_change
|
67
|
+
|
68
|
+
resource.token_issued_at = Time.at(token_issued_at).utc
|
69
|
+
end
|
70
|
+
|
71
|
+
#refresh token code=======================================
|
72
|
+
|
73
|
+
def self.refresh_token_association(resource)
|
74
|
+
resource.class.refresh_token_association
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.refresh_token_enabled?(resource)
|
78
|
+
refresh_token_association(resource).present?
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.refresh_tokens_for(resource)
|
82
|
+
refresh_token_association = refresh_token_association(resource)
|
83
|
+
resource.send(refresh_token_association)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.find_refresh_token_of(resource, refresh_token)
|
87
|
+
refresh_tokens_for(resource).find_by_token(refresh_token)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Generate and return unique refresh token for the resource
|
91
|
+
def self.uniq_refresh_token(resource)
|
92
|
+
loop do
|
93
|
+
random_token = SecureRandom.urlsafe_base64
|
94
|
+
return random_token unless refresh_tokens_for(resource).exists?(token: random_token)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Create a new refresh_token for the current resource
|
99
|
+
def self.new_refresh_token(resource)
|
100
|
+
return unless refresh_token_enabled?(resource)
|
101
|
+
|
102
|
+
refresh_tokens_for(resource).create(token: uniq_refresh_token(resource)).token
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.destroy_all_refresh_tokens(resource)
|
106
|
+
return unless refresh_token_enabled?(resource)
|
107
|
+
|
108
|
+
refresh_tokens_for(resource).destroy_all
|
109
|
+
end
|
110
|
+
|
111
|
+
# blacklisted ======================================================
|
112
|
+
def self.blacklisted_token_association(resource)
|
113
|
+
debugger
|
114
|
+
resource.class.blacklisted_token_association
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.token_blacklisting_enabled?(resource)
|
118
|
+
debugger
|
119
|
+
blacklisted_token_association(resource).present?
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.blacklisted_tokens_for(resource)
|
123
|
+
blacklisted_token_association = blacklisted_token_association(resource)
|
124
|
+
resource.send(blacklisted_token_association)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns whether the JWT token is blacklisted or not
|
128
|
+
def self.blacklisted?(resource)
|
129
|
+
return false unless token_blacklisting_enabled?(resource)
|
130
|
+
|
131
|
+
blacklisted_tokens_for(resource).exists?(token: @token)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Blacklist the current JWT token from future access
|
135
|
+
def self.blacklist_token
|
136
|
+
|
137
|
+
return unless token_blacklisting_enabled?(current_resource)
|
138
|
+
blacklisted_tokens_for(current_resource).create(token: @token, expire_at: Time.at(@decoded_token[:exp]).utc)
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/{api_guard_grape/jwt_auth/json_web_token.rb → api_guard/jwt_auth/refresh_jwt_token.rb}
RENAMED
@@ -1,75 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
module ApiGuardGrape
|
3
|
+
module ApiGuard
|
6
4
|
module JwtAuth
|
7
|
-
# Common module for
|
8
|
-
module
|
9
|
-
def self.current_time
|
10
|
-
@current_time ||= Time.now.utc
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.token_expire_at
|
14
|
-
@token_expire_at ||= (current_time + ApiGuardGrape.token_validity).to_i
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.token_issued_at
|
18
|
-
@token_issued_at ||= current_time.to_i
|
19
|
-
end
|
20
|
-
|
21
|
-
# Encode the payload with the secret key and return the JWT token
|
22
|
-
def self.encode(payload)
|
23
|
-
JWT.encode(payload, ApiGuardGrape.token_signing_secret)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Decode the JWT token and return the payload
|
27
|
-
def self.decode(token, verify = true)
|
28
|
-
HashWithIndifferentAccess.new(
|
29
|
-
JWT.decode(token, ApiGuardGrape.token_signing_secret, verify, verify_iat: true)[0]
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Create a JWT token with resource detail in payload.
|
34
|
-
# Also, create refresh token if enabled for the resource.
|
35
|
-
#
|
36
|
-
# This creates expired JWT token if the argument 'expired_token' is true which can be used for testing.
|
37
|
-
def self.jwt_and_refresh_token(resource, resource_name, expired_token = false)
|
38
|
-
payload = {
|
39
|
-
"#{resource_name}_id": resource.id,
|
40
|
-
exp: expired_token ? token_issued_at : token_expire_at,
|
41
|
-
iat: token_issued_at
|
42
|
-
}
|
43
|
-
|
44
|
-
# Add custom data in the JWT token payload
|
45
|
-
payload.merge!(resource.jwt_token_payload) if resource.respond_to?(:jwt_token_payload)
|
46
|
-
|
47
|
-
[encode(payload), new_refresh_token(resource)]
|
48
|
-
end
|
49
|
-
|
50
|
-
# Create tokens and set response headers
|
51
|
-
def self.create_token_and_set_header(resource, resource_name)
|
52
|
-
access_token, refresh_token = jwt_and_refresh_token(resource, resource_name)
|
53
|
-
set_token_headers(access_token, refresh_token)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Set token details in response headers
|
57
|
-
def self.set_token_headers(token, refresh_token = nil)
|
58
|
-
response.headers['Access-Token'] = token
|
59
|
-
response.headers['Refresh-Token'] = refresh_token if refresh_token
|
60
|
-
response.headers['Expire-At'] = token_expire_at.to_s
|
61
|
-
end
|
62
|
-
|
63
|
-
# Set token issued at to current timestamp
|
64
|
-
# to restrict access to old access(JWT) tokens
|
65
|
-
def self.invalidate_old_jwt_tokens(resource)
|
66
|
-
return unless ApiGuardGrape.invalidate_old_tokens_on_password_change
|
67
|
-
|
68
|
-
resource.token_issued_at = Time.at(token_issued_at).utc
|
69
|
-
end
|
70
|
-
|
71
|
-
# =================================REFRESH JWT TOKEN================
|
72
|
-
|
5
|
+
# Common module for refresh token functionality
|
6
|
+
module RefreshJwtToken
|
73
7
|
def self.refresh_token_association(resource)
|
74
8
|
resource.class.refresh_token_association
|
75
9
|
end
|
@@ -108,37 +42,7 @@ module ApiGuardGrape
|
|
108
42
|
refresh_tokens_for(resource).destroy_all
|
109
43
|
end
|
110
44
|
|
111
|
-
|
112
|
-
|
113
|
-
def self.blacklisted_token_association(resource)
|
114
|
-
resource.class.blacklisted_token_association
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.token_blacklisting_enabled?(resource)
|
118
|
-
blacklisted_token_association(resource).present?
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.blacklisted_tokens_for(resource)
|
122
|
-
blacklisted_token_association = blacklisted_token_association(resource)
|
123
|
-
resource.send(blacklisted_token_association)
|
124
|
-
end
|
125
|
-
|
126
|
-
# Returns whether the JWT token is blacklisted or not
|
127
|
-
def self.blacklisted?(resource)
|
128
|
-
return false unless token_blacklisting_enabled?(resource)
|
129
|
-
|
130
|
-
blacklisted_tokens_for(resource).exists?(token: @token)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Blacklist the current JWT token from future access
|
134
|
-
def self.blacklist_token
|
135
|
-
return unless token_blacklisting_enabled?(current_resource)
|
136
|
-
|
137
|
-
blacklisted_tokens_for(current_resource).create(token: @token, expire_at: Time.at(@decoded_token[:exp]).utc)
|
138
|
-
end
|
139
|
-
|
140
|
-
# =================================AUTHENTICATION JWT TOKEN================
|
141
|
-
|
45
|
+
# authenticat-----------
|
142
46
|
|
143
47
|
def self.method_missing(name, *args)
|
144
48
|
method_name = name.to_s
|
@@ -160,17 +64,17 @@ module ApiGuardGrape
|
|
160
64
|
@resource_name = resource_name
|
161
65
|
|
162
66
|
@token = request.headers['Authorization']&.split('Bearer ')&.last
|
163
|
-
return render_error(401, message: I18n.t('
|
67
|
+
return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token
|
164
68
|
|
165
69
|
authenticate_token
|
166
70
|
|
167
71
|
# Render error response only if no resource found and no previous render happened
|
168
|
-
render_error(401, message: I18n.t('
|
72
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid')) if !current_resource && !performed?
|
169
73
|
rescue JWT::DecodeError => e
|
170
74
|
if e.message == 'Signature has expired'
|
171
|
-
render_error(401, message: I18n.t('
|
75
|
+
render_error(401, message: I18n.t('api_guard.access_token.expired'))
|
172
76
|
else
|
173
|
-
render_error(401, message: I18n.t('
|
77
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
174
78
|
end
|
175
79
|
end
|
176
80
|
|
@@ -185,7 +89,7 @@ module ApiGuardGrape
|
|
185
89
|
# Returns whether the JWT token is issued after the last password change
|
186
90
|
# Returns true if password hasn't changed by the user
|
187
91
|
def self.valid_issued_at?(resource)
|
188
|
-
return true unless
|
92
|
+
return true unless ApiGuard.invalidate_old_tokens_on_password_change
|
189
93
|
|
190
94
|
!resource.token_issued_at || @decoded_token[:iat] >= resource.token_issued_at.to_i
|
191
95
|
end
|
@@ -212,7 +116,7 @@ module ApiGuardGrape
|
|
212
116
|
if resource && valid_issued_at?(resource) && !blacklisted?(resource)
|
213
117
|
define_current_resource_accessors(resource)
|
214
118
|
else
|
215
|
-
render_error(401, message: I18n.t('
|
119
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
216
120
|
end
|
217
121
|
end
|
218
122
|
|
@@ -228,7 +132,6 @@ module ApiGuardGrape
|
|
228
132
|
|
229
133
|
public_send("current_#{@resource_name}")
|
230
134
|
end
|
231
|
-
|
232
135
|
end
|
233
136
|
end
|
234
137
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiGuard
|
4
|
+
module Models
|
5
|
+
module Concerns
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def api_guard_associations(refresh_token: nil, blacklisted_token: nil)
|
10
|
+
return if ApiGuard.api_guard_associations[name]
|
11
|
+
|
12
|
+
ApiGuard.api_guard_associations[name] = {}
|
13
|
+
ApiGuard.api_guard_associations[name][:refresh_token] = refresh_token
|
14
|
+
ApiGuard.api_guard_associations[name][:blacklisted_token] = blacklisted_token
|
15
|
+
end
|
16
|
+
|
17
|
+
def refresh_token_association
|
18
|
+
ApiGuard.api_guard_associations.dig(name, :refresh_token)
|
19
|
+
end
|
20
|
+
|
21
|
+
def blacklisted_token_association
|
22
|
+
ApiGuard.api_guard_associations.dig(name, :blacklisted_token)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|