devise 1.3.4 → 1.4.1

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 (74) hide show
  1. data/.travis.yml +3 -2
  2. data/CHANGELOG.rdoc +29 -0
  3. data/Gemfile +10 -7
  4. data/Gemfile.lock +47 -47
  5. data/README.rdoc +2 -2
  6. data/Rakefile +1 -1
  7. data/app/controllers/devise/confirmations_controller.rb +2 -2
  8. data/app/controllers/devise/passwords_controller.rb +10 -2
  9. data/app/controllers/devise/registrations_controller.rb +6 -4
  10. data/app/controllers/devise/unlocks_controller.rb +2 -2
  11. data/app/helpers/devise_helper.rb +1 -1
  12. data/app/mailers/devise/mailer.rb +4 -77
  13. data/config/locales/en.yml +3 -0
  14. data/lib/devise.rb +45 -13
  15. data/lib/devise/controllers/helpers.rb +5 -2
  16. data/lib/devise/controllers/internal_helpers.rb +15 -1
  17. data/lib/devise/controllers/rememberable.rb +1 -1
  18. data/lib/devise/email.rb +23 -0
  19. data/lib/devise/hooks/forgetable.rb +1 -1
  20. data/lib/devise/hooks/trackable.rb +1 -1
  21. data/lib/devise/mailers/helpers.rb +84 -0
  22. data/lib/devise/mapping.rb +23 -7
  23. data/lib/devise/models/authenticatable.rb +14 -6
  24. data/lib/devise/models/database_authenticatable.rb +18 -1
  25. data/lib/devise/models/recoverable.rb +1 -1
  26. data/lib/devise/models/rememberable.rb +7 -5
  27. data/lib/devise/models/validatable.rb +5 -7
  28. data/lib/devise/modules.rb +1 -1
  29. data/lib/devise/omniauth.rb +0 -5
  30. data/lib/devise/omniauth/config.rb +6 -0
  31. data/lib/devise/rails/routes.rb +65 -10
  32. data/lib/devise/strategies/rememberable.rb +2 -7
  33. data/lib/devise/version.rb +1 -1
  34. data/lib/generators/devise/install_generator.rb +2 -2
  35. data/lib/generators/devise/simple_form_for/confirmations/new.html.erb +15 -0
  36. data/lib/generators/devise/simple_form_for/passwords/edit.html.erb +19 -0
  37. data/lib/generators/devise/simple_form_for/passwords/new.html.erb +15 -0
  38. data/lib/generators/devise/simple_form_for/registrations/edit.html.erb +22 -0
  39. data/lib/generators/devise/simple_form_for/registrations/new.html.erb +17 -0
  40. data/lib/generators/devise/simple_form_for/sessions/new.html.erb +15 -0
  41. data/lib/generators/devise/simple_form_for/unlocks/new.html.erb +15 -0
  42. data/lib/generators/devise/views_generator.rb +61 -9
  43. data/lib/generators/templates/devise.rb +13 -3
  44. data/test/controllers/internal_helpers_test.rb +9 -2
  45. data/test/generators/views_generator_test.rb +10 -0
  46. data/test/helpers/devise_helper_test.rb +43 -0
  47. data/test/integration/authenticatable_test.rb +74 -5
  48. data/test/integration/confirmable_test.rb +39 -1
  49. data/test/integration/database_authenticatable_test.rb +22 -0
  50. data/test/integration/http_authenticatable_test.rb +8 -0
  51. data/test/integration/lockable_test.rb +62 -4
  52. data/test/integration/omniauthable_test.rb +1 -3
  53. data/test/integration/recoverable_test.rb +66 -6
  54. data/test/integration/registerable_test.rb +1 -1
  55. data/test/integration/rememberable_test.rb +20 -1
  56. data/test/integration/trackable_test.rb +17 -0
  57. data/test/mapping_test.rb +5 -0
  58. data/test/models/database_authenticatable_test.rb +56 -1
  59. data/test/models/encryptable_test.rb +1 -1
  60. data/test/models/recoverable_test.rb +14 -3
  61. data/test/models/rememberable_test.rb +8 -0
  62. data/test/models/token_authenticatable_test.rb +0 -6
  63. data/test/models/validatable_test.rb +17 -4
  64. data/test/models_test.rb +4 -0
  65. data/test/omniauth/url_helpers_test.rb +4 -0
  66. data/test/rails_app/app/controllers/home_controller.rb +9 -0
  67. data/test/rails_app/app/controllers/users_controller.rb +6 -1
  68. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  69. data/test/rails_app/app/views/home/join.html.erb +1 -0
  70. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  71. data/test/rails_app/config/initializers/devise.rb +6 -0
  72. data/test/rails_app/config/routes.rb +30 -2
  73. data/test/routes_test.rb +54 -0
  74. metadata +21 -4
