devise-api 0.1.1 → 0.1.3

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: e7b573587b480d33fc2b6615142cdc7ca1c0215497fc3d3755d6a88b303a1788
4
- data.tar.gz: 4151e896ab7a40573a92bffa88383758dd96c4af22998ebc61a6167a82b9cfe1
3
+ metadata.gz: 7d47e2be72c7d15e0c0de4535943a208d8d37e7d2b801de167ccf5f5c8e3d08e
4
+ data.tar.gz: 87d42ee2c7784370789032608d0caa634f5a703c7c4cbb15139c82d34ca26664
5
5
  SHA512:
6
- metadata.gz: f5d4f26d865ea6d3341726017a82f66c911d088f518ca55fb4af10e4a01b5ed783cbee87aae6f5bca1e4fe6207d7db3404626ac6528fe1cf7b647d9e5b637bea
7
- data.tar.gz: 5789da3efd48c951b8199663f02a2bba978664b5a38a5c58c1fc752db5fb6eafdabb41af67d48241ff4bd7823a00b3b680a53e58f32ddb521164e05e858c5d83
6
+ metadata.gz: 6b6045dbf6c5906a5ef70de320d39df12f79b1c7599ce91851c98e61be2449959b0f7e263ad3a795d21070d56b9a84944d4799e1a5156fee8ae90039f8c9642e
7
+ data.tar.gz: b92e03c4fdb2d18eb3d3cf1ca690782e9f9149362b27b4535ccae3c739dbae3e14550b9e5d4535da6a3aa7658ee25936b59e49c937a3093b90b88d9477ca0f13
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devise-api (0.0.0)
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)
data/README.md CHANGED
@@ -69,6 +69,8 @@ Your user model is now ready to use `devise-api` gem. It will draw routes for to
69
69
  | sign_in_user_tokens | POST | /users/tokens/sign_in | devise/api/tokens#sign_in |
70
70
  | info_user_tokens | GET | /users/tokens/info | devise/api/tokens#info |
71
71
 
72
+ ### You can look up the [example requests](#example-api-requests).
73
+
72
74
  ## Configuration
73
75
 
74
76
  `devise-api` is a full configurable gem. You can configure it to your needs. Here is a basic usage example:
@@ -89,6 +91,8 @@ Devise.setup do |config|
89
91
  api.refresh_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }
90
92
  api.refresh_token.expires_in_infinite = ->(_resource_owner) { false }
91
93
 
94
+ # Sign up
95
+ api.sign_up.enabled = true
92
96
 
93
97
  # Authorization
94
98
  api.authorization.key = 'Authorization'
@@ -226,9 +230,49 @@ class Api::V1::TokensController < YourBaseController
226
230
  end
