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
@@ -1,4 +1,4 @@
1
- require 'bcrypt'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DeviseTokenAuth::Concerns::User
4
4
  extend ActiveSupport::Concern
@@ -7,34 +7,32 @@ module DeviseTokenAuth::Concerns::User
7
7
  @token_equality_cache ||= {}
8
8
 
9
9
  key = "#{token_hash}/#{token}"
10
- result = @token_equality_cache[key] ||= (::BCrypt::Password.new(token_hash) == token)
11
- if @token_equality_cache.size > 10000
12
- @token_equality_cache = {}
13
- end
10
+ result = @token_equality_cache[key] ||= DeviseTokenAuth::TokenFactory.token_hash_is_token?(token_hash, token)
11
+ @token_equality_cache = {} if @token_equality_cache.size > 10000
14
12
  result
15
13
  end
16
14
 
17
15
  included do
18
16
  # Hack to check if devise is already enabled
19
- unless self.method_defined?(:devise_modules)
20
- devise :database_authenticatable, :registerable,
21
- :recoverable, :trackable, :validatable, :confirmable
17
+ if method_defined?(:devise_modules)
18
+ devise_modules.delete(:omniauthable)
22
19
  else
23
- self.devise_modules.delete(:omniauthable)
20
+ devise :database_authenticatable, :registerable,
21
+ :recoverable, :validatable, :confirmable
22
+ end
23
+
24
+ if const_defined?('ActiveRecord') && ancestors.include?(ActiveRecord::Base)
25
+ include DeviseTokenAuth::Concerns::ActiveRecordSupport
24
26
  end
25
27
 
26
- unless tokens_has_json_column_type?
27
- serialize :tokens, JSON
28
+ if const_defined?('Mongoid') && ancestors.include?(Mongoid::Document)
29
+ include DeviseTokenAuth::Concerns::MongoidSupport
28
30
  end
29
31
 
30
32
  if DeviseTokenAuth.default_callbacks
31
33
  include DeviseTokenAuth::Concerns::UserOmniauthCallbacks
32
34
  end
33
35
 
34
- # can't set default on text fields in mysql, simulate here instead.
35
- after_save :set_empty_token_hash
36
- after_initialize :set_empty_token_hash
37
-
38
36
  # get rid of dead tokens
39
37
  before_save :destroy_expired_tokens
40
38
 
@@ -46,17 +44,21 @@ module DeviseTokenAuth::Concerns::User
46
44
  def email_changed?; false; end
47
45
  def will_save_change_to_email?; false; end
48
46
 
47
+ if DeviseTokenAuth.send_confirmation_email && devise_modules.include?(:confirmable)
48
+ include DeviseTokenAuth::Concerns::ConfirmableSupport
49
+ end
50
+
49
51
  def password_required?
50
52
  return false unless provider == 'email'
51
53
  super
52
54
  end
53
55
 
54
56
  # override devise method to include additional info as opts hash
55
- def send_confirmation_instructions(opts={})
57
+ def send_confirmation_instructions(opts = {})
56
58
  generate_confirmation_token! unless @raw_confirmation_token
57
59
 
58
60
  # fall back to "default" config name
59
- opts[:client_config] ||= "default"
61
+ opts[:client_config] ||= 'default'
60
62
  opts[:to] = unconfirmed_email if pending_reconfirmation?
61
63
  opts[:redirect_url] ||= DeviseTokenAuth.default_confirm_success_url
62
64
 
@@ -64,149 +66,126 @@ module DeviseTokenAuth::Concerns::User
64
66
  end
65
67
 
66
68
  # override devise method to include additional info as opts hash
67
- def send_reset_password_instructions(opts={})
69
+ def send_reset_password_instructions(opts = {})
68
70
  token = set_reset_password_token
69
71
 
70
72
  # fall back to "default" config name
71
- opts[:client_config] ||= "default"
73
+ opts[:client_config] ||= 'default'
72
74
 