@@ -23,6 +23,7 @@ module Devise
23
23
  attr_reader :password, :current_password
24
24
  attr_accessor :password_confirmation
25
25
  before_validation :downcase_keys
26
+ before_validation :strip_whitespace
26
27
  end
27
28
 
28
29
  # Generates password encryption based on the given value.
@@ -58,8 +59,9 @@ module Devise
58
59
  result = if valid_password?(current_password)
59
60
  update_attributes(params)
60
61
  else
61
- self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
62
62
  self.attributes = params
63
+ self.valid?
64
+ self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
63
65
  false
64
66
  end
65
67
 
@@ -67,6 +69,17 @@ module Devise
67
69
  result
68
70
  end
69
71
 
72
+ # Updates record attributes without asking for the current password.
73
+ # Never allows to change the current password
74
+ def update_without_password(params={})
75
+ params.delete(:password)
76
+ params.delete(:password_confirmation)
77
+
78
+ result = update_attributes(params)
79
+ clean_up_passwords
80
+ result
81
+ end
82
+
70
83
  def after_database_authentication
71
84
  end
72
85
 
@@ -81,6 +94,10 @@ module Devise
81
94
  def downcase_keys
82
95
  (self.class.case_insensitive_keys || []).each { |k| self[k].try(:downcase!) }
83
96
  end
97
+
98
+ def strip_whitespace
99
+ (self.class.strip_whitespace_keys || []).each { |k| self[k].try(:strip!) }
100
+ end
84
101
 
85
102
  # Digests the password using bcrypt.
86
103
  def password_digest(password)
@@ -42,7 +42,7 @@ module Devise
42
42
  # Checks if the reset password token sent is within the limit time.
43
43
  # We do this by calculating if the difference between today and the
44
44
  # sending date does not exceed the confirm in time configured.
45
- # Returns true if the ressource is not responding to reset_password_sent_at at all.
45
+ # Returns true if the resource is not responding to reset_password_sent_at at all.
46
46
  # reset_password_within is a model configuration, must always be an integer value.
47
47
  #
48
48
  # Example:
@@ -54,12 +54,14 @@ module Devise
54
54
  save(:validate => false)
55
55
  end
56
56
 
57
- # Removes the remember token only if it exists, and save the record
58
- # without validations.
57
+ # If the record is persisted, remove the remember token (but only if
58
+ # it exists), and save the record without validations.
59
59
  def forget_me!
60
- self.remember_token = nil if respond_to?(:remember_token=)
61
- self.remember_created_at = nil
62
- save(:validate => false)
60
+ if persisted?
61
+ self.remember_token = nil if respond_to?(:remember_token=)
62
+ self.remember_created_at = nil
63
+ save(:validate => false)
64
+ end
63
65
  end
64
66
 
65
67
  # Remember token should be expired if expiration time not overpass now.
@@ -23,14 +23,12 @@ module Devise
23
23
 
24
24
  base.class_eval do
25
25
  validates_presence_of :email, :if => :email_required?
26
- validates_uniqueness_of :email, :case_sensitive => (case_insensitive_keys != false), :allow_blank => true
27
- validates_format_of :email, :with => email_regexp, :allow_blank => true
26
+ validates_uniqueness_of :email, :case_sensitive => (case_insensitive_keys != false), :allow_blank => true, :if => :email_changed?
27
+ validates_format_of :email, :with => email_regexp, :allow_blank => true, :if => :email_changed?
28
28
 
29
- with_options :if => :password_required? do |v|
30
- v.validates_presence_of :password
31
- v.validates_confirmation_of :password
32
- v.validates_length_of :password, :within => password_length, :allow_blank => true
33
- end
29
+ validates_presence_of :password, :if => :password_required?
30
+ validates_confirmation_of :password, :if => :password_required?
31
+ validates_length_of :password, :within => password_length, :allow_blank => true
34
32
  end
35
33
  end
36
34
 
@@ -5,7 +5,7 @@ Devise.with_options :model => true do |d|
5
5
  d.with_options :strategy => true do |s|
