devise_token_auth 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/devise_token_auth/application_controller.rb +8 -0
  3. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +14 -1
  4. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +31 -7
  5. data/app/controllers/devise_token_auth/confirmations_controller.rb +8 -4
  6. data/app/controllers/devise_token_auth/passwords_controller.rb +6 -2
  7. data/app/controllers/devise_token_auth/sessions_controller.rb +7 -1
  8. data/app/controllers/devise_token_auth/unlocks_controller.rb +6 -2
  9. data/app/models/devise_token_auth/concerns/active_record_support.rb +0 -2
  10. data/app/models/devise_token_auth/concerns/confirmable_support.rb +2 -1
  11. data/app/models/devise_token_auth/concerns/tokens_serialization.rb +16 -4
  12. data/app/models/devise_token_auth/concerns/user.rb +4 -9
  13. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +3 -0
  14. data/app/validators/devise_token_auth_email_validator.rb +1 -1
  15. data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
  16. data/config/locales/en.yml +3 -0
  17. data/lib/devise_token_auth/blacklist.rb +5 -1
  18. data/lib/devise_token_auth/controllers/helpers.rb +5 -9
  19. data/lib/devise_token_auth/engine.rb +6 -0
  20. data/lib/devise_token_auth/rails/routes.rb +15 -10
  21. data/lib/devise_token_auth/version.rb +1 -1
  22. data/lib/generators/devise_token_auth/install_generator.rb +1 -1
  23. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +1 -1
  24. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +91 -19
  25. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +2 -2
  26. data/test/controllers/devise_token_auth/passwords_controller_test.rb +73 -21
  27. data/test/controllers/devise_token_auth/registrations_controller_test.rb +28 -15
  28. data/test/controllers/devise_token_auth/sessions_controller_test.rb +39 -10
  29. data/test/controllers/devise_token_auth/unlocks_controller_test.rb +21 -4
  30. data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
  31. data/test/dummy/app/views/layouts/application.html.erb +0 -2
  32. data/test/dummy/config/application.rb +0 -1
  33. data/test/dummy/config/environments/development.rb +0 -10
  34. data/test/dummy/config/environments/production.rb +0 -16
  35. data/test/dummy/tmp/generators/app/controllers/application_controller.rb +6 -0
  36. data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +56 -0
  37. data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +60 -0
  38. data/test/lib/devise_token_auth/blacklist_test.rb +11 -3
  39. data/test/lib/devise_token_auth/rails/custom_routes_test.rb +29 -0
  40. data/test/lib/devise_token_auth/rails/routes_test.rb +87 -0
  41. data/test/lib/generators/devise_token_auth/install_generator_test.rb +1 -1
  42. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +1 -1
  43. data/test/models/concerns/tokens_serialization_test.rb +39 -5
  44. data/test/test_helper.rb +35 -4
  45. metadata +15 -25
  46. data/test/dummy/config/initializers/assets.rb +0 -10
  47. data/test/dummy/tmp/generators/app/views/devise/mailer/confirmation_instructions.html.erb +0 -5
  48. data/test/dummy/tmp/generators/app/views/devise/mailer/reset_password_instructions.html.erb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 395c104491ef2762e5c41f0b35af5f2421f8d24c99cc10145231d1cb2cab2d70
4
- data.tar.gz: c637be9bc9c731f1b6218002925c0e558dbc62f2d6fb999fdd187d31d60e20c4
3
+ metadata.gz: fb2d73d7859e1754b505d6f554c8d298ba899444b4fe4e1b47d50ca9bab453e8
4
+ data.tar.gz: 3572d4ff07d68f62d8e51270959fd20451d9edb4832d576b9342939275390dee
5
5
  SHA512:
