devise_invitable 1.0.2 → 1.1.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.
- data/README.rdoc +18 -0
- data/app/controllers/devise/invitations_controller.rb +2 -2
- data/app/views/devise/invitations/edit.html.erb +2 -2
- data/app/views/devise/invitations/new.html.erb +2 -4
- data/config/locales/en.yml +6 -0
- data/lib/devise_invitable/controllers/registrations.rb +8 -9
- data/lib/devise_invitable/controllers/registrations.rb~ +14 -21
- data/lib/devise_invitable/mailer.rb +1 -1
- data/lib/devise_invitable/model.rb +66 -22
- data/lib/devise_invitable/model.rb~ +5 -30
- data/lib/devise_invitable/routes.rb +2 -2
- data/lib/devise_invitable/version.rb +1 -1
- data/lib/devise_invitable.rb +5 -0
- data/lib/generators/devise_invitable/install_generator.rb +9 -9
- data/lib/generators/devise_invitable/templates/simple_form_for/invitations/edit.html.erb +11 -0
- data/lib/generators/devise_invitable/templates/simple_form_for/invitations/new.html.erb +11 -0
- data/lib/generators/devise_invitable/views_generator.rb +27 -5
- metadata +39 -26
- data/app/controllers/devise/invitations_controller.rb~ +0 -48
- data/app/views/devise/invitations/new.html.erb~ +0 -14
- data/lib/devise_invitable.rb~ +0 -68
- data/lib/generators/devise_invitable/install_generator.rb~ +0 -54
data/README.rdoc
CHANGED
|
@@ -96,6 +96,8 @@ or directly as parameters to the <tt>devise</tt> method:
|
|
|
96
96
|
|
|
97
97
|
* resend_invitation: resend invitation if user with invited status is invited again. Enabled by default.
|
|
98
98
|
|
|
99
|
+
* invited_by_class_name: The class name of the inviting model. If this is nil, polymorphic association is used.
|
|
100
|
+
|
|
99
101
|
For more details, see <tt>config/initializers/devise.rb</tt> (after you invoked the "devise_invitable:install" generator described above).
|
|
100
102
|
|
|
101
103
|
== Configuring views
|
|
@@ -153,6 +155,15 @@ You can add :skip_invitation to attributes hash if skip_invitation is added to a
|
|
|
153
155
|
User.invite!(:email => "new_user@example.com", :name => "John Doe", :skip_invitation => true)
|
|
154
156
|
# => the record will be created, but the invitation email will not be sent
|
|
155
157
|
|
|
158
|
+
You can send an invitation to an existing user if your workflow creates them separately:
|
|
159
|
+
|
|
160
|
+
user = User.find(42)
|
|
161
|
+
user.invite!(current_user) # current user is optional to set the invited_by attribute
|
|
162
|
+
|
|
163
|
+
You can also set <tt>invited_by</tt> when using the <tt>invite!</tt> class method:
|
|
164
|
+
|
|
165
|
+
User.invite!({:email => "new_user@example.com"}, current_user) # current_user will be set as invited_by
|
|
166
|
+
|
|
156
167
|
=== Accept an invitation
|
|
157
168
|
|
|
158
169
|
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.
|
|
@@ -171,6 +182,13 @@ A callback event is fired before and after an invitation is accepted (User#accep
|
|
|
171
182
|
|
|
172
183
|
The callbacks support all options and arguments available to the standard callbacks provided by AR.
|
|
173
184
|
|
|
185
|
+
=== Scopes
|
|
186
|
+
|
|
187
|
+
A pair of scopes to find those users that have accepted, and those that have not accepted, invitations are defined:
|
|
188
|
+
|
|
189
|
+
User.invitation_accepted # => returns all Users for whom the invitation_accepted_at attribute is not nil
|
|
190
|
+
User.invitation_not_accepted # => returns all Users for whom the invitation_accepted_at attribute is nil
|
|
191
|
+
|
|
174
192
|
== Integration in a Rails application
|
|
175
193
|
|
|
176
194
|
Since the invitations controller take care of all the creation/acceptation of an invitation, in most cases you wouldn't call the <tt>invite!</tt> and <tt>accept_invitation!</tt> methods directly.
|
|
@@ -13,7 +13,7 @@ class Devise::InvitationsController < DeviseController
|
|
|
13
13
|
|
|
14
14
|
# POST /resource/invitation
|
|
15
15
|
def create
|
|
16
|
-
self.resource = resource_class.invite!(
|
|
16
|
+
self.resource = resource_class.invite!(resource_params, current_inviter)
|
|
17
17
|
|
|
18
18
|
if resource.errors.empty?
|
|
19
19
|
set_flash_message :notice, :send_instructions, :email => self.resource.email
|
|
@@ -35,7 +35,7 @@ class Devise::InvitationsController < DeviseController
|
|
|
35
35
|
|
|
36
36
|
# PUT /resource/invitation
|
|
37
37
|
def update
|
|
38
|
-
self.resource = resource_class.accept_invitation!(
|
|
38
|
+
self.resource = resource_class.accept_invitation!(resource_params)
|
|
39
39
|
|
|
40
40
|
if resource.errors.empty?
|
|
41
41
|
set_flash_message :notice, :updated
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h2
|
|
1
|
+
<h2><%= t 'devise.invitations.edit.header' %></h2>
|
|
2
2
|
|
|
3
3
|
<%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
|
|
4
4
|
<%= devise_error_messages! %>
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
<p><%= f.label :password_confirmation %><br />
|
|
11
11
|
<%= f.password_field :password_confirmation %></p>
|
|
12
12
|
|
|
13
|
-
<p><%= f.submit "
|
|
13
|
+
<p><%= f.submit t("devise.invitations.edit.submit_button") %></p>
|
|
14
14
|
<% end %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h2
|
|
1
|
+
<h2><%= t "devise.invitations.new.header" %></h2>
|
|
2
2
|
|
|
3
3
|
<%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
|
|
4
4
|
<%= devise_error_messages! %>
|
|
@@ -8,7 +8,5 @@
|
|
|
8
8
|
<%= f.text_field field %></p>
|
|
9
9
|
<% end -%>
|
|
10
10
|
|
|
11
|
-
<p><%= f.submit "
|
|
11
|
+
<p><%= f.submit t("devise.invitations.new.submit_button") %></p>
|
|
12
12
|
<% end %>
|
|
13
|
-
|
|
14
|
-
<%= link_to "Home", after_sign_in_path_for(resource_name) %><br />
|
data/config/locales/en.yml
CHANGED
|
@@ -5,6 +5,12 @@ en:
|
|
|
5
5
|
invitation_token_invalid: 'The invitation token provided is not valid!'
|
|
6
6
|
updated: 'Your password was set successfully. You are now signed in.'
|
|
7
7
|
no_invitations_remaining: "No invitations remaining"
|
|
8
|
+
new:
|
|
9
|
+
header: "Send invitation"
|
|
10
|
+
submit_button: "Send an invitation"
|
|
11
|
+
edit:
|
|
12
|
+
header: "Set your password"
|
|
13
|
+
submit_button: "Set my password"
|
|
8
14
|
mailer:
|
|
9
15
|
invitation_instructions:
|
|
10
16
|
subject: 'Invitation instructions'
|
|
@@ -10,30 +10,29 @@ module DeviseInvitable::Controllers::Registrations
|
|
|
10
10
|
if hash && hash[:email]
|
|
11
11
|
resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first
|
|
12
12
|
if resource
|
|
13
|
-
@invitation_info = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@invitation_info[:invited_by_type] = resource[:invited_by_type]
|
|
13
|
+
@invitation_info = Hash[resource.invitation_fields.map {|field|
|
|
14
|
+
[field, resource[field]]
|
|
15
|
+
}]
|
|
17
16
|
resource.destroy
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
end
|
|
21
|
-
|
|
20
|
+
|
|
22
21
|
def keep_invitation_info
|
|
23
22
|
resource_invitable = resource_class.devise_modules.include?(:invitable)
|
|
24
23
|
destroy_if_previously_invited if resource_invitable
|
|
25
24
|
yield
|
|
26
25
|
reset_invitation_info if resource_invitable
|
|
27
26
|
end
|
|
28
|
-
|
|
27
|
+
|
|
29
28
|
def reset_invitation_info
|
|
30
29
|
# Restore info about the last invitation (for later reference)
|
|
31
30
|
# Reset the invitation_info only, if invited_by_id is still nil at this stage:
|
|
32
31
|
resource = resource_class.where(:email => params[resource_name][:email], :invited_by_id => nil).first
|
|
33
32
|
if resource && @invitation_info
|
|
34
|
-
resource
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
resource.invitation_fields.each do |field|
|
|
34
|
+
resource[field] = @invitation_info[field]
|
|
35
|
+
end
|
|
37
36
|
resource.save!
|
|
38
37
|
end
|
|
39
38
|
end
|
|
@@ -1,42 +1,35 @@
|
|
|
1
1
|
module DeviseInvitable::Controllers::Registrations
|
|
2
2
|
def self.included(controller)
|
|
3
|
-
controller.send :around_filter, :
|
|
3
|
+
controller.send :around_filter, :destroy_if_previously_invited, :only => :create
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
protected
|
|
7
7
|
|
|
8
8
|
def destroy_if_previously_invited
|
|
9
|
-
|
|
9
|
+
invitation_info = {}
|
|
10
10
|
|
|
11
11
|
hash = params[resource_name]
|
|
12
|
-
if hash && hash[:email]
|
|
12
|
+
if resource_class.modules.include?(:invitable) && hash && hash[:email]
|
|
13
13
|
resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first
|
|
14
14
|
if resource
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
invitation_info[:invitation_sent_at] = resource[:invitation_sent_at]
|
|
16
|
+
invitation_info[:invited_by_id] = resource[:invited_by_id]
|
|
17
|
+
invitation_info[:invited_by_type] = resource[:invited_by_type]
|
|
18
18
|
resource.destroy
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def keep_invitation_info
|
|
24
|
-
resource_invitable = resource_class.devise_modules.include?(:invitable)
|
|
25
|
-
destroy_if_previously_invited if resource_invitable
|
|
21
|
+
|
|
22
|
+
# execute the action (create)
|
|
26
23
|
yield
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def reset_invitation_info
|
|
31
|
-
puts @invitation_info.inspect
|
|
24
|
+
# Note that the after_filter is executed at THIS position !
|
|
25
|
+
|
|
32
26
|
# Restore info about the last invitation (for later reference)
|
|
33
27
|
# Reset the invitation_info only, if invited_by_id is still nil at this stage:
|
|
34
|
-
resource = resource_class.where(:email =>
|
|
35
|
-
puts resource.inspect
|
|
28
|
+
resource = resource_class.where(:email => hash[:email], :invited_by_id => nil).first
|
|
36
29
|
if resource
|
|
37
|
-
resource[:invitation_sent_at] =
|
|
38
|
-
resource[:invited_by_id] =
|
|
39
|
-
resource[:invited_by_type] =
|
|
30
|
+
resource[:invitation_sent_at] = invitation_info[:invitation_sent_at]
|
|
31
|
+
resource[:invited_by_id] = invitation_info[:invited_by_id]
|
|
32
|
+
resource[:invited_by_type] = invitation_info[:invited_by_type]
|
|
40
33
|
resource.save!
|
|
41
34
|
end
|
|
42
35
|
end
|
|
@@ -27,55 +27,99 @@ module Devise
|
|
|
27
27
|
attr_accessor :completing_invite
|
|
28
28
|
|
|
29
29
|
included do
|
|
30
|
-
include ::DeviseInvitable::Inviter
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
include ::DeviseInvitable::Inviter
|
|
31
|
+
if Devise.invited_by_class_name
|
|
32
|
+
belongs_to :invited_by, :class_name => Devise.invited_by_class_name
|
|
33
|
+
else
|
|
34
|
+
belongs_to :invited_by, :polymorphic => true
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
include ActiveSupport::Callbacks
|
|
34
38
|
define_callbacks :invitation_accepted
|
|
35
|
-
|
|
39
|
+
|
|
36
40
|
attr_writer :skip_password
|
|
41
|
+
|
|
42
|
+
scope :invitation_not_accepted, where(:invitation_accepted_at => nil)
|
|
43
|
+
if defined?(Mongoid) && self < Mongoid::Document
|
|
44
|
+
scope :invitation_accepted, where(:invitation_accepted_at.ne => nil)
|
|
45
|
+
else
|
|
46
|
+
scope :invitation_accepted, where(arel_table[:invitation_accepted_at].not_eq(nil))
|
|
47
|
+
|
|
48
|
+
[:before_invitation_accepted, :after_invitation_accepted].each do |callback_method|
|
|
49
|
+
send callback_method do
|
|
50
|
+
notify_observers callback_method
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.required_fields(klass)
|
|
57
|
+
fields = [:invitation_token, :invitation_sent_at, :invitation_accepted_at,
|
|
58
|
+
:invitation_limit, :invited_by_id, :invited_by_type]
|
|
59
|
+
if Devise.invited_by_class_name
|
|
60
|
+
fields -= :invited_by_type
|
|
61
|
+
end
|
|
62
|
+
fields
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def invitation_fields
|
|
66
|
+
fields = [:invitation_sent_at, :invited_by_id, :invited_by_type]
|
|
67
|
+
if Devise.invited_by_class_name
|
|
68
|
+
fields -= :invited_by_type
|
|
69
|
+
end
|
|
70
|
+
fields
|
|
37
71
|
end
|
|
38
72
|
|
|
39
73
|
# Accept an invitation by clearing invitation token and and setting invitation_accepted_at
|
|
40
74
|
# Confirms it if model is confirmable
|
|
41
75
|
def accept_invitation!
|
|
42
|
-
self.
|
|
76
|
+
self.invitation_accepted_at = Time.now.utc
|
|
43
77
|
if self.invited_to_sign_up? && self.valid?
|
|
44
78
|
run_callbacks :invitation_accepted do
|
|
45
79
|
self.invitation_token = nil
|
|
46
|
-
self.invitation_accepted_at = Time.now.utc if respond_to? :"invitation_accepted_at="
|
|
47
|
-
self.completing_invite = false
|
|
48
80
|
self.save(:validate => false)
|
|
49
81
|
end
|
|
50
82
|
end
|
|
51
83
|
end
|
|
52
84
|
|
|
53
|
-
# Verifies whether a user has accepted an
|
|
85
|
+
# Verifies whether a user has accepted an invitation (or is accepting it), or was never invited
|
|
54
86
|
def accepting_or_not_invited?
|
|
55
|
-
|
|
87
|
+
ActiveSupport::Deprecation.warn "accepting_or_not_invited? is deprecated and will be removed from DeviseInvitable 1.1.0 (use accepted_or_not_invited? instead)"
|
|
88
|
+
accepted_or_not_invited?
|
|
56
89
|
end
|
|
57
90
|
|
|
58
91
|
# Verifies whether a user has been invited or not
|
|
59
92
|
def invited_to_sign_up?
|
|
60
93
|
persisted? && invitation_token.present?
|
|
61
94
|
end
|
|
62
|
-
|
|
95
|
+
|
|
96
|
+
# Verifies whether a user accepted an invitation (or is accepting it)
|
|
97
|
+
def invitation_accepted?
|
|
98
|
+
invitation_accepted_at.present?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Verifies whether a user has accepted an invitation (or is accepting it), or was never invited
|
|
102
|
+
def accepted_or_not_invited?
|
|
103
|
+
invitation_accepted? || !invited_to_sign_up?
|
|
104
|
+
end
|
|
105
|
+
|
|
63
106
|
def invited?
|
|
107
|
+
ActiveSupport::Deprecation.warn "invited? is deprecated and will be removed from DeviseInvitable 1.1.0 (use invited_to_sign_up? instead)"
|
|
64
108
|
invited_to_sign_up?
|
|
65
109
|
end
|
|
66
|
-
deprecate :invited?
|
|
67
110
|
|
|
68
111
|
# Reset invitation token and send invitation again
|
|
69
|
-
def invite!
|
|
112
|
+
def invite!(invited_by = nil)
|
|
70
113
|
was_invited = invited_to_sign_up?
|
|
71
114
|
self.skip_confirmation! if self.new_record? && self.respond_to?(:skip_confirmation!)
|
|
72
115
|
generate_invitation_token if self.invitation_token.nil?
|
|
73
116
|
self.invitation_sent_at = Time.now.utc
|
|
74
|
-
|
|
117
|
+
self.invited_by = invited_by if invited_by
|
|
118
|
+
|
|
75
119
|
# Call these before_validate methods since we aren't validating on save
|
|
76
120
|
self.downcase_keys if self.new_record? && self.respond_to?(:downcase_keys)
|
|
77
121
|
self.strip_whitespace if self.new_record? && self.respond_to?(:strip_whitespace)
|
|
78
|
-
|
|
122
|
+
|
|
79
123
|
if save(:validate => false)
|
|
80
124
|
self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
|
|
81
125
|
deliver_invitation unless @skip_invitation
|
|
@@ -93,12 +137,12 @@ module Devise
|
|
|
93
137
|
def valid_password?(password)
|
|
94
138
|
super unless invited_to_sign_up?
|
|
95
139
|
end
|
|
96
|
-
|
|
140
|
+
|
|
97
141
|
def reset_password!(new_password, new_password_confirmation)
|
|
98
142
|
super
|
|
99
143
|
accept_invitation!
|
|
100
144
|
end
|
|
101
|
-
|
|
145
|
+
|
|
102
146
|
def invite_key_valid?
|
|
103
147
|
return true unless self.class.invite_key.is_a? Hash # FIXME: remove this line when deprecation is removed
|
|
104
148
|
self.class.invite_key.all? do |key, regexp|
|
|
@@ -114,7 +158,7 @@ module Devise
|
|
|
114
158
|
|
|
115
159
|
# Deliver the invitation email
|
|
116
160
|
def deliver_invitation
|
|
117
|
-
|
|
161
|
+
send_devise_notification(:invitation_instructions)
|
|
118
162
|
end
|
|
119
163
|
|
|
120
164
|
# Checks if the invitation for the user is within the limit time.
|
|
@@ -156,7 +200,7 @@ module Devise
|
|
|
156
200
|
Array(invite_key)
|
|
157
201
|
end
|
|
158
202
|
end
|
|
159
|
-
|
|
203
|
+
|
|
160
204
|
# Attempt to find a user by it's email. If a record is not found, create a new
|
|
161
205
|
# user and send invitation to it. If user is found, returns the user with an
|
|
162
206
|
# email already exists error.
|
|
@@ -190,7 +234,7 @@ module Devise
|
|
|
190
234
|
end
|
|
191
235
|
[invitable, mail]
|
|
192
236
|
end
|
|
193
|
-
|
|
237
|
+
|
|
194
238
|
# Override this method if the invitable is using Mass Assignment Security
|
|
195
239
|
# and the inviter has a non-default role.
|
|
196
240
|
def inviter_role(inviter)
|
|
@@ -226,16 +270,16 @@ module Devise
|
|
|
226
270
|
def invitation_token
|
|
227
271
|
generate_token(:invitation_token)
|
|
228
272
|
end
|
|
229
|
-
|
|
273
|
+
|
|
230
274
|
# Callback convenience methods
|
|
231
275
|
def before_invitation_accepted(*args, &blk)
|
|
232
276
|
set_callback(:invitation_accepted, :before, *args, &blk)
|
|
233
277
|
end
|
|
234
|
-
|
|
278
|
+
|
|
235
279
|
def after_invitation_accepted(*args, &blk)
|
|
236
280
|
set_callback(:invitation_accepted, :after, *args, &blk)
|
|
237
281
|
end
|
|
238
|
-
|
|
282
|
+
|
|
239
283
|
|
|
240
284
|
Devise::Models.config(self, :invite_for)
|
|
241
285
|
Devise::Models.config(self, :validate_on_invite)
|
|
@@ -52,7 +52,7 @@ module Devise
|
|
|
52
52
|
|
|
53
53
|
# Verifies whether a user has accepted an invite, was never invited, or is in the process of accepting an invitation, or not
|
|
54
54
|
def accepting_or_not_invited?
|
|
55
|
-
!!completing_invite ||
|
|
55
|
+
!!completing_invite || invited_to_sign_up?
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Verifies whether a user has been invited or not
|
|
@@ -98,13 +98,6 @@ module Devise
|
|
|
98
98
|
super
|
|
99
99
|
accept_invitation!
|
|
100
100
|
end
|
|
101
|
-
|
|
102
|
-
def invite_key_valid?
|
|
103
|
-
return true unless self.class.invite_key.is_a? Hash # FIXME: remove this line when deprecation is removed
|
|
104
|
-
self.class.invite_key.all? do |key, regexp|
|
|
105
|
-
regexp.nil? || self.send(key).try(:match, regexp)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
101
|
|
|
109
102
|
protected
|
|
110
103
|
# Overriding the method in Devise's :validatable module so password is not required on inviting
|
|
@@ -147,16 +140,6 @@ module Devise
|
|
|
147
140
|
end
|
|
148
141
|
|
|
149
142
|
module ClassMethods
|
|
150
|
-
# Return fields to invite
|
|
151
|
-
def invite_key_fields
|
|
152
|
-
if invite_key.is_a? Hash
|
|
153
|
-
invite_key.keys
|
|
154
|
-
else
|
|
155
|
-
ActiveSupport::Deprecation.warn("invite_key should be a hash like {#{invite_key.inspect} => /.../}")
|
|
156
|
-
Array(invite_key)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
143
|
# Attempt to find a user by it's email. If a record is not found, create a new
|
|
161
144
|
# user and send invitation to it. If user is found, returns the user with an
|
|
162
145
|
# email already exists error.
|
|
@@ -164,24 +147,16 @@ module Devise
|
|
|
164
147
|
# resend_invitation is set to false
|
|
165
148
|
# Attributes must contain the user email, other attributes will be set in the record
|
|
166
149
|
def _invite(attributes={}, invited_by=nil, &block)
|
|
167
|
-
|
|
168
|
-
attributes_hash = {}
|
|
169
|
-
invite_key_array.each do |k,v|
|
|
170
|
-
attributes_hash[k] = attributes.delete(k)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
invitable = find_or_initialize_with_errors(invite_key_array, attributes_hash)
|
|
150
|
+
invitable = find_or_initialize_with_error_by(invite_key, attributes.delete(invite_key))
|
|
174
151
|
invitable.assign_attributes(attributes, :as => inviter_role(invited_by))
|
|
175
152
|
invitable.invited_by = invited_by
|
|
176
153
|
|
|
177
154
|
invitable.skip_password = true
|
|
178
155
|
invitable.valid? if self.validate_on_invite
|
|
179
156
|
if invitable.new_record?
|
|
180
|
-
invitable.errors.clear if !self.validate_on_invite and invitable.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
invitable.errors.add(key, :taken)
|
|
184
|
-
end
|
|
157
|
+
invitable.errors.clear if !self.validate_on_invite and invitable.email.try(:match, Devise.email_regexp)
|
|
158
|
+
else
|
|
159
|
+
invitable.errors.add(invite_key, :taken) unless invitable.invited_to_sign_up? && self.resend_invitation
|
|
185
160
|
end
|
|
186
161
|
|
|
187
162
|
if invitable.errors.empty?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module ActionDispatch::Routing
|
|
2
2
|
class Mapper
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
protected
|
|
5
5
|
def devise_invitation(mapping, controllers)
|
|
6
6
|
resource :invitation, :only => [:new, :create, :update],
|
|
@@ -8,6 +8,6 @@ module ActionDispatch::Routing
|
|
|
8
8
|
get :edit, :path => mapping.path_names[:accept], :as => :accept
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
end
|
|
13
13
|
end
|
data/lib/devise_invitable.rb
CHANGED
|
@@ -54,6 +54,11 @@ module Devise
|
|
|
54
54
|
# config.resend_invitation = false
|
|
55
55
|
mattr_accessor :resend_invitation
|
|
56
56
|
@@resend_invitation = true
|
|
57
|
+
|
|
58
|
+
# Public: The class name of the inviting model. If this is nil,
|
|
59
|
+
# the #invited_by association is declared to be polymorphic. (default: nil)
|
|
60
|
+
mattr_accessor :invited_by_class_name
|
|
61
|
+
@@invited_by_class_name = nil
|
|
57
62
|
end
|
|
58
63
|
|
|
59
64
|
Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => :invitation
|
|
@@ -3,16 +3,16 @@ module DeviseInvitable
|
|
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
|
4
4
|
source_root File.expand_path("../../templates", __FILE__)
|
|
5
5
|
desc "Add DeviseInvitable config variables to the Devise initializer and copy DeviseInvitable locale files to your application."
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
# def devise_install
|
|
8
8
|
# invoke "devise:install"
|
|
9
9
|
# end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def add_config_options_to_initializer
|
|
12
12
|
devise_initializer_path = "config/initializers/devise.rb"
|
|
13
13
|
if File.exist?(devise_initializer_path)
|
|
14
14
|
old_content = File.read(devise_initializer_path)
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
if old_content.match(Regexp.new(/^\s# ==> Configuration for :invitable\n/))
|
|
17
17
|
false
|
|
18
18
|
else
|
|
@@ -23,20 +23,20 @@ module DeviseInvitable
|
|
|
23
23
|
# this period, the invited resource won't be able to accept the invitation.
|
|
24
24
|
# When invite_for is 0 (the default), the invitation won't expire.
|
|
25
25
|
# config.invite_for = 2.weeks
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
# Number of invitations users can send.
|
|
28
28
|
# If invitation_limit is nil, users can send unlimited invitations.
|
|
29
29
|
# If invitation_limit is 0, users can't send invitations.
|
|
30
30
|
# If invitation_limit n > 0, users can send n invitations.
|
|
31
31
|
# Default: nil
|
|
32
32
|
# config.invitation_limit = 5
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# The key to be used to check existing users when sending an invitation
|
|
35
35
|
# and the regexp used to test it when validate_on_invite is not set.
|
|
36
36
|
# config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
|
|
37
37
|
# config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :username => nil}
|
|
38
|
-
|
|
39
|
-
# Flag that force a record to be valid before being actually invited
|
|
38
|
+
|
|
39
|
+
# Flag that force a record to be valid before being actually invited
|
|
40
40
|
# Default: false
|
|
41
41
|
# config.validate_on_invite = true
|
|
42
42
|
|
|
@@ -45,11 +45,11 @@ CONTENT
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
def copy_locale
|
|
50
50
|
copy_file "../../../config/locales/en.yml", "config/locales/devise_invitable.en.yml"
|
|
51
51
|
end
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<h2><%= t 'devise.invitations.edit.header' %></h2>
|
|
2
|
+
|
|
3
|
+
<%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
|
|
4
|
+
<%= devise_error_messages! %>
|
|
5
|
+
<%= f.hidden_field :invitation_token %>
|
|
6
|
+
|
|
7
|
+
<%= f.input :password %>
|
|
8
|
+
<%= f.input :password_confirmation %>
|
|
9
|
+
|
|
10
|
+
<%= f.submit t("devise.invitations.edit.submit_button") %>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<h2><%= t "devise.invitations.new.header" %></h2>
|
|
2
|
+
|
|
3
|
+
<%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
|
|
4
|
+
<%= devise_error_messages! %>
|
|
5
|
+
|
|
6
|
+
<% resource.class.invite_key_fields.each do |field| -%>
|
|
7
|
+
<%= f.input field %>
|
|
8
|
+
<% end -%>
|
|
9
|
+
|
|
10
|
+
<%= f.submit t("devise.invitations.new.submit_button") %>
|
|
11
|
+
<% end %>
|
|
@@ -2,18 +2,40 @@ require 'generators/devise/views_generator'
|
|
|
2
2
|
|
|
3
3
|
module DeviseInvitable
|
|
4
4
|
module Generators
|
|
5
|
-
class
|
|
6
|
-
|
|
5
|
+
class InvitationViewsGenerator < Rails::Generators::Base
|
|
6
|
+
include ::Devise::Generators::ViewPathTemplates
|
|
7
|
+
|
|
8
|
+
def copy_views
|
|
9
|
+
view_directory :invitations
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class SimpleFormForGenerator < InvitationViewsGenerator
|
|
14
|
+
source_root File.expand_path("../templates/simple_form_for", __FILE__)
|
|
15
|
+
end
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
17
|
+
class FormForGenerator < InvitationViewsGenerator
|
|
18
|
+
source_root File.expand_path("../../../../app/views/devise", __FILE__)
|
|
19
|
+
end
|
|
10
20
|
|
|
21
|
+
class MailerViewsGenerator < Rails::Generators::Base
|
|
11
22
|
include ::Devise::Generators::ViewPathTemplates
|
|
12
23
|
source_root File.expand_path("../../../../app/views/devise", __FILE__)
|
|
24
|
+
desc "Copies Devise mail erb views to your application."
|
|
25
|
+
hide!
|
|
26
|
+
|
|
13
27
|
def copy_views
|
|
14
|
-
view_directory :invitations
|
|
15
28
|
view_directory :mailer
|
|
16
29
|
end
|
|
17
30
|
end
|
|
31
|
+
|
|
32
|
+
class ViewsGenerator < Rails::Generators::Base
|
|
33
|
+
desc 'Copies all DeviseInvitable views to your application.'
|
|
34
|
+
argument :scope, :required => false, :default => nil, :desc => "The scope to copy views to"
|
|
35
|
+
|
|
36
|
+
invoke MailerViewsGenerator
|
|
37
|
+
|
|
38
|
+
hook_for :form_builder, :aliases => "-b", :desc => "Form builder to be used", :default => defined?(SimpleForm) ? "simple_form_for" : "form_for"
|
|
39
|
+
end
|
|
18
40
|
end
|
|
19
41
|
end
|
metadata
CHANGED
|
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
|
+
- 1
|
|
8
9
|
- 0
|
|
9
|
-
|
|
10
|
-
version: 1.0.2
|
|
10
|
+
version: 1.1.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Sergio Cambra
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2012-
|
|
18
|
+
date: 2012-08-20 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: bundler
|
|
@@ -23,7 +23,7 @@ dependencies:
|
|
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
24
|
none: false
|
|
25
25
|
requirements:
|
|
26
|
-
- -
|
|
26
|
+
- - ">="
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
28
|
hash: 19
|
|
29
29
|
segments:
|
|
@@ -34,7 +34,7 @@ dependencies:
|
|
|
34
34
|
type: :development
|
|
35
35
|
version_requirements: *id001
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
|
-
name:
|
|
37
|
+
name: railties
|
|
38
38
|
prerelease: false
|
|
39
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
|
40
40
|
none: false
|
|
@@ -49,21 +49,36 @@ dependencies:
|
|
|
49
49
|
type: :runtime
|
|
50
50
|
version_requirements: *id002
|
|
51
51
|
- !ruby/object:Gem::Dependency
|
|
52
|
-
name:
|
|
52
|
+
name: actionmailer
|
|
53
53
|
prerelease: false
|
|
54
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ~>
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
hash: 7
|
|
60
|
+
segments:
|
|
61
|
+
- 3
|
|
62
|
+
- 0
|
|
63
|
+
version: "3.0"
|
|
64
|
+
type: :runtime
|
|
65
|
+
version_requirements: *id003
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: devise
|
|
68
|
+
prerelease: false
|
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
55
70
|
none: false
|
|
56
71
|
requirements:
|
|
57
72
|
- - ">="
|
|
58
73
|
- !ruby/object:Gem::Version
|
|
59
|
-
hash:
|
|
74
|
+
hash: 11
|
|
60
75
|
segments:
|
|
61
76
|
- 2
|
|
77
|
+
- 1
|
|
62
78
|
- 0
|
|
63
|
-
|
|
64
|
-
version: 2.0.0
|
|
79
|
+
version: 2.1.0
|
|
65
80
|
type: :runtime
|
|
66
|
-
version_requirements: *
|
|
81
|
+
version_requirements: *id004
|
|
67
82
|
description: It adds support for send invitations by email (it requires to be authenticated) and accept the invitation by setting a password.
|
|
68
83
|
email:
|
|
69
84
|
- sergio@entrecables.com
|
|
@@ -74,33 +89,31 @@ extensions: []
|
|
|
74
89
|
extra_rdoc_files: []
|
|
75
90
|
|
|
76
91
|
files:
|
|
77
|
-
- app/
|
|
78
|
-
- app/views/devise/invitations/new.html.erb~
|
|
92
|
+
- app/controllers/devise/invitations_controller.rb
|
|
79
93
|
- app/views/devise/invitations/edit.html.erb
|
|
80
94
|
- app/views/devise/invitations/new.html.erb
|
|
81
|
-
- app/
|
|
82
|
-
- app/controllers/devise/invitations_controller.rb~
|
|
95
|
+
- app/views/devise/mailer/invitation_instructions.html.erb
|
|
83
96
|
- config/locales/en.yml
|
|
84
97
|
- lib/devise_invitable.rb
|
|
85
|
-
- lib/devise_invitable.rb
|
|
86
|
-
- lib/devise_invitable/routes.rb
|
|
98
|
+
- lib/devise_invitable/mailer.rb
|
|
87
99
|
- lib/devise_invitable/model.rb
|
|
88
100
|
- lib/devise_invitable/rails.rb
|
|
89
|
-
- lib/devise_invitable/
|
|
101
|
+
- lib/devise_invitable/routes.rb
|
|
90
102
|
- lib/devise_invitable/version.rb
|
|
91
|
-
- lib/devise_invitable/model.rb~
|
|
92
|
-
- lib/devise_invitable/inviter.rb
|
|
93
|
-
- lib/devise_invitable/controllers/url_helpers.rb
|
|
94
103
|
- lib/devise_invitable/controllers/helpers.rb
|
|
95
|
-
- lib/devise_invitable/controllers/
|
|
104
|
+
- lib/devise_invitable/controllers/url_helpers.rb
|
|
96
105
|
- lib/devise_invitable/controllers/registrations.rb
|
|
97
|
-
- lib/
|
|
106
|
+
- lib/devise_invitable/controllers/registrations.rb~
|
|
107
|
+
- lib/devise_invitable/inviter.rb
|
|
108
|
+
- lib/devise_invitable/model.rb~
|
|
98
109
|
- lib/generators/active_record/devise_invitable_generator.rb
|
|
99
|
-
- lib/generators/
|
|
100
|
-
- lib/generators/devise_invitable/install_generator.rb
|
|
110
|
+
- lib/generators/active_record/templates/migration.rb
|
|
101
111
|
- lib/generators/devise_invitable/views_generator.rb
|
|
102
112
|
- lib/generators/devise_invitable/devise_invitable_generator.rb
|
|
103
|
-
- lib/generators/devise_invitable/install_generator.rb
|
|
113
|
+
- lib/generators/devise_invitable/install_generator.rb
|
|
114
|
+
- lib/generators/devise_invitable/templates/simple_form_for/invitations/edit.html.erb
|
|
115
|
+
- lib/generators/devise_invitable/templates/simple_form_for/invitations/new.html.erb
|
|
116
|
+
- lib/generators/mongoid/devise_invitable_generator.rb
|
|
104
117
|
- LICENSE
|
|
105
118
|
- README.rdoc
|
|
106
119
|
homepage: https://github.com/scambra/devise_invitable
|
|
@@ -138,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
138
151
|
requirements: []
|
|
139
152
|
|
|
140
153
|
rubyforge_project:
|
|
141
|
-
rubygems_version: 1.8.
|
|
154
|
+
rubygems_version: 1.8.23
|
|
142
155
|
signing_key:
|
|
143
156
|
specification_version: 3
|
|
144
157
|
summary: An invitation strategy for Devise
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
class Devise::InvitationsController < ApplicationController
|
|
2
|
-
include Devise::Controllers::InternalHelpers
|
|
3
|
-
|
|
4
|
-
before_filter :authenticate_inviter!, :only => [:new, :create]
|
|
5
|
-
before_filter :require_no_authentication, :only => [:edit, :update]
|
|
6
|
-
helper_method :after_sign_in_path_for
|
|
7
|
-
|
|
8
|
-
# GET /resource/invitation/new
|
|
9
|
-
def new
|
|
10
|
-
build_resource
|
|
11
|
-
render_with_scope :new
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# POST /resource/invitation
|
|
15
|
-
def create
|
|
16
|
-
self.resource = resource_class.invite!(params[resource_name])
|
|
17
|
-
|
|
18
|
-
if resource.errors.empty?
|
|
19
|
-
puts params.inspect
|
|
20
|
-
set_flash_message :notice, :send_instructions, :email => self.resource.email
|
|
21
|
-
redirect_to after_sign_in_path_for(resource_name)
|
|
22
|
-
else
|
|
23
|
-
render_with_scope :new
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# GET /resource/invitation/accept?invitation_token=abcdef
|
|
28
|
-
def edit
|
|
29
|
-
if params[:invitation_token] && self.resource = resource_class.first(:conditions => { :invitation_token => params[:invitation_token] })
|
|
30
|
-
render_with_scope :edit
|
|
31
|
-
else
|
|
32
|
-
set_flash_message(:alert, :invitation_token_invalid)
|
|
33
|
-
redirect_to after_sign_out_path_for(resource_name)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# PUT /resource/invitation
|
|
38
|
-
def update
|
|
39
|
-
self.resource = resource_class.accept_invitation!(params[resource_name])
|
|
40
|
-
|
|
41
|
-
if resource.errors.empty?
|
|
42
|
-
set_flash_message :notice, :updated
|
|
43
|
-
sign_in_and_redirect(resource_name, resource)
|
|
44
|
-
else
|
|
45
|
-
render_with_scope :edit
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<h2>Send invitation</h2>
|
|
2
|
-
|
|
3
|
-
<%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
|
|
4
|
-
<%= devise_error_messages! %>
|
|
5
|
-
|
|
6
|
-
<% Array(resource.class.invite_key).each do |field| -%>
|
|
7
|
-
<p><%= f.label field %><br />
|
|
8
|
-
<%= f.text_field field %></p>
|
|
9
|
-
<% end -%>
|
|
10
|
-
|
|
11
|
-
<p><%= f.submit "Send an invitation" %></p>
|
|
12
|
-
<% end %>
|
|
13
|
-
|
|
14
|
-
<%= link_to "Home", after_sign_in_path_for(resource_name) %><br />
|
data/lib/devise_invitable.rb~
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require 'devise'
|
|
2
|
-
|
|
3
|
-
module DeviseInvitable
|
|
4
|
-
autoload :Inviter, 'devise_invitable/inviter'
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
require 'devise_invitable/mailer'
|
|
8
|
-
require 'devise_invitable/routes'
|
|
9
|
-
require 'devise_invitable/controllers/url_helpers'
|
|
10
|
-
require 'devise_invitable/controllers/registrations'
|
|
11
|
-
require 'devise_invitable/controllers/helpers'
|
|
12
|
-
require 'devise_invitable/rails'
|
|
13
|
-
|
|
14
|
-
module Devise
|
|
15
|
-
# Public: Validity period of the invitation token (default: 0). If
|
|
16
|
-
# invite_for is 0 or nil, the invitation will never expire.
|
|
17
|
-
# Set invite_for in the Devise configuration file (in config/initializers/devise.rb).
|
|
18
|
-
#
|
|
19
|
-
# config.invite_for = 2.weeks # => The invitation token will be valid 2 weeks
|
|
20
|
-
mattr_accessor :invite_for
|
|
21
|
-
@@invite_for = 0
|
|
22
|
-
|
|
23
|
-
# Public: Flag that force a record to be valid before being actually invited
|
|
24
|
-
# (default: false).
|
|
25
|
-
#
|
|
26
|
-
# Examples (in config/initializers/devise.rb)
|
|
27
|
-
#
|
|
28
|
-
# config.validate_on_invite = true
|
|
29
|
-
mattr_accessor :validate_on_invite
|
|
30
|
-
@@validate_on_invite = false
|
|
31
|
-
|
|
32
|
-
# Public: number of invitations the user is allowed to send
|
|
33
|
-
#
|
|
34
|
-
# Examples (in config/initializers/devise.rb)
|
|
35
|
-
#
|
|
36
|
-
# config.invitation_limit = nil
|
|
37
|
-
mattr_accessor :invitation_limit
|
|
38
|
-
@@invitation_limit = nil
|
|
39
|
-
|
|
40
|
-
# Public: The key to be used to check existing users when sending an invitation.
|
|
41
|
-
# It can be an array.
|
|
42
|
-
#
|
|
43
|
-
# Examples (in config/initializers/devise.rb)
|
|
44
|
-
#
|
|
45
|
-
# config.invite_key = :email
|
|
46
|
-
mattr_accessor :invite_key
|
|
47
|
-
@@invite_key = :email
|
|
48
|
-
|
|
49
|
-
# Public: The regexp to be used to test invite key when sending an invitation.
|
|
50
|
-
# It must be a hash indexed by invite_key
|
|
51
|
-
#
|
|
52
|
-
# Examples (in config/initializers/devise.rb)
|
|
53
|
-
#
|
|
54
|
-
# config.invite_key = :email
|
|
55
|
-
mattr_accessor :invite_key_validation_regexp
|
|
56
|
-
@@invite_key_validation_regexp = {:email => Devise.email_regexp}
|
|
57
|
-
|
|
58
|
-
# Public: Resend invitation if user with invited status is invited again
|
|
59
|
-
# (default: true)
|
|
60
|
-
#
|
|
61
|
-
# Example (in config/initializers/devise.rb)
|
|
62
|
-
#
|
|
63
|
-
# config.resend_invitation = false
|
|
64
|
-
mattr_accessor :resend_invitation
|
|
65
|
-
@@resend_invitation = true
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => :invitation
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
module DeviseInvitable
|
|
2
|
-
module Generators
|
|
3
|
-
class InstallGenerator < Rails::Generators::Base
|
|
4
|
-
source_root File.expand_path("../../templates", __FILE__)
|
|
5
|
-
desc "Add DeviseInvitable config variables to the Devise initializer and copy DeviseInvitable locale files to your application."
|
|
6
|
-
|
|
7
|
-
# def devise_install
|
|
8
|
-
# invoke "devise:install"
|
|
9
|
-
# end
|
|
10
|
-
|
|
11
|
-
def add_config_options_to_initializer
|
|
12
|
-
devise_initializer_path = "config/initializers/devise.rb"
|
|
13
|
-
if File.exist?(devise_initializer_path)
|
|
14
|
-
old_content = File.read(devise_initializer_path)
|
|
15
|
-
|
|
16
|
-
if old_content.match(Regexp.new(/^\s# ==> Configuration for :invitable\n/))
|
|
17
|
-
false
|
|
18
|
-
else
|
|
19
|
-
inject_into_file(devise_initializer_path, :before => " # ==> Configuration for :confirmable\n") do
|
|
20
|
-
<<-CONTENT
|
|
21
|
-
# ==> Configuration for :invitable
|
|
22
|
-
# The period the generated invitation token is valid, after
|
|
23
|
-
# this period, the invited resource won't be able to accept the invitation.
|
|
24
|
-
# When invite_for is 0 (the default), the invitation won't expire.
|
|
25
|
-
# config.invite_for = 2.weeks
|
|
26
|
-
|
|
27
|
-
# Number of invitations users can send.
|
|
28
|
-
# If invitation_limit is nil, users can send unlimited invitations.
|
|
29
|
-
# If invitation_limit is 0, users can't send invitations.
|
|
30
|
-
# If invitation_limit n > 0, users can send n invitations.
|
|
31
|
-
# Default: nil
|
|
32
|
-
# config.invitation_limit = 5
|
|
33
|
-
|
|
34
|
-
# The key to be used to check existing users when sending an invitation.
|
|
35
|
-
# config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
|
|
36
|
-
# config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :username => nil}
|
|
37
|
-
|
|
38
|
-
# Flag that force a record to be valid before being actually invited
|
|
39
|
-
# Default: false
|
|
40
|
-
# config.validate_on_invite = true
|
|
41
|
-
|
|
42
|
-
CONTENT
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def copy_locale
|
|
49
|
-
copy_file "../../../config/locales/en.yml", "config/locales/devise_invitable.en.yml"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|