devise_token_auth 0.1.43 → 1.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.
Files changed (183) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +42 -895
  3. data/Rakefile +11 -4
  4. data/app/controllers/devise_token_auth/application_controller.rb +19 -8
  5. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +26 -12
  6. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +106 -85
  7. data/app/controllers/devise_token_auth/confirmations_controller.rb +73 -17
  8. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +95 -51
  9. data/app/controllers/devise_token_auth/passwords_controller.rb +65 -57
  10. data/app/controllers/devise_token_auth/registrations_controller.rb +61 -61
  11. data/app/controllers/devise_token_auth/sessions_controller.rb +22 -18
  12. data/app/controllers/devise_token_auth/token_validations_controller.rb +5 -3
  13. data/app/controllers/devise_token_auth/unlocks_controller.rb +20 -16
  14. data/app/models/devise_token_auth/concerns/active_record_support.rb +14 -0
  15. data/app/models/devise_token_auth/concerns/confirmable_support.rb +28 -0
  16. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  17. data/app/models/devise_token_auth/concerns/tokens_serialization.rb +31 -0
  18. data/app/models/devise_token_auth/concerns/user.rb +92 -100
  19. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +8 -3
  20. data/app/validators/{email_validator.rb → devise_token_auth_email_validator.rb} +5 -3
  21. data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
  22. data/config/locales/da-DK.yml +11 -9
  23. data/config/locales/de.yml +2 -0
  24. data/config/locales/en.yml +10 -0
  25. data/config/locales/es.yml +2 -0
  26. data/config/locales/fr.yml +2 -0
  27. data/config/locales/he.yml +52 -0
  28. data/config/locales/it.yml +2 -0
  29. data/config/locales/ja.yml +4 -2
  30. data/config/locales/ko.yml +51 -0
  31. data/config/locales/nl.yml +2 -0
  32. data/config/locales/pl.yml +6 -3
  33. data/config/locales/pt-BR.yml +2 -0
  34. data/config/locales/pt.yml +6 -3
  35. data/config/locales/ro.yml +2 -0
  36. data/config/locales/ru.yml +2 -0
  37. data/config/locales/sq.yml +2 -0
  38. data/config/locales/sv.yml +52 -0
  39. data/config/locales/uk.yml +2 -0
  40. data/config/locales/vi.yml +2 -0
  41. data/config/locales/zh-CN.yml +2 -0
  42. data/config/locales/zh-HK.yml +2 -0
  43. data/config/locales/zh-TW.yml +2 -0
  44. data/lib/devise_token_auth/blacklist.rb +6 -0
  45. data/lib/devise_token_auth/controllers/helpers.rb +21 -13
  46. data/lib/devise_token_auth/controllers/url_helpers.rb +2 -0
  47. data/lib/devise_token_auth/engine.rb +26 -14
  48. data/lib/devise_token_auth/errors.rb +8 -0
  49. data/lib/devise_token_auth/rails/routes.rb +37 -30
  50. data/lib/devise_token_auth/token_factory.rb +126 -0
  51. data/lib/devise_token_auth/url.rb +11 -4
  52. data/lib/devise_token_auth/version.rb +3 -1
  53. data/lib/devise_token_auth.rb +11 -5
  54. data/lib/generators/devise_token_auth/USAGE +2 -2
  55. data/lib/generators/devise_token_auth/install_generator.rb +36 -105
  56. data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
  57. data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
  58. data/lib/generators/devise_token_auth/install_views_generator.rb +7 -5
  59. data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +12 -0
  60. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +8 -14
  61. data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
  62. data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
  63. data/lib/tasks/devise_token_auth_tasks.rake +2 -0
  64. data/test/controllers/custom/custom_confirmations_controller_test.rb +5 -1
  65. data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +4 -0
  66. data/test/controllers/custom/custom_passwords_controller_test.rb +6 -2
  67. data/test/controllers/custom/custom_registrations_controller_test.rb +17 -8
  68. data/test/controllers/custom/custom_sessions_controller_test.rb +7 -5
  69. data/test/controllers/custom/custom_token_validations_controller_test.rb +5 -3
  70. data/test/controllers/demo_group_controller_test.rb +4 -6
  71. data/test/controllers/demo_mang_controller_test.rb +3 -3
  72. data/test/controllers/demo_user_controller_test.rb +53 -25
  73. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +159 -25
  74. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +117 -47
  75. data/test/controllers/devise_token_auth/passwords_controller_test.rb +309 -126
  76. data/test/controllers/devise_token_auth/registrations_controller_test.rb +65 -23
  77. data/test/controllers/devise_token_auth/sessions_controller_test.rb +93 -61
  78. data/test/controllers/devise_token_auth/token_validations_controller_test.rb +18 -6
  79. data/test/controllers/devise_token_auth/unlocks_controller_test.rb +24 -5
  80. data/test/controllers/overrides/confirmations_controller_test.rb +6 -2
  81. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +5 -1
  82. data/test/controllers/overrides/passwords_controller_test.rb +27 -29
  83. data/test/controllers/overrides/registrations_controller_test.rb +33 -27
  84. data/test/controllers/overrides/sessions_controller_test.rb +6 -4
  85. data/test/controllers/overrides/token_validations_controller_test.rb +5 -3
  86. data/test/dummy/app/active_record/confirmable_user.rb +11 -0
  87. data/test/dummy/app/{models → active_record}/lockable_user.rb +2 -0
  88. data/test/dummy/app/{models → active_record}/mang.rb +2 -0
  89. data/test/dummy/app/{models → active_record}/only_email_user.rb +2 -0
  90. data/test/dummy/app/{models → active_record}/scoped_user.rb +4 -2
  91. data/test/dummy/app/{models → active_record}/unconfirmable_user.rb +3 -2
  92. data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
  93. data/test/dummy/app/active_record/user.rb +6 -0
  94. data/test/dummy/app/controllers/application_controller.rb +2 -0
  95. data/test/dummy/app/controllers/auth_origin_controller.rb +2 -0
  96. data/test/dummy/app/controllers/custom/confirmations_controller.rb +2 -2
  97. data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +2 -0
  98. data/test/dummy/app/controllers/custom/passwords_controller.rb +3 -4
  99. data/test/dummy/app/controllers/custom/registrations_controller.rb +3 -3
  100. data/test/dummy/app/controllers/custom/sessions_controller.rb +3 -3
  101. data/test/dummy/app/controllers/custom/token_validations_controller.rb +3 -3
  102. data/test/dummy/app/controllers/demo_group_controller.rb +2 -0
  103. data/test/dummy/app/controllers/demo_mang_controller.rb +2 -0
  104. data/test/dummy/app/controllers/demo_user_controller.rb +2 -0
  105. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +8 -6
  106. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +5 -3
  107. data/test/dummy/app/controllers/overrides/passwords_controller.rb +10 -8
  108. data/test/dummy/app/controllers/overrides/registrations_controller.rb +5 -3
  109. data/test/dummy/app/controllers/overrides/sessions_controller.rb +12 -12
  110. data/test/dummy/app/controllers/overrides/token_validations_controller.rb +5 -5
  111. data/test/dummy/app/helpers/application_helper.rb +1029 -1036
  112. data/test/dummy/app/models/{user.rb → concerns/favorite_color.rb} +8 -7
  113. data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
  114. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  115. data/test/dummy/app/mongoid/mang.rb +46 -0
  116. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  117. data/test/dummy/app/mongoid/scoped_user.rb +50 -0
  118. data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
  119. data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
  120. data/test/dummy/app/mongoid/user.rb +49 -0
  121. data/test/dummy/app/views/layouts/application.html.erb +0 -2
  122. data/test/dummy/config/application.rb +26 -3
  123. data/test/dummy/config/boot.rb +8 -2
  124. data/test/dummy/config/environment.rb +3 -1
  125. data/test/dummy/config/environments/development.rb +5 -13
  126. data/test/dummy/config/environments/production.rb +2 -16
  127. data/test/dummy/config/environments/test.rb +3 -1
  128. data/test/dummy/config/initializers/backtrace_silencers.rb +2 -0
  129. data/test/dummy/config/initializers/cookies_serializer.rb +3 -1
  130. data/test/dummy/config/initializers/devise.rb +287 -0
  131. data/test/dummy/config/initializers/devise_token_auth.rb +37 -4
  132. data/test/dummy/config/initializers/figaro.rb +3 -1
  133. data/test/dummy/config/initializers/filter_parameter_logging.rb +2 -0
  134. data/test/dummy/config/initializers/inflections.rb +2 -0
  135. data/test/dummy/config/initializers/mime_types.rb +2 -0
  136. data/test/dummy/config/initializers/omniauth.rb +5 -2
  137. data/test/dummy/config/initializers/session_store.rb +2 -0
  138. data/test/dummy/config/initializers/wrap_parameters.rb +2 -0
  139. data/test/dummy/config/routes.rb +14 -29
  140. data/test/dummy/config/spring.rb +2 -0
  141. data/test/dummy/config.ru +5 -3
  142. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +9 -14
  143. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +8 -13
  144. data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +2 -0
  145. data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +2 -0
  146. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +6 -11
  147. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +8 -13
  148. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +8 -13
  149. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +8 -13
  150. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +8 -13
  151. data/test/dummy/{tmp/generators/db/migrate/20171014052631_devise_token_auth_create_users.rb → db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb} +8 -14
  152. data/test/dummy/db/schema.rb +11 -71
  153. data/test/dummy/lib/migration_database_helper.rb +15 -1
  154. data/test/dummy/tmp/generators/app/controllers/application_controller.rb +6 -0
  155. data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +56 -0
  156. data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +12 -0
  157. data/test/factories/users.rb +41 -0
  158. data/test/lib/devise_token_auth/blacklist_test.rb +19 -0
  159. data/test/lib/devise_token_auth/rails/custom_routes_test.rb +29 -0
  160. data/test/lib/devise_token_auth/rails/routes_test.rb +87 -0
  161. data/test/lib/devise_token_auth/token_factory_test.rb +191 -0
  162. data/test/lib/devise_token_auth/url_test.rb +9 -7
  163. data/test/lib/generators/devise_token_auth/install_generator_test.rb +67 -37
  164. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +222 -0
  165. data/test/lib/generators/devise_token_auth/install_views_generator_test.rb +3 -1
  166. data/test/models/concerns/mongoid_support_test.rb +31 -0
  167. data/test/models/concerns/tokens_serialization_test.rb +104 -0
  168. data/test/models/confirmable_user_test.rb +35 -0
  169. data/test/models/only_email_user_test.rb +2 -8
  170. data/test/models/user_test.rb +18 -79
  171. data/test/support/controllers/routes.rb +43 -0
  172. data/test/test_helper.rb +83 -26
  173. metadata +153 -44
  174. data/config/initializers/devise.rb +0 -196
  175. data/lib/generators/devise_token_auth/templates/user.rb +0 -7
  176. data/test/dummy/app/models/evil_user.rb +0 -3
  177. data/test/dummy/app/models/nice_user.rb +0 -7
  178. data/test/dummy/app/models/unregisterable_user.rb +0 -7
  179. data/test/dummy/config/initializers/assets.rb +0 -8
  180. data/test/dummy/db/migrate/20140928231203_devise_token_auth_create_evil_users.rb +0 -64
  181. data/test/dummy/db/migrate/20150409095712_devise_token_auth_create_nice_users.rb +0 -61
  182. data/test/dummy/tmp/generators/app/models/user.rb +0 -11
  183. data/test/integration/navigation_test.rb +0 -10
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'bundler/setup'
3
5
  rescue LoadError
