devise_invitable 1.3.4 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec084ea3f59520fb7b2cfb978cd79d53ec5c1488
4
- data.tar.gz: 257a48340805f6bfe02bc4fd1279a8694ab24c5c
3
+ metadata.gz: 9ebdddd2e1426fdde9ad700f7f60e4cedf3e48ab
4
+ data.tar.gz: 3a783c0d76c73a4a6af2c07cda15b80904fecdcf
5
5
  SHA512:
6
- metadata.gz: 51c1385e5d2235ef7d3004208e489ecd241e99ade5afd8d7f5a1289e48cc7e9af6ba599b058862b82c5eb9c64ee02dc63d1be1526d692ccd86c33099bda8c8a8
7
- data.tar.gz: 86ff8fa5e4f3990ca8c5dee25acc0e663204b671337e479fc19cfc0c5d2145d79f85f5a68c1ac53790b8a4c967050e13b0a070cf8943c6c4d639684ad68898b7
6
+ metadata.gz: b85b1eabee1011a5175f98ca92f05f39a1f49e3da2666f17bafa8a87d22115700d6f7beee89261a5096d70dcfeec473834dc43bfcaa5a967b63fc78b7789bb7f
7
+ data.tar.gz: 483b574690f8a3064b7d4f941a7fad4e321fe89d677192b82e68d0d0f3feba49d92125054f17e89521c2810e9feb80de12ee135895728d7d1f633bdd845845ea
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ Override valid_password? and unauthenticated_message instead of active_for_authentication? and inactive_message, active_for_authentication? doesn't work for default behavior of invited users without password
2
+
3
+ = 1.4.0
4
+ Override active_for_authentication? and inactive_message instead of valid_password?
5
+ To use counter_cache, invited_by_counter_cache must be set, no more checking of invitations_count to enable counter cache
6
+
1
7
  = 1.3.0
2
8
  Now devise 3.1 compatible, @token must be used instead of @resource.invitation_token in mail views
3
9
 
data/README.rdoc CHANGED
@@ -1,5 +1,5 @@
1
1
  = DeviseInvitable