73
75
  send_devise_notification(:reset_password_instructions, token, opts)
74
76
  token
75
77
  end
76
78
 
77
79
  # override devise method to include additional info as opts hash
78
- def send_unlock_instructions(opts={})
80
+ def send_unlock_instructions(opts = {})
79
81
  raw, enc = Devise.token_generator.generate(self.class, :unlock_token)
80
82
  self.unlock_token = enc
81
83
  save(validate: false)
82
84
 
83
85
  # fall back to "default" config name
84
- opts[:client_config] ||= "default"
86
+ opts[:client_config] ||= 'default'
85
87
 
86
88
  send_devise_notification(:unlock_instructions, raw, opts)
87
89
  raw
88
90
  end
89
- end
90
91
 
91
- def create_token(client_id: nil, token: nil, expiry: nil, **token_extras)
92
- client_id ||= SecureRandom.urlsafe_base64(nil, false)
93
- token ||= SecureRandom.urlsafe_base64(nil, false)
94
- expiry ||= (Time.now + token_lifespan).to_i
92
+ def create_token(client: nil, lifespan: nil, cost: nil, **token_extras)
93
+ token = DeviseTokenAuth::TokenFactory.create(client: client, lifespan: lifespan, cost: cost)
95
94
 
96
- self.tokens[client_id] = {
97
- token: BCrypt::Password.create(token),
98
- expiry: expiry
99
- }.merge!(token_extras)
95
+ tokens[token.client] = {
96
+ token: token.token_hash,
97
+ expiry: token.expiry
98
+ }.merge!(token_extras)
100
99
 
101
- [client_id, token, expiry]
102
- end
103
-
104
- module ClassMethods
105
- protected
106
-
107
- def tokens_has_json_column_type?
108
- database_exists? && table_exists? && self.columns_hash['tokens'] && self.columns_hash['tokens'].type.in?([:json, :jsonb])
109
- end
100
+ clean_old_tokens
110
101
 
111
- def database_exists?
112
- ActiveRecord::Base.connection_pool.with_connection { |con| con.active? } rescue false
102
+ token
113
103
  end
114
104
  end
115
105
 
116
-
117
- def valid_token?(token, client_id='default')
118
- return false unless tokens[client_id]
119
- return true if token_is_current?(token, client_id)
120
- return true if token_can_be_reused?(token, client_id)
106
+ def valid_token?(token, client = 'default')
107
+ return false unless tokens[client]
108
+ return true if token_is_current?(token, client)
109
+ return true if token_can_be_reused?(token, client)
121
110
 
122
111
  # return false if none of the above conditions are met
123
- return false
112
+ false
124
113
  end
125
114
 
126
-
127
115
  # this must be done from the controller so that additional params
128
116
  # can be passed on from the client
129
117
  def send_confirmation_notification?; false; end
130
118
 
131
-
132
- def token_is_current?(token, client_id)
119
+ def token_is_current?(token, client)
133
120
  # ghetto HashWithIndifferentAccess
134
- expiry = tokens[client_id]['expiry'] || tokens[client_id][:expiry]
135
- token_hash = tokens[client_id]['token'] || tokens[client_id][:token]
121
+ expiry = tokens[client]['expiry'] || tokens[client][:expiry]
122
+ token_hash = tokens[client]['token'] || tokens[client][:token]
136
123
 
137
124
  return true if (
138
125
  # ensure that expiry and token are set
139
126
  expiry && token &&
140
127
 
141
128
  # ensure that the token has not yet expired
142
- DateTime.strptime(expiry.to_s, '%s') > Time.now &&
129
+ DateTime.strptime(expiry.to_s, '%s') > Time.zone.now &&
143
130
 
144
131
  # ensure that the token is valid
145
132
  DeviseTokenAuth::Concerns::User.tokens_match?(token_hash, token)
146
133
  )
147
134
  end