@@ -14,11 +16,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
16
  rdoc.rdoc_files.include('lib/**/*.rb')
15
17
  end
16
18
 
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
19
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
18
20
  load 'rails/tasks/engine.rake'
19
21
 
20
-
21
-
22
22
  Bundler::GemHelper.install_tasks
23
23
 
24
24
  require 'rake/testtask'
@@ -31,5 +31,12 @@ Rake::TestTask.new(:test) do |t|
31
31
  t.warning = false
32
32
  end
33
33
 
34
-
35
34
  task default: :test
35
+
36
+ require 'rubocop/rake_task'
37
+
38
+ desc 'Run RuboCop'
39
+ RuboCop::RakeTask.new(:rubocop) do |task|
40
+ task.formatters = %w[fuubar offenses worst]
41
+ task.fail_on_error = false # don't abort rake on failure
42
+ end
@@ -1,22 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseTokenAuth
2
4
  class ApplicationController < DeviseController
3
5
  include DeviseTokenAuth::Concerns::SetUserByToken
4
- include DeviseTokenAuth::Concerns::ResourceFinder
5
6
 
6
- def resource_data(opts={})
7
+ def resource_data(opts = {})
7
8
  response_data = opts[:resource_json] || @resource.as_json
8
- if json_api?
9
- response_data['type'] = @resource.class.name.parameterize
10
- end
9
+ response_data['type'] = @resource.class.name.parameterize if json_api?
11
10
  response_data
