devise_token_auth 0.1.43 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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