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.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +97 -0
  4. data/Rakefile +42 -0
  5. data/app/controllers/devise_token_auth/application_controller.rb +79 -0
  6. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +44 -0
  7. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +178 -0
  8. data/app/controllers/devise_token_auth/confirmations_controller.rb +39 -0
  9. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +239 -0
  10. data/app/controllers/devise_token_auth/passwords_controller.rb +185 -0
  11. data/app/controllers/devise_token_auth/registrations_controller.rb +198 -0
  12. data/app/controllers/devise_token_auth/sessions_controller.rb +131 -0
  13. data/app/controllers/devise_token_auth/token_validations_controller.rb +31 -0
  14. data/app/controllers/devise_token_auth/unlocks_controller.rb +89 -0
  15. data/app/models/devise_token_auth/concerns/active_record_support.rb +34 -0
  16. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  17. data/app/models/devise_token_auth/concerns/user.rb +262 -0
  18. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +28 -0
  19. data/app/validators/devise_token_auth/email_validator.rb +23 -0
  20. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  21. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  22. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  23. data/app/views/devise_token_auth/omniauth_external_window.html.erb +38 -0
  24. data/config/locales/da-DK.yml +50 -0
  25. data/config/locales/de.yml +49 -0
  26. data/config/locales/en.yml +50 -0
  27. data/config/locales/es.yml +49 -0
  28. data/config/locales/fr.yml +49 -0
  29. data/config/locales/it.yml +46 -0
  30. data/config/locales/ja.yml +46 -0
  31. data/config/locales/nl.yml +30 -0
  32. data/config/locales/pl.yml +48 -0
  33. data/config/locales/pt-BR.yml +46 -0
  34. data/config/locales/pt.yml +48 -0
  35. data/config/locales/ro.yml +46 -0
  36. data/config/locales/ru.yml +50 -0
  37. data/config/locales/sq.yml +46 -0
  38. data/config/locales/sv.yml +50 -0
  39. data/config/locales/uk.yml +59 -0
  40. data/config/locales/vi.yml +50 -0
  41. data/config/locales/zh-CN.yml +46 -0
  42. data/config/locales/zh-HK.yml +48 -0
  43. data/config/locales/zh-TW.yml +48 -0
  44. data/lib/devise_token_auth.rb +13 -0
  45. data/lib/devise_token_auth/blacklist.rb +2 -0
  46. data/lib/devise_token_auth/controllers/helpers.rb +161 -0
  47. data/lib/devise_token_auth/controllers/url_helpers.rb +10 -0
  48. data/lib/devise_token_auth/engine.rb +90 -0
  49. data/lib/devise_token_auth/errors.rb +8 -0
  50. data/lib/devise_token_auth/rails/routes.rb +116 -0
  51. data/lib/devise_token_auth/url.rb +41 -0
  52. data/lib/devise_token_auth/version.rb +5 -0
  53. data/lib/generators/devise_token_auth/USAGE +31 -0
  54. data/lib/generators/devise_token_auth/install_generator.rb +91 -0
  55. data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
  56. data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
  57. data/lib/generators/devise_token_auth/install_views_generator.rb +18 -0
  58. data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +50 -0
  59. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +56 -0
  60. data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
  61. data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +63 -0
  62. data/lib/tasks/devise_token_auth_tasks.rake +6 -0
  63. data/test/controllers/custom/custom_confirmations_controller_test.rb +25 -0
  64. data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +33 -0
  65. data/test/controllers/custom/custom_passwords_controller_test.rb +79 -0
  66. data/test/controllers/custom/custom_registrations_controller_test.rb +63 -0
  67. data/test/controllers/custom/custom_sessions_controller_test.rb +39 -0
  68. data/test/controllers/custom/custom_token_validations_controller_test.rb +42 -0
  69. data/test/controllers/demo_group_controller_test.rb +151 -0
  70. data/test/controllers/demo_mang_controller_test.rb +284 -0
  71. data/test/controllers/demo_user_controller_test.rb +629 -0
  72. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +127 -0
  73. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +376 -0
  74. data/test/controllers/devise_token_auth/passwords_controller_test.rb +639 -0
  75. data/test/controllers/devise_token_auth/registrations_controller_test.rb +880 -0
  76. data/test/controllers/devise_token_auth/sessions_controller_test.rb +541 -0
  77. data/test/controllers/devise_token_auth/token_validations_controller_test.rb +102 -0
  78. data/test/controllers/devise_token_auth/unlocks_controller_test.rb +196 -0
  79. data/test/controllers/overrides/confirmations_controller_test.rb +47 -0
  80. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +53 -0
  81. data/test/controllers/overrides/passwords_controller_test.rb +64 -0
  82. data/test/controllers/overrides/registrations_controller_test.rb +46 -0
  83. data/test/controllers/overrides/sessions_controller_test.rb +35 -0
  84. data/test/controllers/overrides/token_validations_controller_test.rb +43 -0
  85. data/test/dummy/README.rdoc +28 -0
  86. data/test/dummy/app/active_record/lockable_user.rb +7 -0
  87. data/test/dummy/app/active_record/mang.rb +5 -0
  88. data/test/dummy/app/active_record/only_email_user.rb +7 -0
  89. data/test/dummy/app/active_record/scoped_user.rb +9 -0
  90. data/test/dummy/app/active_record/unconfirmable_user.rb +9 -0
  91. data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
  92. data/test/dummy/app/active_record/user.rb +6 -0
  93. data/test/dummy/app/controllers/application_controller.rb +18 -0
  94. data/test/dummy/app/controllers/auth_origin_controller.rb +7 -0
  95. data/test/dummy/app/controllers/custom/confirmations_controller.rb +13 -0
  96. data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +13 -0
  97. data/test/dummy/app/controllers/custom/passwords_controller.rb +39 -0
  98. data/test/dummy/app/controllers/custom/registrations_controller.rb +39 -0
  99. data/test/dummy/app/controllers/custom/sessions_controller.rb +29 -0
  100. data/test/dummy/app/controllers/custom/token_validations_controller.rb +19 -0
  101. data/test/dummy/app/controllers/demo_group_controller.rb +15 -0
  102. data/test/dummy/app/controllers/demo_mang_controller.rb +14 -0
  103. data/test/dummy/app/controllers/demo_user_controller.rb +27 -0
  104. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +28 -0
  105. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +16 -0
  106. data/test/dummy/app/controllers/overrides/passwords_controller.rb +35 -0
  107. data/test/dummy/app/controllers/overrides/registrations_controller.rb +29 -0
  108. data/test/dummy/app/controllers/overrides/sessions_controller.rb +36 -0
  109. data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
  110. data/test/dummy/app/helpers/application_helper.rb +1058 -0
  111. data/test/dummy/app/models/concerns/favorite_color.rb +19 -0
  112. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  113. data/test/dummy/app/mongoid/mang.rb +53 -0
  114. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  115. data/test/dummy/app/mongoid/scoped_user.rb +57 -0
  116. data/test/dummy/app/mongoid/unconfirmable_user.rb +51 -0
  117. data/test/dummy/app/mongoid/unregisterable_user.rb +54 -0
  118. data/test/dummy/app/mongoid/user.rb +56 -0
  119. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  120. data/test/dummy/config.ru +18 -0
  121. data/test/dummy/config/application.rb +48 -0
  122. data/test/dummy/config/application.yml.bk +0 -0
  123. data/test/dummy/config/boot.rb +11 -0
  124. data/test/dummy/config/environment.rb +7 -0
  125. data/test/dummy/config/environments/development.rb +46 -0
  126. data/test/dummy/config/environments/production.rb +84 -0
  127. data/test/dummy/config/environments/test.rb +50 -0
  128. data/test/dummy/config/initializers/assets.rb +10 -0
  129. data/test/dummy/config/initializers/backtrace_silencers.rb +9 -0
  130. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  131. data/test/dummy/config/initializers/devise.rb +17 -0
  132. data/test/dummy/config/initializers/devise_token_auth.rb +24 -0
  133. data/test/dummy/config/initializers/figaro.rb +3 -0
  134. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  135. data/test/dummy/config/initializers/inflections.rb +18 -0
  136. data/test/dummy/config/initializers/mime_types.rb +6 -0
  137. data/test/dummy/config/initializers/omniauth.rb +10 -0
  138. data/test/dummy/config/initializers/session_store.rb +5 -0
  139. data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
  140. data/test/dummy/config/routes.rb +55 -0
  141. data/test/dummy/config/spring.rb +3 -0
  142. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +65 -0
  143. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +64 -0
  144. data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +8 -0
  145. data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +7 -0
  146. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +62 -0
  147. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +63 -0
  148. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +63 -0
  149. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +63 -0
  150. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +63 -0
  151. data/test/dummy/db/schema.rb +200 -0
  152. data/test/dummy/lib/migration_database_helper.rb +43 -0
  153. data/test/dummy/tmp/generators/app/models/user.rb +9 -0
  154. data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +50 -0
  155. data/test/dummy/tmp/generators/db/migrate/20181030122248_devise_token_auth_create_users.rb +56 -0
  156. data/test/factories/users.rb +40 -0
  157. data/test/lib/devise_token_auth/blacklist_test.rb +11 -0
  158. data/test/lib/devise_token_auth/url_test.rb +26 -0
  159. data/test/lib/generators/devise_token_auth/install_generator_test.rb +217 -0
  160. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +222 -0
  161. data/test/lib/generators/devise_token_auth/install_views_generator_test.rb +25 -0
  162. data/test/models/concerns/mongoid_support_test.rb +31 -0
  163. data/test/models/only_email_user_test.rb +37 -0
  164. data/test/models/user_test.rb +140 -0
  165. data/test/support/controllers/routes.rb +43 -0
  166. data/test/test_helper.rb +103 -0
  167. 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,7 @@
1
+ <p><%= t :hello %> <%= @resource.email %>!</p>
2
+
3
+ <p><%= t '.account_lock_msg' %></p>
4
+
5
+ <p><%= t '.unlock_link_msg' %></p>
6
+
7
+ <p><%= link_to t('.unlock_link'), unlock_url(@resource, unlock_token: @token, config: message['client-config'].to_s) %></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"