devise-api 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f6b2f86ff9cf332790f64f74212b25afff00bc6ff02ffe66389925db4b8fdc6
4
- data.tar.gz: a7e8420897cf4e587a73a297d2121fcd0d20f4750deb01e9a7685bf4e635059b
3
+ metadata.gz: 2d86e2276841e4ca3ae7497278542d686da38368f5f5cdf76629abd463c7976f
4
+ data.tar.gz: 3f33438f2a503b0f1bd510e6020c0d88f61a82715aff8b701a1872a4901ffb75
5
5
  SHA512:
6
- metadata.gz: d5a5ec029117561416f93e6748f278f8489aeef2ec4ce832bce7136790a7587d93de2f5490bbbbfe4a202ccb4275c2f371012e435fdb7cb077999189372039f5
7
- data.tar.gz: 43cad74cafb53ce017ebcf1e7ae41e250138eb9d8b0407ee89baf4ed8e2137394d4008f60c7c4f1f7116859aca43571361906a95ebbc1888348f71884f03a817
6
+ metadata.gz: acea2091463ddb32d14df2c6b6aaf88e55549796b79ba35855ffdd08f3f78e8a5e5d9f305f48a855a2f3d17aa2cee2c8e7fce7ce07efda222af9de785a9f57cf
7
+ data.tar.gz: 8cecc648a297705d7d7f82420aa48fd6f4ed7d8899ba721cf0002cbae34f9f1e3fae5032877a4efa826f609c50592f894f9407adeeed6a12c7ca856b2dd9c5d2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devise-api (0.1.2)
4
+ devise-api (0.1.3)
5
5
  devise (>= 4.7.2)
6
6
  dry-configurable (~> 1.0, >= 1.0.1)
7
7
  dry-initializer (>= 3.1.1)
@@ -259,6 +259,7 @@ GEM
259
259
  PLATFORMS
260
260
  arm64-darwin-21
261
261
  arm64-darwin-22
262
+ arm64-darwin-23
262
263
 
263
264
  DEPENDENCIES
264
265
  awesome_print
data/README.md CHANGED
@@ -91,6 +91,9 @@ Devise.setup do |config|
91
91
  api.refresh_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }
92
92
  api.refresh_token.expires_in_infinite = ->(_resource_owner) { false }
93
93
 
94
+ # Sign up
95
+ api.sign_up.enabled = true
96
+ api.sign_up.extra_fields = []
94
97
 
95
98
  # Authorization
96
99
  api.authorization.key = 'Authorization'
@@ -114,8 +117,8 @@ Devise.setup do |config|
114
117
  # Before callbacks
115
118
  api.before_sign_in = ->(_params, _request, _resource_class) { }
116
119
  api.before_sign_up = ->(_params, _request, _resource_class) { }
117
- api.before_refresh = ->(_params, _request, _resource_class) { }
118
- api.before_revoke = ->(_params, _request, _resource_class) { }
120
+ api.before_refresh = ->(_token_model, _request) { }
121
+ api.before_revoke = ->(_token_model, _request) { }
119
122
  end
120
123
  end
121
124
  ```
@@ -155,10 +158,12 @@ module Devise::Api::Responses::TokenResponseDecorator
155
158
  end
156
159
  ```
157
160
 
158
- Then you need to prepend your decorator to the response class. For example:
161
+ Then you need to load and prepend your decorator to the response class. For example:
159
162
 