6
- metadata.gz: a1a184d38110e9157c941f1b5e2b8a0cdd7901702f12c7316a4ffba2b5af239455bddc9c288d8fbbd2c909aadfdfe388283c16abcce1814abf595cfe853e3c51
7
- data.tar.gz: 7ac1939d622a50f46e9ce3943826b85e67e9457178bba79326c5656f4c8fbacc5205b44828aa4935be4c2c4dc713f68ab1d44b8d7485ced86fa90416769e1431
6
+ metadata.gz: 50c95181401bedfd959a407d450f222ab185d75000825385dd691a064e831b36263eb1338d25f6378a743ac9009b73f80df3e24cb09ce5680a0e6723fc98acb9
7
+ data.tar.gz: 91910874d7e473d31eb39cf40c6860da4ab5b59aa874a0f1296faa17718103124018568cf289486a9d49a3ec1b967f14e23c18afb8d3f6cd3ec2fd837d663a83
@@ -75,5 +75,13 @@ module DeviseTokenAuth
75
75
  response = response.merge(data) if data
76
76
  render json: response, status: status
77
77
  end
78
+
79
+ def success_message(name, email)
80
+ if Devise.paranoid
81
+ I18n.t("devise_token_auth.#{name}.sended_paranoid")
82
+ else
83
+ I18n.t("devise_token_auth.#{name}.sended", email: email)
84
+ end
85
+ end
78
86
  end
79
87
  end
@@ -20,7 +20,7 @@ module DeviseTokenAuth::Concerns::ResourceFinder
20
20
  end
21
21
 
22
22
  def find_resource(field, value)
23
- @resource = if resource_class.try(:connection_config).try(:[], :adapter).try(:include?, 'mysql')
23
+ @resource = if database_adapter&.include?('mysql')
24
24
  # fix for mysql default case insensitivity
25
25
  resource_class.where("BINARY #{field} = ? AND provider= ?", value, provider).first
26
26
  else
@@ -28,6 +28,19 @@ module DeviseTokenAuth::Concerns::ResourceFinder
28
28
  end
29
29
  end
30
30
 
31
+ def database_adapter
32
+ @database_adapter ||= begin
33
+ rails_version = [Rails::VERSION::MAJOR, Rails::VERSION::MINOR].join(".")
34
+
35
+ adapter =
36
+ if rails_version >= "6.1"
37
+ resource_class.try(:connection_db_config)&.try(:adapter)
38
+ else
39
+ resource_class.try(:connection_config)&.try(:[], :adapter)
40
+ end
41
+ end
42
+ end
43
+
31
44
  def resource_class(m = nil)
32
45
  mapping = if m
33
46
  Devise.mappings[m]
@@ -17,7 +17,7 @@ module DeviseTokenAuth::Concerns::SetUserByToken
17
17
  @used_auth_by_token = true
18
18
 
19
19
  # initialize instance variables
20
- @token = DeviseTokenAuth::TokenFactory.new
20
+ @token ||= DeviseTokenAuth::TokenFactory.new
21
21
  @resource ||= nil
22
22
  @is_batch_request ||= nil
23
23
  end
@@ -35,18 +35,27 @@ module DeviseTokenAuth::Concerns::SetUserByToken
35
35
  access_token_name = DeviseTokenAuth.headers_names[:'access-token']
36
36
  client_name = DeviseTokenAuth.headers_names[:'client']
37
37
 
38
+ # gets values from cookie if configured and present
39
+ parsed_auth_cookie = {}
40
+ if DeviseTokenAuth.cookie_enabled
41
+ auth_cookie = request.cookies[DeviseTokenAuth.cookie_name]
42
+ if auth_cookie.present?
43
+ parsed_auth_cookie = JSON.parse(auth_cookie)
44
+ end
45
+ end
46
+
38
47
  # parse header for values necessary for authentication
39
- uid = request.headers[uid_name] || params[uid_name]
48
+ uid = request.headers[uid_name] || params[uid_name] || parsed_auth_cookie[uid_name]
40
49
  @token = DeviseTokenAuth::TokenFactory.new unless @token
