devise 1.4.2 → 1.4.3

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 (71) hide show
  1. data/.gitignore +3 -1
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.rdoc +16 -1
  4. data/Gemfile +4 -2
  5. data/README.rdoc +2 -2
  6. data/Rakefile +1 -1
  7. data/app/controllers/devise/confirmations_controller.rb +7 -1
  8. data/app/controllers/devise/registrations_controller.rb +8 -2
  9. data/app/controllers/devise/sessions_controller.rb +6 -4
  10. data/app/views/devise/confirmations/new.html.erb +3 -3
  11. data/app/views/devise/passwords/edit.html.erb +5 -5
  12. data/app/views/devise/passwords/new.html.erb +3 -3
  13. data/app/views/devise/registrations/edit.html.erb +9 -9
  14. data/app/views/devise/registrations/new.html.erb +7 -7
  15. data/app/views/devise/sessions/new.html.erb +6 -6
  16. data/app/views/devise/unlocks/new.html.erb +3 -3
  17. data/config/locales/en.yml +4 -0
  18. data/devise.gemspec +1 -1
  19. data/lib/devise.rb +11 -6
  20. data/lib/devise/controllers/helpers.rb +1 -0
  21. data/lib/devise/controllers/url_helpers.rb +20 -11
  22. data/lib/devise/hooks/timeoutable.rb +1 -1
  23. data/lib/devise/mailers/helpers.rb +9 -2
  24. data/lib/devise/mapping.rb +8 -1
  25. data/lib/devise/models/authenticatable.rb +9 -0
  26. data/lib/devise/models/confirmable.rb +8 -3
  27. data/lib/devise/models/database_authenticatable.rb +3 -0
  28. data/lib/devise/models/lockable.rb +5 -5
  29. data/lib/devise/models/recoverable.rb +10 -3
  30. data/lib/devise/models/trackable.rb +1 -1
  31. data/lib/devise/models/validatable.rb +1 -1
  32. data/lib/devise/rails.rb +13 -0
  33. data/lib/devise/rails/routes.rb +22 -10
  34. data/lib/devise/rails/warden_compat.rb +5 -10
  35. data/lib/devise/schema.rb +5 -3
  36. data/lib/devise/strategies/token_authenticatable.rb +5 -1
  37. data/lib/devise/version.rb +1 -1
  38. data/lib/generators/active_record/devise_generator.rb +10 -5
  39. data/lib/generators/active_record/templates/migration_existing.rb +34 -0
  40. data/lib/generators/devise/orm_helpers.rb +8 -0
  41. data/lib/generators/templates/devise.rb +12 -5
  42. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +1 -1
  43. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +3 -3
  44. data/test/controllers/helpers_test.rb +1 -1
  45. data/test/generators/active_record_generator_test.rb +13 -0
  46. data/test/generators/mongoid_generator_test.rb +4 -3
  47. data/test/helpers/devise_helper_test.rb +10 -2
  48. data/test/integration/authenticatable_test.rb +17 -0
  49. data/test/integration/confirmable_test.rb +10 -1
  50. data/test/integration/lockable_test.rb +1 -1
  51. data/test/integration/recoverable_test.rb +12 -3
  52. data/test/integration/registerable_test.rb +10 -2
  53. data/test/integration/token_authenticatable_test.rb +11 -0
  54. data/test/mailers/confirmation_instructions_test.rb +6 -0
  55. data/test/mailers/reset_password_instructions_test.rb +6 -0
  56. data/test/mailers/unlock_instructions_test.rb +6 -0
  57. data/test/models/confirmable_test.rb +2 -2
  58. data/test/models/encryptable_test.rb +4 -2
  59. data/test/models/validatable_test.rb +3 -2
  60. data/test/models_test.rb +9 -11
  61. data/test/orm/mongoid.rb +3 -0
  62. data/test/rails_app/app/active_record/user.rb +0 -2
  63. data/test/rails_app/app/mailers/users/mailer.rb +3 -0
  64. data/test/rails_app/app/mongoid/shim.rb +0 -5
  65. data/test/rails_app/config/application.rb +1 -0
  66. data/test/rails_app/config/initializers/devise.rb +3 -2
  67. data/test/rails_app/config/routes.rb +1 -1
  68. data/test/rails_app/lib/shared_user.rb +1 -0
  69. metadata +12 -12
  70. data/Gemfile.lock +0 -158
  71. data/lib/devise/email.rb +0 -23
