devise_invitable 1.5.3 → 1.5.5

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.

Potentially problematic release.


This version of devise_invitable might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 34b7a909db3f99e89240bf2b81107b5981e656cb
4
- data.tar.gz: 47f3c423acd3c430232c028e130174c23720081e
5
- SHA512:
6
- metadata.gz: fb028f99d4fc760cdecc7f747b3070fa7c2373d3e5655cdb51c2526245a546f1c8b4b84175810b9b8c1df33f054a0b5b1c4190f2280eda5d31f6f7377e7cffbf
7
- data.tar.gz: e04a795483022a82a601790ad24d682934322e45348026bd6a3b387b8284b41ca8403e55afddaf57b51d630961cb2650e8fbcea15d9144c07d3e1fde8f23976f
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c73f548d678402b25124902905d122de26316161
4
+ data.tar.gz: 39b1f217bf6a01ab772a462f5488f75a519b15fb
5
+ SHA512:
6
+ metadata.gz: 6150c3a9debc6a2974662801bff49a4bc3ab5ef1c6c24ca9a31d355d5633f48b591c99d80349a3feb4319b6bddf33ad5ae6159e2131fcd03b17aeed52b593f15
7
+ data.tar.gz: a6e3025090643913f77bcbb4d20c8a31db17573eb62e26a13256d6ffc83bc4812f0b84182c2e75456575761192a22b8f637be0f0c859e5dc315641491dd00b5f
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ - Ensure that all invited user passwords conform to a format
2
+ - Call set_minimum_password_length (if exists) on accept invitation as devise does
3
+ - Controllers inheriting from Devise::InvitationsController will now use 'devise.invitations' translations
4
+ when using Devise >= 3.5. See https://github.com/plataformatec/devise/pull/3407 for more details.
5
+ - Add invitation due date to mailer
6
+
7
+ = 1.5.3
8
+
9
+ - Fix #585, avoid generating new password if there already is a encrypted one
10
+ - Give error if trying to register with a registered email
11
+
1
12
  = 1.5.2
2
13
 
3
14
  - Fix #571, accept invitation when password changes only if reset_password_token was present
@@ -185,7 +185,7 @@ To change behaviour of inviting or accepting users, you can simply override two
185
185
  # should return an instance of resource class
186
186
  def invite_resource
187
187
  ## skip sending emails on invite
188
- resource_class.invite!(invite_params, current_inviter) do |u|
188
+ super do |u|
189
189
  u.skip_invitation = true
190
190
  end
191
191
  end
@@ -247,21 +247,21 @@ the value is temporarily available when you invite a user and will be decrypted
247
247
 
248
248
  accept_user_invitation_url(:invitation_token => user.raw_invitation_token)
249
249
 
250
- When skip_invitation is used, you must also then set the invitation_sent_at field when the user is sent their
251
- token. Failure to do so will yield "Invalid invitation token" errors when the user attempts to accept the invite.
250
+ When <tt>skip_invitation</tt> is used, you must also then set the <tt>invitation_sent_at</tt> field when the user is sent their
251
+ token. Failure to do so will yield <tt>Invalid invitation token</tt> error when the user attempts to accept the invite.
252
252
  You can set it like so:
253
253
 
254
254
  user.deliver_invitation
255
255
 
256
- You can add :skip_invitation to attributes hash if skip_invitation is added to attr_accessible.
256
+ You can add <tt>:skip_invitation</tt> to attributes hash if <tt>skip_invitation</tt> is added to <tt>attr_accessible</tt>.
257
257
 
258
258
  User.invite!(:email => "new_user@example.com", :name => "John Doe", :skip_invitation => true)
259
259
  # => the record will be created, but the invitation email will not be sent
260
260
 
261
- Skip_invitation skips sending the email, but sets invitation_token, so <tt>invited_to_sign_up?</tt> on the
261
+ <tt>skip_invitation</tt> skips sending the email, but sets <tt>invitation_token</tt>, so <tt>invited_to_sign_up?</tt> on the
262
262
  resulting user returns true.
263
263
 
264
- To check if a perticular user is created by invitation, irrespective to state of invitation one can use <tt>created_by_invite?</tt>
264
+ To check if a particular user is created by invitation, irrespective to state of invitation one can use <tt>created_by_invite?</tt>
265
265
 
266
266
  **Warning**
267
267
 
@@ -31,6 +31,7 @@ class Devise::InvitationsController < DeviseController
31
31
 
32
32
  # GET /resource/invitation/accept?invitation_token=abcdef