148
135
 
149
-
150
136
  # allow batch requests to use the previous token
151
- def token_can_be_reused?(token, client_id)
137
+ def token_can_be_reused?(token, client)
152
138
  # ghetto HashWithIndifferentAccess
153
- updated_at = tokens[client_id]['updated_at'] || tokens[client_id][:updated_at]
154
- last_token = tokens[client_id]['last_token'] || tokens[client_id][:last_token]
139
+ updated_at = tokens[client]['updated_at'] || tokens[client][:updated_at]
140
+ last_token_hash = tokens[client]['last_token'] || tokens[client][:last_token]
155
141
 
156
142
  return true if (
157
143
  # ensure that the last token and its creation time exist
158
- updated_at && last_token &&
144
+ updated_at && last_token_hash &&
159
145
 
160
146
  # ensure that previous token falls within the batch buffer throttle time of the last request
161
- Time.parse(updated_at) > Time.now - DeviseTokenAuth.batch_request_buffer_throttle &&
147
+ updated_at.to_time > Time.zone.now - DeviseTokenAuth.batch_request_buffer_throttle &&
162
148
 
163
149
  # ensure that the token is valid
164
- ::BCrypt::Password.new(last_token) == token
150
+ DeviseTokenAuth::TokenFactory.token_hash_is_token?(last_token_hash, token)
165
151
  )
166
152
  end
167
153
 
168
-
169
154
  # update user's auth token (should happen on each request)
170
- def create_new_auth_token(client_id=nil)
171
- now = Time.now
155
+ def create_new_auth_token(client = nil)
156
+ now = Time.zone.now
172
157
 