41
- @token.token ||= request.headers[access_token_name] || params[access_token_name]
42
- @token.client ||= request.headers[client_name] || params[client_name]
50
+ @token.token ||= request.headers[access_token_name] || params[access_token_name] || parsed_auth_cookie[access_token_name]
51
+ @token.client ||= request.headers[client_name] || params[client_name] || parsed_auth_cookie[client_name]
43
52
 
44
53
  # client isn't required, set to 'default' if absent
45
54
  @token.client ||= 'default'
46
55
 
47
56
  # check for an existing user, authenticated via warden/devise, if enabled
48
57
  if DeviseTokenAuth.enable_standard_devise_support
49
- devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
58
+ devise_warden_user = warden.user(mapping)
50
59
  if devise_warden_user && devise_warden_user.tokens[@token.client].nil?
51
60
  @used_auth_by_token = false
52
61
  @resource = devise_warden_user
@@ -101,9 +110,13 @@ module DeviseTokenAuth::Concerns::SetUserByToken
101
110
  # update the response header
102
111
  response.headers.merge!(auth_header)
103
112
 
113
+ # set a server cookie if configured
114
+ if DeviseTokenAuth.cookie_enabled
115
+ set_cookie(auth_header)
116
+ end
104
117
  else
105
118
  unless @resource.reload.valid?
106
- @resource = resource_class.find(@resource.to_param) # errors remain after reload
119
+ @resource = @resource.class.find(@resource.to_param) # errors remain after reload
107
120
  # if we left the model in a bad state, something is wrong in our app
108
121
  unless @resource.valid?
109
122
  raise DeviseTokenAuth::Errors::InvalidModel, "Cannot set auth token in invalid model. Errors: #{@resource.errors.full_messages}"
@@ -123,11 +136,22 @@ module DeviseTokenAuth::Concerns::SetUserByToken
123
136
  # cleared by sign out in the meantime
124
137
  return if @used_auth_by_token && @resource.tokens[@token.client].nil?
125
138
 
139
+ _auth_header_from_batch_request = auth_header_from_batch_request
140
+
126
141
  # update the response header
127
- response.headers.merge!(auth_header_from_batch_request)
142
+ response.headers.merge!(_auth_header_from_batch_request)
143
+
144
+ # set a server cookie if configured
145
+ if DeviseTokenAuth.cookie_enabled
146
+ set_cookie(_auth_header_from_batch_request)
147
+ end
128
148
  end # end lock
129
149
  end
130
150
 
151
+ def set_cookie(auth_header)
152
+ cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json)
153
+ end
154
+
131
155
  def is_batch_request?(user, client)
132
156
  !params[:unbatch] &&
133
157
  user.tokens[client] &&
@@ -55,13 +55,17 @@ module DeviseTokenAuth
55
55
 
56
56
  def render_create_success
57
57
  render json: {
58
- success: true,
59
- message: I18n.t('devise_token_auth.confirmations.sended', email: @email)
60
- }
58
+ success: true,
59
+ message: success_message('confirmations', @email)
60
+ }
61
61
  end
62
62
 
63
63
  def render_not_found_error
64
- render_error(404, I18n.t('devise_token_auth.confirmations.user_not_found', email: @email))
64
+ if Devise.paranoid
65
+ render_error(404, I18n.t('devise_token_auth.confirmations.sended_paranoid'))
66
+ else
67
+ render_error(404, I18n.t('devise_token_auth.confirmations.user_not_found', email: @email))
68
+ end
65
69
  end
66
70
 
67
71
  private
@@ -128,7 +128,7 @@ module DeviseTokenAuth
128
128
  def render_create_success
129
129
  render json: {
130
130
  success: true,
131
- message: I18n.t('devise_token_auth.passwords.sended', email: @email)
131
+ message: success_message('passwords', @email)
132
132
  }
133
133
  end
134
134
 
@@ -181,7 +181,11 @@ module DeviseTokenAuth
181
181
  end
182
182
 
183
183
  def render_not_found_error
