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.
- checksums.yaml +5 -5
- data/README.md +42 -895
- data/Rakefile +11 -4
- data/app/controllers/devise_token_auth/application_controller.rb +19 -8
- data/app/controllers/devise_token_auth/concerns/resource_finder.rb +26 -12
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +106 -85
- data/app/controllers/devise_token_auth/confirmations_controller.rb +73 -17
- data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +95 -51
- data/app/controllers/devise_token_auth/passwords_controller.rb +65 -57
- data/app/controllers/devise_token_auth/registrations_controller.rb +61 -61
- data/app/controllers/devise_token_auth/sessions_controller.rb +22 -18
- data/app/controllers/devise_token_auth/token_validations_controller.rb +5 -3
- data/app/controllers/devise_token_auth/unlocks_controller.rb +20 -16
- 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 +92 -100
- data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +8 -3
- data/app/validators/{email_validator.rb → devise_token_auth_email_validator.rb} +5 -3
- data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
- data/config/locales/da-DK.yml +11 -9
- 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 +4 -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 +52 -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 +21 -13
- data/lib/devise_token_auth/controllers/url_helpers.rb +2 -0
- data/lib/devise_token_auth/engine.rb +26 -14
- data/lib/devise_token_auth/errors.rb +8 -0
- data/lib/devise_token_auth/rails/routes.rb +37 -30
- data/lib/devise_token_auth/token_factory.rb +126 -0
- data/lib/devise_token_auth/url.rb +11 -4
- data/lib/devise_token_auth/version.rb +3 -1
- data/lib/devise_token_auth.rb +11 -5
- data/lib/generators/devise_token_auth/USAGE +2 -2
- data/lib/generators/devise_token_auth/install_generator.rb +36 -105
- 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/install_views_generator.rb +7 -5
- data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +12 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +8 -14
- data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
- data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
- data/lib/tasks/devise_token_auth_tasks.rake +2 -0
- data/test/controllers/custom/custom_confirmations_controller_test.rb +5 -1
- data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +4 -0
- data/test/controllers/custom/custom_passwords_controller_test.rb +6 -2
- data/test/controllers/custom/custom_registrations_controller_test.rb +17 -8
- data/test/controllers/custom/custom_sessions_controller_test.rb +7 -5
- data/test/controllers/custom/custom_token_validations_controller_test.rb +5 -3
- data/test/controllers/demo_group_controller_test.rb +4 -6
- data/test/controllers/demo_mang_controller_test.rb +3 -3
- data/test/controllers/demo_user_controller_test.rb +53 -25
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +159 -25
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +117 -47
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +309 -126
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +65 -23
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +93 -61
- data/test/controllers/devise_token_auth/token_validations_controller_test.rb +18 -6
- data/test/controllers/devise_token_auth/unlocks_controller_test.rb +24 -5
- data/test/controllers/overrides/confirmations_controller_test.rb +6 -2
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +5 -1
- data/test/controllers/overrides/passwords_controller_test.rb +27 -29
- data/test/controllers/overrides/registrations_controller_test.rb +33 -27
- data/test/controllers/overrides/sessions_controller_test.rb +6 -4
- data/test/controllers/overrides/token_validations_controller_test.rb +5 -3
- data/test/dummy/app/active_record/confirmable_user.rb +11 -0
- data/test/dummy/app/{models → active_record}/lockable_user.rb +2 -0
- data/test/dummy/app/{models → active_record}/mang.rb +2 -0
- data/test/dummy/app/{models → active_record}/only_email_user.rb +2 -0
- data/test/dummy/app/{models → active_record}/scoped_user.rb +4 -2
- data/test/dummy/app/{models → active_record}/unconfirmable_user.rb +3 -2
- data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
- data/test/dummy/app/active_record/user.rb +6 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/auth_origin_controller.rb +2 -0
- data/test/dummy/app/controllers/custom/confirmations_controller.rb +2 -2
- data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +2 -0
- data/test/dummy/app/controllers/custom/passwords_controller.rb +3 -4
- data/test/dummy/app/controllers/custom/registrations_controller.rb +3 -3
- data/test/dummy/app/controllers/custom/sessions_controller.rb +3 -3
- data/test/dummy/app/controllers/custom/token_validations_controller.rb +3 -3
- data/test/dummy/app/controllers/demo_group_controller.rb +2 -0
- data/test/dummy/app/controllers/demo_mang_controller.rb +2 -0
- data/test/dummy/app/controllers/demo_user_controller.rb +2 -0
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +8 -6
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +5 -3
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +10 -8
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +5 -3
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +12 -12
- data/test/dummy/app/controllers/overrides/token_validations_controller.rb +5 -5
- data/test/dummy/app/helpers/application_helper.rb +1029 -1036
- data/test/dummy/app/models/{user.rb → concerns/favorite_color.rb} +8 -7
- 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 +26 -3
- data/test/dummy/config/boot.rb +8 -2
- data/test/dummy/config/environment.rb +3 -1
- data/test/dummy/config/environments/development.rb +5 -13
- data/test/dummy/config/environments/production.rb +2 -16
- data/test/dummy/config/environments/test.rb +3 -1
- data/test/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -1
- data/test/dummy/config/initializers/devise.rb +287 -0
- data/test/dummy/config/initializers/devise_token_auth.rb +37 -4
- data/test/dummy/config/initializers/figaro.rb +3 -1
- data/test/dummy/config/initializers/filter_parameter_logging.rb +2 -0
- data/test/dummy/config/initializers/inflections.rb +2 -0
- data/test/dummy/config/initializers/mime_types.rb +2 -0
- data/test/dummy/config/initializers/omniauth.rb +5 -2
- data/test/dummy/config/initializers/session_store.rb +2 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/test/dummy/config/routes.rb +14 -29
- data/test/dummy/config/spring.rb +2 -0
- data/test/dummy/config.ru +5 -3
- data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +9 -14
- data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +8 -13
- data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +2 -0
- data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +2 -0
- data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +6 -11
- data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +8 -13
- data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +8 -13
- data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +8 -13
- data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +8 -13
- 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
- data/test/dummy/db/schema.rb +11 -71
- data/test/dummy/lib/migration_database_helper.rb +15 -1
- data/test/dummy/tmp/generators/app/controllers/application_controller.rb +6 -0
- data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +56 -0
- data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +12 -0
- data/test/factories/users.rb +41 -0
- 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 +9 -7
- data/test/lib/generators/devise_token_auth/install_generator_test.rb +67 -37
- data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +222 -0
- data/test/lib/generators/devise_token_auth/install_views_generator_test.rb +3 -1
- 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 +2 -8
- data/test/models/user_test.rb +18 -79
- data/test/support/controllers/routes.rb +43 -0
- data/test/test_helper.rb +83 -26
- metadata +153 -44
- data/config/initializers/devise.rb +0 -196
- data/lib/generators/devise_token_auth/templates/user.rb +0 -7
- data/test/dummy/app/models/evil_user.rb +0 -3
- data/test/dummy/app/models/nice_user.rb +0 -7
- data/test/dummy/app/models/unregisterable_user.rb +0 -7
- data/test/dummy/config/initializers/assets.rb +0 -8
- data/test/dummy/db/migrate/20140928231203_devise_token_auth_create_evil_users.rb +0 -64
- data/test/dummy/db/migrate/20150409095712_devise_token_auth_create_nice_users.rb +0 -61
- data/test/dummy/tmp/generators/app/models/user.rb +0 -11
- data/test/integration/navigation_test.rb +0 -10
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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] ||=
|
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
|
-
|
20
|
-
|
21
|
-
:recoverable, :trackable, :validatable, :confirmable
|
17
|
+
if method_defined?(:devise_modules)
|
18
|
+
devise_modules.delete(:omniauthable)
|
22
19
|
else
|
23
|
-
|
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
|
-
|
27
|
-
|
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] ||=
|
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] ||=
|
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] ||=
|
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
|
-
|
92
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
95
|
+
tokens[token.client] = {
|
96
|
+
token: token.token_hash,
|
97
|
+
expiry: token.expiry
|
98
|
+
}.merge!(token_extras)
|
100
99
|
|
101
|
-
|
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
|
-
|
112
|
-
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? } rescue false
|
102
|
+
token
|
113
103
|
end
|
114
104
|
end
|
115
105
|
|
116
|
-
|
117
|
-
|
118
|
-
return
|
119
|
-
return true if
|
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
|
-
|
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[
|
135
|
-
token_hash = tokens[
|
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,
|
137
|
+
def token_can_be_reused?(token, client)
|
152
138
|
# ghetto HashWithIndifferentAccess
|
153
|
-
updated_at = tokens[
|
154
|
-
|
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 &&
|
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
|
-
|
147
|
+
updated_at.to_time > Time.zone.now - DeviseTokenAuth.batch_request_buffer_throttle &&
|
162
148
|
|
163
149
|
# ensure that the token is valid
|
164
|
-
::
|
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(
|
171
|
-
now = Time.now
|
155
|
+
def create_new_auth_token(client = nil)
|
156
|
+
now = Time.zone.now
|
172
157
|
|
173
|
-
|
174
|
-
|
175
|
-
|
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,
|
164
|
+
update_auth_header(token.token, token.client)
|
181
165
|
end
|
182
166
|
|
183
|
-
def build_auth_header(token,
|
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[
|
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"] =>
|
191
|
-
DeviseTokenAuth.headers_names[:"client"] =>
|
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,
|
198
|
-
headers = build_auth_header(token,
|
199
|
-
|
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
|
-
|
219
|
-
|
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: [
|
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[
|
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
|
-
|
252
|
-
encrypted_password_changed? && tokens && tokens.many?
|
226
|
+
return unless should_remove_tokens_after_password_reset?
|
253
227
|
|
254
|
-
if
|
255
|
-
|
256
|
-
self.tokens = {
|
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,
|
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.
|
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
|
-
|
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
|
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('<%=
|
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
@@ -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: "
|
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: "
|
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
|
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
|
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
|
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: "
|
42
|
-
password_change_link: "
|
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: "
|
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
|
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"
|
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,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: "上記のリンクにアクセスして新しいパスワードを作成するまで、現在のパスワードは変更されません。"
|