33
33
  def edit
34
+ set_minimum_password_length if respond_to? :set_minimum_password_length
34
35
  resource.invitation_token = params[:invitation_token]
35
36
  render :edit
36
37
  end
@@ -103,5 +104,8 @@ class Devise::InvitationsController < DeviseController
103
104
  devise_parameter_sanitizer.sanitize(:accept_invitation)
104
105
  end
105
106
 
107
+ def translation_scope
108
+ 'devise.invitations'
109
+ end
106
110
  end
107
111
 
@@ -4,4 +4,8 @@
4
4
 
5
5
  <p><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, :invitation_token => @token) %></p>
6
6
 
7
+ <% if @resource.invitation_due_at %>
8
+ <p><%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %></p>
9
+ <% end %>
10
+
7
11
  <p><%= t("devise.mailer.invitation_instructions.ignore").html_safe %></p>
@@ -21,4 +21,11 @@ en:
21
21
  hello: "Hello %{email}"
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
+ accept_until: "This invitation will be due in %{due_date}."
24
25
  ignore: "If you don't want to accept the invitation, please ignore this email.<br />Your account won't be created until you access the link above and set your password."
26
+ time:
27
+ formats:
28
+ devise:
29
+ mailer:
30
+ invitation_instructions:
31
+ accept_until_format: "%B %d, %Y %I:%M %p"
@@ -2,7 +2,6 @@ module DeviseInvitable::Controllers::Helpers
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  included do
5
- hide_action :after_invite_path_for, :after_accept_path_for
6
5
  end
7
6
 
8
7
  def after_invite_path_for(resource)
@@ -34,9 +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
+ if fk = Devise.invited_by_foreign_key
38
+ belongs_to_options[:foreign_key] = fk
39
+ end
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
@@ -109,8 +109,8 @@ module Devise
109
109
  end
110
110
 
111
111
  # Reset invitation token and send invitation again
112
- def invite!(invited_by = nil)
113
- # This is an order-dependant assignment, this can't be moved
112
+ def invite!(invited_by = nil, options = {})
113
+ # This is an order-dependant assignment, this can't be moved
114
114
  was_invited = invited_to_sign_up?
115
115
 
116
116
  # Required to workaround confirmable model's confirmation_required? method
@@ -131,7 +131,7 @@ module Devise
131
131
 
132
132
  if save(:validate => false)
133
133
  self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
134
- deliver_invitation unless skip_invitation
134
+ deliver_invitation(options) unless skip_invitation
135
135
  end
136
136
  end
137
137
 
@@ -164,10 +164,10 @@ module Devise
164
164
  end
165
165
 
166
166
  # Deliver the invitation email
167
- def deliver_invitation
167
+ def deliver_invitation(options = {})
168
168
  generate_invitation_token! unless @raw_invitation_token
169
169
  self.update_attribute :invitation_sent_at, Time.now.utc unless self.invitation_sent_at
170
- send_devise_notification(:invitation_instructions, @raw_invitation_token)
170
+ send_devise_notification(:invitation_instructions, @raw_invitation_token, options)
171
171
  end
172
172
 
173
173
  # provide alias to the encrypted invitation_token stored by devise
@@ -179,6 +179,13 @@ module Devise
179
179
  respond_to?(:confirmation_required?, true) && confirmation_required?
180
180
  end
181
181
 
182
+ def invitation_due_at
183
+ return nil unless self.class.invite_for
184
+
185
+ time = self.invitation_created_at || self.invitation_sent_at
186
+ time + self.class.invite_for
187
+ end
188
+
182
189
  protected
183
190
 
184
191
  def block_from_invitation?
@@ -242,7 +249,7 @@ module Devise
242
249
  # email is resent unless resend_invitation is set to false.
243
250
  # Attributes must contain the user's email, other attributes will be
244
251
  # set in the record
245
- def _invite(attributes={}, invited_by=nil, &block)
252
+ def _invite(attributes={}, invited_by=nil, options = {}, &block)
246
253
  invite_key_array = invite_key_fields
247
254
  attributes_hash = {}
248
255
  invite_key_array.each do |k,v|
@@ -255,7 +262,7 @@ module Devise
255
262
  invitable.assign_attributes(attributes)
256
263
  invitable.invited_by = invited_by
257
264
  unless invitable.password || invitable.encrypted_password.present?
258
- invitable.password = Devise.friendly_token[0, 20]
265
+ invitable.password = random_password
259
266
  end
260
267
 