184
- render_error(404, I18n.t('devise_token_auth.passwords.user_not_found', email: @email))
184
+ if Devise.paranoid
185
+ render_error(404, I18n.t('devise_token_auth.passwords.sended_paranoid'))
186
+ else
187
+ render_error(404, I18n.t('devise_token_auth.passwords.user_not_found', email: @email))
188
+ end
185
189
  end
186
190
 
187
191
  def validate_redirect_url_param
@@ -48,13 +48,19 @@ module DeviseTokenAuth
48
48
  def destroy
49
49
  # remove auth instance variables so that after_action does not run
50
50
  user = remove_instance_variable(:@resource) if @resource
51
- client = @token.client if @token.client
51
+ client = @token.client
52
52
  @token.clear!
53
53
 
54
54
  if user && client && user.tokens[client]
55
55
  user.tokens.delete(client)
56
56
  user.save!
57
57
 
58
+ if DeviseTokenAuth.cookie_enabled
59
+ # If a cookie is set with a domain specified then it must be deleted with that domain specified
60
+ # See https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
61
+ cookies.delete(DeviseTokenAuth.cookie_name, domain: DeviseTokenAuth.cookie_attributes[:domain])
62
+ end
63
+
58
64
  yield user if block_given?
59
65
 
60
66
  render_destroy_success
@@ -63,7 +63,7 @@ module DeviseTokenAuth
63
63
  def render_create_success
64
64
  render json: {
65
65
  success: true,
66
- message: I18n.t('devise_token_auth.unlocks.sended', email: @email)
66
+ message: success_message('unlocks', @email)
67
67
  }
68
68
  end
69
69
 
@@ -79,7 +79,11 @@ module DeviseTokenAuth
79
79
  end
80
80
 
81
81
  def render_not_found_error
82
- render_error(404, I18n.t('devise_token_auth.unlocks.user_not_found', email: @email))
82
+ if Devise.paranoid
83
+ render_error(404, I18n.t('devise_token_auth.unlocks.sended_paranoid'))
84
+ else
85
+ render_error(404, I18n.t('devise_token_auth.unlocks.user_not_found', email: @email))
86
+ end
83
87
  end
84
88
 
85
89
  def resource_params
@@ -1,5 +1,3 @@
1
- require_relative 'tokens_serialization'
2
-
3
1
  module DeviseTokenAuth::Concerns::ActiveRecordSupport
4
2
  extend ActiveSupport::Concern
5
3
 
@@ -18,7 +18,8 @@ module DeviseTokenAuth::Concerns::ConfirmableSupport
18
18
  protected
19
19
 
20
20
  def email_value_in_database
21
- if Devise.rails51? && respond_to?(:email_in_database)
21
+ rails51 = Rails.gem_version >= Gem::Version.new("5.1.x")
22
+ if rails51 && respond_to?(:email_in_database)
22
23
  email_in_database
23
24
  else
24
25
  email_was
@@ -1,12 +1,14 @@
1
1
  module DeviseTokenAuth::Concerns::TokensSerialization
2
+ extend self
2
3
  # Serialization hash to json
3
- def self.dump(object)
4
- object.each_value(&:compact!) unless object.nil?
5
- JSON.generate(object)
4
+ def dump(object)
5
+ JSON.generate(object && object.transform_values do |token|
6
+ serialize_updated_at(token).compact
7
+ end.compact)
6
8
  end
7
9
 
8
10
  # Deserialization json to hash
9
- def self.load(json)
11
+ def load(json)
10
12
  case json
11
13
  when String
12
14
  JSON.parse(json)
@@ -16,4 +18,14 @@ module DeviseTokenAuth::Concerns::TokensSerialization
16
18
  json
17
19
  end
18
20
  end
21
+
22
+ private
23
+
24
+ def serialize_updated_at(token)
25
+ updated_at_key = ['updated_at', :updated_at].find(&token.method(:[]))
26
+
27
+ return token unless token[updated_at_key].respond_to?(:iso8601)
28
+
29
+ token.merge updated_at_key => token[updated_at_key].iso8601
30
+ end
19
31
  end
