devise 4.0.0.rc1 → 4.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -6
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +3 -3
  5. data/Gemfile.lock +52 -53
  6. data/README.md +3 -6
  7. data/app/controllers/devise/confirmations_controller.rb +1 -1
  8. data/app/controllers/devise/passwords_controller.rb +2 -2
  9. data/app/controllers/devise/registrations_controller.rb +3 -3
  10. data/app/controllers/devise/sessions_controller.rb +3 -3
  11. data/app/controllers/devise/unlocks_controller.rb +1 -1
  12. data/app/controllers/devise_controller.rb +9 -2
  13. data/app/views/devise/confirmations/new.html.erb +1 -1
  14. data/bin/test +13 -0
  15. data/gemfiles/Gemfile.rails-4.1-stable +4 -4
  16. data/gemfiles/Gemfile.rails-4.1-stable.lock +45 -46
  17. data/gemfiles/Gemfile.rails-4.2-stable +4 -4
  18. data/gemfiles/Gemfile.rails-4.2-stable.lock +47 -48
  19. data/gemfiles/Gemfile.rails-5.0-beta +19 -19
  20. data/gemfiles/Gemfile.rails-5.0-beta.lock +61 -106
  21. data/lib/devise.rb +4 -4
  22. data/lib/devise/controllers/helpers.rb +1 -1
  23. data/lib/devise/encryptor.rb +4 -4
  24. data/lib/devise/failure_app.rb +4 -5
  25. data/lib/devise/mailers/helpers.rb +1 -1
  26. data/lib/devise/models/confirmable.rb +2 -2
  27. data/lib/devise/models/database_authenticatable.rb +7 -5
  28. data/lib/devise/models/lockable.rb +1 -1
  29. data/lib/devise/omniauth/url_helpers.rb +62 -4
  30. data/lib/devise/rails/routes.rb +14 -16
  31. data/lib/devise/strategies/database_authenticatable.rb +3 -3
  32. data/lib/devise/test_helpers.rb +1 -1
  33. data/lib/devise/version.rb +1 -1
  34. data/lib/generators/active_record/devise_generator.rb +8 -2
  35. data/lib/generators/active_record/templates/migration.rb +1 -1
  36. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  37. data/lib/generators/devise/install_generator.rb +15 -0
  38. data/lib/generators/templates/devise.rb +10 -10
  39. data/test/failure_app_test.rb +1 -1
  40. data/test/generators/install_generator_test.rb +14 -3
  41. data/test/mailers/confirmation_instructions_test.rb +6 -6
  42. data/test/mailers/reset_password_instructions_test.rb +5 -5
  43. data/test/mailers/unlock_instructions_test.rb +5 -5
  44. data/test/models/confirmable_test.rb +2 -2
  45. data/test/models/database_authenticatable_test.rb +6 -6
  46. data/test/omniauth/url_helpers_test.rb +4 -6
  47. data/test/rails_app/config/initializers/devise.rb +1 -1
  48. data/test/routes_test.rb +2 -2
  49. data/test/test_helpers_test.rb +2 -2
  50. data/test/test_models.rb +1 -1
  51. metadata +4 -2
@@ -61,9 +61,9 @@ module Devise
61
61
  mattr_accessor :rememberable_options
62
62
  @@rememberable_options = {}
63
63
 
64
- # The number of times to encrypt password.
64
+ # The number of times to hash the password.
65
65
  mattr_accessor :stretches
66
- @@stretches = 10
66
+ @@stretches = 11
67
67
 
68
68
  # The default key used when authenticating over http auth.
69
69
  mattr_accessor :http_authentication_key
@@ -146,7 +146,7 @@ module Devise
146
146
  mattr_accessor :timeout_in
147
147
  @@timeout_in = 30.minutes
148
148
 
149
- # Used to encrypt password. Please generate one with rake secret.
149
+ # Used to hash the password. Please generate one with rake secret.
150
150
  mattr_accessor :pepper
