devise_token_auth 1.0.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +6 -3
- data/app/controllers/devise_token_auth/application_controller.rb +23 -3
- data/app/controllers/devise_token_auth/concerns/resource_finder.rb +24 -11
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +78 -57
- data/app/controllers/devise_token_auth/confirmations_controller.rb +69 -19
- data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +89 -44
- data/app/controllers/devise_token_auth/passwords_controller.rb +55 -31
- data/app/controllers/devise_token_auth/registrations_controller.rb +33 -40
- data/app/controllers/devise_token_auth/sessions_controller.rb +36 -14
- data/app/controllers/devise_token_auth/unlocks_controller.rb +12 -7
- data/app/models/devise_token_auth/concerns/active_record_support.rb +14 -0
- data/app/models/devise_token_auth/concerns/confirmable_support.rb +28 -0
- data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
- data/app/models/devise_token_auth/concerns/tokens_serialization.rb +31 -0
- data/app/models/devise_token_auth/concerns/user.rb +79 -80
- data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +12 -5
- data/app/validators/{email_validator.rb → devise_token_auth_email_validator.rb} +11 -3
- data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
- data/config/locales/da-DK.yml +2 -0
- data/config/locales/de.yml +2 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/es.yml +2 -0
- data/config/locales/fr.yml +2 -0
- data/config/locales/he.yml +52 -0
- data/config/locales/it.yml +2 -0
- data/config/locales/ja.yml +16 -2
- data/config/locales/ko.yml +51 -0
- data/config/locales/nl.yml +2 -0
- data/config/locales/pl.yml +6 -3
- data/config/locales/pt-BR.yml +2 -0
- data/config/locales/pt.yml +6 -3
- data/config/locales/ro.yml +2 -0
- data/config/locales/ru.yml +2 -0
- data/config/locales/sq.yml +2 -0
- data/config/locales/sv.yml +2 -0
- data/config/locales/uk.yml +2 -0
- data/config/locales/vi.yml +2 -0
- data/config/locales/zh-CN.yml +2 -0
- data/config/locales/zh-HK.yml +2 -0
- data/config/locales/zh-TW.yml +2 -0
- data/lib/devise_token_auth/blacklist.rb +6 -0
- data/lib/devise_token_auth/controllers/helpers.rb +5 -9
- data/lib/devise_token_auth/engine.rb +17 -2
- data/lib/devise_token_auth/rails/routes.rb +22 -16
- data/lib/devise_token_auth/token_factory.rb +126 -0
- data/lib/devise_token_auth/url.rb +3 -0
- data/lib/devise_token_auth/version.rb +1 -1
- data/lib/devise_token_auth.rb +6 -3
- data/lib/generators/devise_token_auth/USAGE +1 -1
- data/lib/generators/devise_token_auth/install_generator.rb +7 -91
- data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
- data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +21 -5
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +1 -8
- data/lib/generators/devise_token_auth/templates/user.rb.erb +2 -2
- data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
- data/test/controllers/custom/custom_confirmations_controller_test.rb +2 -2
- data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +1 -1
- data/test/controllers/demo_mang_controller_test.rb +37 -8
- data/test/controllers/demo_user_controller_test.rb +39 -10
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +170 -22
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +117 -53
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +299 -122
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +56 -16
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +139 -75
- data/test/controllers/devise_token_auth/token_validations_controller_test.rb +43 -2
- data/test/controllers/devise_token_auth/unlocks_controller_test.rb +44 -5
- data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +1 -1
- data/test/dummy/app/active_record/confirmable_user.rb +11 -0
- data/test/dummy/app/{models → active_record}/scoped_user.rb +2 -2
- data/test/dummy/app/{models → active_record}/unconfirmable_user.rb +1 -2
- data/test/dummy/app/{models → active_record}/unregisterable_user.rb +3 -3
- data/test/dummy/app/active_record/user.rb +6 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -6
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +5 -4
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +5 -4
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +2 -2
- data/test/dummy/app/models/{user.rb → concerns/favorite_color.rb} +7 -8
- data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
- data/test/dummy/app/mongoid/lockable_user.rb +38 -0
- data/test/dummy/app/mongoid/mang.rb +46 -0
- data/test/dummy/app/mongoid/only_email_user.rb +33 -0
- data/test/dummy/app/mongoid/scoped_user.rb +50 -0
- data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
- data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
- data/test/dummy/app/mongoid/user.rb +49 -0
- data/test/dummy/app/views/layouts/application.html.erb +0 -2
- data/test/dummy/config/application.rb +22 -1
- data/test/dummy/config/boot.rb +4 -0
- data/test/dummy/config/environments/development.rb +0 -10
- data/test/dummy/config/environments/production.rb +0 -16
- data/test/dummy/config/environments/test.rb +6 -2
- data/test/dummy/config/initializers/devise.rb +285 -0
- data/test/dummy/config/initializers/devise_token_auth.rb +35 -4
- data/test/dummy/config/initializers/figaro.rb +1 -1
- data/test/dummy/config/initializers/omniauth.rb +1 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +0 -7
- data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +0 -7
- data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +0 -7
- data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +0 -7
- data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +0 -7
- data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +0 -7
- data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +0 -7
- data/test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb +49 -0
- data/test/dummy/db/schema.rb +31 -33
- data/test/dummy/tmp/generators/app/models/user.rb +9 -0
- data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +66 -0
- data/test/dummy/tmp/generators/db/migrate/20230415183419_devise_token_auth_create_users.rb +49 -0
- data/test/factories/users.rb +3 -2
- data/test/lib/devise_token_auth/blacklist_test.rb +19 -0
- data/test/lib/devise_token_auth/rails/custom_routes_test.rb +29 -0
- data/test/lib/devise_token_auth/rails/routes_test.rb +87 -0
- data/test/lib/devise_token_auth/token_factory_test.rb +191 -0
- data/test/lib/devise_token_auth/url_test.rb +2 -2
- data/test/lib/generators/devise_token_auth/install_generator_test.rb +51 -31
- data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +51 -31
- data/test/models/concerns/mongoid_support_test.rb +31 -0
- data/test/models/concerns/tokens_serialization_test.rb +104 -0
- data/test/models/confirmable_user_test.rb +35 -0
- data/test/models/only_email_user_test.rb +0 -8
- data/test/models/user_test.rb +13 -23
- data/test/test_helper.rb +45 -4
- metadata +190 -97
- data/config/initializers/devise.rb +0 -198
- data/test/dummy/config/initializers/assets.rb +0 -10
- data/test/dummy/tmp/generators/app/views/devise/mailer/confirmation_instructions.html.erb +0 -5
- data/test/dummy/tmp/generators/app/views/devise/mailer/reset_password_instructions.html.erb +0 -8
- /data/test/dummy/app/{models → active_record}/lockable_user.rb +0 -0
- /data/test/dummy/app/{models → active_record}/mang.rb +0 -0
- /data/test/dummy/app/{models → active_record}/only_email_user.rb +0 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module DeviseTokenAuth::Concerns::ConfirmableSupport
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
# Override standard devise `postpone_email_change?` method
|
6
|
+
# for not to use `will_save_change_to_email?` & `email_changed?` methods.
|
7
|
+
def postpone_email_change?
|
8
|
+
postpone = self.class.reconfirmable &&
|
9
|
+
email_value_in_database != email &&
|
10
|
+
!@bypass_confirmation_postpone &&
|
11
|
+
self.email.present? &&
|
12
|
+
(!@skip_reconfirmation_in_callback || !email_value_in_database.nil?)
|
13
|
+
@bypass_confirmation_postpone = false
|
14
|
+
postpone
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def email_value_in_database
|
21
|
+
rails51 = Rails.gem_version >= Gem::Version.new("5.1.x")
|
22
|
+
if rails51 && respond_to?(:email_in_database)
|
23
|
+
email_in_database
|
24
|
+
else
|
25
|
+
email_was
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DeviseTokenAuth::Concerns::MongoidSupport
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
def as_json(options = {})
|
5
|
+
options[:except] = (options[:except] || []) + [:_id]
|
6
|
+
hash = super(options)
|
7
|
+
hash['id'] = to_param
|
8
|
+
hash
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
# It's abstract replacement .find_by
|
13
|
+
def dta_find_by(attrs = {})
|
14
|
+
find_by(attrs)
|
15
|
+
rescue Mongoid::Errors::DocumentNotFound
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DeviseTokenAuth::Concerns::TokensSerialization
|
2
|
+
extend self
|
3
|
+
# Serialization hash to json
|
4
|
+
def dump(object)
|
5
|
+
JSON.generate(object && object.transform_values do |token|
|
6
|
+
serialize_updated_at(token).compact
|
7
|
+
end.compact)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Deserialization json to hash
|
11
|
+
def load(json)
|
12
|
+
case json
|
13
|
+
when String
|
14
|
+
JSON.parse(json)
|
15
|
+
when NilClass
|
16
|
+
{}
|
17
|
+
else
|
18
|
+
json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def serialize_updated_at(token)
|
25
|
+
updated_at_key = ['updated_at', :updated_at].find(&token.method(:[]))
|
26
|
+
|
27
|
+
return token unless token[updated_at_key].respond_to?(:iso8601)
|
28
|
+
|
29
|
+
token.merge updated_at_key => token[updated_at_key].iso8601
|
30
|
+
end
|
31
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'bcrypt'
|
4
|
-
|
5
3
|
module DeviseTokenAuth::Concerns::User
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
|
@@ -9,7 +7,7 @@ module DeviseTokenAuth::Concerns::User
|
|
9
7
|
@token_equality_cache ||= {}
|
10
8
|
|
11
9
|
key = "#{token_hash}/#{token}"
|
12
|
-
result = @token_equality_cache[key] ||=
|
10
|
+
result = @token_equality_cache[key] ||= DeviseTokenAuth::TokenFactory.token_hash_is_token?(token_hash, token)
|
13
11
|
@token_equality_cache = {} if @token_equality_cache.size > 10000
|
14
12
|
result
|
15
13
|
end
|
@@ -20,19 +18,21 @@ module DeviseTokenAuth::Concerns::User
|
|
20
18
|
devise_modules.delete(:omniauthable)
|
21
19
|
else
|
22
20
|
devise :database_authenticatable, :registerable,
|
23
|
-
:recoverable, :
|
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
|
-
|
28
|
+
if const_defined?('Mongoid') && ancestors.include?(Mongoid::Document)
|
29
|
+
include DeviseTokenAuth::Concerns::MongoidSupport
|
30
|
+
end
|
27
31
|
|
28
32
|
if DeviseTokenAuth.default_callbacks
|
29
33
|
include DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
30
34
|
end
|
31
35
|
|
32
|
-
# can't set default on text fields in mysql, simulate here instead.
|
33
|
-
after_save :set_empty_token_hash
|
34
|
-
after_initialize :set_empty_token_hash
|
35
|
-
|
36
36
|
# get rid of dead tokens
|
37
37
|
before_save :destroy_expired_tokens
|
38
38
|
|
@@ -44,6 +44,10 @@ module DeviseTokenAuth::Concerns::User
|
|
44
44
|
def email_changed?; false; end
|
45
45
|
def will_save_change_to_email?; false; end
|
46
46
|
|
47
|
+
if DeviseTokenAuth.send_confirmation_email && devise_modules.include?(:confirmable)
|
48
|
+
include DeviseTokenAuth::Concerns::ConfirmableSupport
|
49
|
+
end
|
50
|
+
|
47
51
|
def password_required?
|
48
52
|
return false unless provider == 'email'
|
49
53
|
super
|
@@ -84,39 +88,25 @@ module DeviseTokenAuth::Concerns::User
|
|
84
88
|
send_devise_notification(:unlock_instructions, raw, opts)
|
85
89
|
raw
|
86
90
|
end
|
87
|
-
end
|
88
91
|
|
89
|
-
|
90
|
-
|
91
|
-
token ||= SecureRandom.urlsafe_base64(nil, false)
|
92
|
-
expiry ||= (Time.zone.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)
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
tokens[token.client] = {
|
96
|
+
token: token.token_hash,
|
97
|
+
expiry: token.expiry
|
98
|
+
}.merge!(token_extras)
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
[client_id, token, expiry]
|
102
|
-
end
|
103
|
-
|
104
|
-
module ClassMethods
|
105
|
-
protected
|
100
|
+
clean_old_tokens
|
106
101
|
|
107
|
-
|
108
|
-
database_exists? && table_exists? && columns_hash['tokens'] && columns_hash['tokens'].type.in?([:json, :jsonb])
|
109
|
-
end
|
110
|
-
|
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
|
-
def valid_token?(token,
|
117
|
-
return false unless tokens[
|
118
|
-
return true if token_is_current?(token,
|
119
|
-
return true if token_can_be_reused?(token,
|
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)
|
120
110
|
|
121
111
|
# return false if none of the above conditions are met
|
122
112
|
false
|
@@ -126,10 +116,11 @@ module DeviseTokenAuth::Concerns::User
|
|
126
116
|
# can be passed on from the client
|
127
117
|
def send_confirmation_notification?; false; end
|
128
118
|
|
129
|
-
def token_is_current?(token,
|
119
|
+
def token_is_current?(token, client)
|
130
120
|
# ghetto HashWithIndifferentAccess
|
131
|
-
expiry = tokens[
|
132
|
-
token_hash = tokens[
|
121
|
+
expiry = tokens[client]['expiry'] || tokens[client][:expiry]
|
122
|
+
token_hash = tokens[client]['token'] || tokens[client][:token]
|
123
|
+
previous_token_hash = tokens[client]['previous_token'] || tokens[client][:previous_token]
|
133
124
|
|
134
125
|
return true if (
|
135
126
|
# ensure that expiry and token are set
|
@@ -139,58 +130,79 @@ module DeviseTokenAuth::Concerns::User
|
|
139
130
|
DateTime.strptime(expiry.to_s, '%s') > Time.zone.now &&
|
140
131
|
|
141
132
|
# ensure that the token is valid
|
142
|
-
|
133
|
+
(
|
134
|
+
# check if the latest token matches
|
135
|
+
does_token_match?(token_hash, token) ||
|
136
|
+
|
137
|
+
# check if the previous token matches
|
138
|
+
does_token_match?(previous_token_hash, token)
|
139
|
+
)
|
143
140
|
)
|
144
141
|
end
|
145
142
|
|
146
|
-
#
|
147
|
-
def
|
143
|
+
# check if the hash of received token matches the stored token
|
144
|
+
def does_token_match?(token_hash, token)
|
145
|
+
return false if token_hash.nil?
|
146
|
+
|
147
|
+
DeviseTokenAuth::Concerns::User.tokens_match?(token_hash, token)
|
148
|
+
end
|
149
|
+
|
150
|
+
# allow batch requests to use the last token
|
151
|
+
def token_can_be_reused?(token, client)
|
148
152
|
# ghetto HashWithIndifferentAccess
|
149
|
-
updated_at = tokens[
|
150
|
-
|
153
|
+
updated_at = tokens[client]['updated_at'] || tokens[client][:updated_at]
|
154
|
+
last_token_hash = tokens[client]['last_token'] || tokens[client][:last_token]
|
151
155
|
|
152
156
|
return true if (
|
153
157
|
# ensure that the last token and its creation time exist
|
154
|
-
updated_at &&
|
158
|
+
updated_at && last_token_hash &&
|
155
159
|
|
156
|
-
# ensure that
|
157
|
-
|
160
|
+
# ensure that last token falls within the batch buffer throttle time of the last request
|
161
|
+
updated_at.to_time > Time.zone.now - DeviseTokenAuth.batch_request_buffer_throttle &&
|
158
162
|
|
159
163
|
# ensure that the token is valid
|
160
|
-
::
|
164
|
+
DeviseTokenAuth::TokenFactory.token_hash_is_token?(last_token_hash, token)
|
161
165
|
)
|
162
166
|
end
|
163
167
|
|
164
168
|
# update user's auth token (should happen on each request)
|
165
|
-
def create_new_auth_token(
|
169
|
+
def create_new_auth_token(client = nil)
|
166
170
|
now = Time.zone.now
|
167
171
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
last_token: tokens.fetch(
|
172
|
+
token = create_token(
|
173
|
+
client: client,
|
174
|
+
previous_token: tokens.fetch(client, {})['token'],
|
175
|
+
last_token: tokens.fetch(client, {})['previous_token'],
|
172
176
|
updated_at: now
|
173
177
|
)
|
174
178
|
|
175
|
-
|
179
|
+
update_auth_headers(token.token, token.client)
|
176
180
|
end
|
177
181
|
|
178
|
-
def
|
182
|
+
def build_auth_headers(token, client = 'default')
|
179
183
|
# client may use expiry to prevent validation request if expired
|
180
184
|
# must be cast as string or headers will break
|
181
|
-
expiry = tokens[
|
182
|
-
|
183
|
-
{
|
185
|
+
expiry = tokens[client]['expiry'] || tokens[client][:expiry]
|
186
|
+
headers = {
|
184
187
|
DeviseTokenAuth.headers_names[:"access-token"] => token,
|
185
188
|
DeviseTokenAuth.headers_names[:"token-type"] => 'Bearer',
|
186
|
-
DeviseTokenAuth.headers_names[:"client"] =>
|
189
|
+
DeviseTokenAuth.headers_names[:"client"] => client,
|
187
190
|
DeviseTokenAuth.headers_names[:"expiry"] => expiry.to_s,
|
188
191
|
DeviseTokenAuth.headers_names[:"uid"] => uid
|
189
192
|
}
|
193
|
+
headers.merge(build_bearer_token(headers))
|
194
|
+
end
|
195
|
+
|
196
|
+
def build_bearer_token(auth)
|
197
|
+
return {} if DeviseTokenAuth.cookie_enabled # There is no need for the bearer token if it is using cookies
|
198
|
+
|
199
|
+
encoded_token = Base64.strict_encode64(auth.to_json)
|
200
|
+
bearer_token = "Bearer #{encoded_token}"
|
201
|
+
{ DeviseTokenAuth.headers_names[:"authorization"] => bearer_token }
|
190
202
|
end
|
191
203
|
|
192
|
-
def
|
193
|
-
headers =
|
204
|
+
def update_auth_headers(token, client = 'default')
|
205
|
+
headers = build_auth_headers(token, client)
|
194
206
|
clean_old_tokens
|
195
207
|
save!
|
196
208
|
|
@@ -204,9 +216,9 @@ module DeviseTokenAuth::Concerns::User
|
|
204
216
|
DeviseTokenAuth::Url.generate(base_url, args)
|
205
217
|
end
|
206
218
|
|
207
|
-
def extend_batch_buffer(token,
|
208
|
-
tokens[
|
209
|
-
|
219
|
+
def extend_batch_buffer(token, client)
|
220
|
+
tokens[client]['updated_at'] = Time.zone.now
|
221
|
+
update_auth_headers(token, client)
|
210
222
|
end
|
211
223
|
|
212
224
|
def confirmed?
|
@@ -217,16 +229,8 @@ module DeviseTokenAuth::Concerns::User
|
|
217
229
|
as_json(except: %i[tokens created_at updated_at])
|
218
230
|
end
|
219
231
|
|
220
|
-
def token_lifespan
|
221
|
-
DeviseTokenAuth.token_lifespan
|
222
|
-
end
|
223
|
-
|
224
232
|
protected
|
225
233
|
|
226
|
-
def set_empty_token_hash
|
227
|
-
self.tokens ||= {} if has_attribute?(:tokens)
|
228
|
-
end
|
229
|
-
|
230
234
|
def destroy_expired_tokens
|
231
235
|
if tokens
|
232
236
|
tokens.delete_if do |cid, v|
|
@@ -237,21 +241,16 @@ module DeviseTokenAuth::Concerns::User
|
|
237
241
|
end
|
238
242
|
|
239
243
|
def should_remove_tokens_after_password_reset?
|
240
|
-
|
241
|
-
encrypted_password_changed? &&
|
242
|
-
DeviseTokenAuth.remove_tokens_after_password_reset
|
243
|
-
else
|
244
|
-
saved_change_to_encrypted_password? &&
|
245
|
-
DeviseTokenAuth.remove_tokens_after_password_reset
|
246
|
-
end
|
244
|
+
DeviseTokenAuth.remove_tokens_after_password_reset &&
|
245
|
+
(respond_to?(:encrypted_password_changed?) && encrypted_password_changed?)
|
247
246
|
end
|
248
247
|
|
249
248
|
def remove_tokens_after_password_reset
|
250
249
|
return unless should_remove_tokens_after_password_reset?
|
251
250
|
|
252
251
|
if tokens.present? && tokens.many?
|
253
|
-
|
254
|
-
self.tokens = {
|
252
|
+
client, token_data = tokens.max_by { |cid, v| v[:expiry] || v['expiry'] }
|
253
|
+
self.tokens = { client => token_data }
|
255
254
|
end
|
256
255
|
end
|
257
256
|
|
@@ -4,12 +4,12 @@ module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
validates :email, presence: true,if:
|
8
|
-
validates :email,
|
9
|
-
validates_presence_of :uid,
|
7
|
+
validates :email, presence: true, if: lambda { uid_and_provider_defined? && email_provider? }
|
8
|
+
validates :email, :devise_token_auth_email => true, allow_nil: true, allow_blank: true, if: lambda { uid_and_provider_defined? && email_provider? }
|
9
|
+
validates_presence_of :uid, if: lambda { uid_and_provider_defined? && !email_provider? }
|
10
10
|
|
11
11
|
# only validate unique emails among email registration users
|
12
|
-
validates :email, uniqueness: { scope: :provider }, on: :create, if:
|
12
|
+
validates :email, uniqueness: { case_sensitive: false, scope: :provider }, on: :create, if: lambda { uid_and_provider_defined? && email_provider? }
|
13
13
|
|
14
14
|
# keep uid in sync with email
|
15
15
|
before_save :sync_uid
|
@@ -18,11 +18,18 @@ module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
|
18
18
|
|
19
19
|
protected
|
20
20
|
|
21
|
+
def uid_and_provider_defined?
|
22
|
+
defined?(provider) && defined?(uid)
|
23
|
+
end
|
24
|
+
|
21
25
|
def email_provider?
|
22
26
|
provider == 'email'
|
23
27
|
end
|
24
28
|
|
25
29
|
def sync_uid
|
26
|
-
self.
|
30
|
+
unless self.new_record?
|
31
|
+
return if devise_modules.include?(:confirmable) && !@bypass_confirmation_postpone && postpone_email_change?
|
32
|
+
end
|
33
|
+
self.uid = email if uid_and_provider_defined? && email_provider?
|
27
34
|
end
|
28
35
|
end
|
@@ -1,9 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class
|
3
|
+
class DeviseTokenAuthEmailValidator < ActiveModel::EachValidator
|
4
|
+
EMAIL_REGEXP = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def validate?(email)
|
8
|
+
email =~ EMAIL_REGEXP
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
def validate_each(record, attribute, value)
|
5
|
-
unless value
|
6
|
-
record.errors
|
13
|
+
unless DeviseTokenAuthEmailValidator.validate?(value)
|
14
|
+
record.errors.add(attribute, email_invalid_message)
|
7
15
|
end
|
8
16
|
end
|
9
17
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
Cordova / PhoneGap)
|
16
16
|
*/
|
17
17
|
|
18
|
-
var data = JSON.parse(decodeURIComponent('<%=
|
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") {
|
data/config/locales/da-DK.yml
CHANGED
@@ -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."
|
data/config/locales/de.yml
CHANGED
@@ -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."
|
data/config/locales/en.yml
CHANGED
@@ -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."
|
data/config/locales/es.yml
CHANGED
@@ -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."
|
data/config/locales/fr.yml
CHANGED
@@ -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: "ברוך הבא"
|
data/config/locales/it.yml
CHANGED
@@ -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."
|
data/config/locales/ja.yml
CHANGED
@@ -14,27 +14,41 @@ 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 が与えられていません。"
|
20
22
|
not_allowed_redirect_url: "'%{redirect_url}' へのリダイレクトは許可されていません。"
|
21
23
|
sended: "'%{email}' にパスワードリセットの案内が送信されました。"
|
24
|
+
sended_paranoid: "すでにメールアドレスがデータベースに登録されている場合、 数分後にパスワード再発行用のリンクを記載したメールをお送りします。"
|
22
25
|
user_not_found: "メールアドレス '%{email}' のユーザーが見つかりません。"
|
23
26
|
password_not_required: "このアカウントはパスワードを要求していません。'%{provider}' を利用してログインしてください。"
|
24
27
|
missing_passwords: "'Password', 'Password confirmation' パラメータが与えられていません。"
|
25
28
|
successfully_updated: "パスワードの更新に成功しました。"
|
29
|
+
unlocks:
|
30
|
+
missing_email: "メールアドレスが与えられていません。"
|
31
|
+
sended: "%{email}' にアカウントのロックを解除する方法を記載したメールが送信されました。"
|
32
|
+
sended_paranoid: "アカウントが存在する場合、数分後にロックを解除する方法を記載したメールをお送りします。"
|
33
|
+
user_not_found: "メールアドレス '%{email}' を持つユーザーが見つかりません。"
|
34
|
+
confirmations:
|
35
|
+
sended: "'%{email}' にアカウントの確認方法を記載したメールが送信されました。"
|
36
|
+
sended_paranoid: "すでにメールアドレスがデータベースに登録されている場合、数分後にメールアドレスの確認方法を記載したメールをお送りします。"
|
37
|
+
user_not_found: "メールアドレス '%{email}' を持つユーザーが見つかりません。"
|
38
|
+
missing_email: "メールアドレスが与えられていません。"
|
39
|
+
|
26
40
|
errors:
|
27
41
|
messages:
|
28
42
|
validate_sign_up_params: "リクエストボディに適切なアカウント新規登録データを送信してください。"
|
29
43
|
validate_account_update_params: "リクエストボディに適切なアカウント更新のデータを送信してください。"
|
30
|
-
not_email: "
|
44
|
+
not_email: "は有効ではありません"
|
31
45
|
devise:
|
32
46
|
mailer:
|
33
47
|
confirmation_instructions:
|
34
48
|
confirm_link_msg: "下記のリンクからアカウントを有効化できます:"
|
35
49
|
confirm_account_link: "アカウントを有効化する"
|
36
50
|
reset_password_instructions:
|
37
|
-
request_reset_link_msg: "
|
51
|
+
request_reset_link_msg: "パスワード変更のリクエストが送信されました。下記のリンクからパスワードの変更ができます。"
|
38
52
|
password_change_link: "パスワードを変更する"
|
39
53
|
ignore_mail_msg: "もしこの内容に覚えがない場合は、このメールを無視してください。"
|
40
54
|
no_changes_msg: "上記のリンクにアクセスして新しいパスワードを作成するまで、現在のパスワードは変更されません。"
|