devise_invitable 2.0.2 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +696 -0
- data/app/controllers/devise/invitations_controller.rb +3 -3
- data/config/locales/ar.yml +23 -0
- data/config/locales/ca.yml +32 -0
- data/config/locales/da.yml +41 -0
- data/config/locales/de.yml +31 -0
- data/config/locales/es.yml +31 -0
- data/config/locales/et.yml +23 -0
- data/config/locales/fa.yml +31 -0
- data/config/locales/fr.yml +31 -0
- data/config/locales/id.yml +31 -0
- data/config/locales/it.yml +31 -0
- data/config/locales/ja.yml +31 -0
- data/config/locales/ko.yml +24 -0
- data/config/locales/nl.yml +32 -0
- data/config/locales/no.yml +17 -0
- data/config/locales/pl.yml +31 -0
- data/config/locales/pt-BR.yml +23 -0
- data/config/locales/pt.yml +23 -0
- data/config/locales/ru.yml +23 -0
- data/config/locales/tr.yml +24 -0
- data/config/locales/ua.yml +31 -0
- data/config/locales/vi.yml +25 -0
- data/config/locales/zh-CN.yml +31 -0
- data/config/locales/zh-HK.yml +31 -0
- data/config/locales/zh-TW.yml +34 -0
- data/lib/devise_invitable/controllers/helpers.rb +4 -0
- data/lib/devise_invitable/mapping.rb +4 -2
- data/lib/devise_invitable/models/authenticatable.rb +7 -1
- data/lib/devise_invitable/models.rb +16 -12
- data/lib/devise_invitable/version.rb +1 -1
- data/lib/generators/active_record/templates/migration.rb +0 -1
- data/lib/generators/devise_invitable/devise_invitable_generator.rb +1 -1
- data/test/functional/controller_helpers_test.rb +10 -0
- data/test/generators_test.rb +3 -2
- data/test/integration/invitation_test.rb +1 -1
- data/test/mailers/invitation_mail_test.rb +1 -1
- data/test/model_tests_helper.rb +1 -1
- data/test/models/invitable_test.rb +80 -11
- data/test/orm/active_record.rb +10 -5
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -2
- data/test/test_helper.rb +10 -2
- metadata +31 -11
- data/README.rdoc +0 -439
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
zh-CN:
|
|
2
|
+
devise:
|
|
3
|
+
failure:
|
|
4
|
+
invited: "您有一封待处理的帐号邀请,请接受邀请完成创建您的帐号。"
|
|
5
|
+
invitations:
|
|
6
|
+
send_instructions: "邀请电子邮件已发送至 %{email}。"
|
|
7
|
+
invitation_token_invalid: "所提供的邀请验证无效!"
|
|
8
|
+
updated: "您的密码已设置成功,。现在您已经登入了。"
|
|
9
|
+
updated_not_active: "您的密码已设置成功。"
|
|
10
|
+
no_invitations_remaining: "没有待处理的邀请"
|
|
11
|
+
invitation_removed: "您的邀请被删除了。"
|
|
12
|
+
new:
|
|
13
|
+
header: "发送邀请"
|
|
14
|
+
submit_button: "发送邀请"
|
|
15
|
+
edit:
|
|
16
|
+
header: "设置您的密码"
|
|
17
|
+
submit_button: "设置密码"
|
|
18
|
+
mailer:
|
|
19
|
+
invitation_instructions:
|
|
20
|
+
subject: "邀请"
|
|
21
|
+
hello: "%{email} 您好"
|
|
22
|
+
someone_invited_you: "邀请您加入 %{url},您可以通过以下的网页链接接受邀请,并创设帐号:"
|
|
23
|
+
accept: "接受邀请"
|
|
24
|
+
accept_until: "这封邀请将于 %{due_date} 到期。"
|
|
25
|
+
ignore: "如果您不想接受邀请,请忽略这封电子邮件。只要未选取上述“接受邀请”的链接并且设置密码,您的帐号就不会成立。"
|
|
26
|
+
time:
|
|
27
|
+
formats:
|
|
28
|
+
devise:
|
|
29
|
+
mailer:
|
|
30
|
+
invitation_instructions:
|
|
31
|
+
accept_until_format: "%B %d, %Y %I:%M %p"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
zh-HK:
|
|
2
|
+
devise:
|
|
3
|
+
failure:
|
|
4
|
+
invited: "你有一個待處理的邀請, 請接受它以完成創建您的帳戶。"
|
|
5
|
+
invitations:
|
|
6
|
+
send_instructions: "邀請電子郵件已發送到%{email)。"
|
|
7
|
+
invitation_token_invalid: "提供嘅邀請令牌無效!"
|
|
8
|
+
updated: "你嘅密碼設置成功。 你而家已經登錄。"
|
|
9
|
+
updated_not_active: "你嘅密碼設置成功。"
|
|
10
|
+
no_invitations_remaining: "冇剩餘邀請"
|
|
11
|
+
invitation_removed: "你嘅邀請已被刪除。"
|
|
12
|
+
new:
|
|
13
|
+
header: "發送邀請"
|
|
14
|
+
submit_button: "發送邀請"
|
|
15
|
+
edit:
|
|
16
|
+
header: "設置密碼"
|
|
17
|
+
submit_button: "設置密碼"
|
|
18
|
+
mailer:
|
|
19
|
+
invitation_instructions:
|
|
20
|
+
subject: "邀請指示"
|
|
21
|
+
hello: "你好%{email}"
|
|
22
|
+
someone_invited_you: "有人邀請你去%{url}, 你可以通過下面嘅連結接受它。"
|
|
23
|
+
accept: "接受邀請"
|
|
24
|
+
accept_until: "此邀請就喺%{due_date} 中到期。"
|
|
25
|
+
ignore: "如果你唔想接受邀請, 請忽略此電子郵件。 系你訪問上面的連結並設置密碼之前, 不會創建您的帳戶。"
|
|
26
|
+
time:
|
|
27
|
+
formats:
|
|
28
|
+
devise:
|
|
29
|
+
mailer:
|
|
30
|
+
invitation_instructions:
|
|
31
|
+
accept_until_format: "%B %d, %Y %I:%M %p"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
zh-TW:
|
|
2
|
+
devise:
|
|
3
|
+
failure:
|
|
4
|
+
invited: "你有一封設立帳號的邀請,請接受邀請來創建你的帳號。"
|
|
5
|
+
invitations:
|
|
6
|
+
send_instructions: "邀請已發送至%{email)"
|
|
7
|
+
invitation_token_invalid: "所提供的邀請驗證無效!"
|
|
8
|
+
updated: "你的密碼已設置成功,現在你已經登入了。"
|
|
9
|
+
updated_not_active: "密碼設置成功"
|
|
10
|
+
no_invitations_remaining: "邀請名額已用盡"
|
|
11
|
+
invitation_removed: "你的邀請被刪除了"
|
|
12
|
+
new:
|
|
13
|
+
header: "發送邀請"
|
|
14
|
+
submit_button: "發送邀請"
|
|
15
|
+
edit:
|
|
16
|
+
header: "設置密碼"
|
|
17
|
+
submit_button: "設置密碼"
|
|
18
|
+
mailer:
|
|
19
|
+
invitation_instructions:
|
|
20
|
+
subject: "邀請"
|
|
21
|
+
hello: "%{email} 你好,"
|
|
22
|
+
someone_invited_you: “邀請你加入%{url}。你可以通過以下的網頁連結接受邀請,並創設帳號:"
|
|
23
|
+
accept: "接受邀請"
|
|
24
|
+
accept_until: "這封邀請將於 %{due_date} 到期。"
|
|
25
|
+
ignore:
|
|
26
|
+
"如果你不想接受邀請,
|
|
27
|
+
請忽略這封電子郵件。只要未選取上述“接受邀請”的連結並且設置密碼,你的帳號就不會成立。"
|
|
28
|
+
|
|
29
|
+
time:
|
|
30
|
+
formats:
|
|
31
|
+
devise:
|
|
32
|
+
mailer:
|
|
33
|
+
invitation_instructions:
|
|
34
|
+
accept_until_format: "%B %d, %Y %I:%M %p"
|
|
@@ -3,8 +3,10 @@ module DeviseInvitable
|
|
|
3
3
|
private
|
|
4
4
|
|
|
5
5
|
def default_controllers(options)
|
|
6
|
-
options[:
|
|
7
|
-
|
|
6
|
+
unless options[:module]
|
|
7
|
+
options[:controllers] ||= {}
|
|
8
|
+
options[:controllers][:registrations] ||= 'devise_invitable/registrations'
|
|
9
|
+
end
|
|
8
10
|
super
|
|
9
11
|
end
|
|
10
12
|
end
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
module Devise
|
|
2
2
|
module Models
|
|
3
3
|
module Authenticatable
|
|
4
|
-
|
|
4
|
+
list = %i[
|
|
5
5
|
invitation_token invitation_created_at invitation_sent_at
|
|
6
6
|
invitation_accepted_at invitation_limit invited_by_type
|
|
7
7
|
invited_by_id invitations_count
|
|
8
8
|
]
|
|
9
|
+
|
|
10
|
+
if defined?(UNSAFE_ATTRIBUTES_FOR_SERIALIZATION)
|
|
11
|
+
UNSAFE_ATTRIBUTES_FOR_SERIALIZATION.concat(list)
|
|
12
|
+
else
|
|
13
|
+
BLACKLIST_FOR_SERIALIZATION.concat(list)
|
|
14
|
+
end
|
|
9
15
|
end
|
|
10
16
|
end
|
|
11
17
|
end
|
|
@@ -30,12 +30,12 @@ module Devise
|
|
|
30
30
|
|
|
31
31
|
included do
|
|
32
32
|
include ::DeviseInvitable::Inviter
|
|
33
|
-
belongs_to_options = if
|
|
34
|
-
{ class_name:
|
|
33
|
+
belongs_to_options = if invited_by_class_name
|
|
34
|
+
{ class_name: invited_by_class_name }
|
|
35
35
|
else
|
|
36
36
|
{ polymorphic: true }
|
|
37
37
|
end
|
|
38
|
-
if fk =
|
|
38
|
+
if fk = invited_by_foreign_key
|
|
39
39
|
belongs_to_options[:foreign_key] = fk
|
|
40
40
|
end
|
|
41
41
|
if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && self < ActiveRecord::Base
|
|
@@ -76,9 +76,9 @@ module Devise
|
|
|
76
76
|
|
|
77
77
|
def self.required_fields(klass)
|
|
78
78
|
fields = [:invitation_token, :invitation_created_at, :invitation_sent_at, :invitation_accepted_at,
|
|
79
|
-
:invitation_limit,
|
|
79
|
+
:invitation_limit, klass.invited_by_foreign_key || :invited_by_id, :invited_by_type]
|
|
80
80
|
fields << :invitations_count if defined?(ActiveRecord) && self < ActiveRecord::Base
|
|
81
|
-
fields -= [:invited_by_type] if
|
|
81
|
+
fields -= [:invited_by_type] if klass.invited_by_class_name
|
|
82
82
|
fields
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -158,7 +158,8 @@ module Devise
|
|
|
158
158
|
self.downcase_keys if new_record_and_responds_to?(:downcase_keys)
|
|
159
159
|
self.strip_whitespace if new_record_and_responds_to?(:strip_whitespace)
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
validate = options.key?(:validate) ? options[:validate] : self.class.validate_on_invite
|
|
162
|
+
if save(validate: validate)
|
|
162
163
|
self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
|
|
163
164
|
deliver_invitation(options) unless skip_invitation
|
|
164
165
|
end
|
|
@@ -194,7 +195,7 @@ module Devise
|
|
|
194
195
|
def clear_reset_password_token
|
|
195
196
|
reset_password_token_present = reset_password_token.present?
|
|
196
197
|
super
|
|
197
|
-
accept_invitation! if reset_password_token_present &&
|
|
198
|
+
accept_invitation! if reset_password_token_present && valid_invitation?
|
|
198
199
|
end
|
|
199
200
|
|
|
200
201
|
def clear_errors_on_valid_keys
|
|
@@ -221,16 +222,16 @@ module Devise
|
|
|
221
222
|
|
|
222
223
|
def invitation_due_at
|
|
223
224
|
return nil if (self.class.invite_for == 0 || self.class.invite_for.nil?)
|
|
224
|
-
#return nil unless self.class.invite_for
|
|
225
225
|
|
|
226
|
-
time = self.invitation_created_at || self.invitation_sent_at
|
|
226
|
+
return unless (time = self.invitation_created_at || self.invitation_sent_at)
|
|
227
|
+
|
|
227
228
|
time + self.class.invite_for
|
|
228
229
|
end
|
|
229
230
|
|
|
230
231
|
def add_taken_error(key)
|
|
231
232
|
errors.add(key, :taken)
|
|
232
233
|
end
|
|
233
|
-
|
|
234
|
+
|
|
234
235
|
def invitation_taken?
|
|
235
236
|
!invited_to_sign_up?
|
|
236
237
|
end
|
|
@@ -324,7 +325,7 @@ module Devise
|
|
|
324
325
|
end
|
|
325
326
|
|
|
326
327
|
yield invitable if block_given?
|
|
327
|
-
mail = invitable.invite!(nil, options) if invitable.errors.empty?
|
|
328
|
+
mail = invitable.invite!(nil, options.merge(validate: false)) if invitable.errors.empty?
|
|
328
329
|
[invitable, mail]
|
|
329
330
|
end
|
|
330
331
|
|
|
@@ -397,7 +398,10 @@ module Devise
|
|
|
397
398
|
# lower + upper case, a digit and a symbol.
|
|
398
399
|
# For more unusual rules, this method can be overridden.
|
|
399
400
|
def random_password
|
|
400
|
-
|
|
401
|
+
length = respond_to?(:password_length) ? password_length : Devise.password_length
|
|
402
|
+
|
|
403
|
+
prefix = 'aA1!'
|
|
404
|
+
prefix + Devise.friendly_token(length.last - prefix.length)
|
|
401
405
|
end
|
|
402
406
|
end
|
|
403
407
|
end
|
|
@@ -8,7 +8,6 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration<%
|
|
|
8
8
|
t.integer :invitation_limit
|
|
9
9
|
t.references :invited_by, polymorphic: true
|
|
10
10
|
t.integer :invitations_count, default: 0
|
|
11
|
-
t.index :invitations_count
|
|
12
11
|
t.index :invitation_token, unique: true # for invitable
|
|
13
12
|
t.index :invited_by_id
|
|
14
13
|
end
|
|
@@ -7,7 +7,7 @@ module DeviseInvitable
|
|
|
7
7
|
|
|
8
8
|
def inject_devise_invitable_content
|
|
9
9
|
path = File.join('app', 'models', "#{file_path}.rb")
|
|
10
|
-
inject_into_file(path, 'invitable, :', after: 'devise :') if File.
|
|
10
|
+
inject_into_file(path, 'invitable, :', after: 'devise :') if File.exist?(path)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
hook_for :orm
|
|
@@ -41,4 +41,14 @@ class ControllerHelpersTest < ActionController::TestCase
|
|
|
41
41
|
assert Devise::InvitationsController.method_defined? :after_accept_path_for
|
|
42
42
|
assert !Devise::InvitationsController.instance_methods(false).include?(:after_accept_path_for)
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
test 'invalid token path defaults to after sign out path' do
|
|
46
|
+
assert_equal @controller.send(:after_sign_out_path_for, :user), @controller.invalid_token_path_for(:user)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test 'invalid token path is customizable from application controller' do
|
|
50
|
+
custom_path = 'customized/invalid/token/path'
|
|
51
|
+
@controller.instance_eval "def invalid_token_path_for(resource_name) '#{custom_path}' end"
|
|
52
|
+
assert_equal @controller.invalid_token_path_for(:user), custom_path
|
|
53
|
+
end
|
|
44
54
|
end
|
data/test/generators_test.rb
CHANGED
|
@@ -17,13 +17,14 @@ class GeneratorsTest < ActiveSupport::TestCase
|
|
|
17
17
|
|
|
18
18
|
test "rails g devise_invitable:install" do
|
|
19
19
|
@output = `cd #{RAILS_APP_PATH} && rails g devise_invitable:install -p`
|
|
20
|
-
|
|
20
|
+
puts @output
|
|
21
|
+
assert @output.match(%r{(inject|insert|File unchanged! The supplied flag value not found!).* config/initializers/devise\.rb\n})
|
|
21
22
|
assert @output.match(%r|create.* config/locales/devise_invitable\.en\.yml\n|)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
test "rails g devise_invitable Octopussy" do
|
|
25
26
|
@output = `cd #{RAILS_APP_PATH} && rails g devise_invitable Octopussy -p`
|
|
26
|
-
assert @output.match(%r{(inject|insert).* app/models/octopussy\.rb\n})
|
|
27
|
+
assert @output.match(%r{(inject|insert|File unchanged! The supplied flag value not found!).* app/models/octopussy\.rb\n})
|
|
27
28
|
assert @output.match(%r|invoke.* #{DEVISE_ORM}\n|)
|
|
28
29
|
if DEVISE_ORM == :active_record
|
|
29
30
|
assert @output.match(%r|create.* db/migrate/\d{14}_devise_invitable_add_to_octopussies\.rb\n|)
|
|
@@ -98,7 +98,7 @@ class InvitationTest < ActionDispatch::IntegrationTest
|
|
|
98
98
|
fill_in 'Password confirmation', with: 'other_password'
|
|
99
99
|
end
|
|
100
100
|
assert_equal user_invitation_path, current_path
|
|
101
|
-
assert page.has_css?('#error_explanation li', text: /Password .*doesn
|
|
101
|
+
assert page.has_css?('#error_explanation li', text: /Password .*doesn['’]t match/)
|
|
102
102
|
assert !user.confirmed?
|
|
103
103
|
end
|
|
104
104
|
|
|
@@ -102,7 +102,7 @@ class InvitationMailTest < ActionMailer::TestCase
|
|
|
102
102
|
def initialize(*args); end
|
|
103
103
|
def deliver; end
|
|
104
104
|
end
|
|
105
|
-
Devise.mailer = CustomMailer
|
|
105
|
+
Devise.mailer = 'InvitationMailTest::CustomMailer'
|
|
106
106
|
|
|
107
107
|
User.invite!({ email: 'valid@email.com' }, nil, { invited_at: Time.now })
|
|
108
108
|
end
|
data/test/model_tests_helper.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
require 'model_tests_helper'
|
|
3
3
|
|
|
4
|
+
class Validatable < User
|
|
5
|
+
devise :validatable, password_length: 10..20
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
class InvitableTest < ActiveSupport::TestCase
|
|
5
9
|
|
|
6
10
|
def setup
|
|
@@ -85,12 +89,12 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
85
89
|
user.invite!
|
|
86
90
|
old_invitation_created_at = 3.days.ago
|
|
87
91
|
old_invitation_sent_at = 3.days.ago
|
|
88
|
-
user.
|
|
92
|
+
user.update(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
|
|
89
93
|
3.times do
|
|
90
94
|
user.invite!
|
|
91
95
|
refute_equal old_invitation_sent_at, user.invitation_sent_at
|
|
92
96
|
refute_equal old_invitation_created_at, user.invitation_created_at
|
|
93
|
-
user.
|
|
97
|
+
user.update(invitation_sent_at: old_invitation_sent_at, invitation_created_at: old_invitation_created_at)
|
|
94
98
|
end
|
|
95
99
|
end
|
|
96
100
|
|
|
@@ -275,6 +279,23 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
275
279
|
refute_predicate user, :invited_to_sign_up?
|
|
276
280
|
end
|
|
277
281
|
|
|
282
|
+
test 'should not accept expired invitation while resetting the password' do
|
|
283
|
+
User.stubs(:invite_for).returns(1.day)
|
|
284
|
+
user = User.invite!(email: 'valid@email.com')
|
|
285
|
+
assert user.invited_to_sign_up?
|
|
286
|
+
user.invitation_created_at = Time.now.utc - 2.days
|
|
287
|
+
token, user.reset_password_token = Devise.token_generator.generate(User, :reset_password_token)
|
|
288
|
+
user.reset_password_sent_at = Time.now.utc
|
|
289
|
+
user.save
|
|
290
|
+
|
|
291
|
+
assert user.reset_password_token.present?
|
|
292
|
+
assert user.invitation_token.present?
|
|
293
|
+
User.reset_password_by_token(reset_password_token: token, password: '123456789', password_confirmation: '123456789')
|
|
294
|
+
assert_nil user.reload.reset_password_token
|
|
295
|
+
assert user.reload.invitation_token.present?
|
|
296
|
+
assert user.reload.invited_to_sign_up?
|
|
297
|
+
end
|
|
298
|
+
|
|
278
299
|
test 'should not accept invitation on failing to reset the password' do
|
|
279
300
|
user = User.invite!(email: 'valid@email.com')
|
|
280
301
|
assert user.invited_to_sign_up?
|
|
@@ -362,15 +383,51 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
362
383
|
User.validate_on_invite = validate_on_invite
|
|
363
384
|
end
|
|
364
385
|
|
|
386
|
+
test 'should not validate other attributes when validate_on_invite is disabled (for instance method)' do
|
|
387
|
+
validate_on_invite = User.validate_on_invite
|
|
388
|
+
User.validate_on_invite = false
|
|
389
|
+
user = new_user(email: 'valid@email.com', username: 'a' * 50)
|
|
390
|
+
user.invite!(nil, validate: false)
|
|
391
|
+
assert_empty user.errors
|
|
392
|
+
User.validate_on_invite = validate_on_invite
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
test 'should validate other attributes when validate_on_invite is disabled and validate option is enabled (for instance method)' do
|
|
396
|
+
validate_on_invite = User.validate_on_invite
|
|
397
|
+
User.validate_on_invite = false
|
|
398
|
+
user = new_user(email: 'valid@email.com', username: 'a' * 50)
|
|
399
|
+
user.invite!(nil, validate: true)
|
|
400
|
+
refute_empty user.errors[:username]
|
|
401
|
+
User.validate_on_invite = validate_on_invite
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
test 'should validate other attributes when validate_on_invite is enabled and validate option is disabled (for instance method)' do
|
|
405
|
+
validate_on_invite = User.validate_on_invite
|
|
406
|
+
User.validate_on_invite = true
|
|
407
|
+
user = new_user(email: 'valid@email.com', username: 'a' * 50)
|
|
408
|
+
user.invite!
|
|
409
|
+
refute_empty user.errors[:username]
|
|
410
|
+
User.validate_on_invite = validate_on_invite
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
test 'should validate other attributes when validate_on_invite is enabled and validate option is disabled explicitly (for instance method)' do
|
|
414
|
+
validate_on_invite = User.validate_on_invite
|
|
415
|
+
User.validate_on_invite = true
|
|
416
|
+
user = new_user(email: 'valid@email.com', username: 'a' * 50)
|
|
417
|
+
user.invite!(nil, validate: false)
|
|
418
|
+
assert_empty user.errors
|
|
419
|
+
User.validate_on_invite = validate_on_invite
|
|
420
|
+
end
|
|
421
|
+
|
|
365
422
|
test 'should return a record with errors if user was found by e-mail' do
|
|
366
423
|
existing_user = User.new(email: 'valid@email.com')
|
|
367
424
|
existing_user.save(validate: false)
|
|
368
425
|
user = User.invite!(email: 'valid@email.com')
|
|
369
426
|
assert_equal user, existing_user
|
|
370
|
-
assert_equal [
|
|
427
|
+
assert_equal [{error: :taken}], user.errors.details[:email]
|
|
371
428
|
same_user = User.invite!(email: 'valid@email.com')
|
|
372
429
|
assert_equal same_user, existing_user
|
|
373
|
-
assert_equal [
|
|
430
|
+
assert_equal [{error: :taken}], same_user.errors.details[:email]
|
|
374
431
|
end
|
|
375
432
|
|
|
376
433
|
test 'should return a record with errors if user with pending invitation was found by e-mail' do
|
|
@@ -384,7 +441,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
384
441
|
|
|
385
442
|
user = User.invite!(email: 'valid@email.com')
|
|
386
443
|
assert_equal user, existing_user
|
|
387
|
-
assert_equal [
|
|
444
|
+
assert_equal [{error: :taken}], user.errors.details[:email]
|
|
388
445
|
ensure
|
|
389
446
|
User.resend_invitation = resend_invitation
|
|
390
447
|
end
|
|
@@ -398,7 +455,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
398
455
|
existing_user.save(validate: false)
|
|
399
456
|
user = User.invite!(email: 'valid@email.com', username: 'a' * 50)
|
|
400
457
|
assert_equal user, existing_user
|
|
401
|
-
assert_equal [
|
|
458
|
+
assert_equal [{error: :taken}], user.errors.details[:email]
|
|
402
459
|
refute_empty user.errors[:username]
|
|
403
460
|
ensure
|
|
404
461
|
User.validate_on_invite = validate_on_invite
|
|
@@ -408,13 +465,13 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
408
465
|
test 'should return a new record with errors if e-mail is blank' do
|
|
409
466
|
invited_user = User.invite!(email: '')
|
|
410
467
|
assert invited_user.new_record?
|
|
411
|
-
assert_equal [
|
|
468
|
+
assert_equal [{error: :blank}], invited_user.errors.details[:email]
|
|
412
469
|
end
|
|
413
470
|
|
|
414
471
|
test 'should return a new record with errors if e-mail is invalid' do
|
|
415
472
|
invited_user = User.invite!(email: 'invalid_email')
|
|
416
473
|
assert invited_user.new_record?
|
|
417
|
-
assert_equal [
|
|
474
|
+
assert_equal [{error: :invalid}], invited_user.errors.details[:email]
|
|
418
475
|
end
|
|
419
476
|
|
|
420
477
|
test 'should set all attributes with errors if e-mail is invalid' do
|
|
@@ -434,13 +491,13 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
434
491
|
test 'should return a new record with errors if no invitation_token is found' do
|
|
435
492
|
invited_user = User.accept_invitation!(invitation_token: 'invalid_token')
|
|
436
493
|
assert invited_user.new_record?
|
|
437
|
-
assert_equal [
|
|
494
|
+
assert_equal [{error: :invalid}], invited_user.errors.details[:invitation_token]
|
|
438
495
|
end
|
|
439
496
|
|
|
440
497
|
test 'should return a new record with errors if invitation_token is blank' do
|
|
441
498
|
invited_user = User.accept_invitation!(invitation_token: '')
|
|
442
499
|
assert invited_user.new_record?
|
|
443
|
-
assert_equal [
|
|
500
|
+
assert_equal [{error: :blank}], invited_user.errors.details[:invitation_token]
|
|
444
501
|
end
|
|
445
502
|
|
|
446
503
|
test 'should return record with errors if invitation_token has expired' do
|
|
@@ -450,7 +507,7 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
450
507
|
invited_user.save(validate: false)
|
|
451
508
|
user = User.accept_invitation!(invitation_token: Thread.current[:token])
|
|
452
509
|
assert_equal user, invited_user
|
|
453
|
-
assert_equal [
|
|
510
|
+
assert_equal [{error: :invalid}], user.errors.details[:invitation_token]
|
|
454
511
|
end
|
|
455
512
|
|
|
456
513
|
test 'should allow record modification using block' do
|
|
@@ -760,4 +817,16 @@ class InvitableTest < ActiveSupport::TestCase
|
|
|
760
817
|
assert user.persisted?
|
|
761
818
|
assert user.errors.empty?
|
|
762
819
|
end
|
|
820
|
+
|
|
821
|
+
test 'should set initial password following Devise.password_length' do
|
|
822
|
+
user = User.invite!(email: 'valid@email.com')
|
|
823
|
+
assert_empty user.errors
|
|
824
|
+
assert_equal Devise.password_length.last, user.password.length
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
test 'should set initial passsword using :validatable with custom password_length' do
|
|
828
|
+
user = Validatable.invite!(email: 'valid@email.com')
|
|
829
|
+
assert_empty user.errors
|
|
830
|
+
assert_equal Validatable.password_length.last, user.password.length
|
|
831
|
+
end
|
|
763
832
|
end
|
data/test/orm/active_record.rb
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
ActiveRecord::Migration.verbose = false
|
|
2
2
|
ActiveRecord::Base.logger = Logger.new(nil)
|
|
3
3
|
|
|
4
|
-
if
|
|
5
|
-
ActiveRecord::MigrationContext.new(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
|
5
|
+
ActiveRecord::MigrationContext.new(
|
|
6
|
+
File.expand_path('../../rails_app/db/migrate/', __FILE__)
|
|
7
|
+
).migrate
|
|
8
|
+
else # rails 6
|
|
9
|
+
ActiveRecord::MigrationContext.new(
|
|
10
|
+
File.expand_path('../../rails_app/db/migrate/', __FILE__),
|
|
11
|
+
ActiveRecord::Base.connection.schema_migration
|
|
12
|
+
).migrate
|
|
13
|
+
end
|
|
@@ -32,7 +32,6 @@ class CreateTables < (Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRe
|
|
|
32
32
|
t.timestamps :null => false
|
|
33
33
|
end
|
|
34
34
|
add_index :users, :invitation_token, :unique => true
|
|
35
|
-
add_index :users, :invitations_count
|
|
36
35
|
|
|
37
36
|
create_table :admins do |t|
|
|
38
37
|
## Database authenticatable
|
|
@@ -41,6 +40,5 @@ class CreateTables < (Rails.version < '5.1' ? ActiveRecord::Migration : ActiveRe
|
|
|
41
40
|
|
|
42
41
|
t.integer :invitations_count, :default => 0
|
|
43
42
|
end
|
|
44
|
-
add_index :admins, :invitations_count
|
|
45
43
|
end
|
|
46
44
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -7,13 +7,15 @@ require "rails_app/config/environment"
|
|
|
7
7
|
require 'rails/test_help'
|
|
8
8
|
require "orm/#{DEVISE_ORM}"
|
|
9
9
|
require 'capybara/rails'
|
|
10
|
-
require 'mocha/
|
|
10
|
+
require 'mocha/minitest'
|
|
11
11
|
|
|
12
12
|
ActionMailer::Base.delivery_method = :test
|
|
13
13
|
ActionMailer::Base.perform_deliveries = true
|
|
14
14
|
ActionMailer::Base.default_url_options[:host] = 'example.com'
|
|
15
15
|
|
|
16
|
-
ActiveSupport::Deprecation.silenced
|
|
16
|
+
if ActiveSupport::Deprecation.respond_to?(:silenced=)
|
|
17
|
+
ActiveSupport::Deprecation.silenced = true
|
|
18
|
+
end
|
|
17
19
|
$VERBOSE = false
|
|
18
20
|
|
|
19
21
|
class ActionDispatch::IntegrationTest
|
|
@@ -31,3 +33,9 @@ class ActionController::TestCase
|
|
|
31
33
|
self.use_transactional_tests = true
|
|
32
34
|
end
|
|
33
35
|
end
|
|
36
|
+
|
|
37
|
+
# This is a workaround for the issue with Rails 8.0 and lazy loading of routes.
|
|
38
|
+
# see: https://github.com/heartcombo/devise/issues/5705
|
|
39
|
+
if Rails.gem_version >= Gem::Version.new('8.0')
|
|
40
|
+
Rails.application.routes_reloader.execute_unless_loaded
|
|
41
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devise_invitable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sergio Cambra
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: actionmailer
|
|
@@ -44,14 +43,14 @@ dependencies:
|
|
|
44
43
|
requirements:
|
|
45
44
|
- - "~>"
|
|
46
45
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 2.0
|
|
46
|
+
version: '2.0'
|
|
48
47
|
type: :development
|
|
49
48
|
prerelease: false
|
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
50
|
requirements:
|
|
52
51
|
- - "~>"
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 2.0
|
|
53
|
+
version: '2.0'
|
|
55
54
|
description: It adds support for send invitations by email (it requires to be authenticated)
|
|
56
55
|
and accept the invitation by setting a password.
|
|
57
56
|
email:
|
|
@@ -62,14 +61,38 @@ extra_rdoc_files: []
|
|
|
62
61
|
files:
|
|
63
62
|
- CHANGELOG.md
|
|
64
63
|
- LICENSE
|
|
65
|
-
- README.
|
|
64
|
+
- README.md
|
|
66
65
|
- app/controllers/devise/invitations_controller.rb
|
|
67
66
|
- app/controllers/devise_invitable/registrations_controller.rb
|
|
68
67
|
- app/views/devise/invitations/edit.html.erb
|
|
69
68
|
- app/views/devise/invitations/new.html.erb
|
|
70
69
|
- app/views/devise/mailer/invitation_instructions.html.erb
|
|
71
70
|
- app/views/devise/mailer/invitation_instructions.text.erb
|
|
71
|
+
- config/locales/ar.yml
|
|
72
|
+
- config/locales/ca.yml
|
|
73
|
+
- config/locales/da.yml
|
|
74
|
+
- config/locales/de.yml
|
|
72
75
|
- config/locales/en.yml
|
|
76
|
+
- config/locales/es.yml
|
|
77
|
+
- config/locales/et.yml
|
|
78
|
+
- config/locales/fa.yml
|
|
79
|
+
- config/locales/fr.yml
|
|
80
|
+
- config/locales/id.yml
|
|
81
|
+
- config/locales/it.yml
|
|
82
|
+
- config/locales/ja.yml
|
|
83
|
+
- config/locales/ko.yml
|
|
84
|
+
- config/locales/nl.yml
|
|
85
|
+
- config/locales/no.yml
|
|
86
|
+
- config/locales/pl.yml
|
|
87
|
+
- config/locales/pt-BR.yml
|
|
88
|
+
- config/locales/pt.yml
|
|
89
|
+
- config/locales/ru.yml
|
|
90
|
+
- config/locales/tr.yml
|
|
91
|
+
- config/locales/ua.yml
|
|
92
|
+
- config/locales/vi.yml
|
|
93
|
+
- config/locales/zh-CN.yml
|
|
94
|
+
- config/locales/zh-HK.yml
|
|
95
|
+
- config/locales/zh-TW.yml
|
|
73
96
|
- lib/devise_invitable.rb
|
|
74
97
|
- lib/devise_invitable/controllers/helpers.rb
|
|
75
98
|
- lib/devise_invitable/inviter.rb
|
|
@@ -147,10 +170,9 @@ homepage: https://github.com/scambra/devise_invitable
|
|
|
147
170
|
licenses:
|
|
148
171
|
- MIT
|
|
149
172
|
metadata: {}
|
|
150
|
-
post_install_message:
|
|
151
173
|
rdoc_options:
|
|
152
174
|
- "--main"
|
|
153
|
-
- README.
|
|
175
|
+
- README.md
|
|
154
176
|
- "--charset=UTF-8"
|
|
155
177
|
require_paths:
|
|
156
178
|
- lib
|
|
@@ -165,9 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
165
187
|
- !ruby/object:Gem::Version
|
|
166
188
|
version: '0'
|
|
167
189
|
requirements: []
|
|
168
|
-
|
|
169
|
-
rubygems_version: 2.7.9
|
|
170
|
-
signing_key:
|
|
190
|
+
rubygems_version: 3.6.9
|
|
171
191
|
specification_version: 4
|
|
172
192
|
summary: An invitation strategy for Devise
|
|
173
193
|
test_files:
|