151
151
  @@pepper = nil
152
152
 
@@ -276,7 +276,7 @@ module Devise
276
276
  mattr_accessor :token_generator
277
277
  @@token_generator = nil
278
278
 
279
- # Default way to setup Devise. Run rails generate devise_install to create
279
+ # Default way to set up Devise. Run rails generate devise_install to create
280
280
  # a fresh initializer with all configuration values.
281
281
  def self.setup
282
282
  yield self
@@ -150,7 +150,7 @@ module Devise
150
150
  is_a?(::DeviseController)
151
151
  end
152
152
 
153
- # Setup a param sanitizer to filter parameters using strong_parameters. See
153
+ # Set up a param sanitizer to filter parameters using strong_parameters. See
154
154
  # lib/devise/parameter_sanitizer.rb for more info. Override this
155
155
  # method in your application controller to use your own parameter sanitizer.
156
156
  def devise_parameter_sanitizer
@@ -9,14 +9,14 @@ module Devise
9
9
  ::BCrypt::Password.create(password, cost: klass.stretches).to_s
10
10
  end
11
11
 
12
- def self.compare(klass, encrypted_password, password)
13
- return false if encrypted_password.blank?
14
- bcrypt = ::BCrypt::Password.new(encrypted_password)
12
+ def self.compare(klass, hashed_password, password)
13
+ return false if hashed_password.blank?
14
+ bcrypt = ::BCrypt::Password.new(hashed_password)
15
15
  if klass.pepper.present?
16
16
  password = "#{password}#{klass.pepper}"
17
17
  end
18
18
  password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
19
- Devise.secure_compare(password, encrypted_password)
19
+ Devise.secure_compare(password, hashed_password)
20
20
  end
21
21
  end
22
22
  end
@@ -140,11 +140,10 @@ module Devise
140
140
 
141
141
  config = Rails.application.config
142
142
 
143
- # Rails 4.2 goes into an infinite loop if opts[:script_name] is unset
144
- if (Rails::VERSION::MAJOR >= 4) && (Rails::VERSION::MINOR >= 2)
145
- opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root))
146
- else
147
- if config.respond_to?(:relative_url_root) && config.relative_url_root.present?
143
+ if config.respond_to?(:relative_url_root)
144
+ # Rails 4.2 goes into an infinite loop if opts[:script_name] is unset
145
+ rails_4_2 = (Rails::VERSION::MAJOR >= 4) && (Rails::VERSION::MINOR >= 2)
146
+ if config.relative_url_root.present? || rails_4_2
148
147
  opts[:script_name] = config.relative_url_root
149
148
  end
150
149
  end
@@ -64,7 +64,7 @@ module Devise
64
64
  template_path
65
65
  end
66
66
 
67
- # Setup a subject doing an I18n lookup. At first, it attempts to set a subject
67
+ # Set up a subject doing an I18n lookup. At first, it attempts to set a subject
68
68
  # based on the current mapping:
69
69
  #
70
70
  # en:
@@ -24,7 +24,7 @@ module Devise
24
24
  # By default allow_unconfirmed_access_for is zero, it means users always have to confirm to sign in.
25
25
  # * +reconfirmable+: requires any email changes to be confirmed (exactly the same way as
26
26
  # initial account confirmation) to be applied. Requires additional unconfirmed_email
27
- # db field to be setup (t.reconfirmable in migrations). Until confirmed, new email is
27
+ # db field to be set up (t.reconfirmable in migrations). Until confirmed, new email is
28
28
  # stored in unconfirmed email column, and copied to email column on successful
29
29
  # confirmation.
30
30
  # * +confirm_within+: the time before a sent confirmation token becomes invalid.
@@ -179,7 +179,7 @@ module Devise
179
179
  # Checks if the confirmation for the user is within the limit time.
180
180
  # We do this by calculating if the difference between today and the