@@ -158,7 +158,7 @@ module DeviseTokenAuth::Concerns::User
158
158
  token = create_token(
159
159
  client: client,
160
160
  last_token: tokens.fetch(client, {})['token'],
161
- updated_at: now.to_s(:rfc822)
161
+ updated_at: now
162
162
  )
163
163
 
164
164
  update_auth_header(token.token, token.client)
@@ -194,7 +194,7 @@ module DeviseTokenAuth::Concerns::User
194
194
  end
195
195
 
196
196
  def extend_batch_buffer(token, client)
197
- tokens[client]['updated_at'] = Time.zone.now.to_s(:rfc822)
197
+ tokens[client]['updated_at'] = Time.zone.now
198
198
  update_auth_header(token, client)
199
199
  end
200
200
 
@@ -218,13 +218,8 @@ module DeviseTokenAuth::Concerns::User
218
218
  end
219
219
 
220
220
  def should_remove_tokens_after_password_reset?
221
- if Rails::VERSION::MAJOR <= 5 ||defined?('Mongoid')
222
- encrypted_password_changed? &&
223
- DeviseTokenAuth.remove_tokens_after_password_reset
224
- else
225
- saved_change_to_attribute?(:encrypted_password) &&
226
- DeviseTokenAuth.remove_tokens_after_password_reset
227
- end
221
+ DeviseTokenAuth.remove_tokens_after_password_reset &&
222
+ (respond_to?(:encrypted_password_changed?) && encrypted_password_changed?)
228
223
  end
229
224
 
230
225
  def remove_tokens_after_password_reset
@@ -23,6 +23,9 @@ module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
23
23
  end
24
24
 
25
25
  def sync_uid
26
+ unless self.new_record?
27
+ return if devise_modules.include?(:confirmable) && !@bypass_confirmation_postpone && postpone_email_change?
28
+ end
26
29
  self.uid = email if email_provider?
27
30
  end
28
31
  end
@@ -3,7 +3,7 @@
3
3
  class DeviseTokenAuthEmailValidator < ActiveModel::EachValidator
4
4
  def validate_each(record, attribute, value)
5
5
  unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
6
- record.errors[attribute] << email_invalid_message
6
+ record.errors.add(attribute, email_invalid_message)
7
7
  end
8
8
  end
9
9
 
@@ -15,7 +15,7 @@
15
15
  Cordova / PhoneGap)
16
16
  */
17
17
 
18
- var data = JSON.parse(decodeURIComponent('<%= URI::escape( @data.to_json ) %>'));
18
+ var data = JSON.parse(decodeURIComponent('<%= ERB::Util.url_encode( @data.to_json ) %>'));
19
19
 
