devise_invitable 1.5.1 → 1.5.2
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 +4 -4
- data/CHANGELOG +58 -0
- data/README.rdoc +11 -9
- data/app/controllers/devise_invitable/registrations_controller.rb +2 -2
- data/lib/devise_invitable.rb +5 -0
- data/lib/devise_invitable/model.rb +9 -13
- data/lib/devise_invitable/version.rb +1 -1
- data/lib/generators/active_record/templates/migration.rb +0 -10
- data/lib/generators/devise_invitable/install_generator.rb +4 -0
- data/test/functional/registrations_controller_test.rb +0 -1
- data/test/integration/invitation_test.rb +2 -2
- data/test/models/invitable_test.rb +5 -0
- data/test/rails_app/config/initializers/devise.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21840c71f560017345f75d9152e44b295ccb8043
|
4
|
+
data.tar.gz: 8470539a88ef73abb3ef396a4c043e9405eecd57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 451e491d4a3a8135bc4d1447d1b9035624f2be5757f03544fe1bf8925e0b08df1317a57ec93cb20f293e5dc77397e3c1ba6a6e854f1b8a7646804ce6b43258fc
|
7
|
+
data.tar.gz: ee5f07eb0c08aca5310d36b42eb7fa20fee2bbc657a101a79981c5072e6da3593a813ca79bb08ef05d3494db65e228017f692dc96645c1e62b9ff3c4f189e4f8
|
data/CHANGELOG
CHANGED
@@ -1,11 +1,69 @@
|
|
1
|
+
= 1.5.2
|
2
|
+
|
3
|
+
- Fix #571, accept invitation when password changes only if reset_password_token was present
|
4
|
+
- Add support for setting invited_by foreign key
|
5
|
+
- Set random initial password for invited users
|
6
|
+
- Don't override password while User.invite!
|
7
|
+
|
8
|
+
= 1.5.1
|
9
|
+
|
10
|
+
- Fix #562 Avoid using after_password_reset
|
11
|
+
- Fix #564
|
12
|
+
|
13
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.5.0...v1.5.1
|
14
|
+
|
15
|
+
= 1.5.0
|
16
|
+
|
1
17
|
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
18
|
|
19
|
+
- Get list & check for user(s) created by invite irrespective of status
|
20
|
+
- Update simple_form template's hash syntax
|
21
|
+
- Update migration template's hash syntax
|
22
|
+
- Check if after_password_reset is defined
|
23
|
+
|
24
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.4.2...v1.5.0
|
25
|
+
|
26
|
+
= 1.4.2
|
27
|
+
|
28
|
+
- Add option to allow controlling of auto sign in functionality for security
|
29
|
+
- Add intermediate method in active_for_authentication? for more flexibility
|
30
|
+
- Add intermediate block_from_invitation? method for more flexibility
|
31
|
+
- Fix undefined method `invite_key_fields'
|
32
|
+
- Fix override valid_password? instead of active_for_authentication? (fixes #541)
|
33
|
+
|
34
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.4.1...v1.4.2
|
35
|
+
|
36
|
+
= 1.4.1
|
37
|
+
|
38
|
+
- Begin testing against devise 3.4
|
39
|
+
- Use current_inviter to get redirect path after invite
|
40
|
+
(https://github.com/scambra/devise_invitable/pull/523)
|
41
|
+
|
42
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.4.0...v1.4.1
|
43
|
+
|
3
44
|
= 1.4.0
|
45
|
+
|
4
46
|
Override active_for_authentication? and inactive_message instead of valid_password?
|
5
47
|
To use counter_cache, invited_by_counter_cache must be set, no more checking of invitations_count to enable counter cache
|
6
48
|
|
49
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.3.6...v1.4.0
|
50
|
+
|
51
|
+
= 1.3.6
|
52
|
+
|
53
|
+
- Regenerate invitation token each time even if "skip_invitation" was true
|
54
|
+
- Add passing a block to instance #invite! method
|
55
|
+
- Improvements to tests
|
56
|
+
|
57
|
+
Compare: https://github.com/scambra/devise_invitable/compare/v1.3.5...v1.3.6
|
58
|
+
|
59
|
+
= 1.3.5
|
60
|
+
|
61
|
+
No notes yet, contributions welcome.
|
62
|
+
|
7
63
|
= 1.3.0
|
64
|
+
|
8
65
|
Now devise 3.1 compatible, @token must be used instead of @resource.invitation_token in mail views
|
9
66
|
|
10
67
|
= 1.2.0
|
68
|
+
|
11
69
|
Add invitation_created_at column which is set when invitation is created even when sending is skipped. This new field is used to check invitation period valid
|
data/README.rdoc
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
= DeviseInvitable
|
2
|
-
{<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[
|
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]
|
3
3
|
|
4
|
-
It adds support to devise[
|
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
|
-
DeviseInvitable currently supports Rails 3 and 4, if you want to use it with Rails 2.3 you must install version {0.2.3}[
|
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
|
If you want to use devise 3.0.x, you must use 1.2.1, newer versions require devise >= 3.1.0
|
9
9
|
|
@@ -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
|
+
* invited_by_foreign_key: The foreign key to the inviting model (only used if invited_by_class_name is set, otherwise :invited_by_id)
|
136
|
+
|
135
137
|
* allow_insecure_sign_in_after_accept: automatically sign in the user after they set a password. Enabled by default.
|
136
138
|
|
137
139
|
For more details, see <tt>config/initializers/devise.rb</tt> (after you invoked the "devise_invitable:install" generator described above).
|
@@ -150,11 +152,11 @@ Then turn scoped views on in config/initializers/devise.rb:
|
|
150
152
|
|
151
153
|
config.scoped_views = true
|
152
154
|
|
153
|
-
Please refer to {Devise's README}[
|
155
|
+
Please refer to {Devise's README}[https://github.com/plataformatec/devise] for more information about views.
|
154
156
|
|
155
157
|
== Configuring controllers
|
156
158
|
|
157
|
-
To change the controller's behavior, create a controller that inherits from <tt>Devise::InvitationsController</tt>. The available methods are: new, create, edit, and update. You should read the {original controllers source}[https://
|
159
|
+
To change the controller's behavior, create a controller that inherits from <tt>Devise::InvitationsController</tt>. The available methods are: new, create, edit, and update. You should read the {original controllers source}[https://github.com/scambra/devise_invitable/blob/master/app/controllers/devise/invitations_controller.rb] before editing any of these actions. Your controller might now look something like this:
|
158
160
|
|
159
161
|
class Users::InvitationsController < Devise::InvitationsController
|
160
162
|
def update
|
@@ -200,7 +202,7 @@ To change behaviour of inviting or accepting users, you can simply override two
|
|
200
202
|
|
201
203
|
== Strong Parameters
|
202
204
|
|
203
|
-
When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing DeviseInvitable to handle this concern at the controller as well. Read about it in {devise README}[
|
205
|
+
When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing DeviseInvitable to handle this concern at the controller as well. Read about it in {devise README}[https://github.com/plataformatec/devise#strong-parameters]
|
204
206
|
|
205
207
|
There are just two actions in DeviseInvitable that allows any set of parameters to be passed down to the model, therefore requiring sanitization. Their names and the permited parameters by default are:
|
206
208
|
|
@@ -310,7 +312,7 @@ Instead, in your views, put a link to <tt>new_user_invitation_path</tt> or <tt>n
|
|
310
312
|
|
311
313
|
After an invitation is created and sent, the inviter will be redirected to after_invite_path_for(resource_name), which is stored path or the same path as after_sign_in_path_for by default.
|
312
314
|
|
313
|
-
After an invitation is accepted, the invitee will be redirected to after_accept_path_for(resource), which is the same path as after_sign_in_path_for by default. If you want to override the path, override invitations controller and define after_accept_path_for method. This is useful in the common case that a user is invited to a specific location in your application. More on {Devise's README}[
|
315
|
+
After an invitation is accepted, the invitee will be redirected to after_accept_path_for(resource), which is the same path as after_sign_in_path_for by default. If you want to override the path, override invitations controller and define after_accept_path_for method. This is useful in the common case that a user is invited to a specific location in your application. More on {Devise's README}[https://github.com/plataformatec/devise], "Controller filters and helpers" section.
|
314
316
|
|
315
317
|
The invitation email includes a link to accept the invitation that looks like this: <tt>/users/invitation/accept?invitation_token=abcd123</tt>. When clicked, the invited must set a password in order to accept its invitation. Note that if the invitation_token is not present or not valid, the invited is redirected to after_sign_out_path_for(resource_name).
|
316
318
|
|
@@ -409,9 +411,9 @@ To test DeviseInvitable for the ActiveRecord ORM with RVM, Ruby 1.9.2, and Rubyg
|
|
409
411
|
|
410
412
|
Check them all at:
|
411
413
|
|
412
|
-
|
414
|
+
https://github.com/scambra/devise_invitable/contributors
|
413
415
|
|
414
|
-
Special thanks to rymai[
|
416
|
+
Special thanks to rymai[https://github.com/rymai] for the Rails 3 support, his fork was a great help.
|
415
417
|
|
416
418
|
== Note on Patches/Pull Requests
|
417
419
|
|
@@ -4,8 +4,8 @@ class DeviseInvitable::RegistrationsController < Devise::RegistrationsController
|
|
4
4
|
def build_resource(hash = nil)
|
5
5
|
hash ||= resource_params || {}
|
6
6
|
if hash[:email]
|
7
|
-
self.resource = resource_class.where(:email => hash[:email]
|
8
|
-
if self.resource
|
7
|
+
self.resource = resource_class.where(:email => hash[:email]).first
|
8
|
+
if self.resource and self.resource.invited_to_sign_up?
|
9
9
|
self.resource.attributes = hash
|
10
10
|
self.resource.send_confirmation_instructions if self.resource.confirmation_required_for_invited?
|
11
11
|
self.resource.accept_invitation
|
data/lib/devise_invitable.rb
CHANGED
@@ -62,6 +62,11 @@ module Devise
|
|
62
62
|
mattr_accessor :invited_by_class_name
|
63
63
|
@@invited_by_class_name = nil
|
64
64
|
|
65
|
+
# Public: The foreign key to the inviting model (if invited_by_class_name is set)
|
66
|
+
# (default: :invited_by_id)
|
67
|
+
mattr_accessor :invited_by_foreign_key
|
68
|
+
@@invited_by_foreign_key = nil
|
69
|
+
|
65
70
|
# Public: The column name used for counter_cache column. If this is nil,
|
66
71
|
# the #invited_by association is declared without counter_cache. (default: nil)
|
67
72
|
mattr_accessor :invited_by_counter_cache
|
@@ -34,6 +34,9 @@ module Devise
|
|
34
34
|
else
|
35
35
|
{:polymorphic => true}
|
36
36
|
end
|
37
|
+
if fk = Devise.invited_by_foreign_key
|
38
|
+
belongs_to_options[:foreign_key] = fk
|
39
|
+
end
|
37
40
|
if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && self < ActiveRecord::Base
|
38
41
|
counter_cache = Devise.invited_by_counter_cache
|
39
42
|
belongs_to_options.merge! :counter_cache => counter_cache if counter_cache
|
@@ -43,8 +46,6 @@ module Devise
|
|
43
46
|
include ActiveSupport::Callbacks
|
44
47
|
define_callbacks :invitation_accepted
|
45
48
|
|
46
|
-
attr_writer :skip_password
|
47
|
-
|
48
49
|
scope :no_active_invitation, lambda { where(:invitation_token => nil) }
|
49
50
|
if defined?(Mongoid) && defined?(Mongoid::Document) && self < Mongoid::Document
|
50
51
|
scope :created_by_invite, lambda { where(:invitation_sent_at.ne => nil) }
|
@@ -63,7 +64,7 @@ module Devise
|
|
63
64
|
|
64
65
|
def self.required_fields(klass)
|
65
66
|
fields = [:invitation_token, :invitation_created_at, :invitation_sent_at, :invitation_accepted_at,
|
66
|
-
:invitation_limit, :invited_by_id, :invited_by_type]
|
67
|
+
:invitation_limit, Devise.invited_by_foreign_key || :invited_by_id, :invited_by_type]
|
67
68
|
fields << :invitations_count if defined?(ActiveRecord) && self < ActiveRecord::Base
|
68
69
|
fields -= [:invited_by_type] if Devise.invited_by_class_name
|
69
70
|
fields
|
@@ -151,8 +152,9 @@ module Devise
|
|
151
152
|
end
|
152
153
|
|
153
154
|
def clear_reset_password_token
|
155
|
+
reset_password_token_present = reset_password_token.present?
|
154
156
|
super
|
155
|
-
accept_invitation! if invited_to_sign_up?
|
157
|
+
accept_invitation! if reset_password_token_present && invited_to_sign_up?
|
156
158
|
end
|
157
159
|
|
158
160
|
def clear_errors_on_valid_keys
|
@@ -178,14 +180,6 @@ module Devise
|
|
178
180
|
end
|
179
181
|
|
180
182
|
protected
|
181
|
-
# Overriding the method in Devise's :validatable module so password is not required on inviting
|
182
|
-
def password_required?
|
183
|
-
!skip_password && super
|
184
|
-
end
|
185
|
-
|
186
|
-
def skip_password
|
187
|
-
@skip_password ||= false
|
188
|
-
end
|
189
183
|
|
190
184
|
def block_from_invitation?
|
191
185
|
invited_to_sign_up?
|
@@ -260,8 +254,10 @@ module Devise
|
|
260
254
|
invitable = find_or_initialize_with_errors(invite_key_array, attributes_hash)
|
261
255
|
invitable.assign_attributes(attributes)
|
262
256
|
invitable.invited_by = invited_by
|
257
|
+
unless invitable.password
|
258
|
+
invitable.password = Devise.friendly_token[0, 20]
|
259
|
+
end
|
263
260
|
|
264
|
-
invitable.skip_password = true
|
265
261
|
invitable.valid? if self.validate_on_invite
|
266
262
|
if invitable.new_record?
|
267
263
|
invitable.clear_errors_on_valid_keys if !self.validate_on_invite
|
@@ -12,12 +12,6 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
|
|
12
12
|
t.index :invitation_token, unique: true # for invitable
|
13
13
|
t.index :invited_by_id
|
14
14
|
end
|
15
|
-
|
16
|
-
# And allow null encrypted_password and password_salt:
|
17
|
-
change_column_null :<%= table_name %>, :encrypted_password, true
|
18
|
-
<% if class_name.constantize.columns_hash['password_salt'] -%>
|
19
|
-
change_column_null :<%= table_name %>, :password_salt, true
|
20
|
-
<% end -%>
|
21
15
|
end
|
22
16
|
|
23
17
|
def down
|
@@ -25,9 +19,5 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
|
|
25
19
|
t.remove_references :invited_by, polymorphic: true
|
26
20
|
t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
|
27
21
|
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 -%>
|
32
22
|
end
|
33
23
|
end
|
@@ -52,6 +52,10 @@ module DeviseInvitable
|
|
52
52
|
# Default: nil
|
53
53
|
# config.invited_by_class_name = 'User'
|
54
54
|
|
55
|
+
# The foreign key to the inviting model (if invited_by_class_name is set)
|
56
|
+
# Default: :invited_by_id
|
57
|
+
# config.invited_by_foreign_key = :invited_by_id
|
58
|
+
|
55
59
|
# The column name used for counter_cache column. If this is nil,
|
56
60
|
# the #invited_by association is declared without counter_cache.
|
57
61
|
# Default: nil
|
@@ -25,7 +25,6 @@ class DeviseInvitable::RegistrationsControllerTest < ActionController::TestCase
|
|
25
25
|
sign_out @issuer
|
26
26
|
|
27
27
|
@invitee = User.where(:email => invitee_email).first
|
28
|
-
assert @invitee.encrypted_password.blank?, "the password should be unset"
|
29
28
|
assert_nil @invitee.invitation_accepted_at
|
30
29
|
assert_not_nil @invitee.invitation_token
|
31
30
|
assert !@invitee.confirmed?
|
@@ -99,7 +99,7 @@ class InvitationTest < ActionDispatch::IntegrationTest
|
|
99
99
|
end
|
100
100
|
assert_equal user_invitation_path, current_path
|
101
101
|
assert page.has_css?('#error_explanation li', :text => /Password .*doesn\'t match/)
|
102
|
-
assert user.
|
102
|
+
assert !user.confirmed?
|
103
103
|
end
|
104
104
|
|
105
105
|
test 'not authenticated user with valid data should be able to change his password' do
|
@@ -109,6 +109,7 @@ class InvitationTest < ActionDispatch::IntegrationTest
|
|
109
109
|
assert_equal root_path, current_path
|
110
110
|
assert page.has_css?('p#notice', :text => 'Your password was set successfully. You are now signed in.')
|
111
111
|
assert user.reload.valid_password?('987654321')
|
112
|
+
assert user.confirmed?
|
112
113
|
end
|
113
114
|
|
114
115
|
test 'after entering invalid data user should still be able to set his password' do
|
@@ -118,7 +119,6 @@ class InvitationTest < ActionDispatch::IntegrationTest
|
|
118
119
|
end
|
119
120
|
assert_equal user_invitation_path, current_path
|
120
121
|
assert page.has_css?('#error_explanation')
|
121
|
-
assert user.encrypted_password.blank?
|
122
122
|
|
123
123
|
set_password :visit => false
|
124
124
|
assert page.has_css?('p#notice', :text => 'Your password was set successfully. You are now signed in.')
|
@@ -181,6 +181,11 @@ class InvitableTest < ActiveSupport::TestCase
|
|
181
181
|
assert_not_equal old_encrypted_password, user.encrypted_password
|
182
182
|
end
|
183
183
|
|
184
|
+
test 'should not override password on invite!' do
|
185
|
+
user = User.invite!(:email => "valid@email.com", :password => 'password', :password_confirmation => 'password', :skip_invitation => true)
|
186
|
+
assert user.valid?
|
187
|
+
end
|
188
|
+
|
184
189
|
test 'should clear invitation token and set invitation_accepted_at while accepting the password' do
|
185
190
|
user = User.invite!(:email => "valid@email.com")
|
186
191
|
assert user.invitation_token.present?
|
@@ -124,6 +124,10 @@ Devise.setup do |config|
|
|
124
124
|
# Default: nil
|
125
125
|
# config.invited_by_class_name = 'User'
|
126
126
|
|
127
|
+
# The foreign key to the inviting model (if invited_by_class_name is set)
|
128
|
+
# Default: :invited_by_id
|
129
|
+
# config.invited_by_foreign_key = :invited_by_id
|
130
|
+
|
127
131
|
# The column name used for counter_cache column. If this is nil,
|
128
132
|
# the #invited_by association is declared without counter_cache.
|
129
133
|
# Default: nil
|
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.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergio Cambra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|