181
181
  # confirmation sent date does not exceed the confirm in time configured.
182
- # Confirm_within is a model configuration, must always be an integer value.
182
+ # allow_unconfirmed_access_for is a model configuration, must always be an integer value.
183
183
  #
184
184
  # Example:
185
185
  #
@@ -7,8 +7,8 @@ module Devise
7
7
  end
8
8
 
9
9
  module Models
10
- # Authenticatable Module, responsible for encrypting password and validating
11
- # authenticity of a user while signing in.
10
+ # Authenticatable Module, responsible for hashing the password and
11
+ # validating the authenticity of a user while signing in.
12
12
  #
13
13
  # == Options
14
14
  #
@@ -37,7 +37,9 @@ module Devise
37
37
  [:encrypted_password] + klass.authentication_keys
38
38
  end
39
39
 
40
- # Generates password encryption based on the given value.
40
+ # Generates a hashed password based on the given value.
41
+ # For legacy reasons, we use `encrypted_password` to store
42
+ # the hashed password.
41
43
  def password=(new_password)
42
44
  attribute_will_change! 'password'
43
45
  @password = new_password
@@ -142,11 +144,11 @@ module Devise
142
144
 
143
145
  protected
144
146
 
145
- # Digests the password using bcrypt. Custom encryption should override
147
+ # Hashes the password using bcrypt. Custom hash functions should override
146
148
  # this method to apply their own algorithm.
147
149
  #
148
150
  # See https://github.com/plataformatec/devise-encryptable for examples
149
- # of other encryption engines.
151
+ # of other hashing engines.
150
152
  def password_digest(password)
151
153
  Devise::Encryptor.digest(self.class, password)
152
154
  end
@@ -7,7 +7,7 @@ module Devise
7
7
  # blocked: email and time. The former will send an email to the user when
8
8
  # the lock happens, containing a link to unlock its account. The second
9
9
  # will unlock the user automatically after some configured time (ie 2.hours).
10
- # It's also possible to setup lockable to use both email and time strategies.
10
+ # It's also possible to set up lockable to use both email and time strategies.
11
11
  #
12
12
  # == Options
13
13
  #
@@ -2,16 +2,74 @@ module Devise
2
2
  module OmniAuth
3
3
  module UrlHelpers
4
4
  def self.define_helpers(mapping)
5
+ return unless mapping.omniauthable?
6
+
7
+ mapping = mapping.name
8
+
9
+ class_eval do
10
+ define_method("#{mapping}_omniauth_authorize_path") do |provider, *args|
11
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc)
12
+ [Devise] #{mapping}_omniauth_authorize_path(#{provider.inspect}) is deprecated and it will be removed from Devise 4.1.
13
+
14
+ Please use #{mapping}_#{provider}_omniauth_authorize_path instead.
15
+ DEPRECATION
16
+ send("#{mapping}_#{provider}_omniauth_authorize_path", *args)
17
+ end
18
+
19
+ define_method("#{mapping}_omniauth_authorize_url") do |provider, *args|
20
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc)
21
+ [Devise] #{mapping}_omniauth_authorize_url(#{provider.inspect}) is deprecated and it will be removed from Devise 4.1.
22
+
23
+ Please use #{mapping}_#{provider}_omniauth_authorize_url instead.
24
+ DEPRECATION
25
+ send("#{mapping}_#{provider}_omniauth_authorize_url", *args)
26
+ end
27
+
28
+ define_method("#{mapping}_omniauth_callback_path") do |provider, *args|
29
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc)
30
+ [Devise] #{mapping}_omniauth_callback_path(#{provider.inspect}) is deprecated and it will be removed from Devise 4.1.
31
+
32
+ Please use #{mapping}_#{provider}_omniauth_callback_path instead.
33
+ DEPRECATION
34
+ send("#{mapping}_#{provider}_omniauth_callback_path", *args)
35
+ end
36
+
37
+ define_method("#{mapping}_omniauth_callback_url") do |provider, *args|
38
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc)
39
+ [Devise] #{mapping}_omniauth_callback_url(#{provider.inspect}) is deprecated and it will be removed from Devise 4.1.
40
+
41
+ Please use #{mapping}_#{provider}_omniauth_callback_url instead.
42
+ DEPRECATION
43
+ send("#{mapping}_#{provider}_omniauth_callback_url", *args)
44
+ end
45
+ end
46
+
47
+ ActiveSupport.on_load(:action_controller) do
48
+ if respond_to?(:helper_method)
49
+ helper_method "#{mapping}_omniauth_authorize_path", "#{mapping}_omniauth_authorize_url"
50
+ helper_method "#{mapping}_omniauth_callback_path", "#{mapping}_omniauth_callback_url"
51
+ end
52
+ end
53
+ end
54
+
55
+ def omniauth_authorize_path(resource_or_scope, provider, *args)
56
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
57
+ _devise_route_context.send("#{scope}_#{provider}_omniauth_authorize_path", *args)
58
+ end
59
+
60
+ def omniauth_authorize_url(resource_or_scope, provider, *args)
61
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
62
+ _devise_route_context.send("#{scope}_#{provider}_omniauth_authorize_url", *args)
5
63
  end