data/.gitignore CHANGED
@@ -7,4 +7,6 @@ coverage/*
7
7
  rdoc/*
8
8
  pkg
9
9
  log
10
- test/tmp/*
10
+ test/tmp/*
11
+ Gemfile.lock
12
+
@@ -3,5 +3,6 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - ree
6
- - jruby
7
- - rubinius
6
+ - rbx
7
+ - rbx-2.0
8
+ - jruby
@@ -1,7 +1,22 @@
1
+ == 1.4.3
2
+
3
+ * enhancements
4
+ * Improve Rails 3.1 compatibility
5
+ * Use serialize_into_session and serialize_from_session in Warden serialize to improve extensibility
6
+
7
+ * bug fix
8
+ * Generator properly generates a change_table migration if a model already exists
9
+ * Properly deprecate setup_mail
10
+ * Fix encoding issues with email regexp
11
+ * Only generate helpers for the used mappings
12
+ * Wrap :action constraints in the proper hash
13
+
14
+ * deprecations
15
+ * Loosened the used email regexp to simply assert the existent of "@". If someone relies on a more strict regexp, they may use https://github.com/SixArm/sixarm_ruby_email_address_validation
16
+
1
17
  == 1.4.2
2
18
 
3
19
  * bug fix
4
- * Improve Rails 3.1 compatibility
5
20
  * Provide a more robust behavior to serializers and add :force_except option
6
21
 
7
22
  == 1.4.1
data/Gemfile CHANGED
@@ -2,10 +2,12 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rails", "~> 3.0.7"
5
+ gem "rails", "~> 3.1.0.rc8"
6
6
  gem "oa-oauth", '~> 0.2.0', :require => "omniauth/oauth"
7
7
  gem "oa-openid", '~> 0.2.0', :require => "omniauth/openid"
8
8
 
9
+ gem "rdoc"
10
+
9
11
  group :test do
10
12
  gem "webrat", "0.7.2", :require => false
11
13
  gem "mocha", :require => false
@@ -26,7 +28,7 @@ platforms :ruby do
26
28
 
27
29
  group :mongoid do
28
30
  gem "mongo", "~> 1.3.0"
29
- gem "mongoid", "2.0.1"
31
+ gem "mongoid", "~> 2.0"
30
32
  gem "bson_ext", "~> 1.3.0"
31
33
  end
32
34
  end
@@ -7,7 +7,7 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
7
7
  * Allows you to have multiple roles (or models/scopes) signed in at the same time;
8
8
  * Is based on a modularity concept: use just what you really need.
9
9
 
10
- It's composed of 12 modules:
10
+ It's comprised of 12 modules:
11
11
 
12
12
  * Database Authenticatable: encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
13
13
  * Token Authenticatable: signs in a user based on an authentication token (also known as "single access token"). The token can be given both through query string or HTTP Basic Authentication.
@@ -97,7 +97,7 @@ If you are building your first Rails application, we recommend you to *not* use
97
97
  * Michael Hartl's online book: http://railstutorial.org/chapters/modeling-and-viewing-users-two#top
98
98
  * Ryan Bates' Railscast: http://railscasts.com/episodes/250-authentication-from-scratch
99
99
 
100
- Once you have solidified you understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :)
100
+ Once you have solidified your understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :)
101
101
 
102
102
  == Getting started
103
103
 
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'rake/testtask'
4
- require 'rake/rdoctask'
4
+ require 'rdoc/task'
5
5
 
6
6
  desc 'Default: run tests for all ORMs.'
7
7
  task :default => :test
@@ -26,7 +26,7 @@ class Devise::ConfirmationsController < ApplicationController
26
26
  if resource.errors.empty?
27
27
  set_flash_message(:notice, :confirmed) if is_navigational_format?
28
28
  sign_in(resource_name, resource)
29
- respond_with_navigational(resource){ redirect_to redirect_location(resource_name, resource) }
29
+ respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
30
30
  else
31
31
  respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
32
32
  end
@@ -38,4 +38,10 @@ class Devise::ConfirmationsController < ApplicationController
38
38
  def after_resending_confirmation_instructions_path_for(resource_name)
39
39
  new_session_path(resource_name)
40
40
  end
41
+
42
+ # The path used after confirmation.
43
+ def after_confirmation_path_for(resource_name, resource)
44
+ redirect_location(resource_name, resource)
45
+ end
46
+
41
47
  end
@@ -19,7 +19,7 @@ class Devise::RegistrationsController < ApplicationController
19
19
  sign_in(resource_name, resource)
20
20
  respond_with resource, :location => redirect_location(resource_name, resource)
21
21
  else
22
- set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
22
+ set_flash_message :notice, :inactive_signed_up, :reason => inactive_reason(resource) if is_navigational_format?
23
23
  expire_session_data_after_sign_in!
24
24
  respond_with resource, :location => after_inactive_sign_up_path_for(resource)
25
25
  end
@@ -84,10 +84,16 @@ class Devise::RegistrationsController < ApplicationController
84
84
  end
85
85
 
86
86
  # Overwrite redirect_for_sign_in so it takes uses after_sign_up_path_for.
87
- def redirect_location(scope, resource) #:nodoc:
87
+ def redirect_location(scope, resource)
88
88
  stored_location_for(scope) || after_sign_up_path_for(resource)
89
89
  end
90
90
 
91
+ # Returns the inactive reason translated.
92
+ def inactive_reason(resource)
93
+ reason = resource.inactive_message.to_s
94
+ I18n.t("devise.registrations.reasons.#{reason}", :default => reason)
95
+ end
96
+
91
97
  # The path used after sign up for inactive accounts. You need to overwrite
92
98
  # this method in your own RegistrationsController.
93
99
  def after_inactive_sign_up_path_for(resource)
@@ -38,8 +38,10 @@ class Devise::SessionsController < ApplicationController
38
38
  protected
39
39
 
40
40
  def stub_options(resource)
41
- array = resource_class.authentication_keys.dup
42
- array << :password if resource.respond_to?(:password)
43
- { :methods => array, :only => [:password] }
41
+ methods = resource_class.authentication_keys.dup
42
+ methods = methods.keys if methods.is_a?(Hash)
43
+ methods << :password if resource.respond_to?(:password)
44
+ { :methods => methods, :only => [:password] }
44
45
  end
45
- end
46
+ end
47
+
@@ -3,10 +3,10 @@
3
3
  <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
- <p><%= f.label :email %><br />
7
- <%= f.email_field :email %></p>
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
8
 
9
- <p><%= f.submit "Resend confirmation instructions" %></p>
9
+ <div><%= f.submit "Resend confirmation instructions" %></div>
10
10
  <% end %>
11
11
 
12
12
  <%= render :partial => "devise/shared/links" %>
@@ -4,13 +4,13 @@
4
4
  <%= devise_error_messages! %>
5
5
  <%= f.hidden_field :reset_password_token %>
6
6
 
7
- <p><%= f.label :password, "New password" %><br />
8
- <%= f.password_field :password %></p>
7
+ <div><%= f.label :password, "New password" %><br />
8
+ <%= f.password_field :password %></div>
9
9
 
10
- <p><%= f.label :password_confirmation, "Confirm new password" %><br />
11
- <%= f.password_field :password_confirmation %></p>
10
+ <div><%= f.label :password_confirmation, "Confirm new password" %><br />
11
+ <%= f.password_field :password_confirmation %></div>
12
12
 
13
- <p><%= f.submit "Change my password" %></p>
13
+ <div><%= f.submit "Change my password" %></div>
14
14
  <% end %>
15
15
 
16
16
  <%= render :partial => "devise/shared/links" %>
@@ -3,10 +3,10 @@
3
3
  <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
- <p><%= f.label :email %><br />
7
- <%= f.email_field :email %></p>
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
8
 
9
- <p><%= f.submit "Send me reset password instructions" %></p>
9
+ <div><%= f.submit "Send me reset password instructions" %></div>
10
10
  <% end %>
11
11
 
12
12
  <%= render :partial => "devise/shared/links" %>
@@ -3,19 +3,19 @@
3
3
  <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
- <p><%= f.label :email %><br />
7
- <%= f.email_field :email %></p>
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
8
 
9
- <p><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
10
- <%= f.password_field :password %></p>
9
+ <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
10
+ <%= f.password_field :password %></div>
11
11
 
12
- <p><%= f.label :password_confirmation %><br />
13
- <%= f.password_field :password_confirmation %></p>
12
+ <div><%= f.label :password_confirmation %><br />
13
+ <%= f.password_field :password_confirmation %></div>
14
14
 
15
- <p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
16
- <%= f.password_field :current_password %></p>
15
+ <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
16
+ <%= f.password_field :current_password %></div>
17
17
 
18
- <p><%= f.submit "Update" %></p>
18
+ <div><%= f.submit "Update" %></div>
19
19
  <% end %>
20
20
 
21
21
  <h3>Cancel my account</h3>
@@ -3,16 +3,16 @@
3
3
  <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
- <p><%= f.label :email %><br />
7
- <%= f.email_field :email %></p>
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
8
 
9
- <p><%= f.label :password %><br />
10
- <%= f.password_field :password %></p>
9
+ <div><%= f.label :password %><br />
10
+ <%= f.password_field :password %></div>
11
11
 
12
- <p><%= f.label :password_confirmation %><br />
13
- <%= f.password_field :password_confirmation %></p>
12
+ <div><%= f.label :password_confirmation %><br />
13
+ <%= f.password_field :password_confirmation %></div>
14
14
 
15
- <p><%= f.submit "Sign up" %></p>
15
+ <div><%= f.submit "Sign up" %></div>
16
16
  <% end %>
17
17
 
18
18
  <%= render :partial => "devise/shared/links" %>
@@ -1,17 +1,17 @@
1
1
  <h2>Sign in</h2>
2
2
 
3
3
  <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
4
- <p><%= f.label :email %><br />
5
- <%= f.email_field :email %></p>
4
+ <div><%= f.label :email %><br />
5
+ <%= f.email_field :email %></div>
6
6
 
7
- <p><%= f.label :password %><br />
8
- <%= f.password_field :password %></p>
7
+ <div><%= f.label :password %><br />
8
+ <%= f.password_field :password %></div>
9
9
 
10
10
  <% if devise_mapping.rememberable? -%>
11
- <p><%= f.check_box :remember_me %> <%= f.label :remember_me %></p>
11
+ <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
12
12
  <% end -%>
13
13
 
14
- <p><%= f.submit "Sign in" %></p>
14
+ <div><%= f.submit "Sign in" %></div>
15
15
  <% end %>
16
16
 
17
17
  <%= render :partial => "devise/shared/links" %>
@@ -3,10 +3,10 @@
3
3
  <%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
- <p><%= f.label :email %><br />
7
- <%= f.email_field :email %></p>
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
8
 
9
- <p><%= f.submit "Resend unlock instructions" %></p>
9
+ <div><%= f.submit "Resend unlock instructions" %></div>
10
10
  <% end %>
11
11
 
12
12
  <%= render :partial => "devise/shared/links" %>
@@ -37,6 +37,10 @@ en:
37
37
  inactive_signed_up: 'You have signed up successfully. However, we could not sign you in because your account is %{reason}.'
38
38
  updated: 'You updated your account successfully.'
39
39
  destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
40
+ reasons:
41
+ inactive: 'inactive'
42
+ unconfirmed: 'unconfirmed'
43
+ locked: 'locked'
40
44
  unlocks:
41
45
  send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
42
46
  unlocked: 'Your account was successfully unlocked. You are now signed in.'
@@ -21,5 +21,5 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_dependency("warden", "~> 1.0.3")
23
23
  s.add_dependency("orm_adapter", "~> 0.0.3")
24
- s.add_dependency("bcrypt-ruby", "~> 2.1.2")
24
+ s.add_dependency("bcrypt-ruby", "~> 3.0")
25
25
  end
@@ -11,7 +11,6 @@ module Devise
11
11
  autoload :PathChecker, 'devise/path_checker'
12
12
  autoload :Schema, 'devise/schema'
13
13
  autoload :TestHelpers, 'devise/test_helpers'
14
- autoload :Email, 'devise/email'
15
14
 
16
15
  module Controllers
17
16
  autoload :Helpers, 'devise/controllers/helpers'
@@ -105,11 +104,11 @@ module Devise
105
104
  mattr_accessor :http_authentication_realm
106
105
  @@http_authentication_realm = "Application"
107
106
 
108
- # Email regex used to validate email formats. Based on RFC 822 and
109
- # retrieved from Sixarm email validation gem
110
- # (https://github.com/SixArm/sixarm_ruby_email_address_validation).
107
+ # Email regex used to validate email formats. It simply asserts that
108
+ # an one (and only one) @ exists in the given string. This is mainly
109
+ # to give user feedback and not to assert the e-mail validity.
111
110
  mattr_accessor :email_regexp
112
- @@email_regexp = Devise::Email::EXACT_PATTERN
111
+ @@email_regexp = /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
113
112
 
114
113
  # Range validation for password length
115
114
  mattr_accessor :password_length
@@ -398,6 +397,12 @@ module Devise
398
397
  Rails::VERSION::STRING[0,3] != "3.0"
399
398
  end
400
399
 
400
+ # Renegeres url helpers considering Devise.mapping
401
+ def self.regenerate_helpers!
402
+ Devise::Controllers::UrlHelpers.remove_helpers!
403
+ Devise::Controllers::UrlHelpers.generate_helpers!
404
+ end
405
+
401
406
  # A method used internally to setup warden manager from the Rails initialize
402
407
  # block.
403
408
  def self.configure_warden! #:nodoc:
@@ -417,7 +422,7 @@ module Devise
417
422
 
418
423
  # Generate a friendly string randomically to be used as token.
419
424
  def self.friendly_token
420
- SecureRandom.base64(15).tr('+/=', 'xyz')
425
+ SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
421
426
  end
422
427
 
423
428
  # constant-time comparison algorithm to prevent timing attacks
@@ -106,6 +106,7 @@ module Devise
106
106
  warden.session_serializer.store(resource, scope)
107
107
  elsif warden.user(scope) == resource && !options.delete(:force)
108
108
  # Do nothing. User already signed in and we are not forcing it.
109
+ true
109
110
  else
110
111
  warden.set_user(resource, options.merge!(:scope => scope))
111
112
  end
@@ -18,22 +18,31 @@ module Devise
18
18
  #
19
19
  # Those helpers are added to your ApplicationController.
20
20
  module UrlHelpers
21
+ def self.remove_helpers!
22
+ self.instance_methods.map(&:to_s).grep(/_(url|path)$/).each do |method|
23
+ remove_method method
24
+ end
25
+ end
21
26
 
22
- Devise::URL_HELPERS.each do |module_name, actions|
23
- [:path, :url].each do |path_or_url|
24
- actions.each do |action|
25
- action = action ? "#{action}_" : ""
27
+ def self.generate_helpers!
28
+ mappings = Devise.mappings.values.map(&:used_routes).flatten.uniq
29
+ routes = Devise::URL_HELPERS.slice(*mappings)
26
30
 
27
- class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
28
- def #{action}#{module_name}_#{path_or_url}(resource_or_scope, *args)
29
- scope = Devise::Mapping.find_scope!(resource_or_scope)
30
- send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
31
- end
32
- URL_HELPERS
31
+ routes.each do |module_name, actions|
32
+ [:path, :url].each do |path_or_url|
33
+ actions.each do |action|
34
+ action = action ? "#{action}_" : ""
35
+
36
+ class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
37
+ def #{action}#{module_name}_#{path_or_url}(resource_or_scope, *args)
38
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
39
+ send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
40
+ end
41
+ URL_HELPERS
42
+ end
33
43
  end
34
44
  end
35
45
  end
36
-
37
46
  end
38
47
  end
39
48
  end
@@ -1,7 +1,7 @@
1
1
  # Each time a record is set we check whether its session has already timed out
2
2
  # or not, based on last request time. If so, the record is logged out and
3
3
  # redirected to the sign in page. Also, each time the request comes and the
4
- # record is set, we set the last request time inside it's scoped session to
4
+ # record is set, we set the last request time inside its scoped session to
5
5
  # verify timeout in the following request.
6
6
  Warden::Manager.after_set_user do |record, warden, options|
7
7
  scope = options[:scope]
@@ -10,6 +10,11 @@ module Devise
10
10
 
11
11
  protected
12
12
 
13
+ def setup_mail(*args)
14
+ ActiveSupport::Deprecation.warn "setup_mail is deprecated, please use devise_mail instead", caller
15
+ devise_mail(*args)
16
+ end
17
+
13
18
  # Configure default email options
14
19
  def devise_mail(record, action)
15
20
  initialize_from_record(record)
@@ -45,7 +50,9 @@ module Devise
45
50
  end
46
51
 
47
52
  def mailer_sender(mapping)
48
- if Devise.mailer_sender.is_a?(Proc)
53
+ if default_params[:from].present?
54
+ default_params[:from]
55
+ elsif Devise.mailer_sender.is_a?(Proc)
49
56
  Devise.mailer_sender.call(mapping.name)
50
57
  else
51
58
  Devise.mailer_sender
@@ -81,4 +88,4 @@ module Devise
81
88
  end
82
89
  end
83
90
  end
84
- end
91
+ end