6
6
  routes = [nil, :new, :destroy]
7
7
  s.add_module :database_authenticatable, :controller => :sessions, :route => { :session => routes }
8
- s.add_module :token_authenticatable, :controller => :sessions, :route => { :session => routes }
8
+ s.add_module :token_authenticatable
9
9
  s.add_module :rememberable
10
10
  end
11
11
 
@@ -23,10 +23,5 @@ module Devise
23
23
  module OmniAuth
24
24
  autoload :Config, "devise/omniauth/config"
25
25
  autoload :UrlHelpers, "devise/omniauth/url_helpers"
26
-
27
- class << self
28
- delegate :short_circuit_authorizers!, :unshort_circuit_authorizers!,
29
- :test_mode!, :stub!, :reset_stubs!, :to => "Devise::OmniAuth::TestHelpers"
30
- end
31
26
  end
32
27
  end
@@ -10,6 +10,12 @@ module Devise
10
10
  @strategy = nil
11
11
  end
12
12
 
13
+ # open_id strategy can have configurable name
14
+ def strategy_name
15
+ options = @args.last.is_a?(Hash) && @args.last
16
+ options && options[:name] ? options[:name] : @provider
17
+ end
18
+
13
19
  def strategy_class
14
20
  ::OmniAuth::Strategies.const_get("#{::OmniAuth::Utils.camelize(@provider.to_s)}")
15
21
  end
@@ -103,6 +103,13 @@ module ActionDispatch::Routing
103
103
  #
104
104
  # devise_for :users, :only => :sessions
105
105
  #
106
+ # * :format => include "(.:format)" in the generated routes? true by default, set to false to disable:
107
+ #
108
+ # devise_for :users, :format => false
109
+ #
110
+ # * :constraints => works the same as Rails' contraints
111
+ #
112
+ # * :defaults => works the same as Rails' defaults
106
113
  #
107
114
  # ==== Scoping
108
115
  #
@@ -129,9 +136,9 @@ module ActionDispatch::Routing
129
136
  # end
130
137
  #
131
138
  # ==== Adding custom actions to override controllers
132
- #
133
- # You can pass a block to devise_for that will add any routes defined in the block to Devise's
134
- # list of known actions. This is important if you add a custom action to a controller that
139
+ #
140
+ # You can pass a block to devise_for that will add any routes defined in the block to Devise's
141
+ # list of known actions. This is important if you add a custom action to a controller that
135
142
  # overrides an out of the box Devise controller.
136
143
  # For example:
137
144
  #
@@ -159,6 +166,10 @@ module ActionDispatch::Routing
159
166
  options[:module] ||= @scope[:module] if @scope[:module].present?
160
167
  options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
161
168
  options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
169
+ options[:constraints] = (@scope[:constraints] || {}).merge(options[:constraints] || {})
170
+ options[:defaults] = (@scope[:defaults] || {}).merge(options[:defaults] || {})
171
+
172
+ @scope[:options] = (@scope[:options] || {}).merge({:format => false}) if options[:format] == false
162
173
 
163
174
  resources.map!(&:to_sym)
164
175
 
@@ -185,7 +196,7 @@ module ActionDispatch::Routing
185
196
 
186
197
  devise_scope mapping.name do
187
198
  yield if block_given?
188
- with_devise_exclusive_scope mapping.fullpath, mapping.name do
199
+ with_devise_exclusive_scope mapping.fullpath, mapping.name, mapping.constraints, mapping.defaults do
189
200
  routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
190
201
  end
191
202
  end
@@ -208,6 +219,50 @@ module ActionDispatch::Routing
208
219
  end
209
220
  end
210
221
 
222
+ # Allow you to route based on whether a scope is authenticated. You
223
+ # can optionally specify which scope.
224
+ #
225
+ # authenticated :admin do
226
+ # root :to => 'admin/dashboard#show'
227
+ # end
228
+ #
229
+ # authenticated do
230
+ # root :to => 'dashboard#show'
231
+ # end
232
+ #
233
+ # root :to => 'landing#show'
234
+ #
235
+ def authenticated(scope=nil)
236
+ constraint = lambda do |request|
237
+ request.env["warden"].authenticate? :scope => scope
238
+ end
239
+
240
+ constraints(constraint) do
241
+ yield
242
+ end
243
+ end
244
+
245
+ # Allow you to route based on whether a scope is *not* authenticated.
246
+ # You can optionally specify which scope.
247
+ #
248
+ # unauthenticated do
249
+ # as :user do
250
+ # root :to => 'devise/registrations#new'
251
+ # end
252
+ # end
253
+ #
254
+ # root :to => 'dashboard#show'
255
+ #
256
+ def unauthenticated(scope=nil)
257
+ constraint = lambda do |request|
258
+ not request.env["warden"].authenticate? :scope => scope
259
+ end
260
+
261
+ constraints(constraint) do
262
+ yield
263
+ end
264
+ end
265
+
211
266
  # Sets the devise scope to be used in the controller. If you have custom routes,