6
64
 
7
- def omniauth_authorize_path(resource_or_scope, *args)
65
+ def omniauth_callback_path(resource_or_scope, provider, *args)
8
66
  scope = Devise::Mapping.find_scope!(resource_or_scope)
9
- _devise_route_context.send("#{scope}_omniauth_authorize_path", *args)
67
+ _devise_route_context.send("#{scope}_#{provider}_omniauth_callback_path", *args)
10
68
  end
11
69
 
12
- def omniauth_callback_path(resource_or_scope, *args)
70
+ def omniauth_callback_url(resource_or_scope, provider, *args)
13
71
  scope = Devise::Mapping.find_scope!(resource_or_scope)
14
- _devise_route_context.send("#{scope}_omniauth_callback_path", *args)
72
+ _devise_route_context.send("#{scope}_#{provider}_omniauth_callback_url", *args)
15
73
  end
16
74
  end
17
75
  end
@@ -87,17 +87,17 @@ module ActionDispatch::Routing
87
87
  #
88
88
  # You can configure your routes with some options:
89
89
  #
90
- # * class_name: setup a different class to be looked up by devise, if it cannot be
90
+ # * class_name: set up a different class to be looked up by devise, if it cannot be
91
91
  # properly found by the route name.
92
92
  #
93
93
  # devise_for :users, class_name: 'Account'
94
94
  #
95
- # * path: allows you to setup path name that will be used, as rails routes does.
96
- # The following route configuration would setup your route as /accounts instead of /users:
95
+ # * path: allows you to set up path name that will be used, as rails routes does.
96
+ # The following route configuration would set up your route as /accounts instead of /users:
97
97
  #
98
98
  # devise_for :users, path: 'accounts'
99
99
  #
100
- # * singular: setup the singular name for the given resource. This is used as the helper methods
100
+ # * singular: set up the singular name for the given resource. This is used as the helper methods
101
101
  # names in controller ("authenticate_#{singular}!", "#{singular}_signed_in?", "current_#{singular}"
102
102
  # and "#{singular}_session"), as the scope name in routes and as the scope given to warden.
103
103
  #
@@ -441,19 +441,17 @@ ERROR
441
441
 
442
442
  set_omniauth_path_prefix!(path_prefix)
443
443
 
444
- providers = Regexp.union(mapping.to.omniauth_providers.map(&:to_s))
444
+ mapping.to.omniauth_providers.each do |provider|
445
+ match "#{path_prefix}/#{provider}",
446
+ to: "#{controllers[:omniauth_callbacks]}#passthru",
447
+ as: "#{provider}_omniauth_authorize",
448
+ via: [:get, :post]
445
449
 
