devise_token_auth_skycocker_fork 1.0.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 +7 -0
- data/LICENSE +13 -0
- data/README.md +97 -0
- data/Rakefile +42 -0
- data/app/controllers/devise_token_auth/application_controller.rb +79 -0
- data/app/controllers/devise_token_auth/concerns/resource_finder.rb +44 -0
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +178 -0
- data/app/controllers/devise_token_auth/confirmations_controller.rb +39 -0
- data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +239 -0
- data/app/controllers/devise_token_auth/passwords_controller.rb +185 -0
- data/app/controllers/devise_token_auth/registrations_controller.rb +198 -0
- data/app/controllers/devise_token_auth/sessions_controller.rb +131 -0
- data/app/controllers/devise_token_auth/token_validations_controller.rb +31 -0
- data/app/controllers/devise_token_auth/unlocks_controller.rb +89 -0
- data/app/models/devise_token_auth/concerns/active_record_support.rb +34 -0
- data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
- data/app/models/devise_token_auth/concerns/user.rb +262 -0
- data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +28 -0
- data/app/validators/devise_token_auth/email_validator.rb +23 -0
- data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/devise_token_auth/omniauth_external_window.html.erb +38 -0
- data/config/locales/da-DK.yml +50 -0
- data/config/locales/de.yml +49 -0
- data/config/locales/en.yml +50 -0
- data/config/locales/es.yml +49 -0
- data/config/locales/fr.yml +49 -0
- data/config/locales/it.yml +46 -0
- data/config/locales/ja.yml +46 -0
- data/config/locales/nl.yml +30 -0
- data/config/locales/pl.yml +48 -0
- data/config/locales/pt-BR.yml +46 -0
- data/config/locales/pt.yml +48 -0
- data/config/locales/ro.yml +46 -0
- data/config/locales/ru.yml +50 -0
- data/config/locales/sq.yml +46 -0
- data/config/locales/sv.yml +50 -0
- data/config/locales/uk.yml +59 -0
- data/config/locales/vi.yml +50 -0
- data/config/locales/zh-CN.yml +46 -0
- data/config/locales/zh-HK.yml +48 -0
- data/config/locales/zh-TW.yml +48 -0
- data/lib/devise_token_auth.rb +13 -0
- data/lib/devise_token_auth/blacklist.rb +2 -0
- data/lib/devise_token_auth/controllers/helpers.rb +161 -0
- data/lib/devise_token_auth/controllers/url_helpers.rb +10 -0
- data/lib/devise_token_auth/engine.rb +90 -0
- data/lib/devise_token_auth/errors.rb +8 -0
- data/lib/devise_token_auth/rails/routes.rb +116 -0
- data/lib/devise_token_auth/url.rb +41 -0
- data/lib/devise_token_auth/version.rb +5 -0
- data/lib/generators/devise_token_auth/USAGE +31 -0
- data/lib/generators/devise_token_auth/install_generator.rb +91 -0
- 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 +18 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +50 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +56 -0
- data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
- data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +63 -0
- data/lib/tasks/devise_token_auth_tasks.rake +6 -0
- data/test/controllers/custom/custom_confirmations_controller_test.rb +25 -0
- data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +33 -0
- data/test/controllers/custom/custom_passwords_controller_test.rb +79 -0
- data/test/controllers/custom/custom_registrations_controller_test.rb +63 -0
- data/test/controllers/custom/custom_sessions_controller_test.rb +39 -0
- data/test/controllers/custom/custom_token_validations_controller_test.rb +42 -0
- data/test/controllers/demo_group_controller_test.rb +151 -0
- data/test/controllers/demo_mang_controller_test.rb +284 -0
- data/test/controllers/demo_user_controller_test.rb +629 -0
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +127 -0
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +376 -0
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +639 -0
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +880 -0
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +541 -0
- data/test/controllers/devise_token_auth/token_validations_controller_test.rb +102 -0
- data/test/controllers/devise_token_auth/unlocks_controller_test.rb +196 -0
- data/test/controllers/overrides/confirmations_controller_test.rb +47 -0
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +53 -0
- data/test/controllers/overrides/passwords_controller_test.rb +64 -0
- data/test/controllers/overrides/registrations_controller_test.rb +46 -0
- data/test/controllers/overrides/sessions_controller_test.rb +35 -0
- data/test/controllers/overrides/token_validations_controller_test.rb +43 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/app/active_record/lockable_user.rb +7 -0
- data/test/dummy/app/active_record/mang.rb +5 -0
- data/test/dummy/app/active_record/only_email_user.rb +7 -0
- data/test/dummy/app/active_record/scoped_user.rb +9 -0
- data/test/dummy/app/active_record/unconfirmable_user.rb +9 -0
- 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 +18 -0
- data/test/dummy/app/controllers/auth_origin_controller.rb +7 -0
- data/test/dummy/app/controllers/custom/confirmations_controller.rb +13 -0
- data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +13 -0
- data/test/dummy/app/controllers/custom/passwords_controller.rb +39 -0
- data/test/dummy/app/controllers/custom/registrations_controller.rb +39 -0
- data/test/dummy/app/controllers/custom/sessions_controller.rb +29 -0
- data/test/dummy/app/controllers/custom/token_validations_controller.rb +19 -0
- data/test/dummy/app/controllers/demo_group_controller.rb +15 -0
- data/test/dummy/app/controllers/demo_mang_controller.rb +14 -0
- data/test/dummy/app/controllers/demo_user_controller.rb +27 -0
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +28 -0
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +16 -0
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +35 -0
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +29 -0
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +36 -0
- data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
- data/test/dummy/app/helpers/application_helper.rb +1058 -0
- data/test/dummy/app/models/concerns/favorite_color.rb +19 -0
- data/test/dummy/app/mongoid/lockable_user.rb +38 -0
- data/test/dummy/app/mongoid/mang.rb +53 -0
- data/test/dummy/app/mongoid/only_email_user.rb +33 -0
- data/test/dummy/app/mongoid/scoped_user.rb +57 -0
- data/test/dummy/app/mongoid/unconfirmable_user.rb +51 -0
- data/test/dummy/app/mongoid/unregisterable_user.rb +54 -0
- data/test/dummy/app/mongoid/user.rb +56 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +18 -0
- data/test/dummy/config/application.rb +48 -0
- data/test/dummy/config/application.yml.bk +0 -0
- data/test/dummy/config/boot.rb +11 -0
- data/test/dummy/config/environment.rb +7 -0
- data/test/dummy/config/environments/development.rb +46 -0
- data/test/dummy/config/environments/production.rb +84 -0
- data/test/dummy/config/environments/test.rb +50 -0
- data/test/dummy/config/initializers/assets.rb +10 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/devise.rb +17 -0
- data/test/dummy/config/initializers/devise_token_auth.rb +24 -0
- data/test/dummy/config/initializers/figaro.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/test/dummy/config/initializers/inflections.rb +18 -0
- data/test/dummy/config/initializers/mime_types.rb +6 -0
- data/test/dummy/config/initializers/omniauth.rb +10 -0
- data/test/dummy/config/initializers/session_store.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/test/dummy/config/routes.rb +55 -0
- data/test/dummy/config/spring.rb +3 -0
- data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +65 -0
- data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +64 -0
- data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +8 -0
- data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +7 -0
- data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +62 -0
- data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +63 -0
- data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +63 -0
- data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +63 -0
- data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +63 -0
- data/test/dummy/db/schema.rb +200 -0
- data/test/dummy/lib/migration_database_helper.rb +43 -0
- data/test/dummy/tmp/generators/app/models/user.rb +9 -0
- data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +50 -0
- data/test/dummy/tmp/generators/db/migrate/20181030122248_devise_token_auth_create_users.rb +56 -0
- data/test/factories/users.rb +40 -0
- data/test/lib/devise_token_auth/blacklist_test.rb +11 -0
- data/test/lib/devise_token_auth/url_test.rb +26 -0
- data/test/lib/generators/devise_token_auth/install_generator_test.rb +217 -0
- 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 +25 -0
- data/test/models/concerns/mongoid_support_test.rb +31 -0
- data/test/models/only_email_user_test.rb +37 -0
- data/test/models/user_test.rb +140 -0
- data/test/support/controllers/routes.rb +43 -0
- data/test/test_helper.rb +103 -0
- metadata +443 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module DeviseTokenAuth::Concerns::ActiveRecordSupport
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
serialize :tokens, JSON unless tokens_has_json_column_type?
|
|
6
|
+
|
|
7
|
+
# can't set default on text fields in mysql, simulate here instead.
|
|
8
|
+
after_save :set_empty_token_hash
|
|
9
|
+
after_initialize :set_empty_token_hash
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class_methods do
|
|
13
|
+
# It's abstract replacement .find_by
|
|
14
|
+
def dta_find_by(attrs = {})
|
|
15
|
+
find_by(attrs)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
def tokens_has_json_column_type?
|
|
21
|
+
database_exists? && table_exists? && columns_hash['tokens'] && columns_hash['tokens'].type.in?([:json, :jsonb])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def database_exists?
|
|
25
|
+
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? } rescue false
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def set_empty_token_hash
|
|
32
|
+
self.tokens ||= {} if has_attribute?(:tokens)
|
|
33
|
+
end
|
|
34
|
+
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,262 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bcrypt'
|
|
4
|
+
|
|
5
|
+
module DeviseTokenAuth::Concerns::User
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def self.tokens_match?(token_hash, token)
|
|
9
|
+
@token_equality_cache ||= {}
|
|
10
|
+
|
|
11
|
+
key = "#{token_hash}/#{token}"
|
|
12
|
+
result = @token_equality_cache[key] ||= (::BCrypt::Password.new(token_hash) == token)
|
|
13
|
+
@token_equality_cache = {} if @token_equality_cache.size > 10000
|
|
14
|
+
result
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
included do
|
|
18
|
+
# Hack to check if devise is already enabled
|
|
19
|
+
if method_defined?(:devise_modules)
|
|
20
|
+
devise_modules.delete(:omniauthable)
|
|
21
|
+
else
|
|
22
|
+
devise :database_authenticatable, :registerable,
|
|
23
|
+
:recoverable, :trackable, :validatable, :confirmable
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if const_defined?('ActiveRecord') && ancestors.include?(ActiveRecord::Base)
|
|
27
|
+
include DeviseTokenAuth::Concerns::ActiveRecordSupport
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if const_defined?('Mongoid') && ancestors.include?(Mongoid::Document)
|
|
31
|
+
include DeviseTokenAuth::Concerns::MongoidSupport
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if DeviseTokenAuth.default_callbacks
|
|
35
|
+
include DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# get rid of dead tokens
|
|
39
|
+
before_save :destroy_expired_tokens
|
|
40
|
+
|
|
41
|
+
# remove old tokens if password has changed
|
|
42
|
+
before_save :remove_tokens_after_password_reset
|
|
43
|
+
|
|
44
|
+
# don't use default devise email validation
|
|
45
|
+
def email_required?; false; end
|
|
46
|
+
def email_changed?; false; end
|
|
47
|
+
def will_save_change_to_email?; false; end
|
|
48
|
+
|
|
49
|
+
def password_required?
|
|
50
|
+
return false unless provider == 'email'
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# override devise method to include additional info as opts hash
|
|
55
|
+
def send_confirmation_instructions(opts = {})
|
|
56
|
+
generate_confirmation_token! unless @raw_confirmation_token
|
|
57
|
+
|
|
58
|
+
# fall back to "default" config name
|
|
59
|
+
opts[:client_config] ||= 'default'
|
|
60
|
+
opts[:to] = unconfirmed_email if pending_reconfirmation?
|
|
61
|
+
opts[:redirect_url] ||= DeviseTokenAuth.default_confirm_success_url
|
|
62
|
+
|
|
63
|
+
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# override devise method to include additional info as opts hash
|
|
67
|
+
def send_reset_password_instructions(opts = {})
|
|
68
|
+
token = set_reset_password_token
|
|
69
|
+
|
|
70
|
+
# fall back to "default" config name
|
|
71
|
+
opts[:client_config] ||= 'default'
|
|
72
|
+
|
|
73
|
+
send_devise_notification(:reset_password_instructions, token, opts)
|
|
74
|
+
token
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# override devise method to include additional info as opts hash
|
|
78
|
+
def send_unlock_instructions(opts = {})
|
|
79
|
+
raw, enc = Devise.token_generator.generate(self.class, :unlock_token)
|
|
80
|
+
self.unlock_token = enc
|
|
81
|
+
save(validate: false)
|
|
82
|
+
|
|
83
|
+
# fall back to "default" config name
|
|
84
|
+
opts[:client_config] ||= 'default'
|
|
85
|
+
|
|
86
|
+
send_devise_notification(:unlock_instructions, raw, opts)
|
|
87
|
+
raw
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
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.zone.now + token_lifespan).to_i
|
|
95
|
+
|
|
96
|
+
tokens[client_id] = {
|
|
97
|
+
token: BCrypt::Password.create(token),
|
|
98
|
+
expiry: expiry
|
|
99
|
+
}.merge!(token_extras)
|
|
100
|
+
|
|
101
|
+
clean_old_tokens
|
|
102
|
+
|
|
103
|
+
[client_id, token, expiry]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def valid_token?(token, client_id = 'default')
|
|
107
|
+
return false unless tokens[client_id]
|
|
108
|
+
return true if token_is_current?(token, client_id)
|
|
109
|
+
return true if token_can_be_reused?(token, client_id)
|
|
110
|
+
|
|
111
|
+
# return false if none of the above conditions are met
|
|
112
|
+
false
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# this must be done from the controller so that additional params
|
|
116
|
+
# can be passed on from the client
|
|
117
|
+
def send_confirmation_notification?; false; end
|
|
118
|
+
|
|
119
|
+
def token_is_current?(token, client_id)
|
|
120
|
+
# ghetto HashWithIndifferentAccess
|
|
121
|
+
expiry = tokens[client_id]['expiry'] || tokens[client_id][:expiry]
|
|
122
|
+
token_hash = tokens[client_id]['token'] || tokens[client_id][:token]
|
|
123
|
+
|
|
124
|
+
return true if (
|
|
125
|
+
# ensure that expiry and token are set
|
|
126
|
+
expiry && token &&
|
|
127
|
+
|
|
128
|
+
# ensure that the token has not yet expired
|
|
129
|
+
DateTime.strptime(expiry.to_s, '%s') > Time.zone.now &&
|
|
130
|
+
|
|
131
|
+
# ensure that the token is valid
|
|
132
|
+
DeviseTokenAuth::Concerns::User.tokens_match?(token_hash, token)
|
|
133
|
+
)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# allow batch requests to use the previous token
|
|
137
|
+
def token_can_be_reused?(token, client_id)
|
|
138
|
+
# ghetto HashWithIndifferentAccess
|
|
139
|
+
updated_at = tokens[client_id]['updated_at'] || tokens[client_id][:updated_at]
|
|
140
|
+
last_token = tokens[client_id]['last_token'] || tokens[client_id][:last_token]
|
|
141
|
+
|
|
142
|
+
return true if (
|
|
143
|
+
# ensure that the last token and its creation time exist
|
|
144
|
+
updated_at && last_token &&
|
|
145
|
+
|
|
146
|
+
# ensure that previous token falls within the batch buffer throttle time of the last request
|
|
147
|
+
updated_at.to_time > Time.zone.now - DeviseTokenAuth.batch_request_buffer_throttle &&
|
|
148
|
+
|
|
149
|
+
# ensure that the token is valid
|
|
150
|
+
::BCrypt::Password.new(last_token) == token
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# update user's auth token (should happen on each request)
|
|
155
|
+
def create_new_auth_token(client_id = nil)
|
|
156
|
+
now = Time.zone.now
|
|
157
|
+
|
|
158
|
+
client_id, token = create_token(
|
|
159
|
+
client_id: client_id,
|
|
160
|
+
expiry: (now + token_lifespan).to_i,
|
|
161
|
+
last_token: tokens.fetch(client_id, {})['token'],
|
|
162
|
+
updated_at: now
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
update_auth_header(token, client_id)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def build_auth_header(token, client_id = 'default')
|
|
169
|
+
# client may use expiry to prevent validation request if expired
|
|
170
|
+
# must be cast as string or headers will break
|
|
171
|
+
expiry = tokens[client_id]['expiry'] || tokens[client_id][:expiry]
|
|
172
|
+
|
|
173
|
+
{
|
|
174
|
+
DeviseTokenAuth.headers_names[:"access-token"] => token,
|
|
175
|
+
DeviseTokenAuth.headers_names[:"token-type"] => 'Bearer',
|
|
176
|
+
DeviseTokenAuth.headers_names[:"client"] => client_id,
|
|
177
|
+
DeviseTokenAuth.headers_names[:"expiry"] => expiry.to_s,
|
|
178
|
+
DeviseTokenAuth.headers_names[:"uid"] => uid
|
|
179
|
+
}
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def update_auth_header(token, client_id = 'default')
|
|
183
|
+
headers = build_auth_header(token, client_id)
|
|
184
|
+
clean_old_tokens
|
|
185
|
+
save!
|
|
186
|
+
|
|
187
|
+
headers
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def build_auth_url(base_url, args)
|
|
191
|
+
args[:uid] = uid
|
|
192
|
+
args[:expiry] = tokens[args[:client_id]]['expiry']
|
|
193
|
+
|
|
194
|
+
DeviseTokenAuth::Url.generate(base_url, args)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def extend_batch_buffer(token, client_id)
|
|
198
|
+
tokens[client_id]['updated_at'] = Time.zone.now
|
|
199
|
+
update_auth_header(token, client_id)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def confirmed?
|
|
203
|
+
devise_modules.exclude?(:confirmable) || super
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def token_validation_response
|
|
207
|
+
as_json(except: %i[tokens created_at updated_at])
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def token_lifespan
|
|
211
|
+
DeviseTokenAuth.token_lifespan
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
protected
|
|
215
|
+
|
|
216
|
+
def destroy_expired_tokens
|
|
217
|
+
if tokens
|
|
218
|
+
tokens.delete_if do |cid, v|
|
|
219
|
+
expiry = v[:expiry] || v['expiry']
|
|
220
|
+
DateTime.strptime(expiry.to_s, '%s') < Time.zone.now
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def should_remove_tokens_after_password_reset?
|
|
226
|
+
if Rails::VERSION::MAJOR <= 5
|
|
227
|
+
encrypted_password_changed? &&
|
|
228
|
+
DeviseTokenAuth.remove_tokens_after_password_reset
|
|
229
|
+
else
|
|
230
|
+
saved_change_to_encrypted_password? &&
|
|
231
|
+
DeviseTokenAuth.remove_tokens_after_password_reset
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def remove_tokens_after_password_reset
|
|
236
|
+
return unless should_remove_tokens_after_password_reset?
|
|
237
|
+
|
|
238
|
+
if tokens.present? && tokens.many?
|
|
239
|
+
client_id, token_data = tokens.max_by { |cid, v| v[:expiry] || v['expiry'] }
|
|
240
|
+
self.tokens = { client_id => token_data }
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def max_client_tokens_exceeded?
|
|
245
|
+
tokens.length > DeviseTokenAuth.max_number_of_devices
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def clean_old_tokens
|
|
249
|
+
if tokens.present? && max_client_tokens_exceeded?
|
|
250
|
+
# Using Enumerable#sort_by on a Hash will typecast it into an associative
|
|
251
|
+
# Array (i.e. an Array of key-value Array pairs). However, since Hashes
|
|
252
|
+
# have an internal order in Ruby 1.9+, the resulting sorted associative
|
|
253
|
+
# Array can be converted back into a Hash, while maintaining the sorted
|
|
254
|
+
# order.
|
|
255
|
+
self.tokens = tokens.sort_by { |_cid, v| v[:expiry] || v['expiry'] }.to_h
|
|
256
|
+
|
|
257
|
+
# Since the tokens are sorted by expiry, shift the oldest client token
|
|
258
|
+
# off the Hash until it no longer exceeds the maximum number of clients
|
|
259
|
+
tokens.shift while max_client_tokens_exceeded?
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
validates :email, presence: true,if: :email_provider?
|
|
8
|
+
validates :email, 'devise_token_auth/email' => true, allow_nil: true, allow_blank: true, if: :email_provider?
|
|
9
|
+
validates_presence_of :uid, unless: :email_provider?
|
|
10
|
+
|
|
11
|
+
# only validate unique emails among email registration users
|
|
12
|
+
validates :email, uniqueness: { scope: :provider }, on: :create, if: :email_provider?
|
|
13
|
+
|
|
14
|
+
# keep uid in sync with email
|
|
15
|
+
before_save :sync_uid
|
|
16
|
+
before_create :sync_uid
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
|
|
21
|
+
def email_provider?
|
|
22
|
+
provider == 'email'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def sync_uid
|
|
26
|
+
self.uid = email if provider == 'email'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class DeviseTokenAuth::EmailValidator < ActiveModel::EachValidator
|
|
4
|
+
def validate_each(record, attribute, value)
|
|
5
|
+
unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
|
6
|
+
record.errors[attribute] << email_invalid_message
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def email_invalid_message
|
|
13
|
+
# Try strictly set message:
|
|
14
|
+
message = options[:message]
|
|
15
|
+
|
|
16
|
+
if message.nil?
|
|
17
|
+
# Try DeviceTokenAuth translations or fallback to ActiveModel translations
|
|
18
|
+
message = I18n.t(:'errors.messages.not_email', default: :'errors.messages.invalid')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
message
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<p><%= t(:welcome).capitalize + ' ' + @email %>!</p>
|
|
2
|
+
|
|
3
|
+
<p><%= t '.confirm_link_msg' %> </p>
|
|
4
|
+
|
|
5
|
+
<p><%= link_to t('.confirm_account_link'), confirmation_url(@resource, {confirmation_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url']}).html_safe %></p>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<p><%= t(:hello).capitalize %> <%= @resource.email %>!</p>
|
|
2
|
+
|
|
3
|
+
<p><%= t '.request_reset_link_msg' %></p>
|
|
4
|
+
|
|
5
|
+
<p><%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url'].to_s).html_safe %></p>
|
|
6
|
+
|
|
7
|
+
<p><%= t '.ignore_mail_msg' %></p>
|
|
8
|
+
<p><%= t '.no_changes_msg' %></p>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<script>
|
|
5
|
+
/*
|
|
6
|
+
The data is accessible in two ways:
|
|
7
|
+
|
|
8
|
+
1. Using the postMessage api, this window will respond to a
|
|
9
|
+
'message' event with a post of all the data. (This can
|
|
10
|
+
be used by browsers other than IE if this window was
|
|
11
|
+
opened with window.open())
|
|
12
|
+
2. This window has a function called requestCredentials which,
|
|
13
|
+
when called, will return the data. (This can be
|
|
14
|
+
used if this window was opened in an inAppBrowser using
|
|
15
|
+
Cordova / PhoneGap)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
var data = JSON.parse(decodeURIComponent('<%= URI::escape( @data.to_json ) %>'));
|
|
19
|
+
|
|
20
|
+
window.addEventListener("message", function(ev) {
|
|
21
|
+
if (ev.data === "requestCredentials") {
|
|
22
|
+
ev.source.postMessage(data, '*');
|
|
23
|
+
window.close();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
function requestCredentials() {
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
setTimeout(function() {
|
|
30
|
+
document.getElementById('text').innerHTML = (data && data.error) || 'Redirecting...';
|
|
31
|
+
}, 1000);
|
|
32
|
+
</script>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<pre id="text">
|
|
36
|
+
</pre>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
da-DK:
|
|
2
|
+
devise_token_auth:
|
|
3
|
+
sessions:
|
|
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: "Ugyldig kombination af brugernavn og kodeord. Prøv venligst igen."
|
|
6
|
+
not_supported: "Brug POST /sign_in for at logge ind. GET er ikke supporteret."
|
|
7
|
+
user_not_found: "Brugeren er ikke fundet eller er ikke logget ind."
|
|
8
|
+
token_validations:
|
|
9
|
+
invalid: "Ugyldige legitimationsoplysninger."
|
|
10
|
+
registrations:
|
|
11
|
+
missing_confirm_success_url: "Der mangler et 'confirm_success_url' parameter."
|
|
12
|
+
redirect_url_not_allowed: "Omdirigering til '%{redirect_url}' er ikke tilladt."
|
|
13
|
+
email_already_exists: "Der eksisterer allerede en konto med '%{email}'"
|
|
14
|
+
account_with_uid_destroyed: "Kontoen med UID '%{uid}' er slettet."
|
|
15
|
+
account_to_destroy_not_found: "Kan ikke finde kontoen som skal slettes."
|
|
16
|
+
user_not_found: "Brugeren ikke fundet."
|
|
17
|
+
passwords:
|
|
18
|
+
missing_email: "Du skal udfylde email feltet."
|
|
19
|
+
missing_redirect_url: "Der er ingen omdirigeringsadresse."
|
|
20
|
+
redirect_url_not_allowed: "Omdirigering til '%{redirect_url}' er ikke tilladt."
|
|
21
|
+
sended: "En email er blevet sendt til '%{email}' med instruktioner for at nulstille dit kodeord."
|
|
22
|
+
user_not_found: "Kan ikke finde en bruger med '%{email}'."
|
|
23
|
+
password_not_required: "Denne bruger kræver ikke et kodeord. Log ind med '%{provider}' konto i stedet."
|
|
24
|
+
missing_passwords: "Du skal udfylde både kodeord og bekræftelse af kodeord."
|
|
25
|
+
successfully_updated: "Dit kodeord er opdateret."
|
|
26
|
+
unlocks:
|
|
27
|
+
missing_email: "Du skal udfylde en email."
|
|
28
|
+
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 bruger med email '%{email}'."
|
|
30
|
+
errors:
|
|
31
|
+
messages:
|
|
32
|
+
validate_sign_up_params: "Angiv venligst passende registeringsdata i request body."
|
|
33
|
+
validate_account_update_params: "Angiv venligst en passende konto opdatering i request body."
|
|
34
|
+
not_email: "er ikke en email"
|
|
35
|
+
devise:
|
|
36
|
+
mailer:
|
|
37
|
+
confirmation_instructions:
|
|
38
|
+
confirm_link_msg: "Du kan bekræfte din kontos email gennem linket herunder:"
|
|
39
|
+
confirm_account_link: "Bekræft min konto"
|
|
40
|
+
reset_password_instructions:
|
|
41
|
+
request_reset_link_msg: "Nogen har anmodet om et link til at ændre dit kodeord. Det kan du gøre via linket nedenfor."
|
|
42
|
+
password_change_link: "Skift mit kodeord."
|
|
43
|
+
ignore_mail_msg: "Hvis du ikke anmodede om dette, ignorer venligst denne email."
|
|
44
|
+
no_changes_msg: "Dit kodeord ændres først når du følger linket ovenfor og skaber et nyt."
|
|
45
|
+
unlock_instructions:
|
|
46
|
+
account_lock_msg: "Din konto er blevet låst fordi der har været for mange ugyldige log ind-forsøg."
|
|
47
|
+
unlock_link_msg: "Klik linket nedenfor, for at låse din konto op:"
|
|
48
|
+
unlock_link: "Lås min konto op"
|
|
49
|
+
hello: "hej"
|
|
50
|
+
welcome: "velkommen"
|