160
163
  ```ruby
161
164
  # config/initializers/devise.rb
165
+ require 'devise/api/responses/token_response_decorator' # Either do this or autoload the lib directory
166
+
162
167
  Devise.setup do |config|
163
168
  end
164
169
 
@@ -1,15 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Metrics/ClassLength
3
4
  module Devise
4
5
  module Api
5
6
  class TokensController < Devise.api.config.base_controller.constantize
7
+ wrap_parameters false
6
8
  skip_before_action :verify_authenticity_token, raise: false
7
- before_action :authenticate_devise_api_token!, only: %i[info refresh]
9
+ before_action :authenticate_devise_api_token!, only: %i[info]
8
10
 
9
11
  respond_to :json
10
12
 
11
13
  # rubocop:disable Metrics/AbcSize
12
14
  def sign_up
15
+ unless Devise.api.config.sign_up.enabled
16
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :sign_up_disabled,
17
+ resource_class: resource_class)
18
+
19
+ return render json: error_response.body, status: error_response.status
20
+ end
21
+
13
22
  Devise.api.config.before_sign_up.call(sign_up_params, request, resource_class)
14
23
 
15
24
  service = Devise::Api::ResourceOwnerService::SignUp.new(params: sign_up_params,
@@ -103,9 +112,23 @@ module Devise
103
112
  return render json: error_response.body, status: error_response.status
104
113
  end
105
114
 
106
- Devise.api.config.before_refresh.call(current_devise_api_token, request)
115
+ if current_devise_api_refresh_token.blank?
116
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :invalid_token,
117
+ resource_class: resource_class)
118
+
119
+ return render json: error_response.body, status: error_response.status
120
+ end
121
+
122
+ if current_devise_api_refresh_token.revoked?
123
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :revoked_token,
124
+ resource_class: resource_class)
107
125
 
108
- service = Devise::Api::TokensService::Refresh.new(devise_api_token: current_devise_api_token).call
126
+ return render json: error_response.body, status: error_response.status
127
+ end
128
+
129
+ Devise.api.config.before_refresh.call(current_devise_api_refresh_token, request)
130
+
131
+ service = Devise::Api::TokensService::Refresh.new(devise_api_token: current_devise_api_refresh_token).call
109
132
 
110
133
  if service.success?
111
134
  token_response = Devise::Api::Responses::TokenResponse.new(request, token: service.success,
@@ -127,7 +150,7 @@ module Devise
127
150
  private
128
151
 
129
152
  def sign_up_params
130
- params.permit(*resource_class.authentication_keys,
153
+ params.permit(*Devise.api.config.sign_up.extra_fields, *resource_class.authentication_keys,
131
154
  *::Devise::ParameterSanitizer::DEFAULT_PERMITTED_ATTRIBUTES[:sign_up]).to_h
132
155
  end
133
156
 
@@ -141,6 +164,15 @@ module Devise
141
164
 
142
165
  resource_owner.update_tracked_fields!(request)
143
166
  end
167
+
168
+ def current_devise_api_refresh_token
169
+ return @current_devise_api_refresh_token if @current_devise_api_refresh_token
170
+
171
+ token = find_devise_api_token
172
+ devise_api_token_model = Devise.api.config.base_token_model.constantize
173
+ @current_devise_api_refresh_token = devise_api_token_model.find_by(refresh_token: token)
174
+ end
144
175
  end
145
176
  end
146
177
  end
178
+ # rubocop:enable Metrics/ClassLength
@@ -8,7 +8,7 @@ module Devise
8
8
  option :previous_refresh_token, type: Types::String | Types::Nil, default: proc { nil }
9
9
 
10
10
  def call
11
- return Failure(:invalid_resource_owner) unless resource_owner.respond_to?(:access_tokens)
11
+ return Failure(error: :invalid_resource_owner) unless resource_owner.respond_to?(:access_tokens)
12
12
 
13
13
  devise_api_token = yield create_devise_api_token
14
14
 
@@ -8,7 +8,7 @@ module Devise
8
8
  option :resource_owner, default: proc { devise_api_token.resource_owner }
9
9
 
10
10
  def call
11
- return Failure(:expired_refresh_token) if devise_api_token.refresh_token_expired?
11
+ return Failure(error: :expired_refresh_token) if devise_api_token.refresh_token_expired?
12
12
 
13
13
  devise_api_token = yield create_devise_api_token
14
14
  Success(devise_api_token)
@@ -8,6 +8,7 @@ en:
8
8
  expired_refresh_token: "Refresh token has expired"
9
9
  revoked_token: "Token has been revoked"
10
10
  refresh_token_disabled: "Refresh token is disabled for this application"
11
+ sign_up_disabled: "Sign up is disabled for this application"
11
12
  invalid_refresh_token: "Refresh token is invalid"
12
13
  invalid_email: "Email is invalid"
13
14
  invalid_resource_owner: "Resource owner is invalid"
@@ -20,6 +20,11 @@ module Devise
20
20
  setting :expires_in_infinite, default: proc { |_resource_owner| false }, reader: true
21
21
  end
22
22
 
23
+ setting :sign_up, reader: true do
24
+ setting :enabled, default: true, reader: true
25
+ setting :extra_fields, default: [], reader: true
26
+ end
27
+
23
28
  setting :authorization, reader: true do
24
29
  setting :key, default: 'Authorization', reader: true
25
30
  setting :scheme, default: 'Bearer', reader: true
@@ -38,18 +38,11 @@ module Devise
38
38
  end
39
39
 
40
40
  def current_devise_api_token
41
- token = find_devise_api_token
41
+ return @current_devise_api_token if @current_devise_api_token
42
42
 
43
+ token = find_devise_api_token
43
44
  devise_api_token_model = Devise.api.config.base_token_model.constantize
44
-
45
- if Devise.api.config.refresh_token.enabled
46
- return devise_api_token_model
47
- .where(access_token: token)
48
- .or(devise_api_token_model.where(refresh_token: token))
49
- &.first
50
- end
51
-
52
- devise_api_token_model.find_by(access_token: token)
45
+ @current_devise_api_token = devise_api_token_model.find_by(access_token: token)
53
46
  end
54
47
 
55
48
  def current_devise_api_user
@@ -58,6 +51,10 @@ module Devise
58
51
 
59
52
  private
60
53
 
54
+ def resource_class
55
+ current_devise_api_user&.class
56
+ end
57
+
61
58
  def extract_devise_api_token_from_params
62
59
  params[Devise.api.config.authorization.params_key]
63
60
  end
@@ -12,6 +12,7 @@ module Devise
12
12
  expired_refresh_token
13
13
  revoked_token
14
14
  refresh_token_disabled
15
+ sign_up_disabled
15
16
  invalid_refresh_token
16
17
  invalid_email
17
18
  invalid_resource_owner
@@ -112,6 +113,7 @@ module Devise
112
113
  invalid_email_error? ||
113
114
  invalid_refresh_token_error? ||
114
115
  refresh_token_disabled_error? ||
116
+ sign_up_disabled_error? ||
115
117
  invalid_resource_owner_error?
116
118
  end
117
119
  end
@@ -41,15 +41,19 @@ module Devise
41
41
  refresh_token: Devise.api.config.refresh_token.enabled ? token.refresh_token : nil,
42
42
  expires_in: token.expires_in,
43
43
  token_type: ::Devise.api.config.authorization.scheme,
44
- resource_owner: {
45
- id: resource_owner.id,
46
- email: resource_owner.email,
47
- created_at: resource_owner.created_at,
48
- updated_at: resource_owner.updated_at
49
- }
44
+ resource_owner: default_resource_owner
50
45
  }.compact
51
46
  end
52
47
 
48
+ def default_resource_owner
49
+ keys_to_extract = %i[id email created_at updated_at]
50
+ if Devise.api.config.sign_up.extra_fields.present?
51
+ keys_to_extract |= Devise.api.config.sign_up.extra_fields.map(&:to_sym)
52
+ end
53
+
54
+ resource_owner.slice(*keys_to_extract)
55
+ end
56
+
53
57
  def status
54
58
  return :created if sign_up_action?
55
59
  return :no_content if revoke_action?
@@ -41,7 +41,7 @@ module Devise
41
41
  end
42
42
 
43
43
  def inactive?
44
- revoked? && expired?
44
+ revoked? || expired?
45
45
  end
46
46
 
47
47
  def expired?
@@ -51,7 +51,7 @@ module Devise
51
51
  end
52
52
 
53
53
  def refresh_token_expired?
54
- return false unless Devise.api.config.refresh_token.expires_in_infinite.call(resource_owner)
54
+ return false if Devise.api.config.refresh_token.expires_in_infinite.call(resource_owner)
55
55
 
56
56
  Time.now.utc > refresh_token_expires_at
57
57
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Devise
4
4
  module Api
5
- VERSION = '0.1.2'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nejdetkadir
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-30 00:00:00.000000000 Z
11
+ date: 2024-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: devise
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0'
168
168
  requirements: []
169
- rubygems_version: 3.4.12
169
+ rubygems_version: 3.5.18
170
170
  signing_key:
171
171
  specification_version: 4
172
172
  summary: The devise-api gem is a convenient way to add authentication to your Ruby