227
231
  ```
228
232
 
233
+ ## Example API requests
234
+
235
+ ### Sign in
236
+ ```curl
237
+ curl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_in' \
238
+ --header 'Content-Type: application/json' \
239
+ --data-raw '{
240
+ "email": "test@development.com",
241
+ "password": "123456"
242
+ }'
243
+ ```
244
+
245
+ ### Sign up
246
+ ```curl
247
+ curl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_up' \
248
+ --header 'Content-Type: application/json' \
249
+ --data-raw '{
250
+ "email": "test@development.com",
251
+ "password": "123456"
252
+ }'
253
+ ```
254
+
255
+ ### Refresh token
256
+ ```curl
257
+ curl --location --request POST 'http://127.0.0.1:3000/users/tokens/refresh' \
258
+ --header 'Authorization: Bearer <refresh_token>'
259
+ ```
260
+
261
+ ### Revoke
262
+ ```curl
263
+ curl --location --request POST 'http://127.0.0.1:3000/users/tokens/revoke' \
264
+ --header 'Authorization: Bearer <access_token>'
265
+ ```
266
+
267
+ ### Info
268
+ ```curl
269
+ curl --location --request GET 'http://127.0.0.1:3000/users/tokens/info' \
270
+ --header 'Authorization: Bearer <access_token>'
271
+ ```
272
+
229
273
  ## Development
230
274
 
231
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
275
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
232
276
 
233
277
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
234
278
 
@@ -1,15 +1,23 @@
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
6
7
  skip_before_action :verify_authenticity_token, raise: false
7
- before_action :authenticate_devise_api_token!, only: %i[info refresh]
8
+ before_action :authenticate_devise_api_token!, only: %i[info]
8
9
 
9
10
  respond_to :json
10
11
 
11
12
  # rubocop:disable Metrics/AbcSize
12
13
  def sign_up
14
+ unless Devise.api.config.sign_up.enabled
15
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :sign_up_disabled,
16
+ resource_class: resource_class)
17
+
18
+ return render json: error_response.body, status: error_response.status
19
+ end
20
+
13
21
  Devise.api.config.before_sign_up.call(sign_up_params, request, resource_class)
14
22
 
15
23
  service = Devise::Api::ResourceOwnerService::SignUp.new(params: sign_up_params,
@@ -103,9 +111,23 @@ module Devise
103
111
  return render json: error_response.body, status: error_response.status
104
112
  end
105
113
 
106
- Devise.api.config.before_refresh.call(current_devise_api_token, request)
114
+ if current_devise_api_refresh_token.blank?
115
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :invalid_token,
116
+ resource_class: resource_class)
117
+
118
+ return render json: error_response.body, status: error_response.status
119
+ end
120
+
121
+ if current_devise_api_refresh_token.revoked?
122
+ error_response = Devise::Api::Responses::ErrorResponse.new(request, error: :revoked_token,
123
+ resource_class: resource_class)
124
+
125
+ render json: error_response.body, status: error_response.status
126
+ end
127
+
128
+ Devise.api.config.before_refresh.call(current_devise_api_refresh_token, request)
107
129
 
108
- service = Devise::Api::TokensService::Refresh.new(devise_api_token: current_devise_api_token).call
130
+ service = Devise::Api::TokensService::Refresh.new(devise_api_token: current_devise_api_refresh_token).call
109
131
 
110
132
  if service.success?
111
133
  token_response = Devise::Api::Responses::TokenResponse.new(request, token: service.success,
@@ -141,6 +163,15 @@ module Devise
141
163
 
142
164
  resource_owner.update_tracked_fields!(request)
143
165
  end
166
+
167
+ def current_devise_api_refresh_token
168
+ return @current_devise_api_refresh_token if @current_devise_api_refresh_token
169
+
170
+ token = find_devise_api_token
171
+ devise_api_token_model = Devise.api.config.base_token_model.constantize
172
+ @current_devise_api_refresh_token = devise_api_token_model.find_by(refresh_token: token)
173
+ end
144
174
  end
145
175
  end
146
176
  end
177
+ # 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,10 @@ 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
+ end
26
+
23
27
  setting :authorization, reader: true do
24
28
  setting :key, default: 'Authorization', reader: true
25
29
  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
@@ -40,22 +40,6 @@ module Devise
40
40
  def migration_version
41
41
  "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
42
42
  end
43
-
44
- def primary_key_type
45
- fallback = :integer
46
-
47
- begin
48
- ActiveRecord::Base.connection.supports_pgcrypto_uuid? ? :uuid : fallback
49
- rescue StandardError
50
- fallback
51
- end
52
- end
53
-
54
- def table_defaults_for_primary_key_type
55
- return ', type: :uuid' if primary_key_type == :uuid
56
-
57
- ''
58
- end
59
43
  end
60
44
  end
61
45
  end
@@ -2,8 +2,11 @@
2
2
 
3
3
  class CreateDeviseApiTables < ActiveRecord::Migration<%= migration_version %>
4
4
  def change
5
- create_table :devise_api_tokens<%= table_defaults_for_primary_key_type %> do |t|
6
- t.belongs_to :resource_owner, null: false<%= table_defaults_for_primary_key_type %>, polymorphic: true, index: true
5
+ # Use Active Record's configured type for primary and foreign keys
6
+ primary_key_type, foreign_key_type = primary_and_foreign_key_types
7
+
8
+ create_table :devise_api_tokens, id: primary_key_type do |t|
9
+ t.belongs_to :resource_owner, null: false, polymorphic: true, index: true, type: foreign_key_type
7
10
  t.string :access_token, null: false, index: true
8
11
  t.string :refresh_token, null: true, index: true
9
12
  t.integer :expires_in, null: false
@@ -13,4 +16,14 @@ class CreateDeviseApiTables < ActiveRecord::Migration<%= migration_version %>
13
16
  t.timestamps
14
17
  end
15
18
  end
19
+
20
+ private
21
+
22
+ def primary_and_foreign_key_types
23
+ config = Rails.configuration.generators
24
+ setting = config.options[config.orm][:primary_key_type]
25
+ primary_key_type = setting || :primary_key
26
+ foreign_key_type = setting || :bigint
27
+ [primary_key_type, foreign_key_type]
28
+ end
16
29
  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,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.1'
5
+ VERSION = '0.1.3'
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.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - nejdetkadir
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-14 00:00:00.000000000 Z
11
+ date: 2023-08-08 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.3.3
169
+ rubygems_version: 3.4.12
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