173
- client_id, token = create_token(
174
- client_id: client_id,
175
- expiry: (now + token_lifespan).to_i,
176
- last_token: tokens.fetch(client_id, {})['token'],
158
+ token = create_token(
159
+ client: client,
160
+ last_token: tokens.fetch(client, {})['token'],
177
161
  updated_at: now
178
162
  )
179
163
 
180
- update_auth_header(token, client_id)
164
+ update_auth_header(token.token, token.client)
181
165
  end
182
166
 
183
- def build_auth_header(token, client_id='default')
167
+ def build_auth_header(token, client = 'default')
184
168
  # client may use expiry to prevent validation request if expired
185
169
  # must be cast as string or headers will break
186
- expiry = tokens[client_id]['expiry'] || tokens[client_id][:expiry]
170
+ expiry = tokens[client]['expiry'] || tokens[client][:expiry]
187
171
 
188
172
  {
189
173
  DeviseTokenAuth.headers_names[:"access-token"] => token,
190
- DeviseTokenAuth.headers_names[:"token-type"] => "Bearer",
191
- DeviseTokenAuth.headers_names[:"client"] => client_id,
174
+ DeviseTokenAuth.headers_names[:"token-type"] => 'Bearer',
175
+ DeviseTokenAuth.headers_names[:"client"] => client,
192
176
  DeviseTokenAuth.headers_names[:"expiry"] => expiry.to_s,
193
177
  DeviseTokenAuth.headers_names[:"uid"] => uid
194
178
  }
195
179
  end
196
180
 
197
- def update_auth_header(token, client_id='default')
198
- headers = build_auth_header(token, client_id)
199
- while tokens.length > 0 && DeviseTokenAuth.max_number_of_devices < tokens.length
200
- oldest_client_id, _tk = tokens.min_by { |_cid, v| v[:expiry] || v["expiry"] }
201
- tokens.delete(oldest_client_id)
202
- end
203
-
181
+ def update_auth_header(token, client = 'default')
182
+ headers = build_auth_header(token, client)
183
+ clean_old_tokens
204
184
  save!
205
185
 
206
186
  headers
207
187
  end
208
188
 
209
-
210
189
  def build_auth_url(base_url, args)
211
190
  args[:uid] = uid
212
191
  args[:expiry] = tokens[args[:client_id]]['expiry']
@@ -214,10 +193,9 @@ module DeviseTokenAuth::Concerns::User
214
193
  DeviseTokenAuth::Url.generate(base_url, args)
215
194
  end
216
195
 
217
-
218
- def extend_batch_buffer(token, client_id)
219
- self.tokens[client_id]['updated_at'] = Time.now
220
- update_auth_header(token, client_id)
196
+ def extend_batch_buffer(token, client)
197
+ tokens[client]['updated_at'] = Time.zone.now
198
+ update_auth_header(token, client)
221
199
  end
222
200
 
223
201
  def confirmed?
@@ -225,36 +203,50 @@ module DeviseTokenAuth::Concerns::User
225
203
  end
226
204
 
227
205
  def token_validation_response
228
- as_json(except: [:tokens, :created_at, :updated_at])
229
- end
230
-
231
- def token_lifespan
232
- DeviseTokenAuth.token_lifespan
206
+ as_json(except: %i[tokens created_at updated_at])
233
207
  end
234
208
 
235
209
  protected
236
210
 
237
- def set_empty_token_hash
238
- self.tokens ||= {} if has_attribute?(:tokens)
239
- end
240
-
241
211
  def destroy_expired_tokens
242
212
  if tokens
243
213
  tokens.delete_if do |cid, v|
244
- expiry = v[:expiry] || v["expiry"]
245
- DateTime.strptime(expiry.to_s, '%s') < Time.now
214
+ expiry = v[:expiry] || v['expiry']
215
+ DateTime.strptime(expiry.to_s, '%s') < Time.zone.now
246
216
  end
247
217
  end
248
218
  end
249
219
 
220
+ def should_remove_tokens_after_password_reset?
221
+ DeviseTokenAuth.remove_tokens_after_password_reset &&
222
+ (respond_to?(:encrypted_password_changed?) && encrypted_password_changed?)
223
+ end
224
+
250
225
  def remove_tokens_after_password_reset
251
- should_remove_old_tokens = DeviseTokenAuth.remove_tokens_after_password_reset &&
252
- encrypted_password_changed? && tokens && tokens.many?
226
+ return unless should_remove_tokens_after_password_reset?
253
227
 
254
- if should_remove_old_tokens
255
- client_id, token_data = tokens.max_by { |cid, v| v[:expiry] || v["expiry"] }
256
- self.tokens = {client_id => token_data}
228
+ if tokens.present? && tokens.many?
229
+ client, token_data = tokens.max_by { |cid, v| v[:expiry] || v['expiry'] }
230
+ self.tokens = { client => token_data }
257
231
  end
258
232
  end
259
233
 
234
+ def max_client_tokens_exceeded?
235
+ tokens.length > DeviseTokenAuth.max_number_of_devices
236
+ end
237
+
238
+ def clean_old_tokens
239
+ if tokens.present? && max_client_tokens_exceeded?
240
+ # Using Enumerable#sort_by on a Hash will typecast it into an associative
241
+ # Array (i.e. an Array of key-value Array pairs). However, since Hashes
242
+ # have an internal order in Ruby 1.9+, the resulting sorted associative
243
+ # Array can be converted back into a Hash, while maintaining the sorted
244
+ # order.
245
+ self.tokens = tokens.sort_by { |_cid, v| v[:expiry] || v['expiry'] }.to_h
246
+
247
+ # Since the tokens are sorted by expiry, shift the oldest client token
248
+ # off the Hash until it no longer exceeds the maximum number of clients
249
+ tokens.shift while max_client_tokens_exceeded?
250
+ end
251
+ end
260
252
  end
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
2
4
  extend ActiveSupport::Concern
3
5
 
4
6
  included do
5
7
  validates :email, presence: true,if: :email_provider?
6
- validates :email, email: true, allow_nil: true, allow_blank: true, if: :email_provider?
8
+ validates :email, :devise_token_auth_email => true, allow_nil: true, allow_blank: true, if: :email_provider?
7
9
  validates_presence_of :uid, unless: :email_provider?
8
10
 
9
11
  # only validate unique emails among email registration users
10
- validates :email, uniqueness: { scope: :provider }, on: :create, if: :email_provider?
12
+ validates :email, uniqueness: { case_sensitive: false, scope: :provider }, on: :create, if: :email_provider?
11
13
 
12
14
  # keep uid in sync with email
13
15
  before_save :sync_uid
@@ -21,6 +23,9 @@ module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
21
23
  end
22
24
 
23
25
  def sync_uid
24
- self.uid = email if provider == 'email'
26
+ unless self.new_record?
27
+ return if devise_modules.include?(:confirmable) && !@bypass_confirmation_postpone && postpone_email_change?
28
+ end
29
+ self.uid = email if email_provider?
25
30
  end
26
31
  end
@@ -1,7 +1,9 @@
1
- class EmailValidator < ActiveModel::EachValidator
1
+ # frozen_string_literal: true
2
+
3
+ class DeviseTokenAuthEmailValidator < ActiveModel::EachValidator
2
4
  def validate_each(record, attribute, value)
3
5
  unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
4
- record.errors[attribute] << email_invalid_message
6
+ record.errors.add(attribute, email_invalid_message)
5
7
  end
6
8
  end
7
9
 
@@ -18,4 +20,4 @@ class EmailValidator < ActiveModel::EachValidator
18
20
 
19
21
  message
20
22
  end
21
- end
23
+ end
@@ -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") {
@@ -2,11 +2,11 @@ da-DK:
2
2
  devise_token_auth:
3
3
  sessions:
4
4
  not_confirmed: "Der er sendt en bekræftelsesemail til din konto på '%{email}'. Følg venligst instruktionerne i emailen for at aktivere din konto."
5
- bad_credentials: "Ugyldigt kombination af brugernavn og kodeord. Prøv venligst igen."
5
+ bad_credentials: "Ugyldig kombination af brugernavn og kodeord. Prøv venligst igen."
6
6
  not_supported: "Brug POST /sign_in for at logge ind. GET er ikke supporteret."
7
7
  user_not_found: "Brugeren er ikke fundet eller er ikke logget ind."
8
8
  token_validations:
9
- invalid: "Ugyldig legitimationsoplysninger."
9
+ invalid: "Ugyldige legitimationsoplysninger."
10
10
  registrations:
11
11
  missing_confirm_success_url: "Der mangler et 'confirm_success_url' parameter."
12
12
  redirect_url_not_allowed: "Omdirigering til '%{redirect_url}' er ikke tilladt."
@@ -14,6 +14,8 @@ da-DK:
14
14
  account_with_uid_destroyed: "Kontoen med UID '%{uid}' er slettet."
15
15
  account_to_destroy_not_found: "Kan ikke finde kontoen som skal slettes."
16
16
  user_not_found: "Brugeren ikke fundet."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Omdirigering til '%{redirect_url}' er ikke tilladt."
17
19
  passwords:
18
20
  missing_email: "Du skal udfylde email feltet."
19
21
  missing_redirect_url: "Der er ingen omdirigeringsadresse."
@@ -21,12 +23,12 @@ da-DK:
21
23
  sended: "En email er blevet sendt til '%{email}' med instruktioner for at nulstille dit kodeord."
22
24
  user_not_found: "Kan ikke finde en bruger med '%{email}'."
23
25
  password_not_required: "Denne bruger kræver ikke et kodeord. Log ind med '%{provider}' konto i stedet."
24
- missing_passwords: "Du skal fylde alle felter ud som indeholder 'Password' og 'Password confirmation'."
26
+ missing_passwords: "Du skal udfylde både kodeord og bekræftelse af kodeord."
25
27
  successfully_updated: "Dit kodeord er opdateret."
26
28
  unlocks:
27
29
  missing_email: "Du skal udfylde en email."
28
30
  sended: "En email er blevet sendt til '%{email}', som indeholder instruktioner for at låse kontoen op."
29
- user_not_found: "Kan ikke finde en burger med email '%{email}'."
31
+ user_not_found: "Kan ikke finde en bruger med email '%{email}'."
30
32
  errors:
31
33
  messages:
32
34
  validate_sign_up_params: "Angiv venligst passende registeringsdata i request body."
@@ -35,15 +37,15 @@ da-DK:
35
37
  devise:
36
38
  mailer:
37
39
  confirmation_instructions:
38
- confirm_link_msg: "Du kan bekræfte din konto email for linket herunder:"
40
+ confirm_link_msg: "Du kan bekræfte din kontos email gennem linket herunder:"
39
41
  confirm_account_link: "Bekræft min konto"
40
42
  reset_password_instructions:
41
- request_reset_link_msg: "Der er nogle der har anmodet om et link til at ændre dit kodeord. Det kan du gøre gennem linket nedenfor."
42
- password_change_link: "Ændre mit kodeord."
43
+ request_reset_link_msg: "Nogen har anmodet om et link til at ændre dit kodeord. Det kan du gøre via linket nedenfor."
44
+ password_change_link: "Skift mit kodeord."
43
45
  ignore_mail_msg: "Hvis du ikke anmodede om dette, ignorer venligst denne email."
44
- no_changes_msg: "Din kodeord vil ikke ændres indtil du går ind på linket ovenfor og laver et nyt et."
46
+ no_changes_msg: "Dit kodeord ændres først når du følger linket ovenfor og skaber et nyt."
45
47
  unlock_instructions:
46
- account_lock_msg: "Din konto er blevet låst fordi der er for mange forkerte log ind-forsøg."
48
+ account_lock_msg: "Din konto er blevet låst fordi der har været for mange ugyldige log ind-forsøg."
47
49
  unlock_link_msg: "Klik linket nedenfor, for at låse din konto op:"
48
50
  unlock_link: "Lås min konto op"
49
51
  hello: "hej"
@@ -14,6 +14,8 @@ de:
14
14
  account_with_uid_destroyed: "Account mit der uid '%{uid}' wurde gelöscht."
15
15
  account_to_destroy_not_found: "Der zu löschende Account kann nicht gefunden werden."
16
16
  user_not_found: "Benutzer kann nicht gefunden werden."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Weiterleitung zu '%{redirect_url}' ist nicht gestattet."
17
19
  passwords:
18
20
  missing_email: "Sie müssen eine E-Mail-Adresse angeben."
19
21
  missing_redirect_url: "Es fehlt die URL zu Weiterleitung."
@@ -14,11 +14,14 @@ en:
14
14
  account_with_uid_destroyed: "Account with UID '%{uid}' has been destroyed."
15
15
  account_to_destroy_not_found: "Unable to locate account for destruction."
16
16
  user_not_found: "User not found."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Redirect to '%{redirect_url}' not allowed."
17
19
  passwords:
18
20
  missing_email: "You must provide an email address."
19
21
  missing_redirect_url: "Missing redirect URL."
20
22
  not_allowed_redirect_url: "Redirect to '%{redirect_url}' not allowed."
21
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."
22
25
  user_not_found: "Unable to find user with email '%{email}'."
23
26
  password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
24
27
  missing_passwords: "You must fill out the fields labeled 'Password' and 'Password confirmation'."
@@ -26,7 +29,14 @@ en:
26
29
  unlocks:
27
30
  missing_email: "You must provide an email address."
28
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."
33
+ user_not_found: "Unable to find user with email '%{email}'."
34
+ confirmations:
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."
29
37
  user_not_found: "Unable to find user with email '%{email}'."
38
+ missing_email: "You must provide an email address."
39
+
30
40
  errors:
31
41
  messages:
32
42
  validate_sign_up_params: "Please submit proper sign up data in request body."
@@ -14,6 +14,8 @@ es:
14
14
  account_with_uid_destroyed: "La cuenta con el identificador '%{uid}' se ha eliminado."
15
15
  account_to_destroy_not_found: "No se puede encontrar la cuenta a borrar."
16
16
  user_not_found: "Usuario no encontrado."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Redirección hacia '%{redirect_url}' no esta permitida."
17
19
  passwords:
18
20
  missing_email: "Debe incluir un correo electrónico."
19
21
  missing_redirect_url: "Falta el Url de redirección."
@@ -14,6 +14,8 @@ fr:
14
14
  account_with_uid_destroyed: "Le compte avec l'identifiant '%{uid}' a été supprimé."
15
15
  account_to_destroy_not_found: "Le compte à supprimer est introuvable."
16
16
  user_not_found: "Utilisateur introuvable."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Redirection vers '%{redirect_url}' n'est pas autorisée."
17
19
  passwords:
18
20
  missing_email: "Vous devez soumettre un e-mail."
19
21
  missing_redirect_url: "URL de redirection manquante."
@@ -0,0 +1,52 @@
1
+ he:
2
+ devise_token_auth:
3
+ sessions:
4
+ not_confirmed: "הודעת אישור נשלחה לחשבון שלך בכתובת '%{email}'. עליך לפעול לפי ההנחיות שבדוא\"ל לפני הפעלת החשבון שלך"
5
+ bad_credentials: "נתוני כניסה שגויים. בבקשה נסה שוב."
6
+ not_supported: "השתמש ב- POST / sign_in כדי להיכנס. GET אינו נתמך."
7
+ user_not_found: "המשתמש לא נמצא או לא היה מחובר."
8
+ token_validations:
9
+ invalid: "נתוני כניסה שגויים"
10
+ registrations:
11
+ missing_confirm_success_url: "חסר פרמטר 'confirm_success_url'."
12
+ redirect_url_not_allowed: "הפניה אל '%{redirect_url}' אינה מותרת."
13
+ email_already_exists: "כבר קיים חשבון עבור '%{email}'"
14
+ account_with_uid_destroyed: "חשבון עם UID '%{uid}' הושמד."
15
+ account_to_destroy_not_found: "לא ניתן לאתר חשבון להשמדה."
16
+ user_not_found: "המשתמש לא נמצא."
17
+ omniauth:
18
+ not_allowed_redirect_url: "הפניה אל '%{redirect_url}' אינה מותרת."
19
+ passwords:
20
+ missing_email: "עליך לספק כתובת דוא\"ל."
21
+ missing_redirect_url: "כתובת אתר להפניה מחדש חסרה."
22
+ not_allowed_redirect_url: "הפניה אל '%{redirect_url}' אינה מותרת."
23
+ sended: "אימייל נשלח ל '%{email}' המכיל הוראות לאיפוס הסיסמה שלך."
24
+ user_not_found: "לא ניתן למצוא משתמש עם הדוא\"ל '%{email}'."
25
+ password_not_required: "חשבון זה אינו דורש סיסמה. במקום זאת, השתמש בחשבון '%{provider}' שלך."
26
+ missing_passwords: "עליך למלא את השדות 'סיסמה' ו'אישור סיסמה'."
27
+ successfully_updated: "הסיסמה שלך עודכנה בהצלחה."
28
+ unlocks:
29
+ missing_email: "עליך לספק כתובת דוא\"ל."
30
+ sended: "הודעת אימייל נשלחה אל '%{email}' המכילה הוראות לביטול הנעילה של חשבונך."
31
+ user_not_found: "ניתן למצוא את המשתמש עם הדוא\"ל '%{email}'"
32
+ errors:
33
+ messages:
34
+ validate_sign_up_params: "שלח נתוני רישום תקינים בגוף הבקשה."
35
+ validate_account_update_params: "שלחו בבקשה נתוני עדכון חשבון תקינים בגוף הבקשה."
36
+ not_email: "אינו דוא\"ל"
37
+ devise:
38
+ mailer:
39
+ confirmation_instructions:
40
+ confirm_link_msg: "תוכל לאשר את כתובת הדוא\"ל של החשבון שלך באמצעות הקישור הבא:"
41
+ confirm_account_link: "אשר את החשבון שלי"
42
+ reset_password_instructions:
43
+ request_reset_link_msg: "מישהו ביקש קישור לשינוי הסיסמה שלך. תוכל לעשות זאת באמצעות הקישור הבא."
44
+ password_change_link: "שנה את הסיסמה שלי"
45
+ ignore_mail_msg: "אם לא ביקשת זאת, התעלם מדוא\"ל זה."
46
+ no_changes_msg: "הסיסמה שלך לא תשתנה עד שתגיע לקישור שלמעלה ותיצור סיסמה חדשה."
47
+ unlock_instructions:
48
+ account_lock_msg: "החשבון שלך ננעל עקב מספר מופרז של ניסיונות כניסה לא מוצלחים."
49
+ unlock_link_msg: "לחץ על הקישור למטה כדי לבטל את נעילת החשבון שלך:"
50
+ unlock_link: "בטל את הנעילה של החשבון שלי"
51
+ hello: "שלום"
52
+ welcome: "ברוך הבא"
@@ -14,6 +14,8 @@ it:
14
14
  account_with_uid_destroyed: "L'account con UID '%{uid}' è stato eliminato."
15
15
  account_to_destroy_not_found: "Impossibile trovare l'account da eliminare."
16
16
  user_not_found: "Utente non trovato."
17
+ omniauth:
18
+ not_allowed_redirect_url: "Redirezione a '%{redirect_url}' non consentita."
17
19
  passwords:
18
20
  missing_email: "Devi fornire un indirizzo email."
19
21
  missing_redirect_url: "Redirect URL mancante."
@@ -14,6 +14,8 @@ ja:
14
14
  account_with_uid_destroyed: "'%{uid}' のアカウントは削除されました。"
15
15
  account_to_destroy_not_found: "削除するアカウントが見つかりません。"
16
16
  user_not_found: "ユーザーが見つかりません。"
17
+ omniauth:
18
+ not_allowed_redirect_url: "'%{redirect_url}' へのリダイレクトは許可されていません。"
17
19
  passwords:
18
20
  missing_email: "メールアドレスが与えられていません。"
19
21
  missing_redirect_url: "リダイレクト URL が与えられていません。"
@@ -27,14 +29,14 @@ ja:
27
29
  messages:
28
30
  validate_sign_up_params: "リクエストボディに適切なアカウント新規登録データを送信してください。"
29
31
  validate_account_update_params: "リクエストボディに適切なアカウント更新のデータを送信してください。"
30
- not_email: "はメールアドレスではありません"
32
+ not_email: "は有効ではありません"
31
33
  devise:
32
34
  mailer:
33
35
  confirmation_instructions:
34
36
  confirm_link_msg: "下記のリンクからアカウントを有効化できます:"
35
37
  confirm_account_link: "アカウントを有効化する"
36
38
  reset_password_instructions:
37
- request_reset_link_msg: "パスワード変更のリクエストが送信されました。下記のリンクからパスワードの変更をできます。"
39
+ request_reset_link_msg: "パスワード変更のリクエストが送信されました。下記のリンクからパスワードの変更ができます。"
38
40
  password_change_link: "パスワードを変更する"
39
41
  ignore_mail_msg: "もしこの内容に覚えがない場合は、このメールを無視してください。"
40
42
  no_changes_msg: "上記のリンクにアクセスして新しいパスワードを作成するまで、現在のパスワードは変更されません。"