446
- match "#{path_prefix}/:provider",
447
- constraints: { provider: providers },
448
- to: "#{controllers[:omniauth_callbacks]}#passthru",
449
- as: :omniauth_authorize,
450
- via: [:get, :post]
451
-
452
- match "#{path_prefix}/:action/callback",
453
- constraints: { action: providers },
454
- to: "#{controllers[:omniauth_callbacks]}#:action",
455
- as: :omniauth_callback,
456
- via: [:get, :post]
450
+ match "#{path_prefix}/#{provider}/callback",
451
+ to: "#{controllers[:omniauth_callbacks]}##{provider}",
452
+ as: "#{provider}_omniauth_callback",
453
+ via: [:get, :post]
454
+ end
457
455
  ensure
458
456
  @scope = current_scope
459
457
  end
@@ -6,15 +6,15 @@ module Devise
6
6
  class DatabaseAuthenticatable < Authenticatable
7
7
  def authenticate!
8
8
  resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash)
9
- encrypted = false
9
+ hashed = false
10
10
 
11
- if validate(resource){ encrypted = true; resource.valid_password?(password) }
11
+ if validate(resource){ hashed = true; resource.valid_password?(password) }
12
12
  remember_me(resource)
13
13
  resource.after_database_authentication
14
14
  success!(resource)
15
15
  end
16
16
 
17
- mapping.to.new.password = password if !encrypted && Devise.paranoid
17
+ mapping.to.new.password = password if !hashed && Devise.paranoid
18
18
  fail(:not_found_in_database) unless resource
19
19
  end
20
20
  end
@@ -22,7 +22,7 @@ module Devise
22
22
  @response
23
23
  end
24
24
 
25
- # We need to setup the environment variables and the response in the controller.
25
+ # We need to set up the environment variables and the response in the controller.
26
26
  def setup_controller_for_warden #:nodoc:
27
27
  @request.env['action_controller.instance'] = @controller
28
28
  end
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "4.0.0.rc1".freeze
2
+ VERSION = "4.0.0.rc2".freeze
3
3
  end
@@ -11,9 +11,9 @@ module ActiveRecord
11
11
 
12
12
  def copy_devise_migration
13
13
  if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
14
- migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}.rb"
14
+ migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}.rb", migration_version: migration_version
15
15
  else
16
- migration_template "migration.rb", "db/migrate/devise_create_#{table_name}.rb"
16
+ migration_template "migration.rb", "db/migrate/devise_create_#{table_name}.rb", migration_version: migration_version
17
17
  end
18
18
  end
19
19
 
@@ -86,6 +86,12 @@ RUBY
86
86
  config = ActiveRecord::Base.configurations[Rails.env]
87
87
  config && config['adapter'] == 'postgresql'
88
88
  end
89
+
90
+ def migration_version
91
+ if rails5?
92
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
93
+ end
94
+ end
89
95
  end
90
96
  end
91
97
  end
@@ -1,4 +1,4 @@
1
- class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
1
+ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :<%= table_name %> do |t|
4
4
  <%= migration_data -%>
@@ -1,4 +1,4 @@
1
- class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
1
+ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  change_table :<%= table_name %> do |t|
4
4
  <%= migration_data -%>
@@ -3,6 +3,8 @@ require 'securerandom'
3
3
 
4
4
  module Devise
5
5
  module Generators
6
+ MissingORMError = Class.new(Thor::Error)
7
+
6
8
  class InstallGenerator < Rails::Generators::Base
7
9
  source_root File.expand_path("../../templates", __FILE__)
8
10
 
@@ -10,6 +12,19 @@ module Devise
10
12
  class_option :orm
11
13
 
12
14
  def copy_initializer