212
267
  # you are required to call this method (also aliased as :as) in order to specify
213
268
  # to which controller it is targetted.
@@ -286,17 +341,17 @@ module ActionDispatch::Routing
286
341
  @scope[:path] = path
287
342
  end
288
343
 
289
- def with_devise_exclusive_scope(new_path, new_as) #:nodoc:
290
- old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module]
291
- @scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil
344
+ def with_devise_exclusive_scope(new_path, new_as, new_constraints, new_defaults) #:nodoc:
345
+ old_as, old_path, old_module, old_constraints, old_defaults = @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults]
346
+ @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults] = new_as, new_path, nil, new_constraints, new_defaults
292
347
  yield
293
348
  ensure
294
- @scope[:as], @scope[:path], @scope[:module] = old_as, old_path, old_module
349
+ @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults] = old_as, old_path, old_module, old_constraints, old_defaults
295
350
  end
296
351
 
297
352
  def raise_no_devise_method_error!(klass) #:nodoc:
298
- raise "#{klass} does not respond to 'devise' method. This usually means you haven't " <<
299
- "loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " <<
353
+ raise "#{klass} does not respond to 'devise' method. This usually means you haven't " \
354
+ "loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " \
300
355
  "inside 'config/initializers/devise.rb' or before your application definition in 'config/application.rb'"
301
356
  end
302
357
  end
@@ -9,14 +9,14 @@ module Devise
9
9
  class Rememberable < Authenticatable
10
10
  # A valid strategy for rememberable needs a remember token in the cookies.
11
11
  def valid?
12
- remember_cookie.present?
12
+ cookies.key?(remember_key)
13
13
  end
14
14
 
15
15
  # To authenticate a user we deserialize the cookie and attempt finding
16
16
  # the record in the database. If the attempt fails, we pass to another
17
17
  # strategy handle the authentication.
18
18
  def authenticate!
19
- resource = mapping.to.serialize_from_cookie(*remember_cookie)
19
+ resource = mapping.to.serialize_from_cookie(*cookies.signed[remember_key])
20
20
 
21
21
  if validate(resource)
22
22
  success!(resource)
@@ -40,11 +40,6 @@ module Devise
40
40
  def remember_key
41
41
  "remember_#{scope}_token"
42
42
  end
43
-
44
- # Accessor for remember cookie
45
- def remember_cookie
46
- @remember_cookie ||= cookies.signed[remember_key]
47
- end
48
43
  end
49
44
  end
50
45
  end
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "1.3.4".freeze
2
+ VERSION = "1.4.1".freeze
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/secure_random'
1
+ require 'securerandom'
2
2
 
3
3
  module Devise
4
4
  module Generators