12
11
  end
13
12
 
14
13
  def resource_errors
15
- return @resource.errors.to_hash.merge(full_messages: @resource.errors.full_messages)
14
+ @resource.errors.to_hash.merge(full_messages: @resource.errors.full_messages)
16
15
  end
17
16
 
18
17
  protected
19
18
 
19
+ def blacklisted_redirect_url?(redirect_url)
20
+ DeviseTokenAuth.redirect_whitelist && !DeviseTokenAuth::Url.whitelisted?(redirect_url)
21
+ end
22
+
20
23
  def build_redirect_headers(access_token, client, redirect_header_options = {})
21
24
  {
22
25
  DeviseTokenAuth.headers_names[:"access-token"] => access_token,
@@ -38,7 +41,7 @@ module DeviseTokenAuth
38
41
  devise_parameter_sanitizer.instance_values['permitted'][resource]
39
42
  end
40
43
 
41
- def resource_class(m=nil)
44
+ def resource_class(m = nil)
42
45
  if m
43
46
  mapping = Devise.mappings[m]
44
47
  else
@@ -53,7 +56,7 @@ module DeviseTokenAuth
53
56
  return ActiveModel::Serializer.setup do |config|
54
57
  config.adapter == :json_api
55
58
  end if ActiveModel::Serializer.respond_to?(:setup)
56
- return ActiveModelSerializers.config.adapter == :json_api
59
+ ActiveModelSerializers.config.adapter == :json_api
57
60
  end
58
61
 
59
62
  def recoverable_enabled?
@@ -72,5 +75,13 @@ module DeviseTokenAuth
72
75
  response = response.merge(data) if data
73
76
  render json: response, status: status
74
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
75
86
  end
76
87
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseTokenAuth::Concerns::ResourceFinder
2
4
  extend ActiveSupport::Concern
3
5
  include DeviseTokenAuth::Controllers::Helpers
@@ -18,21 +20,33 @@ module DeviseTokenAuth::Concerns::ResourceFinder
18
20
  end
19
21
 
20
22
  def find_resource(field, value)
21
- # fix for mysql default case insensitivity
22
- q = "#{field.to_s} = ? AND provider='#{provider.to_s}'"
23
- if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
24
- q = "BINARY " + q
25
- end
26
-
27
- @resource = resource_class.where(q, value).first
23
+ @resource = if database_adapter&.include?('mysql')
24
+ # fix for mysql default case insensitivity
25
+ resource_class.where("BINARY #{field} = ? AND provider= ?", value, provider).first
26
+ else
27
+ resource_class.dta_find_by(field => value, 'provider' => provider)
28
+ end
28
29
  end
29
30
 
30
- def resource_class(m=nil)
31
- if m
32
- mapping = Devise.mappings[m]
33
- else
34
- mapping = Devise.mappings[resource_name] || Devise.mappings.values.first
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
35
41
  end
42
+ end
43
+
44
+ def resource_class(m = nil)
45
+ mapping = if m
46
+ Devise.mappings[m]
47
+ else
48
+ Devise.mappings[resource_name] || Devise.mappings.values.first
49
+ end
36
50
 
37
51
  mapping.to
38
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseTokenAuth::Concerns::SetUserByToken
2
4
  extend ActiveSupport::Concern
3
5
  include DeviseTokenAuth::Concerns::ResourceFinder
@@ -11,30 +13,17 @@ module DeviseTokenAuth::Concerns::SetUserByToken
11
13
 
12
14
  # keep track of request duration
13
15
  def set_request_start
14
- @request_started_at = Time.now
16
+ @request_started_at = Time.zone.now
15
17
  @used_auth_by_token = true
16
18
 
17
19
  # initialize instance variables
18
- @client_id = nil
19
- @resource = nil
20
- @token = nil
21
- @is_batch_request = nil
22
- end
23
-
24
- def ensure_pristine_resource
25
- if @resource.changed?
26
- # Stash pending changes in the resource before reloading.
27
- changes = @resource.changes
28
- @resource.reload
29
- end
30
- yield
31
- ensure
32
- # Reapply pending changes
33
- @resource.assign_attributes(changes) if changes
20
+ @token ||= DeviseTokenAuth::TokenFactory.new
21
+ @resource ||= nil
22
+ @is_batch_request ||= nil
34
23
  end
35
24
 
36
25
  # user auth
37
- def set_user_by_token(mapping=nil)
26
+ def set_user_by_token(mapping = nil)
38
27
  # determine target authentication class
39
28
  rc = resource_class(mapping)
40
29
 
@@ -46,120 +35,152 @@ module DeviseTokenAuth::Concerns::SetUserByToken
46
35
  access_token_name = DeviseTokenAuth.headers_names[:'access-token']
47
36
  client_name = DeviseTokenAuth.headers_names[:'client']
48
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
+
49
47
  # parse header for values necessary for authentication
50
- uid = request.headers[uid_name] || params[uid_name]
51
- @token ||= request.headers[access_token_name] || params[access_token_name]
52
- @client_id ||= request.headers[client_name] || params[client_name]
48
+ uid = request.headers[uid_name] || params[uid_name] || parsed_auth_cookie[uid_name]
49
+ @token = DeviseTokenAuth::TokenFactory.new unless @token
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]
53
52
 