261
268
  invitable.valid? if self.validate_on_invite
@@ -268,16 +275,16 @@ module Devise
268
275
  end
269
276
 
270
277
  yield invitable if block_given?
271
- mail = invitable.invite! if invitable.errors.empty?
278
+ mail = invitable.invite!(nil, options) if invitable.errors.empty?
272
279
  [invitable, mail]
273
280
  end
274
281
 
275
- def invite!(attributes={}, invited_by=nil, &block)
276
- _invite(attributes.with_indifferent_access, invited_by, &block).first
282
+ def invite!(attributes={}, invited_by=nil, options = {}, &block)
283
+ _invite(attributes.with_indifferent_access, invited_by, options, &block).first
277
284
  end
278
285
 
279
- def invite_mail!(attributes={}, invited_by=nil, &block)
280
- _invite(attributes, invited_by, &block).last
286
+ def invite_mail!(attributes={}, invited_by=nil, options = {}, &block)
287
+ _invite(attributes, invited_by, options, &block).last
281
288
  end
282
289
 
283
290
  # Attempt to find a user by it's invitation_token to set it's password.
@@ -320,8 +327,18 @@ module Devise
320
327
  Devise::Models.config(self, :resend_invitation)
321
328
  Devise::Models.config(self, :allow_insecure_sign_in_after_accept)
322
329
 
330
+ private
331
+
332
+ # The random password, as set after an invitation, must conform
333
+ # to any password format validation rules of the application.
334
+ # This default fixes the most common scenarios: Passwords must contain
335
+ # lower + upper case, a digit and a symbol.
336
+ # For more unusual rules, this method can be overridden.
337
+ def random_password
338
+ "aA1!" + Devise.friendly_token[0, 20]
339
+ end
340
+
323
341
  end
324
342
  end
325
343
  end
326
344
  end
327
-
@@ -1,3 +1,3 @@
1
1
  module DeviseInvitable
2
- VERSION = '1.5.3'
2
+ VERSION = '1.5.5'
3
3
  end
@@ -66,4 +66,30 @@ class InvitationMailTest < ActionMailer::TestCase
66
66
  invitation_url_regexp = %r{<a href=\"http://#{host}/users/invitation/accept\?invitation_token=#{Thread.current[:token]}">}
67
67
  assert_match invitation_url_regexp, body
68
68
  end