@@ -21,4 +21,4 @@ module Devise
21
21
  end
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -0,0 +1,15 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="inputs">
7
+ <%= f.input :email %>
8
+ </div>
9
+
10
+ <div class="actions">
11
+ <%= f.button :submit, "Resend confirmation instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,19 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <%= f.input :reset_password_token, :as => :hidden %>
7
+ <%= f.full_error :reset_password_token %>
8
+
9
+ <div class="inputs">
10
+ <%= f.input :password, :label => "New password" %>
11
+ <%= f.input :password_confirmation, :label => "Confirm your new password", :required => true %>
12
+ </div>
13
+
14
+ <div class="actions">
15
+ <%= f.button :submit, "Change my password" %>
16
+ </div>
17
+ <% end %>
18
+
19
+ <%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="inputs">
7
+ <%= f.input :email %>
8
+ </div>
9
+
10
+ <div class="actions">
11
+ <%= f.button :submit, "Send me reset password instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,22 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="inputs">
7
+ <%= f.input :email, :autofocus => true %>
8
+ <%= f.input :password, :hint => "leave it blank if you don't want to change it", :required => false %>
9
+ <%= f.input :password_confirmation, :required => false %>
10
+ <%= f.input :current_password, :hint => "we need your current password to confirm your changes", :required => true %>
11
+ </div>
12
+
13
+ <div class="actions">
14
+ <%= f.button :submit, "Update" %>
15
+ </div>
16
+ <% end %>
17
+
18
+ <h3>Cancel my account</h3>
19
+
20
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
21
+
22
+ <%= link_to "Back", :back %>
@@ -0,0 +1,17 @@
1
+ <h2>Sign up</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="inputs">
7
+ <%= f.input :email, :autofocus => true %>
8
+ <%= f.input :password %>
9
+ <%= f.input :password_confirmation %>
10
+ </div>
11
+
12
+ <div class="actions">
13
+ <%= f.button :submit, "Sign up" %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Sign in</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
4
+ <div class="inputs">
5
+ <%= f.input :email, :required => false, :autofocus => true %>
6
+ <%= f.input :password, :required => false %>
7
+ <%= f.input :remember_me, :as => :boolean if devise_mapping.rememberable? %>
8
+ </div>
9
+
10
+ <div class="actions">
11
+ <%= f.button :submit, "Sign in" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Resend unlock instructions</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="inputs">
7
+ <%= f.input :email %>
8
+ </div>
9
+
10
+ <div class="actions">
11
+ <%= f.button :submit, "Resend unlock instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render :partial => "devise/shared/links" %>
@@ -1,20 +1,72 @@
1
- require 'tmpdir'
2
-
3
1
  module Devise
4
2
  module Generators
3
+ # Include this module in your generator to generate Devise views.
4
+ # `copy_views` is the main method and by default copies all views
5
+ # with forms.
6
+ module ViewPathTemplates #:nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ argument :scope, :required => false, :default => nil,
11
+ :desc => "The scope to copy views to"
12
+
13
+ public_task :copy_views
14
+ end
15
+
16
+ def copy_views
17
+ view_directory :confirmations
18
+ view_directory :passwords
19
+ view_directory :registrations
20
+ view_directory :sessions
21
+ view_directory :unlocks
22
+ end
23
+
24
+ protected
25
+
26
+ def view_directory(name)
27
+ directory name.to_s, "#{target_path}/#{name}"
28
+ end
29
+
30
+ def target_path
31
+ @target_path ||= "app/views/#{scope || :devise}"
32
+ end
33
+ end
34
+
35
+ class SharedViewsGenerator < Rails::Generators::Base #:nodoc:
36
+ include ViewPathTemplates
37
+ source_root File.expand_path("../../../../app/views/devise", __FILE__)
38
+ desc "Copies shared Devise views to your application."
39
+
40
+ # Override copy_views to just copy mailer and shared.
41
+ def copy_views
42
+ view_directory :mailer
43
+ view_directory :shared
44
+ end
45
+ end
46
+
47
+ class FormForGenerator < Rails::Generators::Base #:nodoc:
48
+ include ViewPathTemplates
49
+ source_root File.expand_path("../../../../app/views/devise", __FILE__)
50
+ desc "Copies default Devise views to your application."
51
+ end
52
+
53
+ class SimpleFormForGenerator < Rails::Generators::Base #:nodoc:
54
+ include ViewPathTemplates
55
+ source_root File.expand_path("../simple_form_for", __FILE__)
56
+ desc "Copies simple form enabled views to your application."
57
+ end
58
+
5
59
  class ViewsGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../../../../app/views", __FILE__)
7
- desc "Copies all Devise views to your application."
60
+ desc "Copies Devise views to your application."
8
61
 
9
62
  argument :scope, :required => false, :default => nil,
10
63
  :desc => "The scope to copy views to"
11
64
 
12
- # class_option :template_engine, :type => :string, :aliases => "-t",
13
- # :desc => "Template engine for the views. Available options are 'erb', 'haml' and 'slim'."
65
+ invoke SharedViewsGenerator
14
66
 
15
- def copy_views
16
- directory "devise", "app/views/#{scope || :devise}"
17
- end
67
+ hook_for :form_builder, :aliases => "-b",
68
+ :desc => "Form builder to be used",
69
+ :default => defined?(SimpleForm) ? "simple_form_for" : "form_for"
18
70
  end
19
71
  end
20
72
  end