54
- # client_id isn't required, set to 'default' if absent
55
- @client_id ||= 'default'
53
+ # client isn't required, set to 'default' if absent
54
+ @token.client ||= 'default'
56
55
 
57
56
  # check for an existing user, authenticated via warden/devise, if enabled
58
57
  if DeviseTokenAuth.enable_standard_devise_support
59
- devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
60
- if devise_warden_user && devise_warden_user.tokens[@client_id].nil?
58
+ devise_warden_user = warden.user(mapping)
59
+ if devise_warden_user && devise_warden_user.tokens[@token.client].nil?
61
60
  @used_auth_by_token = false
62
61
  @resource = devise_warden_user
63
- @resource.create_new_auth_token
62
+ # REVIEW: The following line _should_ be safe to remove;
63
+ # the generated token does not get used anywhere.
64
+ # @resource.create_new_auth_token
64
65
  end
65
66
  end
66
67
 
67
68
  # user has already been found and authenticated
68
69
  return @resource if @resource && @resource.is_a?(rc)
69
70
 
70
- # ensure we clear the client_id
71
- if !@token
72
- @client_id = nil
71
+ # ensure we clear the client
72
+ unless @token.present?
73
+ @token.client = nil
73
74
  return
74
75
  end
75
76
 
76
- return false unless @token
77
-
78
77
  # mitigate timing attacks by finding by uid instead of auth token
