devise_invitable 1.5.5 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of devise_invitable might be problematic. Click here for more details.
- checksums.yaml +7 -7
- data/CHANGELOG +15 -0
- data/README.rdoc +23 -12
- data/app/controllers/devise/invitations_controller.rb +14 -5
- data/app/views/devise/invitations/edit.html.erb +2 -0
- data/app/views/devise/mailer/invitation_instructions.text.erb +11 -0
- data/config/locales/en.yml +1 -1
- data/lib/devise_invitable.rb +7 -1
- data/lib/devise_invitable/mapping.rb +3 -7
- data/lib/devise_invitable/model.rb +45 -12
- data/lib/devise_invitable/parameter_sanitizer.rb +27 -19
- data/lib/devise_invitable/rails.rb +2 -2
- data/lib/devise_invitable/version.rb +1 -1
- data/lib/generators/devise_invitable/install_generator.rb +2 -2
- data/test/mailers/invitation_mail_test.rb +20 -6
- data/test/models/invitable_test.rb +90 -62
- data/test/rails_app/app/models/user.rb +8 -3
- data/test/rails_app/config/application.rb +5 -1
- data/test/rails_app/config/database.yml +2 -1
- data/test/rails_app/config/environments/test.rb +2 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +51 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1c29d1de12fe88af51d1a7e23efd9829db040271
|
4
|
+
data.tar.gz: e4ea042b56eac21a082f284d66b2f0d129555a83
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d11eadb4b2f24ca4500a85fbb7c0636c7cca291f2b43dd9af7321bce5a88942e286fe2412ad4a51ae1556cf4441f7244e8910ccac189751a8b073a54510a1335
|
7
|
+
data.tar.gz: a1e51d0f15d30630bbf44f04d1ef7fcabc279ea405f931a0ef390939bfd5ce71d3dc117a178f927d081634344aba03eb96904f04199bbf53558b05d3f6d18351
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
= 1.6.0
|
2
|
+
|
3
|
+
- Support devise 4.0 and rails 5.0
|
4
|
+
- Add before/after invitation_created callbacks
|
5
|
+
- Fix invitation_due_at when invite_for is 0
|
6
|
+
- Add plain text mailer template
|
7
|
+
- Ruby 1.9 not supported anymore
|
8
|
+
- Adds :require_password_on_accepting config option, and ensure invitation is not accepted if password is required and removed from form
|
9
|
+
|
10
|
+
= 1.5.5
|
11
|
+
|
12
|
+
- Add optional options hash to invite! methods, they will be used for send_devise_notification call
|
13
|
+
|
14
|
+
= 1.5.4
|
15
|
+
|
1
16
|
- Ensure that all invited user passwords conform to a format
|
2
17
|
- Call set_minimum_password_length (if exists) on accept invitation as devise does
|
3
18
|
- Controllers inheriting from Devise::InvitationsController will now use 'devise.invitations' translations
|
data/README.rdoc
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
= DeviseInvitable
|
2
|
-
{<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[https://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]
|
2
|
+
{<img src="https://badge.fury.io/rb/devise_invitable.svg"/>}[http://badge.fury.io/rb/devise_invitable] {<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[https://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[https://github.com/plataformatec/devise] for sending invitations by email (it requires to be authenticated) and accept the invitation setting the password.
|
5
5
|
|
6
6
|
DeviseInvitable currently supports Rails 3 and 4, if you want to use it with Rails 2.3 you must install version {0.2.3}[https://rubygems.org/gems/devise_invitable/versions/0.2.3]
|
7
7
|
|
8
|
-
|
8
|
+
It works with Devise >= 3.2
|
9
|
+
If you want to use devise 3.0.x, you must use 1.2.1 or lower
|
10
|
+
If you want to use devise 3.1.x, you must use 1.3.2 or lower
|
9
11
|
|
10
12
|
== Installation
|
11
13
|
|
@@ -130,12 +132,16 @@ or directly as parameters to the <tt>devise</tt> method:
|
|
130
132
|
|
131
133
|
* resend_invitation: resend invitation if user with invited status is invited again. Enabled by default.
|
132
134
|
|
133
|
-
* invited_by_class_name:
|
135
|
+
* invited_by_class_name: the class name of the inviting model. If this is nil, polymorphic association is used.
|
134
136
|
|
135
|
-
* invited_by_foreign_key:
|
137
|
+
* invited_by_foreign_key: the foreign key to the inviting model (only used if invited_by_class_name is set, otherwise :invited_by_id)
|
138
|
+
|
139
|
+
* invited_by_counter_cache: the column name used for counter_cache column. If this is nil (default value), the invited_by association is declared without counter_cache.
|
136
140
|
|
137
141
|
* allow_insecure_sign_in_after_accept: automatically sign in the user after they set a password. Enabled by default.
|
138
142
|
|
143
|
+
* require_password_on_accepting: require password when user accepts the invitation. Enabled by default. Disable if you don't want to ask or enforce to set password while accepting, because is set when user is invited or it will be set later.
|
144
|
+
|
139
145
|
For more details, see <tt>config/initializers/devise.rb</tt> (after you invoked the "devise_invitable:install" generator described above).
|
140
146
|
|
141
147
|
== Configuring views
|
@@ -160,7 +166,7 @@ To change the controller's behavior, create a controller that inherits from <tt>
|
|
160
166
|
|
161
167
|
class Users::InvitationsController < Devise::InvitationsController
|
162
168
|
def update
|
163
|
-
if
|
169
|
+
if some_condition
|
164
170
|
redirect_to root_path
|
165
171
|
else
|
166
172
|
super
|
@@ -174,7 +180,7 @@ Now just tell Devise that you want to use your controller, the controller above
|
|
174
180
|
|
175
181
|
be sure that you generate the views and put them into the controller that you generated, so for this example it would be:
|
176
182
|
|
177
|
-
rails generate devise_invitable:views users
|
183
|
+
rails generate devise_invitable:views users
|
178
184
|
|
179
185
|
To change behaviour of inviting or accepting users, you can simply override two methods:
|
180
186
|
|
@@ -265,7 +271,7 @@ To check if a particular user is created by invitation, irrespective to state of
|
|
265
271
|
|
266
272
|
**Warning**
|
267
273
|
|
268
|
-
When using skip_invitation you must send the email with the user object instance that generated the tokens, as
|
274
|
+
When using skip_invitation you must send the email with the user object instance that generated the tokens, as
|
269
275
|
user.raw_invitation_token is available only to the instance and is not persisted in the database.
|
270
276
|
|
271
277
|
You can send an invitation to an existing user if your workflow creates them separately:
|
@@ -287,12 +293,17 @@ To accept an invitation with a token use the <tt>accept_invitation!</tt> class m
|
|
287
293
|
|
288
294
|
=== Callbacks
|
289
295
|
|
290
|
-
A callback event is fired before and after an invitation is accepted (User#accept_invitation!). For example, in your resource model you can add:
|
296
|
+
A callback event is fired before and after an invitation is created (User#invite!) or accepted (User#accept_invitation!). For example, in your resource model you can add:
|
291
297
|
|
298
|
+
before_invitation_created :email_admins
|
292
299
|
after_invitation_accepted :email_invited_by
|
293
300
|
|
301
|
+
def email_admins
|
302
|
+
# ...
|
303
|
+
end
|
304
|
+
|
294
305
|
def email_invited_by
|
295
|
-
|
306
|
+
# ...
|
296
307
|
end
|
297
308
|
|
298
309
|
The callbacks support all options and arguments available to the standard callbacks provided by AR.
|
@@ -303,7 +314,7 @@ A pair of scopes to find those users that have accepted, and those that have not
|
|
303
314
|
|
304
315
|
User.invitation_accepted # => returns all Users for whom the invitation_accepted_at attribute is not nil
|
305
316
|
User.invitation_not_accepted # => returns all Users for whom the invitation_accepted_at attribute is nil
|
306
|
-
User.created_by_invite # => returns all Users who are created by invitations, irrespective to invitation status
|
317
|
+
User.created_by_invite # => returns all Users who are created by invitations, irrespective to invitation status
|
307
318
|
|
308
319
|
== Integration in a Rails application
|
309
320
|
|
@@ -398,9 +409,9 @@ https://github.com/scambra/devise_invitable/wiki
|
|
398
409
|
|
399
410
|
== Testing
|
400
411
|
|
401
|
-
To test DeviseInvitable for the ActiveRecord ORM with RVM, Ruby
|
412
|
+
To test DeviseInvitable for the ActiveRecord ORM with RVM, Ruby 2.0.0:
|
402
413
|
|
403
|
-
rvm use
|
414
|
+
rvm use 2.0.0
|
404
415
|
rvm gemset create devise_invitable
|
405
416
|
rvm gemset use devise_invitable
|
406
417
|
gem install bundler
|
@@ -1,10 +1,19 @@
|
|
1
1
|
class Devise::InvitationsController < DeviseController
|
2
|
+
if Rails::VERSION::MAJOR >= 5
|
3
|
+
prepend_before_action :authenticate_inviter!, :only => [:new, :create]
|
4
|
+
prepend_before_action :has_invitations_left?, :only => [:create]
|
5
|
+
prepend_before_action :require_no_authentication, :only => [:edit, :update, :destroy]
|
6
|
+
prepend_before_action :resource_from_invitation_token, :only => [:edit, :destroy]
|
7
|
+
else
|
8
|
+
prepend_before_filter :authenticate_inviter!, :only => [:new, :create]
|
9
|
+
prepend_before_filter :has_invitations_left?, :only => [:create]
|
10
|
+
prepend_before_filter :require_no_authentication, :only => [:edit, :update, :destroy]
|
11
|
+
prepend_before_filter :resource_from_invitation_token, :only => [:edit, :destroy]
|
12
|
+
end
|
2
13
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
prepend_before_filter :resource_from_invitation_token, :only => [:edit, :destroy]
|
7
|
-
helper_method :after_sign_in_path_for
|
14
|
+
if respond_to? :helper_method
|
15
|
+
helper_method :after_sign_in_path_for
|
16
|
+
end
|
8
17
|
|
9
18
|
# GET /resource/invitation/new
|
10
19
|
def new
|
@@ -4,11 +4,13 @@
|
|
4
4
|
<%= devise_error_messages! %>
|
5
5
|
<%= f.hidden_field :invitation_token %>
|
6
6
|
|
7
|
+
<% if f.object.class.require_password_on_accepting %>
|
7
8
|
<p><%= f.label :password %><br />
|
8
9
|
<%= f.password_field :password %></p>
|
9
10
|
|
10
11
|
<p><%= f.label :password_confirmation %><br />
|
11
12
|
<%= f.password_field :password_confirmation %></p>
|
13
|
+
<% end %>
|
12
14
|
|
13
15
|
<p><%= f.submit t("devise.invitations.edit.submit_button") %></p>
|
14
16
|
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %>
|
2
|
+
|
3
|
+
<%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %>
|
4
|
+
|
5
|
+
<%= accept_invitation_url(@resource, :invitation_token => @token) %>
|
6
|
+
|
7
|
+
<% if @resource.invitation_due_at %>
|
8
|
+
<%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= strip_tags t("devise.mailer.invitation_instructions.ignore") %>
|
data/config/locales/en.yml
CHANGED
@@ -22,7 +22,7 @@ en:
|
|
22
22
|
someone_invited_you: "Someone has invited you to %{url}, you can accept it through the link below."
|
23
23
|
accept: "Accept invitation"
|
24
24
|
accept_until: "This invitation will be due in %{due_date}."
|
25
|
-
ignore: "If you don't want to accept the invitation, please ignore this email.<br
|
25
|
+
ignore: "If you don't want to accept the invitation, please ignore this email.<br />\nYour account won't be created until you access the link above and set your password."
|
26
26
|
time:
|
27
27
|
formats:
|
28
28
|
devise:
|
data/lib/devise_invitable.rb
CHANGED
@@ -72,10 +72,16 @@ module Devise
|
|
72
72
|
mattr_accessor :invited_by_counter_cache
|
73
73
|
@@invited_by_counter_cache = nil
|
74
74
|
|
75
|
-
# Public: Auto-login after the user accepts the
|
75
|
+
# Public: Auto-login after the user accepts the invitation. If this is false,
|
76
76
|
# the user will need to manually log in after accepting the invite (default: true).
|
77
77
|
mattr_accessor :allow_insecure_sign_in_after_accept
|
78
78
|
@@allow_insecure_sign_in_after_accept = true
|
79
|
+
|
80
|
+
# Public: Require password when user accepts the invitation. Set to false if
|
81
|
+
# you don't want to ask or enforce to set password while accepting, because is
|
82
|
+
# set when user is invited or it will be set later (default: true).
|
83
|
+
mattr_accessor :require_password_on_accepting
|
84
|
+
@@require_password_on_accepting = true
|
79
85
|
end
|
80
86
|
|
81
87
|
Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => {:invitation => [nil, :new, :accept]}
|
@@ -1,14 +1,10 @@
|
|
1
1
|
module DeviseInvitable
|
2
2
|
module Mapping
|
3
|
-
def self.included(base)
|
4
|
-
base.alias_method_chain :default_controllers, :invitable
|
5
|
-
end
|
6
|
-
|
7
3
|
private
|
8
|
-
def
|
4
|
+
def default_controllers(options)
|
9
5
|
options[:controllers] ||= {}
|
10
6
|
options[:controllers][:registrations] ||= "devise_invitable/registrations"
|
11
|
-
|
7
|
+
super
|
12
8
|
end
|
13
9
|
end
|
14
|
-
end
|
10
|
+
end
|
@@ -40,10 +40,12 @@ module Devise
|
|
40
40
|
if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && self < ActiveRecord::Base
|
41
41
|
counter_cache = Devise.invited_by_counter_cache
|
42
42
|
belongs_to_options.merge! :counter_cache => counter_cache if counter_cache
|
43
|
+
belongs_to_options.merge! :optional => true if ActiveRecord::VERSION::MAJOR >= 5
|
43
44
|
end
|
44
45
|
belongs_to :invited_by, belongs_to_options
|
45
46
|
|
46
47
|
include ActiveSupport::Callbacks
|
48
|
+
define_callbacks :invitation_created
|
47
49
|
define_callbacks :invitation_accepted
|
48
50
|
|
49
51
|
scope :no_active_invitation, lambda { where(:invitation_token => nil) }
|
@@ -56,7 +58,14 @@ module Devise
|
|
56
58
|
scope :invitation_not_accepted, lambda { where(arel_table[:invitation_token].not_eq(nil)).where(:invitation_accepted_at => nil) }
|
57
59
|
scope :invitation_accepted, lambda { where(arel_table[:invitation_accepted_at].not_eq(nil)) }
|
58
60
|
|
59
|
-
|
61
|
+
callbacks = [
|
62
|
+
:before_invitation_created,
|
63
|
+
:after_invitation_created,
|
64
|
+
:before_invitation_accepted,
|
65
|
+
:after_invitation_accepted,
|
66
|
+
]
|
67
|
+
|
68
|
+
callbacks.each do |callback_method|
|
60
69
|
send callback_method
|
61
70
|
end
|
62
71
|
end
|
@@ -79,6 +88,7 @@ module Devise
|
|
79
88
|
# Accept an invitation by clearing invitation token and and setting invitation_accepted_at
|
80
89
|
# Saves the model and confirms it if model is confirmable, running invitation_accepted callbacks
|
81
90
|
def accept_invitation!
|
91
|
+
@accepting_invitation = true
|
82
92
|
if self.invited_to_sign_up? && self.valid?
|
83
93
|
run_callbacks :invitation_accepted do
|
84
94
|
self.accept_invitation
|
@@ -98,6 +108,11 @@ module Devise
|
|
98
108
|
persisted? && invitation_token.present?
|
99
109
|
end
|
100
110
|
|
111
|
+
# Returns true if accept_invitation! was called
|
112
|
+
def accepting_invitation?
|
113
|
+
@accepting_invitation
|
114
|
+
end
|
115
|
+
|
101
116
|
# Verifies whether a user accepted an invitation (or is accepting it)
|
102
117
|
def invitation_accepted?
|
103
118
|
invitation_accepted_at.present?
|
@@ -121,17 +136,20 @@ module Devise
|
|
121
136
|
|
122
137
|
yield self if block_given?
|
123
138
|
generate_invitation_token if no_token_present_or_skip_invitation?
|
124
|
-
self.invitation_created_at = Time.now.utc
|
125
|
-
self.invitation_sent_at = self.invitation_created_at unless skip_invitation
|
126
|
-
self.invited_by = invited_by if invited_by
|
127
139
|
|
128
|
-
|
129
|
-
|
130
|
-
|
140
|
+
run_callbacks :invitation_created do
|
141
|
+
self.invitation_created_at = Time.now.utc
|
142
|
+
self.invitation_sent_at = self.invitation_created_at unless skip_invitation
|
143
|
+
self.invited_by = invited_by if invited_by
|
131
144
|
|
132
|
-
|
133
|
-
self.
|
134
|
-
|
145
|
+
# Call these before_validate methods since we aren't validating on save
|
146
|
+
self.downcase_keys if new_record_and_responds_to?(:downcase_keys)
|
147
|
+
self.strip_whitespace if new_record_and_responds_to?(:strip_whitespace)
|
148
|
+
|
149
|
+
if save(:validate => false)
|
150
|
+
self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
|
151
|
+
deliver_invitation(options) unless skip_invitation
|
152
|
+
end
|
135
153
|
end
|
136
154
|
end
|
137
155
|
|
@@ -144,7 +162,12 @@ module Devise
|
|
144
162
|
|
145
163
|
# Only verify password when is not invited
|
146
164
|
def valid_password?(password)
|
147
|
-
super unless block_from_invitation?
|
165
|
+
super unless !accepting_invitation? && block_from_invitation?
|
166
|
+
end
|
167
|
+
|
168
|
+
# Enforce password when invitation is being accepted
|
169
|
+
def password_required?
|
170
|
+
(accepting_invitation? && self.class.require_password_on_accepting) || super
|
148
171
|
end
|
149
172
|
|
150
173
|
def unauthenticated_message
|
@@ -180,7 +203,8 @@ module Devise
|
|
180
203
|
end
|
181
204
|
|
182
205
|
def invitation_due_at
|
183
|
-
return nil
|
206
|
+
return nil if (self.class.invite_for == 0 || self.class.invite_for.nil?)
|
207
|
+
#return nil unless self.class.invite_for
|
184
208
|
|
185
209
|
time = self.invitation_created_at || self.invitation_sent_at
|
186
210
|
time + self.class.invite_for
|
@@ -311,6 +335,14 @@ module Devise
|
|
311
335
|
end
|
312
336
|
|
313
337
|
# Callback convenience methods
|
338
|
+
def before_invitation_created(*args, &blk)
|
339
|
+
set_callback(:invitation_created, :before, *args, &blk)
|
340
|
+
end
|
341
|
+
|
342
|
+
def after_invitation_created(*args, &blk)
|
343
|
+
set_callback(:invitation_created, :after, *args, &blk)
|
344
|
+
end
|
345
|
+
|
314
346
|
def before_invitation_accepted(*args, &blk)
|
315
347
|
set_callback(:invitation_accepted, :before, *args, &blk)
|
316
348
|
end
|
@@ -326,6 +358,7 @@ module Devise
|
|
326
358
|
Devise::Models.config(self, :invite_key)
|
327
359
|
Devise::Models.config(self, :resend_invitation)
|
328
360
|
Devise::Models.config(self, :allow_insecure_sign_in_after_accept)
|
361
|
+
Devise::Models.config(self, :require_password_on_accepting)
|
329
362
|
|
330
363
|
private
|
331
364
|
|
@@ -1,29 +1,37 @@
|
|
1
1
|
module DeviseInvitable
|
2
2
|
module ParameterSanitizer
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def accept_invitation
|
8
|
-
permit self.for(:accept_invitation)
|
9
|
-
end
|
3
|
+
if defined?(Devise::BaseSanitizer)
|
4
|
+
def invite
|
5
|
+
permit self.for(:invite)
|
6
|
+
end
|
10
7
|
|
11
|
-
|
12
|
-
|
8
|
+
def accept_invitation
|
9
|
+
permit self.for(:accept_invitation)
|
10
|
+
end
|
13
11
|
end
|
14
12
|
|
15
13
|
private
|
16
|
-
def permit(keys)
|
17
|
-
default_params.permit(*Array(keys))
|
18
|
-
end
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
if defined?(Devise::BaseSanitizer)
|
16
|
+
def permit(keys)
|
17
|
+
default_params.permit(*Array(keys))
|
18
|
+
end
|
19
|
+
|
20
|
+
def attributes_for(kind)
|
21
|
+
case kind
|
22
|
+
when :invite
|
23
|
+
resource_class.respond_to?(:invite_key_fields) ? resource_class.invite_key_fields : []
|
24
|
+
when :accept_invitation
|
25
|
+
[:password, :password_confirmation, :invitation_token]
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
def initialize(resource_class, resource_name, params)
|
32
|
+
super
|
33
|
+
permit(:invite, keys: (resource_class.respond_to?(:invite_key_fields) ? resource_class.invite_key_fields : []) )
|
34
|
+
permit(:accept_invitation, keys: [:password, :password_confirmation, :invitation_token] )
|
27
35
|
end
|
28
36
|
end
|
29
37
|
end
|
@@ -16,8 +16,8 @@ module DeviseInvitable
|
|
16
16
|
end
|
17
17
|
# extend mapping with after_initialize because it's not reloaded
|
18
18
|
config.after_initialize do
|
19
|
-
Devise::Mapping.send :
|
20
|
-
Devise::ParameterSanitizer.send :
|
19
|
+
Devise::Mapping.send :prepend, DeviseInvitable::Mapping
|
20
|
+
Devise::ParameterSanitizer.send :prepend, DeviseInvitable::ParameterSanitizer
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -63,8 +63,8 @@ module DeviseInvitable
|
|
63
63
|
|
64
64
|
# Auto-login after the user accepts the invite. If this is false,
|
65
65
|
# the user will need to manually log in after accepting the invite.
|
66
|
-
# Default:
|
67
|
-
# config.allow_insecure_sign_in_after_accept =
|
66
|
+
# Default: true
|
67
|
+
# config.allow_insecure_sign_in_after_accept = false
|
68
68
|
|
69
69
|
CONTENT
|
70
70
|
end
|
@@ -23,8 +23,8 @@ class InvitationMailTest < ActionMailer::TestCase
|
|
23
23
|
assert_not_nil mail
|
24
24
|
end
|
25
25
|
|
26
|
-
test 'content type should be set to
|
27
|
-
|
26
|
+
test 'content type should be set to multipart' do
|
27
|
+
assert_match /^multipart\/alternative; boundary="[^"]+"; charset=UTF-8/, mail.content_type
|
28
28
|
end
|
29
29
|
|
30
30
|
test 'send invitation to the user email' do
|
@@ -48,30 +48,44 @@ class InvitationMailTest < ActionMailer::TestCase
|
|
48
48
|
end
|
49
49
|
|
50
50
|
test 'body should have user info' do
|
51
|
-
assert_match /#{user.email}/, mail.body.decoded
|
51
|
+
assert_match /#{user.email}/, mail.html_part.body.decoded
|
52
|
+
assert_match /#{user.email}/, mail.text_part.body.decoded
|
52
53
|
end
|
53
54
|
|
54
55
|
test 'body should have link to confirm the account' do
|
55
56
|
host = ActionMailer::Base.default_url_options[:host]
|
56
|
-
body = mail.body.decoded
|
57
|
+
body = mail.html_part.body.decoded
|
57
58
|
invitation_url_regexp = %r{<a href=\"http://#{host}/users/invitation/accept\?invitation_token=#{Thread.current[:token]}">}
|
58
59
|
assert_match invitation_url_regexp, body
|
60
|
+
|
61
|
+
body = mail.text_part.body.decoded
|
62
|
+
invitation_url_regexp = %r{http://#{host}/users/invitation/accept\?invitation_token=#{Thread.current[:token]}}
|
63
|
+
assert_match invitation_url_regexp, body
|
59
64
|
end
|
60
65
|
|
61
66
|
test 'body should have link to confirm the account on resend' do
|
62
67
|
host = ActionMailer::Base.default_url_options[:host]
|
63
68
|
user
|
64
69
|
@user = User.find(user.id).invite!
|
65
|
-
body = mail.body.decoded
|
70
|
+
body = mail.html_part.body.decoded
|
66
71
|
invitation_url_regexp = %r{<a href=\"http://#{host}/users/invitation/accept\?invitation_token=#{Thread.current[:token]}">}
|
67
72
|
assert_match invitation_url_regexp, body
|
73
|
+
|
74
|
+
body = mail.text_part.body.decoded
|
75
|
+
invitation_url_regexp = %r{http://#{host}/users/invitation/accept\?invitation_token=#{Thread.current[:token]}}
|
76
|
+
assert_match invitation_url_regexp, body
|
68
77
|
end
|
69
78
|
|
70
79
|
test 'body should have invitation due date when it exists' do
|
80
|
+
User.stubs(:invite_for => 5)
|
81
|
+
|
71
82
|
host = ActionMailer::Base.default_url_options[:host]
|
72
83
|
user
|
73
|
-
body = mail.body.decoded
|
84
|
+
body = mail.html_part.body.decoded
|
85
|
+
due_date_regexp = %r{#{I18n.l user.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format' }}
|
86
|
+
assert_match due_date_regexp, body
|
74
87
|
|
88
|
+
body = mail.text_part.body.decoded
|
75
89
|
due_date_regexp = %r{#{I18n.l user.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format' }}
|
76
90
|
assert_match due_date_regexp, body
|
77
91
|
end
|
@@ -29,9 +29,9 @@ class InvitableTest < ActiveSupport::TestCase
|
|
29
29
|
user = new_user
|
30
30
|
user.invite!
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
refute_nil user.invitation_token
|
33
|
+
refute_nil user.raw_invitation_token
|
34
|
+
refute_nil user.invitation_created_at
|
35
35
|
|
36
36
|
3.times do
|
37
37
|
user = User.find(user.id)
|
@@ -40,7 +40,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
40
40
|
user.invite!
|
41
41
|
user.invitation_token
|
42
42
|
}.call
|
43
|
-
|
43
|
+
refute_nil user.raw_invitation_token
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -49,8 +49,8 @@ class InvitableTest < ActiveSupport::TestCase
|
|
49
49
|
user.skip_invitation = true
|
50
50
|
user.invite!
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
refute_nil user.invitation_token
|
53
|
+
refute_nil user.invitation_created_at
|
54
54
|
|
55
55
|
3.times do
|
56
56
|
user = User.find(user.id)
|
@@ -60,8 +60,8 @@ class InvitableTest < ActiveSupport::TestCase
|
|
60
60
|
user.invite!
|
61
61
|
user.invitation_token
|
62
62
|
}.call
|
63
|
-
|
64
|
-
|
63
|
+
refute_nil user.invitation_token
|
64
|
+
refute_nil user.raw_invitation_token
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -88,8 +88,8 @@ class InvitableTest < ActiveSupport::TestCase
|
|
88
88
|
user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
|
89
89
|
3.times do
|
90
90
|
user.invite!
|
91
|
-
|
92
|
-
|
91
|
+
refute_equal old_invitation_sent_at, user.invitation_sent_at
|
92
|
+
refute_equal old_invitation_created_at, user.invitation_created_at
|
93
93
|
user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
|
94
94
|
end
|
95
95
|
end
|
@@ -99,31 +99,32 @@ class InvitableTest < ActiveSupport::TestCase
|
|
99
99
|
|
100
100
|
User.stubs(:invite_for).returns(nil)
|
101
101
|
user.invitation_created_at = Time.now.utc
|
102
|
-
|
102
|
+
assert_predicate user, :valid_invitation?
|
103
103
|
|
104
104
|
User.stubs(:invite_for).returns(nil)
|
105
105
|
user.invitation_created_at = 1.year.ago
|
106
|
-
|
106
|
+
assert_predicate user, :valid_invitation?
|
107
107
|
|
108
108
|
User.stubs(:invite_for).returns(0)
|
109
109
|
user.invitation_created_at = Time.now.utc
|
110
|
-
|
110
|
+
assert_predicate user, :valid_invitation?
|
111
111
|
|
112
112
|
User.stubs(:invite_for).returns(0)
|
113
113
|
user.invitation_created_at = 1.day.ago
|
114
|
-
|
114
|
+
assert_predicate user, :valid_invitation?
|
115
115
|
|
116
116
|
User.stubs(:invite_for).returns(1.day)
|
117
117
|
user.invitation_created_at = Time.now.utc
|
118
|
-
|
118
|
+
assert_predicate user, :valid_invitation?
|
119
119
|
|
120
120
|
User.stubs(:invite_for).returns(1.day)
|
121
121
|
user.invitation_created_at = 2.days.ago
|
122
|
-
|
122
|
+
refute_predicate user, :valid_invitation?
|
123
123
|
end
|
124
124
|
|
125
125
|
test 'should return token validity when there is invite_for' do
|
126
126
|
User.stubs(:invite_for).returns(1.day)
|
127
|
+
|
127
128
|
user = User.invite!(:email => "valid@email.com")
|
128
129
|
sent_at = user.invitation_created_at || user.invitation_sent_at
|
129
130
|
valid_until = sent_at + User.invite_for
|
@@ -131,20 +132,27 @@ class InvitableTest < ActiveSupport::TestCase
|
|
131
132
|
assert_equal user.invitation_due_at, valid_until
|
132
133
|
end
|
133
134
|
|
134
|
-
test 'should return nil
|
135
|
+
test 'should return nil for invitation due date when invite_for is nil' do
|
135
136
|
User.stubs(:invite_for).returns(nil)
|
136
137
|
user = User.invite!(:email => "valid@email.com")
|
137
138
|
|
138
139
|
assert_equal user.invitation_due_at, nil
|
139
140
|
end
|
140
141
|
|
142
|
+
test 'should return nil for invitation due date when invite_for is 0' do
|
143
|
+
User.stubs(:invite_for).returns(0)
|
144
|
+
user = User.invite!(email: 'valid@email.com')
|
145
|
+
|
146
|
+
assert_equal user.invitation_due_at, nil
|
147
|
+
end
|
148
|
+
|
141
149
|
test 'should never generate the same invitation token for different users' do
|
142
150
|
invitation_tokens = []
|
143
151
|
3.times do
|
144
152
|
user = new_user
|
145
153
|
user.invite!
|
146
154
|
token = user.invitation_token
|
147
|
-
|
155
|
+
refute_includes invitation_tokens, token
|
148
156
|
invitation_tokens << token
|
149
157
|
end
|
150
158
|
end
|
@@ -152,36 +160,49 @@ class InvitableTest < ActiveSupport::TestCase
|
|
152
160
|
test 'should invite with multiple columns for invite key' do
|
153
161
|
User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
|
154
162
|
user = User.invite!(:email => "valid@email.com", :username => "name")
|
155
|
-
|
156
|
-
|
163
|
+
assert_predicate user, :persisted?
|
164
|
+
assert_empty user.errors
|
157
165
|
end
|
158
166
|
|
159
167
|
test 'should allow non-string columns for invite key' do
|
160
168
|
User.stubs(:invite_key).returns(:email => Devise.email_regexp, :profile_id => :present?.to_proc, :active => true)
|
161
169
|
user = User.invite!(:email => "valid@email.com", :profile_id => 1, :active => true)
|
162
|
-
|
163
|
-
|
170
|
+
assert_predicate user, :persisted?
|
171
|
+
assert_empty user.errors
|
164
172
|
end
|
165
173
|
|
166
174
|
test 'should not invite with some missing columns when invite key is an array' do
|
167
175
|
User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/, :profile_id => :present?.to_proc, :active => true)
|
168
176
|
user = User.invite!(:email => "valid@email.com")
|
169
|
-
|
170
|
-
|
177
|
+
assert_predicate user, :new_record?
|
178
|
+
refute_empty user.errors
|
171
179
|
assert user.errors[:username]
|
172
180
|
assert user.errors[:profile_id]
|
173
181
|
assert user.errors[:active]
|
174
|
-
|
182
|
+
assert_empty user.errors[:email]
|
175
183
|
end
|
176
184
|
|
177
185
|
test 'should return mail object' do
|
178
186
|
mail = User.invite_mail!(:email => 'valid@email.com')
|
179
|
-
|
187
|
+
assert_instance_of Mail::Message, mail
|
180
188
|
end
|
181
189
|
|
182
190
|
test 'should disallow login when invited' do
|
183
191
|
invited_user = User.invite!(:email => "valid@email.com")
|
184
|
-
|
192
|
+
refute invited_user.valid_password?('1234')
|
193
|
+
end
|
194
|
+
|
195
|
+
test 'should not accept invite without password' do
|
196
|
+
user = User.invite!(:email => "valid@email.com")
|
197
|
+
user = User.accept_invitation!(:invitation_token => Thread.current[:token])
|
198
|
+
refute_predicate user, :invitation_accepted?
|
199
|
+
end
|
200
|
+
|
201
|
+
test 'should accept invite without password if enforce is disabled' do
|
202
|
+
Devise.stubs(:require_password_on_accepting => false)
|
203
|
+
user = User.invite!(:email => "valid@email.com")
|
204
|
+
user = User.accept_invitation!(:invitation_token => Thread.current[:token])
|
205
|
+
assert_predicate user, :invitation_accepted?
|
185
206
|
end
|
186
207
|
|
187
208
|
test 'should set password and password confirmation from params' do
|
@@ -194,7 +215,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
194
215
|
user = User.invite!(:email => "valid@email.com")
|
195
216
|
old_encrypted_password = user.encrypted_password
|
196
217
|
user = User.accept_invitation!(:invitation_token => Thread.current[:token], :password => '123456789', :password_confirmation => '123456789')
|
197
|
-
|
218
|
+
refute_equal old_encrypted_password, user.encrypted_password
|
198
219
|
end
|
199
220
|
|
200
221
|
test 'should not override password on invite!' do
|
@@ -236,7 +257,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
236
257
|
User.reset_password_by_token(:reset_password_token => token, :password => '123456789', :password_confirmation => '123456789')
|
237
258
|
assert_nil user.reload.reset_password_token
|
238
259
|
assert_nil user.reload.invitation_token
|
239
|
-
|
260
|
+
refute_predicate user, :invited_to_sign_up?
|
240
261
|
end
|
241
262
|
|
242
263
|
test 'should not accept invitation on failing to reset the password' do
|
@@ -256,7 +277,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
256
277
|
|
257
278
|
test 'should not set invitation_accepted_at if just resetting password' do
|
258
279
|
user = User.create!(:email => "valid@email.com", :password => "123456780")
|
259
|
-
|
280
|
+
refute_predicate user, :invited_to_sign_up?
|
260
281
|
token, user.reset_password_token = Devise.token_generator.generate(User, :reset_password_token)
|
261
282
|
user.reset_password_sent_at = Time.now.utc
|
262
283
|
user.save
|
@@ -273,30 +294,30 @@ class InvitableTest < ActiveSupport::TestCase
|
|
273
294
|
assert_difference('ActionMailer::Base.deliveries.size') do
|
274
295
|
token = user.invitation_token
|
275
296
|
user.invite!
|
276
|
-
|
297
|
+
refute_equal token, user.invitation_token
|
277
298
|
end
|
278
299
|
end
|
279
300
|
|
280
301
|
test 'should return a record with invitation token and no errors to send invitation by email' do
|
281
302
|
invited_user = User.invite!(:email => "valid@email.com")
|
282
|
-
|
283
|
-
|
303
|
+
assert_empty invited_user.errors
|
304
|
+
assert_predicate invited_user.invitation_token, :present?
|
284
305
|
assert_equal 'valid@email.com', invited_user.email
|
285
|
-
|
306
|
+
assert_predicate invited_user, :persisted?
|
286
307
|
end
|
287
308
|
|
288
309
|
test 'should set all attributes with no errors' do
|
289
310
|
invited_user = User.invite!(:email => "valid@email.com", :username => 'first name')
|
290
|
-
|
311
|
+
assert_empty invited_user.errors
|
291
312
|
assert_equal 'first name', invited_user.username
|
292
|
-
|
313
|
+
assert_predicate invited_user, :persisted?
|
293
314
|
end
|
294
315
|
|
295
316
|
test 'should not validate other attributes when validate_on_invite is disabled' do
|
296
317
|
validate_on_invite = User.validate_on_invite
|
297
318
|
User.validate_on_invite = false
|
298
319
|
invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
|
299
|
-
|
320
|
+
assert_empty invited_user.errors
|
300
321
|
User.validate_on_invite = validate_on_invite
|
301
322
|
end
|
302
323
|
|
@@ -304,7 +325,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
304
325
|
validate_on_invite = User.validate_on_invite
|
305
326
|
User.validate_on_invite = true
|
306
327
|
invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
|
307
|
-
|
328
|
+
refute_empty invited_user.errors[:username]
|
308
329
|
User.validate_on_invite = validate_on_invite
|
309
330
|
end
|
310
331
|
|
@@ -312,8 +333,8 @@ class InvitableTest < ActiveSupport::TestCase
|
|
312
333
|
validate_on_invite = User.validate_on_invite
|
313
334
|
User.validate_on_invite = true
|
314
335
|
invited_user = User.invite!(:email => "valid@email.com", :username => "a"*50)
|
315
|
-
|
316
|
-
|
336
|
+
refute_empty invited_user.errors
|
337
|
+
assert_empty invited_user.errors[:password]
|
317
338
|
User.validate_on_invite = validate_on_invite
|
318
339
|
end
|
319
340
|
|
@@ -321,8 +342,8 @@ class InvitableTest < ActiveSupport::TestCase
|
|
321
342
|
validate_on_invite = User.validate_on_invite
|
322
343
|
User.validate_on_invite = true
|
323
344
|
invited_user = User.invite!(:email => "", :username => "a"*50)
|
324
|
-
|
325
|
-
|
345
|
+
refute_empty invited_user.errors[:email]
|
346
|
+
refute_empty invited_user.errors[:username]
|
326
347
|
User.validate_on_invite = validate_on_invite
|
327
348
|
end
|
328
349
|
|
@@ -363,7 +384,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
363
384
|
user = User.invite!(:email => "valid@email.com", :username => "a"*50)
|
364
385
|
assert_equal user, existing_user
|
365
386
|
assert_equal ['has already been taken'], user.errors[:email]
|
366
|
-
|
387
|
+
refute_empty user.errors[:username]
|
367
388
|
ensure
|
368
389
|
User.validate_on_invite = validate_on_invite
|
369
390
|
end
|
@@ -385,7 +406,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
385
406
|
invited_user = User.invite!(:email => "invalid_email.com", :username => 'first name')
|
386
407
|
assert invited_user.new_record?
|
387
408
|
assert_equal 'first name', invited_user.username
|
388
|
-
|
409
|
+
refute_empty invited_user.errors
|
389
410
|
end
|
390
411
|
|
391
412
|
test 'should find a user to set his password based on invitation_token' do
|
@@ -449,10 +470,10 @@ class InvitableTest < ActiveSupport::TestCase
|
|
449
470
|
:password_confirmation => 'new_password',
|
450
471
|
:username => 'a'*50
|
451
472
|
)
|
452
|
-
|
473
|
+
refute_empty invited_user.errors[:username]
|
453
474
|
|
454
475
|
user.reload
|
455
|
-
|
476
|
+
refute user.valid_password?('new_password')
|
456
477
|
end
|
457
478
|
|
458
479
|
test 'should check if created by invitation' do
|
@@ -492,7 +513,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
492
513
|
|
493
514
|
user.invite!
|
494
515
|
|
495
|
-
|
516
|
+
refute_predicate user, :confirmed?
|
496
517
|
end
|
497
518
|
|
498
519
|
test 'user.has_invitations_left? test' do
|
@@ -508,7 +529,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
508
529
|
# With an individual invitation_limit of 0, a user shouldn't be able to send an invitation
|
509
530
|
user.invitation_limit = 0
|
510
531
|
assert user.save
|
511
|
-
|
532
|
+
refute_predicate user, :has_invitations_left?
|
512
533
|
|
513
534
|
# With in invitation_limit of 2, a user should be able to send two invitations
|
514
535
|
user.invitation_limit = 2
|
@@ -536,7 +557,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
536
557
|
assert_no_difference('ActionMailer::Base.deliveries.size') do
|
537
558
|
user.invite!
|
538
559
|
end
|
539
|
-
|
560
|
+
assert_predicate user, :invitation_created_at
|
540
561
|
assert_nil user.invitation_sent_at
|
541
562
|
end
|
542
563
|
|
@@ -547,7 +568,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
547
568
|
u.skip_invitation = true
|
548
569
|
end
|
549
570
|
end
|
550
|
-
|
571
|
+
assert_predicate user, :invitation_created_at
|
551
572
|
assert_nil user.invitation_sent_at
|
552
573
|
end
|
553
574
|
|
@@ -568,17 +589,17 @@ class InvitableTest < ActiveSupport::TestCase
|
|
568
589
|
|
569
590
|
test 'user.accept_invitation! should trigger callbacks' do
|
570
591
|
user = User.invite!(:email => "valid@email.com")
|
571
|
-
assert_callbacks_not_fired user
|
592
|
+
assert_callbacks_not_fired :after_invitation_accepted, user
|
572
593
|
user.accept_invitation!
|
573
|
-
assert_callbacks_fired user
|
594
|
+
assert_callbacks_fired :after_invitation_accepted, user
|
574
595
|
end
|
575
596
|
|
576
597
|
test 'user.accept_invitation! should not trigger callbacks if validation fails' do
|
577
598
|
user = User.invite!(:email => "valid@email.com")
|
578
|
-
assert_callbacks_not_fired user
|
599
|
+
assert_callbacks_not_fired :after_invitation_accepted, user
|
579
600
|
user.username='a'*50
|
580
601
|
user.accept_invitation!
|
581
|
-
assert_callbacks_not_fired user
|
602
|
+
assert_callbacks_not_fired :after_invitation_accepted, user
|
582
603
|
end
|
583
604
|
|
584
605
|
test 'user.accept_invitation! should confirm user if confirmable' do
|
@@ -593,19 +614,19 @@ class InvitableTest < ActiveSupport::TestCase
|
|
593
614
|
user.username='a'*50
|
594
615
|
user.accept_invitation!
|
595
616
|
|
596
|
-
|
617
|
+
refute_predicate user, :confirmed?
|
597
618
|
end
|
598
619
|
|
599
|
-
def assert_callbacks_fired(user)
|
600
|
-
assert_callbacks_status user, true
|
620
|
+
def assert_callbacks_fired(callback, user)
|
621
|
+
assert_callbacks_status callback, user, true
|
601
622
|
end
|
602
623
|
|
603
|
-
def assert_callbacks_not_fired(user)
|
604
|
-
assert_callbacks_status user, nil
|
624
|
+
def assert_callbacks_not_fired(callback, user)
|
625
|
+
assert_callbacks_status callback, user, nil
|
605
626
|
end
|
606
627
|
|
607
|
-
def assert_callbacks_status(user, fired)
|
608
|
-
assert_equal fired, user.
|
628
|
+
def assert_callbacks_status(callback, user, fired)
|
629
|
+
assert_equal fired, user.send("#{callback}_callback_works".to_sym)
|
609
630
|
end
|
610
631
|
|
611
632
|
test "user.invite! should downcase the class's case_insensitive_keys" do
|
@@ -621,6 +642,13 @@ class InvitableTest < ActiveSupport::TestCase
|
|
621
642
|
assert user.active == true
|
622
643
|
end
|
623
644
|
|
645
|
+
test "user.invite! should trigger callbacks" do
|
646
|
+
user = User.new(email: "valid@email.com")
|
647
|
+
assert_callbacks_not_fired :after_invitation_created, user
|
648
|
+
user.invite!
|
649
|
+
assert_callbacks_fired :after_invitation_created, user
|
650
|
+
end
|
651
|
+
|
624
652
|
test 'should pass validation before accept if field is required in post-invited instance' do
|
625
653
|
user = User.invite!(:email => "valid@email.com")
|
626
654
|
user.testing_accepted_or_not_invited = true
|
@@ -646,7 +674,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
646
674
|
test 'should return instance with errors if invitation_token is nil' do
|
647
675
|
User.create(:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456')
|
648
676
|
user = User.accept_invitation!
|
649
|
-
|
677
|
+
refute_empty user.errors
|
650
678
|
end
|
651
679
|
|
652
680
|
test "should count invited, created_by_invite, accepted and not accepted invitations" do
|
@@ -36,10 +36,11 @@ class User < PARENT_MODEL_CLASS
|
|
36
36
|
|
37
37
|
devise :database_authenticatable, :registerable, :validatable, :confirmable, :invitable, :recoverable
|
38
38
|
|
39
|
-
attr_accessor :
|
39
|
+
attr_accessor :after_invitation_created_callback_works, :after_invitation_accepted_callback_works, :bio, :token
|
40
40
|
validates :username, :length => { :maximum => 20 }
|
41
|
-
|
41
|
+
|
42
42
|
attr_accessor :testing_accepted_or_not_invited
|
43
|
+
|
43
44
|
validates :username, :presence => true, :if => :testing_accepted_or_not_invited_validator?
|
44
45
|
validates :bio, :presence => true, :if => :invitation_accepted?
|
45
46
|
|
@@ -47,8 +48,12 @@ class User < PARENT_MODEL_CLASS
|
|
47
48
|
testing_accepted_or_not_invited && accepted_or_not_invited?
|
48
49
|
end
|
49
50
|
|
51
|
+
after_invitation_created do |object|
|
52
|
+
object.after_invitation_created_callback_works = true
|
53
|
+
end
|
54
|
+
|
50
55
|
after_invitation_accepted do |object|
|
51
|
-
object.
|
56
|
+
object.after_invitation_accepted_callback_works = true
|
52
57
|
end
|
53
58
|
|
54
59
|
def send_devise_notification(method, raw, *args)
|
@@ -7,7 +7,8 @@ require "rails/test_unit/railtie"
|
|
7
7
|
Bundler.require(:default, DEVISE_ORM) if defined?(Bundler)
|
8
8
|
|
9
9
|
begin
|
10
|
-
require "#{DEVISE_ORM}
|
10
|
+
require "#{DEVISE_ORM}" if DEVISE_ORM == :mongoid
|
11
|
+
require "#{DEVISE_ORM}/railtie" unless DEVISE_ORM == :mongoid && Mongoid::VERSION >= '5.0.0'
|
11
12
|
rescue LoadError
|
12
13
|
end
|
13
14
|
PARENT_MODEL_CLASS = DEVISE_ORM == :active_record ? ActiveRecord::Base : Object
|
@@ -20,5 +21,8 @@ module RailsApp
|
|
20
21
|
class Application < Rails::Application
|
21
22
|
config.filter_parameters << :password
|
22
23
|
config.action_mailer.default_url_options = { :host => "localhost:3000" }
|
24
|
+
if DEVISE_ORM == :active_record && Rails.version.start_with?('5')
|
25
|
+
config.active_record.maintain_test_schema = false
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
@@ -29,7 +29,7 @@ class CreateTables < ActiveRecord::Migration
|
|
29
29
|
t.string :invited_by_type
|
30
30
|
t.integer :invitations_count, :default => 0
|
31
31
|
|
32
|
-
t.timestamps
|
32
|
+
t.timestamps :null => false
|
33
33
|
end
|
34
34
|
add_index :users, :invitation_token, :unique => true
|
35
35
|
add_index :users, :invitations_count
|
data/test/test_helper.rb
CHANGED
@@ -4,9 +4,8 @@ DEVISE_ORM = (ENV["DEVISE_ORM"] || :active_record).to_sym
|
|
4
4
|
$:.unshift File.dirname(__FILE__)
|
5
5
|
puts "\n==> Devise.orm = #{DEVISE_ORM.inspect}"
|
6
6
|
require "rails_app/config/environment"
|
7
|
-
include Devise::TestHelpers
|
8
|
-
require "orm/#{DEVISE_ORM}"
|
9
7
|
require 'rails/test_help'
|
8
|
+
require "orm/#{DEVISE_ORM}"
|
10
9
|
require 'capybara/rails'
|
11
10
|
require 'mocha/setup'
|
12
11
|
|
@@ -15,10 +14,11 @@ ActionMailer::Base.perform_deliveries = true
|
|
15
14
|
ActionMailer::Base.default_url_options[:host] = 'test.com'
|
16
15
|
|
17
16
|
ActiveSupport::Deprecation.silenced = true
|
17
|
+
$VERBOSE = false
|
18
18
|
|
19
19
|
class ActionDispatch::IntegrationTest
|
20
20
|
include Capybara::DSL
|
21
21
|
end
|
22
|
-
class ActionController::TestCase
|
23
|
-
include Devise::TestHelpers
|
22
|
+
class ActionController::TestCase
|
23
|
+
include Devise::TestHelpers
|
24
24
|
end
|
metadata
CHANGED
@@ -1,59 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_invitable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Sergio Cambra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2016-04-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.0
|
16
20
|
type: :development
|
17
21
|
prerelease: false
|
18
|
-
|
19
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
20
24
|
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
25
|
+
- !ruby/object:Gem::Version
|
22
26
|
version: 1.1.0
|
23
|
-
|
24
|
-
- !ruby/object:Gem::Dependency
|
27
|
+
- !ruby/object:Gem::Dependency
|
25
28
|
name: actionmailer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.2.6
|
26
34
|
type: :runtime
|
27
35
|
prerelease: false
|
28
|
-
|
29
|
-
requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
30
38
|
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
39
|
+
- !ruby/object:Gem::Version
|
32
40
|
version: 3.2.6
|
33
|
-
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: "5"
|
36
|
-
version_requirements: *id002
|
37
|
-
- !ruby/object:Gem::Dependency
|
41
|
+
- !ruby/object:Gem::Dependency
|
38
42
|
name: devise
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.2.0
|
39
48
|
type: :runtime
|
40
49
|
prerelease: false
|
41
|
-
|
42
|
-
requirements:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
43
52
|
- - ">="
|
44
|
-
- !ruby/object:Gem::Version
|
53
|
+
- !ruby/object:Gem::Version
|
45
54
|
version: 3.2.0
|
46
|
-
|
47
|
-
|
48
|
-
email:
|
55
|
+
description: It adds support for send invitations by email (it requires to be authenticated)
|
56
|
+
and accept the invitation by setting a password.
|
57
|
+
email:
|
49
58
|
- sergio@entrecables.com
|
50
59
|
executables: []
|
51
|
-
|
52
60
|
extensions: []
|
53
|
-
|
54
61
|
extra_rdoc_files: []
|
55
|
-
|
56
|
-
files:
|
62
|
+
files:
|
57
63
|
- CHANGELOG
|
58
64
|
- LICENSE
|
59
65
|
- README.rdoc
|
@@ -62,6 +68,7 @@ files:
|
|
62
68
|
- app/views/devise/invitations/edit.html.erb
|
63
69
|
- app/views/devise/invitations/new.html.erb
|
64
70
|
- app/views/devise/mailer/invitation_instructions.html.erb
|
71
|
+
- app/views/devise/mailer/invitation_instructions.text.erb
|
65
72
|
- config/locales/en.yml
|
66
73
|
- lib/devise_invitable.rb
|
67
74
|
- lib/devise_invitable/controllers/helpers.rb
|
@@ -134,35 +141,33 @@ files:
|
|
134
141
|
- test/routes_test.rb
|
135
142
|
- test/test_helper.rb
|
136
143
|
homepage: https://github.com/scambra/devise_invitable
|
137
|
-
licenses:
|
144
|
+
licenses:
|
138
145
|
- MIT
|
139
146
|
metadata: {}
|
140
|
-
|
141
147
|
post_install_message:
|
142
|
-
rdoc_options:
|
143
|
-
- --main
|
148
|
+
rdoc_options:
|
149
|
+
- "--main"
|
144
150
|
- README.rdoc
|
145
|
-
- --charset=UTF-8
|
146
|
-
require_paths:
|
151
|
+
- "--charset=UTF-8"
|
152
|
+
require_paths:
|
147
153
|
- lib
|
148
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
150
156
|
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
157
|
+
- !ruby/object:Gem::Version
|
152
158
|
version: 1.8.6
|
153
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
-
requirements:
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
155
161
|
- - ">="
|
156
|
-
- !ruby/object:Gem::Version
|
162
|
+
- !ruby/object:Gem::Version
|
157
163
|
version: 1.3.6
|
158
164
|
requirements: []
|
159
|
-
|
160
165
|
rubyforge_project:
|
161
|
-
rubygems_version: 2.4.
|
166
|
+
rubygems_version: 2.4.8
|
162
167
|
signing_key:
|
163
168
|
specification_version: 4
|
164
169
|
summary: An invitation strategy for Devise
|
165
|
-
test_files:
|
170
|
+
test_files:
|
166
171
|
- test/functional/controller_helpers_test.rb
|
167
172
|
- test/functional/registrations_controller_test.rb
|
168
173
|
- test/generators/views_generator_test.rb
|