2
- {<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[http://travis-ci.org/scambra/devise_invitable]
2
+ {<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[http://travis-ci.org/scambra/devise_invitable] {<img src="https://codeclimate.com/github/scambra/devise_invitable/badges/gpa.svg"/}[https://codeclimate.com/github/scambra/devise_invitable]
3
3
 
4
4
  It adds support to devise[http://github.com/plataformatec/devise] for sending invitations by email (it requires to be authenticated) and accept the invitation setting the password.
5
5
 
@@ -16,7 +16,7 @@ Install DeviseInvitable gem, it will also install dependencies (such as devise a
16
16
  Add DeviseInvitable to your Gemfile (and Devise if you weren't using them):
17
17
 
18
18
  gem 'devise', '>= 2.0.0'
19
- gem 'devise_invitable', '~> 1.1.0'
19
+ gem 'devise_invitable', '~> 1.3.4'
20
20
 
21
21
  === Automatic installation
22
22
 
@@ -132,6 +132,8 @@ or directly as parameters to the <tt>devise</tt> method:
132
132
 
133
133
  * invited_by_class_name: The class name of the inviting model. If this is nil, polymorphic association is used.
134
134
 
135
+ * allow_insecure_sign_in_after_accept: automatically sign in the user after they set a password. Enabled by default.
136
+
135
137
  For more details, see <tt>config/initializers/devise.rb</tt> (after you invoked the "devise_invitable:install" generator described above).
136
138
 
137
139
  == Configuring views
@@ -233,11 +235,16 @@ To send an invitation to a user, use the <tt>invite!</tt> class method. <tt>:ema
233
235
 
234
236
  If you want to create the invitation but not send it, you can set <tt>skip_invitation</tt> to true.
235
237
 
236
- User.invite!(:email => "new_user@example.com", :name => "John Doe") do |u|
238
+ user = User.invite!(:email => "new_user@example.com", :name => "John Doe") do |u|
237
239
  u.skip_invitation = true
238
240
  end
239
241
  # => the record will be created, but the invitation email will not be sent
240
242
 
243
+ When generating the <tt>accept_user_invitation_url</tt> yourself, you must use the <tt>raw_invitation_token</tt>
244
+ the value is temporarily available when you invite a user and will be decrypted when recieved.
245
+
246
+ accept_user_invitation_url(:invitation_token => user.raw_invitation_token)
247
+
241
248
  When skip_invitation is used, you must also then set the invitation_sent_at field when the user is sent their
242
249
  token. Failure to do so will yield "Invalid invitation token" errors when the user attempts to accept the invite.
243
250
  You can set it like so:
@@ -249,9 +256,16 @@ You can add :skip_invitation to attributes hash if skip_invitation is added to a
249
256
  User.invite!(:email => "new_user@example.com", :name => "John Doe", :skip_invitation => true)
250
257
  # => the record will be created, but the invitation email will not be sent
251
258
 
252
- Skip_invitation skips sending the email, but sets invitation_token, so invited_to_sign_up? on the
259
+ Skip_invitation skips sending the email, but sets invitation_token, so <tt>invited_to_sign_up?</tt> on the
253
260
  resulting user returns true.
254
261
 
262
+ To check if a perticular user is created by invitation, irrespective to state of invitation one can use <tt>created_by_invite?</tt>
263
+
264
+ **Warning**
265
+
266
+ When using skip_invitation you must send the email with the user object instance that generated the tokens, as
267
+ user.raw_invitation_token is available only to the instance and is not persisted in the database.
268
+
255
269
  You can send an invitation to an existing user if your workflow creates them separately:
256
270
 
257
271
  user = User.find(42)
@@ -261,6 +275,8 @@ You can also set <tt>invited_by</tt> when using the <tt>invite!</tt> class metho
261
275
 
262
276
  User.invite!({:email => "new_user@example.com"}, current_user) # current_user will be set as invited_by
263
277
 
278
+
279
+
264
280
  === Accept an invitation
265
281
 
266
282
  To accept an invitation with a token use the <tt>accept_invitation!</tt> class method. <tt>:invitation_token</tt> must be present in the parameters hash. You can also include other attributes in the hash.
@@ -283,8 +299,9 @@ The callbacks support all options and arguments available to the standard callba
283
299
 
284
300
  A pair of scopes to find those users that have accepted, and those that have not accepted, invitations are defined:
285
301
 
286
- User.invitation_accepted # => returns all Users for whom the invitation_accepted_at attribute is not nil
302
+ User.invitation_accepted # => returns all Users for whom the invitation_accepted_at attribute is not nil
287
303
  User.invitation_not_accepted # => returns all Users for whom the invitation_accepted_at attribute is nil
304
+ User.created_by_invite # => returns all Users who are created by invitations, irrespective to invitation status
288
305
 
289
306
  == Integration in a Rails application
290
307
 
@@ -343,6 +360,7 @@ DeviseInvitable uses flash messages with I18n with the flash keys <tt>:send_inst
343
360
  send_instructions: 'An invitation email has been sent to %{email}.'
344
361
  invitation_token_invalid: 'The invitation token provided is not valid!'
345
362
  updated: 'Your password was set successfully. You are now signed in.'
363
+ updated_not_active: 'Your password was set successfully.'
346
364
 
347
365
  You can also create distinct messages based on the resource you've configured using the singular name given in routes:
348
366
 
@@ -353,6 +371,7 @@ You can also create distinct messages based on the resource you've configured us
353
371
  send_instructions: 'A new user invitation has been sent to %{email}.'
354
372
  invitation_token_invalid: 'Your invitation token is not valid!'
355
373
  updated: 'Welcome on board! You are now signed in.'
374
+ updated_not_active: 'Welcome on board! Sign in to continue.'
356
375
 
357
376
  The DeviseInvitable mailer uses the same pattern as Devise to create mail subject messages:
358
377
 
@@ -369,6 +388,12 @@ Take a look at the generated locale file (in <tt>config/locales/devise_invitable
369
388
 
370
389
  DeviseInvitable supports ActiveRecord and Mongoid, like Devise.
371
390
 
391
+ == Wiki
392
+
393
+ It's possible to find additional information about DeviseInvitable on the Wiki:
394
+
395
+ https://github.com/scambra/devise_invitable/wiki
396
+
372
397
  == Testing
373
398
 
374
399
  To test DeviseInvitable for the ActiveRecord ORM with RVM, Ruby 1.9.2, and Rubygems 1.8.17:
@@ -15,11 +15,15 @@ class Devise::InvitationsController < DeviseController
15
15
  # POST /resource/invitation
16
16
  def create
17
17
  self.resource = invite_resource
18
+ resource_invited = resource.errors.empty?
18
19
 
19
- if resource.errors.empty?
20
- yield resource if block_given?
21
- set_flash_message :notice, :send_instructions, :email => self.resource.email if self.resource.invitation_sent_at
22
- respond_with resource, :location => after_invite_path_for(resource)
20
+ yield resource if block_given?
21
+
22
+ if resource_invited
23
+ if is_flashing_format? && self.resource.invitation_sent_at
24
+ set_flash_message :notice, :send_instructions, :email => self.resource.email
25
+ end
26
+ respond_with resource, :location => after_invite_path_for(current_inviter)
23
27
  else
24
28
  respond_with_navigational(resource) { render :new }
25
29
  end
@@ -34,50 +38,57 @@ class Devise::InvitationsController < DeviseController
34
38
  # PUT /resource/invitation
35
39
  def update
36
40
  self.resource = accept_resource
41
+ invitation_accepted = resource.errors.empty?
42
+
43
+ yield resource if block_given?
37
44
 
38
- if resource.errors.empty?
39
- yield resource if block_given?
40
- flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
41
- set_flash_message :notice, flash_message
42
- sign_in(resource_name, resource)
43
- respond_with resource, :location => after_accept_path_for(resource)
45
+ if invitation_accepted
46
+ if Devise.allow_insecure_sign_in_after_accept
47
+ flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
48
+ set_flash_message :notice, flash_message if is_flashing_format?
49
+ sign_in(resource_name, resource)
50
+ respond_with resource, :location => after_accept_path_for(resource)
51
+ else
52
+ set_flash_message :notice, :updated_not_active if is_flashing_format?
53
+ respond_with resource, :location => new_session_path(resource_name)
54
+ end
44
55
  else
45
56
  respond_with_navigational(resource){ render :edit }
46
57
  end
47
58
  end
48
-
59
+
49
60
  # GET /resource/invitation/remove?invitation_token=abcdef
50
61
  def destroy
51
62
  resource.destroy
52
- set_flash_message :notice, :invitation_removed
63
+ set_flash_message :notice, :invitation_removed if is_flashing_format?
53
64
  redirect_to after_sign_out_path_for(resource_name)
54
65
  end
55
66
 
56
67
  protected
57
68
 
58
- def invite_resource
59
- resource_class.invite!(invite_params, current_inviter)
69
+ def invite_resource(&block)
70
+ resource_class.invite!(invite_params, current_inviter, &block)
60
71
  end
61
-
72
+
62
73
  def accept_resource
63
74
  resource_class.accept_invitation!(update_resource_params)
64
75
  end
65
76
 
66
77
  def current_inviter
67
- @current_inviter ||= authenticate_inviter!
78
+ authenticate_inviter!
68
79
  end
69
80
 
70
81
  def has_invitations_left?
71
82
  unless current_inviter.nil? || current_inviter.has_invitations_left?
72
83
  self.resource = resource_class.new
73
- set_flash_message :alert, :no_invitations_remaining
84
+ set_flash_message :alert, :no_invitations_remaining if is_flashing_format?
74
85
  respond_with_navigational(resource) { render :new }
75
86
  end
76
87
  end
77
-
88
+
78
89
  def resource_from_invitation_token
79
90
  unless params[:invitation_token] && self.resource = resource_class.find_by_invitation_token(params[:invitation_token], true)
80
- set_flash_message(:alert, :invitation_token_invalid)
91
+ set_flash_message(:alert, :invitation_token_invalid) if is_flashing_format?
81
92
  redirect_to after_sign_out_path_for(resource_name)
82
93
  end
83
94
  end
@@ -89,6 +100,6 @@ class Devise::InvitationsController < DeviseController
89
100
  def update_resource_params
90
101
  devise_parameter_sanitizer.sanitize(:accept_invitation)
91
102
  end
92
-
103
+
93
104
  end
94
105
 
@@ -1,8 +1,7 @@
1
- <p>Hello <%= @resource.email %>!</p>
1
+ <p><%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %></p>
2
2
 
3
- <p>Someone has invited you to <%= root_url %>, you can accept it through the link below.</p>
3
+ <p><%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %></p>
4
4
 
5
- <p><%= link_to 'Accept invitation', accept_invitation_url(@resource, :invitation_token => @token) %></p>
5
+ <p><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, :invitation_token => @token) %></p>
6
6
 
7
- <p>If you don't want to accept the invitation, please ignore this email.<br />
8
- Your account won't be created until you access the link above and set your password.</p>
7
+ <p><%= t("devise.mailer.invitation_instructions.ignore").html_safe %></p>
@@ -1,11 +1,14 @@
1
1
  en:
2
2
  devise:
3
+ failure:
4
+ invited: "You have a pending invitation, accept it to finish creating your account."
3
5
  invitations:
4
- send_instructions: 'An invitation email has been sent to %{email}.'
5
- invitation_token_invalid: 'The invitation token provided is not valid!'
6
- updated: 'Your password was set successfully. You are now signed in.'
6
+ send_instructions: "An invitation email has been sent to %{email}."
7
+ invitation_token_invalid: "The invitation token provided is not valid!"
8
+ updated: "Your password was set successfully. You are now signed in."
9
+ updated_not_active: "Your password was set successfully."
7
10
  no_invitations_remaining: "No invitations remaining"
8
- invitation_removed: 'Your invitation was removed.'
11
+ invitation_removed: "Your invitation was removed."
9
12
  new:
10
13
  header: "Send invitation"
11
14
  submit_button: "Send an invitation"
@@ -14,4 +17,8 @@ en:
14
17
  submit_button: "Set my password"
15
18
  mailer:
16
19
  invitation_instructions:
17
- subject: 'Invitation instructions'
20
+ subject: "Invitation instructions"
21
+ hello: "Hello %{email}"
22
+ someone_invited_you: "Someone has invited you to %{url}, you can accept it through the link below."
23
+ accept: "Accept invitation"
24
+ ignore: "If you don't want to accept the invitation, please ignore this email.<br />Your account won't be created until you access the link above and set your password."
@@ -34,12 +34,8 @@ module Devise
34
34
  else
35
35
  {:polymorphic => true}
36
36
  end
37
- if defined?(ActiveRecord) && self < ActiveRecord::Base
37
+ if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && self < ActiveRecord::Base
38
38
  counter_cache = Devise.invited_by_counter_cache
39
- if !counter_cache && Devise.invited_by_class_name
40
- klass = Devise.invited_by_class_name.constantize
41
- counter_cache = klass.table_exists? && klass.columns_hash['invitations_count'].try('name')
42
- end
43
39
  belongs_to_options.merge! :counter_cache => counter_cache if counter_cache
44
40
  end
45
41
  belongs_to :invited_by, belongs_to_options
@@ -49,11 +45,13 @@ module Devise
49
45
 
50
46
  attr_writer :skip_password
51
47
 
52
- scope :active, lambda { where(:invitation_token => nil) }
48
+ scope :no_active_invitation, lambda { where(:invitation_token => nil) }
53
49
  if defined?(Mongoid) && defined?(Mongoid::Document) && self < Mongoid::Document
50
+ scope :created_by_invite, lambda { where(:invitation_sent_at.ne => nil) }
54
51
  scope :invitation_not_accepted, lambda { where(:invitation_accepted_at => nil, :invitation_token.ne => nil) }
55
52
  scope :invitation_accepted, lambda { where(:invitation_accepted_at.ne => nil) }
56
53
  else
54
+ scope :created_by_invite, lambda { where(arel_table[:invitation_sent_at].not_eq(nil)) }
57
55
  scope :invitation_not_accepted, lambda { where(arel_table[:invitation_token].not_eq(nil)).where(:invitation_accepted_at => nil) }
58
56
  scope :invitation_accepted, lambda { where(arel_table[:invitation_accepted_at].not_eq(nil)) }
59
57
 
@@ -89,6 +87,11 @@ module Devise
89
87
  end
90
88
  end
91
89
 
90
+ # Verify wheather a user is created by invitation, irrespective to invitation status
91
+ def created_by_invite?
92
+ invitation_sent_at.present?
93
+ end
94
+
92
95
  # Verifies whether a user has been invited or not
93
96
  def invited_to_sign_up?
94
97
  persisted? && invitation_token.present?
@@ -106,26 +109,28 @@ module Devise
106
109
 
107
110
  # Reset invitation token and send invitation again
108
111
  def invite!(invited_by = nil)
112
+ # This is an order-dependant assignment, this can't be moved
109
113
  was_invited = invited_to_sign_up?
110
114
 
111
115
  # Required to workaround confirmable model's confirmation_required? method
112
116
  # being implemented to check for non-nil value of confirmed_at
113
- if self.new_record? && self.respond_to?(:confirmation_required?, true)
117
+ if new_record_and_responds_to?(:confirmation_required?)
114
118
  def self.confirmation_required?; false; end
115
119
  end
116
120
 
117
- generate_invitation_token if self.invitation_token.nil? || (!@skip_invitation && @raw_invitation_token.nil?)
121
+ yield self if block_given?
122
+ generate_invitation_token if no_token_present_or_skip_invitation?
118
123
  self.invitation_created_at = Time.now.utc
119
- self.invitation_sent_at = self.invitation_created_at unless @skip_invitation
124
+ self.invitation_sent_at = self.invitation_created_at unless skip_invitation
120
125
  self.invited_by = invited_by if invited_by
121
126
 
122
127
  # Call these before_validate methods since we aren't validating on save
123
- self.downcase_keys if self.new_record? && self.respond_to?(:downcase_keys, true)
124
- self.strip_whitespace if self.new_record? && self.respond_to?(:strip_whitespace, true)
128
+ self.downcase_keys if new_record_and_responds_to?(:downcase_keys)
129
+ self.strip_whitespace if new_record_and_responds_to?(:strip_whitespace)
125
130
 
126
131
  if save(:validate => false)
127
132
  self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
128
- deliver_invitation unless @skip_invitation
133
+ deliver_invitation unless skip_invitation
129
134
  end
130
135
  end
131
136
 
@@ -138,11 +143,15 @@ module Devise
138
143
 
139
144
  # Only verify password when is not invited
140
145
  def valid_password?(password)
141
- super unless invited_to_sign_up?
146
+ super unless block_from_invitation?
147
+ end
148
+
149
+ def unauthenticated_message
150
+ block_from_invitation? ? :invited : super
142
151
  end
143
152
 
144
153
  def after_password_reset
145
- super
154
+ super if defined?(super)
146
155
  accept_invitation! if invited_to_sign_up?
147
156
  end
148
157
 
@@ -171,10 +180,17 @@ module Devise
171
180
  protected
172
181
  # Overriding the method in Devise's :validatable module so password is not required on inviting
173
182
  def password_required?
174
- !@skip_password && super
183
+ !skip_password && super
184
+ end
185
+
186
+ def skip_password
187
+ @skip_password ||= false
188
+ end
189
+
190
+ def block_from_invitation?
191
+ invited_to_sign_up?
175
192
  end
176
193
 
177
-
178
194
  # Checks if the invitation for the user is within the limit time.
179
195
  # We do this by calculating if the difference between today and the
180
196
  # invitation sent date does not exceed the invite for time configured.
@@ -211,6 +227,14 @@ module Devise
211
227
  generate_invitation_token && save(:validate => false)
212
228
  end
213
229
 
230
+ def new_record_and_responds_to?(method)
231
+ self.new_record? && self.respond_to?(method, true)
232
+ end
233
+
234
+ def no_token_present_or_skip_invitation?
235
+ self.invitation_token.nil? || (!skip_invitation || @raw_invitation_token.nil?)
236
+ end
237
+
214
238
  module ClassMethods
215
239
  # Return fields to invite
216
240
  def invite_key_fields
@@ -253,13 +277,11 @@ module Devise
253
277
  end
254
278
 
255
279
  def invite!(attributes={}, invited_by=nil, &block)
256
- invitable, mail = _invite(attributes.with_indifferent_access, invited_by, &block)
257
- invitable
280
+ _invite(attributes.with_indifferent_access, invited_by, &block).first
258
281
  end
259
282
 
260
283
  def invite_mail!(attributes={}, invited_by=nil, &block)
261
- invitable, mail = _invite(attributes, invited_by, &block)
262
- mail
284
+ _invite(attributes, invited_by, &block).last
263
285
  end
264
286
 
265
287
  # Attempt to find a user by it's invitation_token to set it's password.
@@ -301,6 +323,8 @@ module Devise
301
323
  Devise::Models.config(self, :invitation_limit)
302
324
  Devise::Models.config(self, :invite_key)
303
325
  Devise::Models.config(self, :resend_invitation)
326
+ Devise::Models.config(self, :allow_insecure_sign_in_after_accept)
327
+
304
328
  end
305
329
  end
306
330
  end
@@ -20,7 +20,7 @@ module DeviseInvitable
20
20
  def attributes_for_with_invitable(kind)
21
21
  case kind
22
22
  when :invite
23
- resource_class.invite_key_fields
23
+ resource_class.respond_to?(:invite_key_fields) ? resource_class.invite_key_fields : []
24
24
  when :accept_invitation
25
25
  [:password, :password_confirmation, :invitation_token]
26
26
  else attributes_for_without_invitable(kind)
@@ -7,12 +7,14 @@ module DeviseInvitable
7
7
 
8
8
  # We use to_prepare instead of after_initialize here because Devise is a Rails engine; its
9
9
  # mailer is reloaded like the rest of the user's app. Got to make sure that our mailer methods
10
- # are included each time Devise::Mailer is (re)loaded.
10
+ # are included each time Devise.mailer is (re)loaded.
11
11
  config.to_prepare do
12
- require 'devise/mailer'
13
- Devise::Mailer.send :include, DeviseInvitable::Mailer
12
+ Devise.mailer.send :include, DeviseInvitable::Mailer
13
+ unless Devise.mailer.ancestors.include?(Devise::Mailers::Helpers)
14
+ Devise.mailer.send :include, Devise::Mailers::Helpers
15
+ end
14
16
  end
15
- # extend mapping with after_initialize becuase is not reloaded
17
+ # extend mapping with after_initialize because it's not reloaded
16
18
  config.after_initialize do
17
19
  Devise::Mapping.send :include, DeviseInvitable::Mapping
18
20
  Devise::ParameterSanitizer.send :include, DeviseInvitable::ParameterSanitizer
@@ -1,3 +1,3 @@
1
1
  module DeviseInvitable
2
- VERSION = '1.3.4'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -66,6 +66,11 @@ module Devise
66
66
  # the #invited_by association is declared without counter_cache. (default: nil)
67
67
  mattr_accessor :invited_by_counter_cache
68
68
  @@invited_by_counter_cache = nil
69
+
70
+ # Public: Auto-login after the user accepts the invite. If this is false,
71
+ # the user will need to manually log in after accepting the invite (default: false).
72
+ mattr_accessor :allow_insecure_sign_in_after_accept
73
+ @@allow_insecure_sign_in_after_accept = true
69
74
  end
70
75
 
71
76
  Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => {:invitation => [nil, :new, :accept]}
@@ -6,7 +6,7 @@ module ActiveRecord
6
6
  source_root File.expand_path("../templates", __FILE__)
7
7
 
8
8
  def copy_devise_migration
9
- migration_template "migration.rb", "db/migrate/devise_invitable_add_to_#{table_name}"
9
+ migration_template "migration.rb", "db/migrate/devise_invitable_add_to_#{table_name}.rb"
10
10
  end
11
11
  end
12
12
  end
@@ -6,10 +6,10 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
6
6
  t.datetime :invitation_sent_at
7
7
  t.datetime :invitation_accepted_at
8
8
  t.integer :invitation_limit
9
- t.references :invited_by, :polymorphic => true
9
+ t.references :invited_by, polymorphic: true
10
10
  t.integer :invitations_count, default: 0
11
11
  t.index :invitations_count
12
- t.index :invitation_token, :unique => true # for invitable
12
+ t.index :invitation_token, unique: true # for invitable
13
13
  t.index :invited_by_id
14
14
  end
15
15
 
@@ -22,8 +22,12 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
22
22
 
23
23
  def down
24
24
  change_table :<%= table_name %> do |t|
25
- t.remove_references :invited_by, :polymorphic => true
25
+ t.remove_references :invited_by, polymorphic: true
26
26
  t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
27
27
  end
28
+ change_column_null :<%= table_name %>, :encrypted_password, false
29
+ <% if class_name.constantize.columns_hash['password_salt'] -%>
30
+ change_column_null :<%= table_name %>, :password_salt,false
31
+ <% end -%>
28
32
  end
29
33
  end
@@ -57,6 +57,11 @@ module DeviseInvitable
57
57
  # Default: nil
58
58
  # config.invited_by_counter_cache = :invitations_count
59
59
 
60
+ # Auto-login after the user accepts the invite. If this is false,
61
+ # the user will need to manually log in after accepting the invite.
62
+ # Default: false
63
+ # config.allow_insecure_sign_in_after_accept = true
64
+
60
65
  CONTENT
61
66
  end
62
67
  end
@@ -1,11 +1,11 @@
1
1
  <h2><%= t 'devise.invitations.edit.header' %></h2>
2
2
 
3
- <%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
3
+ <%= simple_form_for resource, as: resource_name, url: invitation_path(resource_name), html: { method: :put } do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
  <%= f.hidden_field :invitation_token %>
6
6
 
7
7
  <%= f.input :password %>
8
8
  <%= f.input :password_confirmation %>
9
9
 
10
- <%= f.submit t("devise.invitations.edit.submit_button") %>
10
+ <%= f.button :submit, t("devise.invitations.edit.submit_button") %>
11
11
  <% end %>
@@ -1,11 +1,11 @@
1
1
  <h2><%= t "devise.invitations.new.header" %></h2>
2
2
 
3
- <%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
3
+ <%= simple_form_for resource, as: resource_name, url: invitation_path(resource_name), html: { method: :post} do |f| %>
4
4
  <%= devise_error_messages! %>
5
5
 
6
6
  <% resource.class.invite_key_fields.each do |field| -%>
7
7
  <%= f.input field %>
8
8
  <% end -%>
9
9
 
10
- <%= f.submit t("devise.invitations.new.submit_button") %>
10
+ <%= f.button :submit, t("devise.invitations.new.submit_button") %>
11
11
  <% end %>
@@ -4,11 +4,11 @@ class ControllerHelpersTest < ActionController::TestCase
4
4
  tests ApplicationController
5
5
 
6
6
  test "after invite path defaults to after sign in path" do
7
- assert_equal @controller.after_sign_in_path_for(:user), @controller.after_invite_path_for(:user)
7
+ assert_equal @controller.send(:after_sign_in_path_for, :user), @controller.after_invite_path_for(:user)
8
8
  end
9
9
 
10
10
  test "after accept path defaults to after sign in path" do
11
- assert_equal @controller.after_sign_in_path_for(:user), @controller.after_accept_path_for(:user)
11
+ assert_equal @controller.send(:after_sign_in_path_for, :user), @controller.after_accept_path_for(:user)
12
12
  end
13
13
 
14
14
  test 'after invite path is customizable from application controller' do
@@ -36,4 +36,4 @@ class ControllerHelpersTest < ActionController::TestCase
36
36
  assert Devise::InvitationsController.method_defined? :after_accept_path_for
37
37
  assert !Devise::InvitationsController.instance_methods(false).include?(:after_accept_path_for)
38
38
  end
39
- end
39
+ end
@@ -25,7 +25,7 @@ class DeviseInvitable::RegistrationsControllerTest < ActionController::TestCase
25
25
  sign_out @issuer
26
26
 
27
27
  @invitee = User.where(:email => invitee_email).first
28
- assert_blank @invitee.encrypted_password, "the password should be unset"
28
+ assert @invitee.encrypted_password.blank?, "the password should be unset"
29
29
 
30
30
  # sign_up the invitee
31
31
  assert_difference('ActionMailer::Base.deliveries.size') do
@@ -42,13 +42,13 @@ class DeviseInvitable::RegistrationsControllerTest < ActionController::TestCase
42
42
  @invitee.save!
43
43
  end
44
44
 
45
- assert_present @invitee.encrypted_password
45
+ assert @invitee.encrypted_password.present?
46
46
  assert_not_nil @invitee.invitation_accepted_at
47
47
  assert_nil @invitee.invitation_token
48
- assert_present @invitee.invited_by_id
49
- assert_present @invitee.invited_by_type
48
+ assert @invitee.invited_by_id.present?
49
+ assert @invitee.invited_by_type.present?
50
50
  assert !@invitee.confirmed?
51
- assert_present @invitee.confirmation_token
51
+ assert @invitee.confirmation_token.present?
52
52
  end
53
53
 
54
54
  test "not invitable resources can register" do
@@ -58,7 +58,7 @@ class DeviseInvitable::RegistrationsControllerTest < ActionController::TestCase
58
58
  post :create, :admin => {:email => invitee_email, :password => "1password"}
59
59
 
60
60
  @invitee = Admin.where(:email => invitee_email).first
61
- assert_present @invitee.encrypted_password
61
+ assert @invitee.encrypted_password.present?
62
62
  end
63
63
 
64
64
  test "missing params on a create should not cause an error" do
@@ -17,18 +17,18 @@ class GeneratorsTest < ActiveSupport::TestCase
17
17
 
18
18
  test "rails g devise_invitable:install" do
19
19
  @output = `cd #{RAILS_APP_PATH} && rails g devise_invitable:install -p`
20
- assert @output.match(%r{(inject|insert).+ config/initializers/devise\.rb\n})
21
- assert @output.match(%r|create.+ config/locales/devise_invitable\.en\.yml\n|)
20
+ assert @output.match(%r{(inject|insert).* config/initializers/devise\.rb\n})
21
+ assert @output.match(%r|create.* config/locales/devise_invitable\.en\.yml\n|)
22
22
  end
23
23
 
24
24
  test "rails g devise_invitable Octopussy" do
25
25
  @output = `cd #{RAILS_APP_PATH} && rails g devise_invitable Octopussy -p`
26
- assert @output.match(%r{(inject|insert).+ app/models/octopussy\.rb\n})
27
- assert @output.match(%r|invoke.+ #{DEVISE_ORM}\n|)
26
+ assert @output.match(%r{(inject|insert).* app/models/octopussy\.rb\n})
27
+ assert @output.match(%r|invoke.* #{DEVISE_ORM}\n|)
28
28
  if DEVISE_ORM == :active_record
29
- assert @output.match(%r|create.+ db/migrate/\d{14}_devise_invitable_add_to_octopussies\.rb\n|)
29
+ assert @output.match(%r|create.* db/migrate/\d{14}_devise_invitable_add_to_octopussies\.rb\n|)
30
30
  elsif DEVISE_ORM == :mongoid
31
- assert !@output.match(%r|create.+ db/migrate/\d{14}_devise_invitable_add_to_octopussies\.rb\n|)
31
+ assert !@output.match(%r|create.* db/migrate/\d{14}_devise_invitable_add_to_octopussies\.rb\n|)
32
32
  end
33
33
  end
34
34
  end
@@ -4,7 +4,7 @@ require 'integration_tests_helper'
4
4
  class InvitationRemoveTest < ActionDispatch::IntegrationTest
5
5
 
6
6
  test 'invited user can choose to remove his account/invite' do
7
- user = User.invite!(:email => "valid@email.com")
7
+ User.invite!(:email => "valid@email.com")
8
8
 
9
9
  # remove!
10
10
  visit remove_user_invitation_path(:invitation_token => Thread.current[:token])
@@ -64,6 +64,25 @@ class InvitationTest < ActionDispatch::IntegrationTest
64
64
  assert_equal root_path, current_path
65
65
  end
66
66
 
67
+ test 'invited user without password should not be able to sign in' do
68
+ user = User.invite!(:email => "valid@email.com")
69
+ user.password = 'test'
70
+ sign_in_as_user user
71
+
72
+ assert_equal new_user_session_path, current_path
73
+ assert page.has_css?('p#alert', :text => 'You have a pending invitation, accept it to finish creating your account.')
74
+ end
75
+
76
+ test 'invited user with password should not be able to sign in' do
77
+ user = User.invite!(:email => "valid@email.com")
78
+ user.password = '987654321'
79
+ user.save
80
+ sign_in_as_user user
81
+
82
+ assert_equal new_user_session_path, current_path
83
+ assert page.has_css?('p#alert', :text => 'You have a pending invitation, accept it to finish creating your account.')
84
+ end
85
+
67
86
  test 'not authenticated user with invalid invitation token should not be able to set his password' do
68
87
  user = User.invite!(:email => "valid@email.com")
69
88
  user.accept_invitation!
@@ -80,7 +99,7 @@ class InvitationTest < ActionDispatch::IntegrationTest
80
99
  end
81
100
  assert_equal user_invitation_path, current_path
82
101
  assert page.has_css?('#error_explanation li', :text => /Password .*doesn\'t match/)
83
- assert_blank user.encrypted_password
102
+ assert user.encrypted_password.blank?
84
103
  end
85
104
 
86
105
  test 'not authenticated user with valid data should be able to change his password' do
@@ -99,17 +118,33 @@ class InvitationTest < ActionDispatch::IntegrationTest
99
118
  end
100
119
  assert_equal user_invitation_path, current_path
101
120
  assert page.has_css?('#error_explanation')
102
- assert_blank user.encrypted_password
121
+ assert user.encrypted_password.blank?
103
122
 
104
123
  set_password :visit => false
105
124
  assert page.has_css?('p#notice', :text => 'Your password was set successfully. You are now signed in.')
106
125
  assert user.reload.valid_password?('987654321')
107
126
  end
108
127
 
109
- test 'sign in user automatically after setting it\'s password' do
110
- user = User.invite!(:email => "valid@email.com")
128
+ test 'sign in user automatically after setting it\'s password if config.allow_insecure_sign_in_after_accept is true' do
129
+ original_option_value = Devise.allow_insecure_sign_in_after_accept
130
+ Devise.allow_insecure_sign_in_after_accept = true
131
+
132
+ User.invite!(:email => "valid@email.com")
111
133
  set_password :invitation_token => Thread.current[:token]
134
+
112
135
  assert_equal root_path, current_path
136
+ Devise.allow_insecure_sign_in_after_accept = original_option_value
137
+ end
138
+
139
+ test 'does not sign in user automatically after setting it\'s password if config.allow_insecure_sign_in_after_accept is false' do
140
+ original_option_value = Devise.allow_insecure_sign_in_after_accept
141
+ Devise.allow_insecure_sign_in_after_accept = false
142
+
143
+ User.invite!(:email => "valid@email.com")
144
+ set_password :invitation_token => Thread.current[:token]
145
+
146
+ assert_equal new_user_session_path, current_path
147
+ Devise.allow_insecure_sign_in_after_accept = original_option_value
113
148
  end
114
149
 
115
150
  test 'clear token and set invitation_accepted_at after recover password instead of accept_invitation' do
@@ -213,10 +248,20 @@ class InvitationTest < ActionDispatch::IntegrationTest
213
248
  end
214
249
 
215
250
  test 'authenticated admin should be able to send an admin invitation' do
216
- sign_in_as_user Admin.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
251
+ admin = Admin.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
252
+ sign_in_as_user admin
217
253
 
218
254
  send_invitation new_admin_path
219
- assert_equal root_path, current_path
255
+ assert_equal edit_admin_registration_path(admin), current_path
256
+ assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
257
+ end
258
+
259
+ test 'authenticated admin should be redirected to own page after send a free invitation' do
260
+ admin = Admin.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
261
+ sign_in_as_user admin
262
+
263
+ send_invitation new_free_invitation_path
264
+ assert_equal edit_admin_registration_path(admin), current_path
220
265
  assert page.has_css?('p#notice', :text => 'An invitation email has been sent to user@test.com.')
221
266
  end
222
267
  end
@@ -1,9 +1,9 @@
1
- class ActionController::IntegrationTest
1
+ class ActionDispatch::IntegrationTest
2
2
 
3
3
  def warden
4
4
  request.env['warden']
5
5
  end
6
-
6
+
7
7
  def create_full_user
8
8
  @user ||= begin
9
9
  user = User.create!(
@@ -24,7 +24,7 @@ class ActionController::IntegrationTest
24
24
  visit send("new_#{resource_name}_session_path")
25
25
  fill_in "#{resource_name}_email", :with => user.email
26
26
  fill_in "#{resource_name}_password", :with => user.password
27
- click_button 'Sign in'
27
+ click_button 'Log in'
28
28
  end
29
29
 
30
30
  # Fix assert_redirect_to in integration sessions because they don't take into
@@ -28,14 +28,40 @@ class InvitableTest < ActiveSupport::TestCase
28
28
  test 'should regenerate invitation token each time' do
29
29
  user = new_user
30
30
  user.invite!
31
- token = user.invitation_token
31
+
32
32
  assert_not_nil user.invitation_token
33
+ assert_not_nil user.raw_invitation_token
33
34
  assert_not_nil user.invitation_created_at
35
+
34
36
  3.times do
35
37
  user = User.find(user.id)
36
- user.invite!
37
- assert_not_equal token, user.invitation_token
38
- token = user.invitation_token
38
+
39
+ assert_not_same user.invitation_token, lambda {
40
+ user.invite!
41
+ user.invitation_token
42
+ }.call
43
+ assert_not_nil user.raw_invitation_token
44
+ end
45
+ end
46
+
47
+ test 'should regenerate invitation token each time even if "skip_invitation" was true' do
48
+ user = new_user
49
+ user.skip_invitation = true
50
+ user.invite!
51
+
52
+ assert_not_nil user.invitation_token
53
+ assert_not_nil user.invitation_created_at
54
+
55
+ 3.times do
56
+ user = User.find(user.id)
57
+ user.skip_invitation = true
58
+
59
+ assert_not_same user.invitation_token, lambda {
60
+ user.invite!
61
+ user.invitation_token
62
+ }.call
63
+ assert_not_nil user.invitation_token
64
+ assert_not_nil user.raw_invitation_token
39
65
  end
40
66
  end
41
67
 
@@ -143,7 +169,7 @@ class InvitableTest < ActiveSupport::TestCase
143
169
  end
144
170
 
145
171
  test 'should set password and password confirmation from params' do
146
- invited_user = User.invite!(:email => "valid@email.com")
172
+ User.invite!(:email => "valid@email.com")
147
173
  user = User.accept_invitation!(:invitation_token => Thread.current[:token], :password => '123456789', :password_confirmation => '123456789')
148
174
  assert user.valid_password?('123456789')
149
175
  end
@@ -157,21 +183,21 @@ class InvitableTest < ActiveSupport::TestCase
157
183
 
158
184
  test 'should clear invitation token and set invitation_accepted_at while accepting the password' do
159
185
  user = User.invite!(:email => "valid@email.com")
160
- assert_present user.invitation_token
186
+ assert user.invitation_token.present?
161
187
  assert_nil user.invitation_accepted_at
162
188
  user.accept_invitation!
163
189
  user.reload
164
190
  assert_nil user.invitation_token
165
- assert_present user.invitation_accepted_at
191
+ assert user.invitation_accepted_at.present?
166
192
  end
167
193
 
168
194
  test 'should not clear invitation token or set accepted_at if record is invalid' do
169
195
  user = User.invite!(:email => "valid@email.com")
170
- assert_present user.invitation_token
196
+ assert user.invitation_token.present?
171
197
  assert_nil user.invitation_accepted_at
172
198
  User.accept_invitation!(:invitation_token => user.invitation_token, :password => '123456789', :password_confirmation => '987654321')
173
199
  user.reload
174
- assert_present user.invitation_token
200
+ assert user.invitation_token.present?
175
201
  assert_nil user.invitation_accepted_at
176
202
  end
177
203
 
@@ -182,8 +208,8 @@ class InvitableTest < ActiveSupport::TestCase
182
208
  user.reset_password_sent_at = Time.now.utc
183
209
  user.save
184
210
 
185
- assert_present user.reset_password_token
186
- assert_present user.invitation_token
211
+ assert user.reset_password_token.present?
212
+ assert user.invitation_token.present?
187
213
  User.reset_password_by_token(:reset_password_token => token, :password => '123456789', :password_confirmation => '123456789')
188
214
  assert_nil user.reload.reset_password_token
189
215
  assert_nil user.reload.invitation_token
@@ -197,11 +223,11 @@ class InvitableTest < ActiveSupport::TestCase
197
223
  user.reset_password_sent_at = Time.now.utc
198
224
  user.save
199
225
 
200
- assert_present user.reset_password_token
201
- assert_present user.invitation_token
226
+ assert user.reset_password_token.present?
227
+ assert user.invitation_token.present?
202
228
  User.reset_password_by_token(:reset_password_token => token, :password => '123456789', :password_confirmation => '12345678')
203
- assert_present user.reload.reset_password_token
204
- assert_present user.reload.invitation_token
229
+ assert user.reload.reset_password_token.present?
230
+ assert user.reload.invitation_token.present?
205
231
  assert user.invited_to_sign_up?
206
232
  end
207
233
 
@@ -212,7 +238,7 @@ class InvitableTest < ActiveSupport::TestCase
212
238
  user.reset_password_sent_at = Time.now.utc
213
239
  user.save
214
240
 
215
- assert_present user.reset_password_token
241
+ assert user.reset_password_token.present?
216
242
  assert_nil user.invitation_token
217
243
  User.reset_password_by_token(:reset_password_token => token, :password => '123456789', :password_confirmation => '123456789')
218
244
  assert_nil user.reload.invitation_token
@@ -231,7 +257,7 @@ class InvitableTest < ActiveSupport::TestCase
231
257
  test 'should return a record with invitation token and no errors to send invitation by email' do
232
258
  invited_user = User.invite!(:email => "valid@email.com")
233
259
  assert invited_user.errors.blank?
234
- assert_present invited_user.invitation_token
260
+ assert invited_user.invitation_token.present?
235
261
  assert_equal 'valid@email.com', invited_user.email
236
262
  assert invited_user.persisted?
237
263
  end
@@ -380,7 +406,7 @@ class InvitableTest < ActiveSupport::TestCase
380
406
  user = new_user(:password => nil, :password_confirmation => nil)
381
407
  user.invite!
382
408
 
383
- invited_user = User.accept_invitation!(
409
+ User.accept_invitation!(
384
410
  :invitation_token => Thread.current[:token],
385
411
  :password => 'new_password',
386
412
  :password_confirmation => 'new_password'
@@ -405,6 +431,21 @@ class InvitableTest < ActiveSupport::TestCase
405
431
  user.reload
406
432
  assert !user.valid_password?('new_password')
407
433
  end
434
+
435
+ test 'should check if created by invitation' do
436
+ user = User.invite!(:email => "valid@email.com")
437
+ assert user.created_by_invite?
438
+
439
+ invited_user = User.accept_invitation!(
440
+ :invitation_token => Thread.current[:token],
441
+ :password => 'new_password',
442
+ :password_confirmation => 'new_password',
443
+ :username => 'a'
444
+ )
445
+ user.reload
446
+ assert user.created_by_invite?
447
+ end
448
+
408
449
 
409
450
  test 'should set other attributes on accepting invitation' do
410
451
  user = new_user(:password => nil, :password_confirmation => nil)
@@ -454,13 +495,13 @@ class InvitableTest < ActiveSupport::TestCase
454
495
 
455
496
  test 'should not send an invitation if we want to skip the invitation' do
456
497
  assert_no_difference('ActionMailer::Base.deliveries.size') do
457
- invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50, :skip_invitation => true)
498
+ User.invite!(:email => "valid@email.com", :username => "a"*50, :skip_invitation => true)
458
499
  end
459
500
  end
460
501
 
461
502
  test 'should not send an invitation if we want to skip the invitation with block' do
462
503
  assert_no_difference('ActionMailer::Base.deliveries.size') do
463
- invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50) do |u|
504
+ User.invite!(:email => "valid@email.com", :username => "a"*50) do |u|
464
505
  u.skip_invitation = true
465
506
  end
466
507
  end
@@ -472,7 +513,18 @@ class InvitableTest < ActiveSupport::TestCase
472
513
  assert_no_difference('ActionMailer::Base.deliveries.size') do
473
514
  user.invite!
474
515
  end
475
- assert_present user.invitation_created_at
516
+ assert user.invitation_created_at.present?
517
+ assert_nil user.invitation_sent_at
518
+ end
519
+
520
+ test 'user.invite! should not send an invitation if we want to skip the invitation with block' do
521
+ user = new_user
522
+ assert_no_difference('ActionMailer::Base.deliveries.size') do
523
+ user.invite! do |u|
524
+ u.skip_invitation = true
525
+ end
526
+ end
527
+ assert user.invitation_created_at.present?
476
528
  assert_nil user.invitation_sent_at
477
529
  end
478
530
 
@@ -569,24 +621,28 @@ class InvitableTest < ActiveSupport::TestCase
569
621
  end
570
622
 
571
623
  test 'should return instance with errors if invitation_token is nil' do
572
- registered_user = User.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
624
+ User.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
573
625
  user = User.accept_invitation!
574
626
  assert !user.errors.empty?
575
627
  end
576
628
 
577
- test "should count accepted and not accepted invitations" do
629
+ test "should count invited, created_by_invite, accepted and not accepted invitations" do
578
630
  assert_equal 0, User.invitation_not_accepted.count
579
631
  assert_equal 0, User.invitation_accepted.count
632
+ assert_equal 0, User.created_by_invite.count
580
633
 
581
634
  User.invite!(:email => "invalid@email.com")
635
+ User.invite!(:email => "another_invalid@email.com")
582
636
  user = User.invite!(:email => "valid@email.com")
583
637
 
584
- assert_equal 2, User.invitation_not_accepted.count
638
+ assert_equal 3, User.invitation_not_accepted.count
585
639
  assert_equal 0, User.invitation_accepted.count
640
+ assert_equal 3, User.created_by_invite.count
586
641
 
587
642
  user.accept_invitation!
588
- assert_equal 1, User.invitation_not_accepted.count
643
+ assert_equal 2, User.invitation_not_accepted.count
589
644
  assert_equal 1, User.invitation_accepted.count
645
+ assert_equal 3, User.created_by_invite.count
590
646
  end
591
647
 
592
648
  test "should preserve return values of Devise::Recoverable#reset_password!" do
@@ -3,6 +3,13 @@ class ApplicationController < ActionController::Base
3
3
  before_filter :configure_permitted_parameters, :if => :devise_controller?
4
4
 
5
5
  protected
6
+ def after_sign_in_path_for(resource)
7
+ if resource.is_a? Admin
8
+ edit_admin_registration_path(resource)
9
+ else
10
+ super
11
+ end
12
+ end
6
13
 
7
14
  def configure_permitted_parameters
8
15
  devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :bio) } if defined?(ActionController::StrongParameters)
@@ -3,4 +3,10 @@ class FreeInvitationsController < Devise::InvitationsController
3
3
  def authenticate_inviter!
4
4
  # everyone can invite
5
5
  end
6
+ def current_inviter
7
+ current_admin || current_user
8
+ end
9
+ def after_invite_path_for(resource)
10
+ resource ? super : root_path
11
+ end
6
12
  end
@@ -0,0 +1,17 @@
1
+ <h2>Log in</h2>
2
+
3
+ <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
+ <div><%= f.label :email %><br />
5
+ <%= f.email_field :email, autofocus: true %></div>
6
+
7
+ <div><%= f.label :password %><br />
8
+ <%= f.password_field :password, autocomplete: "off" %></div>
9
+
10
+ <% if devise_mapping.rememberable? -%>
11
+ <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
12
+ <% end -%>
13
+
14
+ <div><%= f.submit "Log in" %></div>
15
+ <% end %>
16
+
17
+ <%= render "devise/shared/links" %>
@@ -129,6 +129,11 @@ Devise.setup do |config|
129
129
  # Default: nil
130
130
  config.invited_by_counter_cache = :invitations_count
131
131
 
132
+ # Auto-login after the user accepts the invite. If this is false,
133
+ # the user will need to manually log in after accepting the invite.
134
+ # Default: true
135
+ # config.allow_insecure_sign_in_after_accept = false
136
+
132
137
  # ==> Configuration for :confirmable
133
138
  # A period that the user is allowed to access the website even without
134
139
  # confirming his account. For instance, if set to 2.days, the user will be
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_invitable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio Cambra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-27 00:00:00.000000000 Z
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,9 @@ executables: []
66
66
  extensions: []
67
67
  extra_rdoc_files: []
68
68
  files:
69
+ - CHANGELOG
70
+ - LICENSE
71
+ - README.rdoc
69
72
  - app/controllers/devise/invitations_controller.rb
70
73
  - app/controllers/devise_invitable/registrations_controller.rb
71
74
  - app/views/devise/invitations/edit.html.erb
@@ -90,9 +93,6 @@ files:
90
93
  - lib/generators/devise_invitable/templates/simple_form_for/invitations/new.html.erb
91
94
  - lib/generators/devise_invitable/views_generator.rb
92
95
  - lib/generators/mongoid/devise_invitable_generator.rb
93
- - LICENSE
94
- - README.rdoc
95
- - CHANGELOG
96
96
  - test/functional/controller_helpers_test.rb
97
97
  - test/functional/registrations_controller_test.rb
98
98
  - test/generators/views_generator_test.rb
@@ -117,6 +117,7 @@ files:
117
117
  - test/rails_app/app/models/octopussy.rb
118
118
  - test/rails_app/app/models/user.rb
119
119
  - test/rails_app/app/views/admins/new.html.erb
120
+ - test/rails_app/app/views/devise/sessions/new.html.erb
120
121
  - test/rails_app/app/views/free_invitations/new.html.erb
121
122
  - test/rails_app/app/views/home/index.html.erb
122
123
  - test/rails_app/app/views/layouts/application.html.erb
@@ -167,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
168
  version: 1.3.6
168
169
  requirements: []
169
170
  rubyforge_project:
170
- rubygems_version: 2.1.11
171
+ rubygems_version: 2.4.5
171
172
  signing_key:
172
173
  specification_version: 4
173
174
  summary: An invitation strategy for Devise
@@ -196,6 +197,7 @@ test_files:
196
197
  - test/rails_app/app/models/octopussy.rb
197
198
  - test/rails_app/app/models/user.rb
198
199
  - test/rails_app/app/views/admins/new.html.erb
200
+ - test/rails_app/app/views/devise/sessions/new.html.erb
199
201
  - test/rails_app/app/views/free_invitations/new.html.erb
200
202
  - test/rails_app/app/views/home/index.html.erb
201
203
  - test/rails_app/app/views/layouts/application.html.erb