79
- user = uid && rc.find_by(uid: uid)
78
+ user = uid && rc.dta_find_by(uid: uid)
79
+ scope = rc.to_s.underscore.to_sym
80
80
 
81
- if user && user.valid_token?(@token, @client_id)
81
+ if user && user.valid_token?(@token.token, @token.client)
82
82
  # sign_in with bypass: true will be deprecated in the next version of Devise
83
- if self.respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
84
- bypass_sign_in(user, scope: :user)
83
+ if respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
84
+ bypass_sign_in(user, scope: scope)
85
85
  else
86
- sign_in(:user, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
86
+ sign_in(scope, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
87
87
  end
88
88
  return @resource = user
89
89
  else
90
90
  # zero all values previously set values
91
- @client_id = nil
91
+ @token.client = nil
92
92
  return @resource = nil
93
93
  end
94
94
  end
95
95
 
96
96
  def update_auth_header
97
97
  # cannot save object if model has invalid params
98
- return unless defined?(@resource) && @resource && @resource.valid? && @client_id
98
+ return unless @resource && @token.client
99
99
 
100
- # Generate new client_id with existing authentication
101
- @client_id = nil unless @used_auth_by_token
100
+ # Generate new client with existing authentication
101
+ @token.client = nil unless @used_auth_by_token
102
102
 
103
103
  if @used_auth_by_token && !DeviseTokenAuth.change_headers_on_each_request
104
104
  # should not append auth header if @resource related token was
105
105
  # cleared by sign out in the meantime
106
- return if @resource.reload.tokens[@client_id].nil?
106
+ return if @resource.reload.tokens[@token.client].nil?
107
107
 
108
- auth_header = @resource.build_auth_header(@token, @client_id)
108
+ auth_header = @resource.build_auth_header(@token.token, @token.client)
109
109
 
110
110
  # update the response header
111
111
  response.headers.merge!(auth_header)
112
112
 
113
+ # set a server cookie if configured
114
+ if DeviseTokenAuth.cookie_enabled
115
+ set_cookie(auth_header)
116
+ end
113
117
  else
114
-
115
- ensure_pristine_resource do
116
- # Lock the user record during any auth_header updates to ensure
117
- # we don't have write contention from multiple threads
118
- @resource.with_lock do
119
- # should not append auth header if @resource related token was
120
- # cleared by sign out in the meantime
121
- return if @used_auth_by_token && @resource.tokens[@client_id].nil?
122
-
123
- # determine batch request status after request processing, in case
124
- # another processes has updated it during that processing
125
- @is_batch_request = is_batch_request?(@resource, @client_id)
126
-
127
- auth_header = {}
128
-
129
- # extend expiration of batch buffer to account for the duration of
130
- # this request
131
- if @is_batch_request
132
- auth_header = @resource.extend_batch_buffer(@token, @client_id)
133
-
134
- # Do not return token for batch requests to avoid invalidated
135
- # tokens returned to the client in case of race conditions.
136
- # Use a blank string for the header to still be present and
137
- # being passed in a XHR response in case of
138
- # 304 Not Modified responses.
139
- auth_header[DeviseTokenAuth.headers_names[:"access-token"]] = ' '
140
- auth_header[DeviseTokenAuth.headers_names[:"expiry"]] = ' '
141
-
142
- # update Authorization response header with new token
143
- else
144
- auth_header = @resource.create_new_auth_token(@client_id)
145
- end
146
-
147
- # update the response header
148
- response.headers.merge!(auth_header)
149
-
150
- end # end lock
151
- end # end ensure_pristine_resource
118
+ unless @resource.reload.valid?
119
+ @resource = @resource.class.find(@resource.to_param) # errors remain after reload
120
+ # if we left the model in a bad state, something is wrong in our app
121
+ unless @resource.valid?
122
+ raise DeviseTokenAuth::Errors::InvalidModel, "Cannot set auth token in invalid model. Errors: #{@resource.errors.full_messages}"
123
+ end
124
+ end
125
+ refresh_headers
152
126
  end
153
-
154
127
  end
155
128
 
156
129
  private
157
130
 
131
+ def refresh_headers
132
+ # Lock the user record during any auth_header updates to ensure
133
+ # we don't have write contention from multiple threads
134
+ @resource.with_lock do
135
+ # should not append auth header if @resource related token was
136
+ # cleared by sign out in the meantime
137
+ return if @used_auth_by_token && @resource.tokens[@token.client].nil?
138
+
139
+ _auth_header_from_batch_request = auth_header_from_batch_request
140
+
141
+ # update the response header
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
148
+ end # end lock
149
+ end
158
150
 
159
- def is_batch_request?(user, client_id)
151
+ def set_cookie(auth_header)
152
+ cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json)
153
+ end
154
+
155
+ def is_batch_request?(user, client)
160
156
  !params[:unbatch] &&
161
- user.tokens[client_id] &&
162
- user.tokens[client_id]['updated_at'] &&
163
- Time.parse(user.tokens[client_id]['updated_at']) > @request_started_at - DeviseTokenAuth.batch_request_buffer_throttle
157
+ user.tokens[client] &&
158
+ user.tokens[client]['updated_at'] &&
159
+ user.tokens[client]['updated_at'].to_time > @request_started_at - DeviseTokenAuth.batch_request_buffer_throttle
160
+ end
161
+
162
+ def auth_header_from_batch_request
163
+ # determine batch request status after request processing, in case
164
+ # another processes has updated it during that processing
165
+ @is_batch_request = is_batch_request?(@resource, @token.client)
166
+
167
+ auth_header = {}
168
+ # extend expiration of batch buffer to account for the duration of
169
+ # this request
170
+ if @is_batch_request
171
+ auth_header = @resource.extend_batch_buffer(@token.token, @token.client)
172
+
173
+ # Do not return token for batch requests to avoid invalidated
174
+ # tokens returned to the client in case of race conditions.
175
+ # Use a blank string for the header to still be present and
176
+ # being passed in a XHR response in case of
177
+ # 304 Not Modified responses.
178
+ auth_header[DeviseTokenAuth.headers_names[:"access-token"]] = ' '
179
+ auth_header[DeviseTokenAuth.headers_names[:"expiry"]] = ' '
180
+ else
181
+ # update Authorization response header with new token
182
+ auth_header = @resource.create_new_auth_token(@token.client)
183
+ end
184
+ auth_header
164
185
  end
165
186
  end
@@ -1,30 +1,86 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseTokenAuth
2
4
  class ConfirmationsController < DeviseTokenAuth::ApplicationController
5
+
3
6
  def show
4
- @resource = resource_class.confirm_by_token(params[:confirmation_token])
7
+ @resource = resource_class.confirm_by_token(resource_params[:confirmation_token])
5
8
 
6
- if @resource && @resource.id
7
- expiry = nil
8
- if defined?(@resource.sign_in_count) && @resource.sign_in_count > 0
9
- expiry = (Time.now + 1.second).to_i
10
- end
9
+ if @resource.errors.empty?
10
+ yield @resource if block_given?
11
11
 
12
- client_id, token = @resource.create_token expiry: expiry
12
+ redirect_header_options = { account_confirmation_success: true }
13
13
 
14
- sign_in(@resource)
15
- @resource.save!
14
+ if signed_in?(resource_name)
15
+ token = signed_in_resource.create_token
16
+ signed_in_resource.save!
16
17
 
17
- yield @resource if block_given?
18
+ redirect_headers = build_redirect_headers(token.token,
19
+ token.client,
20
+ redirect_header_options)
18
21
 
19
- redirect_header_options = {account_confirmation_success: true}
20
- redirect_headers = build_redirect_headers(token,
21
- client_id,
22
- redirect_header_options)
23
- redirect_to(@resource.build_auth_url(params[:redirect_url],
24
- redirect_headers))
22
+ redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
23
+ else
24
+ redirect_to_link = DeviseTokenAuth::Url.generate(redirect_url, redirect_header_options)
25
+ end
26
+
27
+ redirect_to(redirect_to_link)
25
28
  else
26
- raise ActionController::RoutingError.new('Not Found')
29
+ raise ActionController::RoutingError, 'Not Found'
27
30
  end
28
31
  end
32
+
33
+ def create
34
+ return render_create_error_missing_email if resource_params[:email].blank?
35
+
36
+ @email = get_case_insensitive_field_from_resource_params(:email)
37
+
38
+ @resource = resource_class.dta_find_by(uid: @email, provider: provider)
39
+
40
+ return render_not_found_error unless @resource
41
+
42
+ @resource.send_confirmation_instructions({
43
+ redirect_url: redirect_url,
44
+ client_config: resource_params[:config_name]
45
+ })
46
+
47
+ return render_create_success
48
+ end
49
+
50
+ protected
51
+
52
+ def render_create_error_missing_email
53
+ render_error(401, I18n.t('devise_token_auth.confirmations.missing_email'))
54
+ end
55
+
56
+ def render_create_success
57
+ render json: {
58
+ success: true,
59
+ message: success_message('confirmations', @email)
60
+ }
61
+ end
62
+
63
+ def render_not_found_error
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
69
+ end
70
+
71
+ private
72
+
73
+ def resource_params
74
+ params.permit(:email, :confirmation_token, :config_name)
75
+ end
76
+
77
+ # give redirect value from params priority or fall back to default value if provided
78
+ def redirect_url
79
+ params.fetch(
80
+ :redirect_url,
81
+ DeviseTokenAuth.default_confirm_success_url
82
+ )
83
+ end
84
+
29
85
  end
30
86
  end