20
20
  window.addEventListener("message", function(ev) {
21
21
  if (ev.data === "requestCredentials") {
@@ -21,6 +21,7 @@ en:
21
21
  missing_redirect_url: "Missing redirect URL."
22
22
  not_allowed_redirect_url: "Redirect to '%{redirect_url}' not allowed."
23
23
  sended: "An email has been sent to '%{email}' containing instructions for resetting your password."
24
+ sended_paranoid: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
24
25
  user_not_found: "Unable to find user with email '%{email}'."
25
26
  password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
26
27
  missing_passwords: "You must fill out the fields labeled 'Password' and 'Password confirmation'."
@@ -28,9 +29,11 @@ en:
28
29
  unlocks:
29
30
  missing_email: "You must provide an email address."
30
31
  sended: "An email has been sent to '%{email}' containing instructions for unlocking your account."
32
+ sended_paranoid: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
31
33
  user_not_found: "Unable to find user with email '%{email}'."
32
34
  confirmations:
33
35
  sended: "An email has been sent to '%{email}' containing instructions for confirming your account."
36
+ sended_paranoid: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
34
37
  user_not_found: "Unable to find user with email '%{email}'."
35
38
  missing_email: "You must provide an email address."
36
39
 
@@ -1,2 +1,6 @@
1
1
  # don't serialize tokens
2
- Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION << :tokens
2
+ if defined? Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
3
+ Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION << :tokens
4
+ else
5
+ Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION << :tokens
6
+ end
@@ -34,12 +34,6 @@ module DeviseTokenAuth
34
34
  class_eval <<-METHODS, __FILE__, __LINE__ + 1
35
35
  def authenticate_#{group_name}!(favourite=nil, opts={})
36
36
  unless #{group_name}_signed_in?
37
- mappings = #{mappings}
38
- mappings.unshift mappings.delete(favourite.to_sym) if favourite
39
- mappings.each do |mapping|
40
- set_user_by_token(mapping)
41
- end
42
-
43
37
  unless current_#{group_name}
44
38
  render_authenticate_error
45
39
  end
@@ -47,12 +41,14 @@ module DeviseTokenAuth
47
41
  end
48
42
 
49
43
  def #{group_name}_signed_in?
50
- #{mappings}.any? do |mapping|
51
- set_user_by_token(mapping)
52
- end
44
+ !!current_#{group_name}
53
45
  end
54
46
 
55
47
  def current_#{group_name}(favourite=nil)
48
+ @current_#{group_name} ||= set_group_user_by_token(favourite)
49
+ end
50
+
51
+ def set_group_user_by_token(favourite)
56
52
  mappings = #{mappings}
57
53
  mappings.unshift mappings.delete(favourite.to_sym) if favourite
58
54
  mappings.each do |mapping|
@@ -25,6 +25,9 @@ module DeviseTokenAuth
25
25
  :remove_tokens_after_password_reset,
26
26
  :default_callbacks,
27
27
  :headers_names,
28
+ :cookie_enabled,
29
+ :cookie_name,
30
+ :cookie_attributes,
28
31
  :bypass_sign_in,
29
32
  :send_confirmation_email,
30
33
  :require_client_password_reset_token
@@ -47,6 +50,9 @@ module DeviseTokenAuth
47
50
  'expiry': 'expiry',
48
51
  'uid': 'uid',
49
52
  'token-type': 'token-type' }
53
+ self.cookie_enabled = false
54
+ self.cookie_name = 'auth_cookie'
55
+ self.cookie_attributes = {}
50
56
  self.bypass_sign_in = true
51
57
  self.send_confirmation_email = false
52
58
  self.require_client_password_reset_token = false
@@ -8,26 +8,31 @@ module ActionDispatch::Routing
8
8
  opts[:skip] ||= []
9
9
 
10
10
  # check for ctrl overrides, fall back to defaults
11
- sessions_ctrl = opts[:controllers][:sessions] || 'devise_token_auth/sessions'
12
- registrations_ctrl = opts[:controllers][:registrations] || 'devise_token_auth/registrations'
13
- passwords_ctrl = opts[:controllers][:passwords] || 'devise_token_auth/passwords'
14
- confirmations_ctrl = opts[:controllers][:confirmations] || 'devise_token_auth/confirmations'
15
- token_validations_ctrl = opts[:controllers][:token_validations] || 'devise_token_auth/token_validations'
16
- omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || 'devise_token_auth/omniauth_callbacks'
17
- unlocks_ctrl = opts[:controllers][:unlocks] || 'devise_token_auth/unlocks'
11
+ sessions_ctrl = opts[:controllers].delete(:sessions) || 'devise_token_auth/sessions'
12
+ registrations_ctrl = opts[:controllers].delete(:registrations) || 'devise_token_auth/registrations'
13
+ passwords_ctrl = opts[:controllers].delete(:passwords) || 'devise_token_auth/passwords'
14
+ confirmations_ctrl = opts[:controllers].delete(:confirmations) || 'devise_token_auth/confirmations'
15
+ token_validations_ctrl = opts[:controllers].delete(:token_validations) || 'devise_token_auth/token_validations'
16
+ omniauth_ctrl = opts[:controllers].delete(:omniauth_callbacks) || 'devise_token_auth/omniauth_callbacks'
17
+ unlocks_ctrl = opts[:controllers].delete(:unlocks) || 'devise_token_auth/unlocks'
18
+
19
+ # check for resource override
20
+ route = opts[:as] || resource.pluralize.underscore.gsub('/', '_')
18
21
 
19
22
  # define devise controller mappings
20
- controllers = { sessions: sessions_ctrl,
23
+ controllers = opts[:controllers].merge(
24
+ sessions: sessions_ctrl,
21
25
  registrations: registrations_ctrl,
22
26
  passwords: passwords_ctrl,
23
- confirmations: confirmations_ctrl }
27
+ confirmations: confirmations_ctrl
28
+ )
24
29
 
25
30
  controllers[:unlocks] = unlocks_ctrl if unlocks_ctrl
26
31
 
27
32
  # remove any unwanted devise modules
28
33
  opts[:skip].each{ |item| controllers.delete(item) }
29
34
 
30
- devise_for resource.pluralize.underscore.gsub('/', '_').to_sym,
35
+ devise_for route.to_sym,
31
36
  class_name: resource,
32
37
  module: :devise,
33
38
  path: opts[:at].to_s,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeviseTokenAuth
4
- VERSION = '1.1.4'.freeze
4
+ VERSION = '1.2.0'.freeze
5
5
  end
@@ -26,7 +26,7 @@ module DeviseTokenAuth
26
26
  inclusion = 'include DeviseTokenAuth::Concerns::User'
27
27
  unless parse_file_for_line(fname, inclusion)
28
28
 
29
- active_record_needle = (Rails::VERSION::MAJOR == 5) ? 'ApplicationRecord' : 'ActiveRecord::Base'
29
+ active_record_needle = (Rails::VERSION::MAJOR >= 5) ? 'ApplicationRecord' : 'ActiveRecord::Base'
30
30
  inject_into_file fname, after: "class #{user_class} < #{active_record_needle}\n" do <<-'RUBY'
31
31
  # Include default devise modules.
32
32
  devise :database_authenticatable, :registerable,
@@ -44,6 +44,6 @@ class DeviseTokenAuthCreate<%= user_class.pluralize.gsub("::","") %> < ActiveRec
44
44
  add_index :<%= table_name %>, [:uid, :provider], unique: true
45
45
  add_index :<%= table_name %>, :reset_password_token, unique: true
46
46
  add_index :<%= table_name %>, :confirmation_token, unique: true
47
- # add_index :<%= table_name %>, :unlock_token, unique: true
47
+ # add_index :<%= table_name %>, :unlock_token, unique: true
48
48
  end
49
49
  end
@@ -92,30 +92,102 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase
92
92
  end
93
93
 
94
94
  describe 'resend confirmation' do
95
- before do
96
- post :create,
97
- params: { email: @new_user.email,
98
- redirect_url: @redirect_url },
99
- xhr: true
100
- @resource = assigns(:resource)
101
-
102
- @mail = ActionMailer::Base.deliveries.last
103
- @token, @client_config = token_and_client_config_from(@mail.body)
104
- end
105
-
106
- test 'user should not be confirmed' do
107
- assert_nil @resource.confirmed_at
95
+ describe 'without paranoid mode' do
96
+
97
+ describe 'on success' do
98
+ before do
99
+ post :create,
100
+ params: { email: @new_user.email,
101
+ redirect_url: @redirect_url },
102
+ xhr: true
103
+ @resource = assigns(:resource)
104
+ @data = JSON.parse(response.body)
105
+ @mail = ActionMailer::Base.deliveries.last
106
+ @token, @client_config = token_and_client_config_from(@mail.body)
107
+ end
108
+
109
+ test 'user should not be confirmed' do
110
+ assert_nil @resource.confirmed_at
111
+ end
112
+
113
+ test 'should generate raw token' do
114
+ assert @token
115
+ assert_equal @new_user.confirmation_token, @token
116
+ end
117
+
118
+ test 'user should receive confirmation email' do
119
+ assert_equal @resource.email, @mail['to'].to_s
120
+ end
121
+
122
+ test 'response should contain message' do
123
+ assert_equal @data['message'], I18n.t('devise_token_auth.confirmations.sended', email: @resource.email)
124
+ end
125
+ end
126
+
127
+ describe 'on failure' do
128
+ before do
129
+ post :create,
130
+ params: { email: 'chester@cheet.ah',
131
+ redirect_url: @redirect_url },
132
+ xhr: true
133
+ @data = JSON.parse(response.body)
134
+ end
135
+
136
+ test 'response should contain errors' do
137
+ assert_equal @data['errors'], [I18n.t('devise_token_auth.confirmations.user_not_found', email: 'chester@cheet.ah')]
138
+ end
139
+ end
108
140
  end
141
+ end
109
142
 
110
- test 'should generate raw token' do
111
- assert @token
112
- assert_equal @new_user.confirmation_token, @token
143
+ describe 'with paranoid mode' do
144
+ describe 'on success' do
145
+ before do
146
+ swap Devise, paranoid: true do
147
+ post :create,
148
+ params: { email: @new_user.email,
149
+ redirect_url: @redirect_url },
150
+ xhr: true
151
+ @resource = assigns(:resource)
152
+ @data = JSON.parse(response.body)
153
+ @mail = ActionMailer::Base.deliveries.last
154
+ @token, @client_config = token_and_client_config_from(@mail.body)
155
+ end
156
+ end
157
+
158
+ test 'user should not be confirmed' do
159
+ assert_nil @resource.confirmed_at
160
+ end
161
+
162
+ test 'should generate raw token' do
163
+ assert @token
164
+ assert_equal @new_user.confirmation_token, @token
165
+ end
166
+
167
+ test 'user should receive confirmation email' do
168
+ assert_equal @resource.email, @mail['to'].to_s
169
+ end
170
+
171
+ test 'response should contain message' do
172
+ assert_equal @data['message'], I18n.t('devise_token_auth.confirmations.sended_paranoid', email: @resource.email)
173
+ end
113
174
  end
114
175
 
115
- test 'user should receive confirmation email' do
116
- assert_equal @resource.email, @mail['to'].to_s
176
+ describe 'on failure' do
177
+ before do
178
+ swap Devise, paranoid: true do
179
+ post :create,
180
+ params: { email: 'chester@cheet.ah',
181
+ redirect_url: @redirect_url },
182
+ xhr: true
183
+ @data = JSON.parse(response.body)
184
+ end
185
+ end
186
+
187
+ test 'response should contain errors' do
188
+ assert_equal @data['errors'], [I18n.t('devise_token_auth.confirmations.sended_paranoid')]
189
+ end
117
190
  end
118
-
119
191
  end
120
192
  end
121
193
 
@@ -18,7 +18,7 @@ class OmniauthTest < ActionDispatch::IntegrationTest
18
18
 
19
19
  def get_parsed_data_json
20
20
  encoded_json_data = @response.body.match(/var data \= JSON.parse\(decodeURIComponent\(\'(.+)\'\)\)\;/)[1]
21
- JSON.parse(URI.unescape(encoded_json_data))
21
+ JSON.parse(CGI.unescape(encoded_json_data))
22
22
  end
23
23
 
24
24
  describe 'success callback' do
@@ -346,7 +346,7 @@ class OmniauthTest < ActionDispatch::IntegrationTest
346
346
  follow_all_redirects!
347
347
 
348
348
  data = get_parsed_data_json
349
- assert_equal "Redirect to &#39;#{@bad_redirect_url}&#39; not allowed.",
349
+ assert_equal "Redirect to '#{@bad_redirect_url}' not allowed.",
350
350
  data['error']
351
351
  end
352
352