15
+ unless options[:orm]
16
+ raise MissingORMError, <<-ERROR.strip_heredoc
17
+ An ORM must be set to install Devise in your application.
18
+
19
+ Be sure to have an ORM like Active Record or Mongoid loaded in your
20
+ app or configure your own at `config/application.rb`.
21
+
22
+ config.generators do |g|
23
+ g.orm :your_orm_gem
24
+ end
25
+ ERROR
26
+ end
27
+
13
28
  template "devise.rb", "config/initializers/devise.rb"
14
29
  end
15
30
 
@@ -91,17 +91,17 @@ Devise.setup do |config|
91
91
  # config.clean_up_csrf_token_on_authentication = true
92
92
 
93
93
  # ==> Configuration for :database_authenticatable
94
- # For bcrypt, this is the cost for hashing the password and defaults to 10. If
95
- # using other encryptors, it sets how many times you want the password re-encrypted.
94
+ # For bcrypt, this is the cost for hashing the password and defaults to 11. If
95
+ # using other algorithms, it sets how many times you want the password to be hashed.
96
96
  #
97
97
  # Limiting the stretches to just one in testing will increase the performance of
98
98
  # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
99
99
  # a value less than 10 in other environments. Note that, for bcrypt (the default
100
- # encryptor), the cost increases exponentially with the number of stretches (e.g.
100
+ # algorithm), the cost increases exponentially with the number of stretches (e.g.
101
101
  # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
102
- config.stretches = Rails.env.test? ? 1 : 10
102
+ config.stretches = Rails.env.test? ? 1 : 11
103
103
 
104
- # Setup a pepper to generate the encrypted password.
104
+ # Set up a pepper to generate the hashed password.
105
105
  # config.pepper = '<%= SecureRandom.hex(64) %>'
106
106
 
107
107
  # Send a notification email when the user's password is changed
@@ -201,11 +201,11 @@ Devise.setup do |config|
201
201
  # config.sign_in_after_reset_password = true
202
202
 
203
203
  # ==> Configuration for :encryptable
204
- # Allow you to use another encryption algorithm besides bcrypt (default). You can use
205
- # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
206
- # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
207
- # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
208
- # REST_AUTH_SITE_KEY to pepper).
204
+ # Allow you to use another hashing or encryption algorithm besides bcrypt (default).
205
+ # You can use :sha1, :sha512 or algorithms from others authentication tools as
206
+ # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
207
+ # for default behavior) and :restful_authentication_sha1 (then you should set
208
+ # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
209
209
  #
210
210
  # Require the `devise-encryptable` gem when using anything other than bcrypt
211
211
  # config.encryptor = :sha512
@@ -160,7 +160,7 @@ class FailureTest < ActiveSupport::TestCase
160
160
  assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
161
161
  end
162
162
 
163
- test 'setup a default message' do
163
+ test 'set up a default message' do
164
164
  call_failure
165
165
  assert_match(/You are being/, @response.last.body)
166
166
  assert_match(/redirected/, @response.last.body)
@@ -5,9 +5,20 @@ class InstallGeneratorTest < Rails::Generators::TestCase
5
5
  destination File.expand_path("../../tmp", __FILE__)
6
6
  setup :prepare_destination
7
7
 
8
- test "Assert all files are properly created" do
9
- run_generator
10
- assert_file "config/initializers/devise.rb"
8
+ test "assert all files are properly created" do
9
+ run_generator(["--orm=active_record"])
10
+ assert_file "config/initializers/devise.rb", /devise\/orm\/active_record/
11
11
  assert_file "config/locales/devise.en.yml"
12
12
  end
13
+
14
+ test "fails if no ORM is specified" do
15
+ stderr = capture(:stderr) do
16
+ run_generator
17
+ end
18
+
19
+ assert_match %r{An ORM must be set to install Devise}, stderr
20
+
21
+ assert_no_file "config/initializers/devise.rb"
22
+ assert_no_file "config/locales/devise.en.yml"
23
+ end
13
24
  end