69
+
70
+ test 'body should have invitation due date when it exists' do
71
+ host = ActionMailer::Base.default_url_options[:host]
72
+ user
73
+ body = mail.body.decoded
74
+
75
+ due_date_regexp = %r{#{I18n.l user.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format' }}
76
+ assert_match due_date_regexp, body
77
+ end
78
+
79
+ test 'options are passed to the delivery method' do
80
+ class CustomMailer < Devise::Mailer
81
+ class << self
82
+ def invitation_instructions(record, name, options = {})
83
+ fail 'Options not as expected' unless options[:invited_at].is_a?(Time)
84
+ new(record, name, options)
85
+ end
86
+ end
87
+
88
+ def initialize(*args); end
89
+ def deliver; end
90
+ end
91
+ Devise.mailer = CustomMailer
92
+
93
+ User.invite!({ email: 'valid@email.com' }, nil, { invited_at: Time.now })
94
+ end
69
95
  end
@@ -1,5 +1,6 @@
1
1
  class ActiveSupport::TestCase
2
2
  def setup_mailer
3
+ Devise.mailer = Devise::Mailer
3
4
  ActionMailer::Base.deliveries = []
4
5
  end
5
6
 
@@ -122,6 +122,22 @@ class InvitableTest < ActiveSupport::TestCase
122
122
  assert !user.valid_invitation?
123
123
  end
124
124
 
125
+ test 'should return token validity when there is invite_for' do
126
+ User.stubs(:invite_for).returns(1.day)
127
+ user = User.invite!(:email => "valid@email.com")
128
+ sent_at = user.invitation_created_at || user.invitation_sent_at
129
+ valid_until = sent_at + User.invite_for
130
+
131
+ assert_equal user.invitation_due_at, valid_until
132
+ end
133
+
134
+ test 'should return nil as token validity when there is not invite_for' do
135
+ User.stubs(:invite_for).returns(nil)
136
+ user = User.invite!(:email => "valid@email.com")
137
+
138
+ assert_equal user.invitation_due_at, nil
139
+ end
140
+
125
141
  test 'should never generate the same invitation token for different users' do
126
142
  invitation_tokens = []
127
143
  3.times do
@@ -657,4 +673,18 @@ class InvitableTest < ActiveSupport::TestCase
657
673
  retval = user.reset_password!('anewpassword', 'anewpassword')
658
674
  assert_equal true, retval
659
675
  end
676
+
677
+ test 'should set initial password with variety of characters' do
678
+ PASSWORD_FORMAT = /\A
679
+ (?=.*\d) # Must contain a digit
680
+ (?=.*[a-z]) # Must contain a lower case character
681
+ (?=.*[A-Z]) # Must contain an upper case character
682
+ (?=.*[[:^alnum:]]) # Must contain a symbol
683
+ /x
684
+ User.stubs(:invite_key).returns(:password => PASSWORD_FORMAT)
685
+ Devise.stubs(:friendly_token).returns('onlylowercaseletters')
686
+ user = User.invite!(:email => "valid@email.com")
687
+ assert user.persisted?
688
+ assert user.errors.empty?
689
+ end
660
690
  end
@@ -3,6 +3,9 @@
3
3
 
4
4
  en:
5
5
  hello: "Hello world"
6
+ time:
7
+ formats:
8
+ short: "%b %d"
6
9
  devise:
7
10
  free_invitations:
8
11
  send_instructions: 'An invitation email has been sent to %{email}.'
metadata CHANGED
@@ -1,71 +1,59 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: devise_invitable
3
- version: !ruby/object:Gem::Version
4
- version: 1.5.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.5.5
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Sergio Cambra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-30 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
11
+
12
+ date: 2015-12-17 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
14
15
  name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: 1.1.0
20
16
  type: :development
21
17
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
26
22
  version: 1.1.0
27
- - !ruby/object:Gem::Dependency
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
28
25
  name: actionmailer
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: 3.2.6
34
- - - <
35
- - !ruby/object:Gem::Version
36
- version: '5'
37
26
  type: :runtime
38
27
  prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - '>='
42
- - !ruby/object:Gem::Version
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
43
32
  version: 3.2.6
44
33
  - - <
45
- - !ruby/object:Gem::Version
46
- version: '5'
47
- - !ruby/object:Gem::Dependency
34
+ - !ruby/object:Gem::Version
35
+ version: "5"
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
48
38
  name: devise
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - '>='
52
- - !ruby/object:Gem::Version
53
- version: 3.2.0
54
39
  type: :runtime
55
40
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - '>='
59
- - !ruby/object:Gem::Version
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
60
45
  version: 3.2.0
61
- description: It adds support for send invitations by email (it requires to be authenticated)
62
- and accept the invitation by setting a password.
63
- email:
46
+ version_requirements: *id003
47
+ description: It adds support for send invitations by email (it requires to be authenticated) and accept the invitation by setting a password.
48
+ email:
64
49
  - sergio@entrecables.com
65
50
  executables: []
51
+
66
52
  extensions: []
53
+
67
54
  extra_rdoc_files: []
68
- files:
55
+
56
+ files:
69
57
  - CHANGELOG
70
58
  - LICENSE
71
59
  - README.rdoc
@@ -146,33 +134,35 @@ files:
146
134
  - test/routes_test.rb
147
135
  - test/test_helper.rb
148
136
  homepage: https://github.com/scambra/devise_invitable
149
- licenses:
137
+ licenses:
150
138
  - MIT
151
139
  metadata: {}
140
+
152
141
  post_install_message:
153
- rdoc_options:
142
+ rdoc_options:
154
143
  - --main
155
144
  - README.rdoc
156
145
  - --charset=UTF-8
157
- require_paths:
146
+ require_paths:
158
147
  - lib
159
- required_ruby_version: !ruby/object:Gem::Requirement
160
- requirements:
161
- - - '>='
162
- - !ruby/object:Gem::Version
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
163
152
  version: 1.8.6
164
- required_rubygems_version: !ruby/object:Gem::Requirement
165
- requirements:
166
- - - '>='
167
- - !ruby/object:Gem::Version
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
168
157
  version: 1.3.6
169
158
  requirements: []
159
+
170
160
  rubyforge_project:
171
- rubygems_version: 2.4.5
161
+ rubygems_version: 2.4.6
172
162
  signing_key:
173
163
  specification_version: 4
174
164
  summary: An invitation strategy for Devise
175
- test_files:
165
+ test_files:
176
166
  - test/functional/controller_helpers_test.rb
177
167
  - test/functional/registrations_controller_test.rb
178
168
  - test/generators/views_generator_test.rb