rodauth 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f6c97c6e01c1026bf027fb99348421103909a668
4
- data.tar.gz: 910777f85e599d240356aeb2eba4339db0c481c3
2
+ SHA256:
3
+ metadata.gz: 62724514e9c4c31b8af9992d86ed3f1de98a38860ee7890f2da54e28fa4f2394
4
+ data.tar.gz: 58ba690b1c2e193728c6341d60df851e043fd3706ed1769c5ae6ecc0eed24592
5
5
  SHA512:
6
- metadata.gz: c2a571d6eac5c96a458da39020a074edb561c2f71ef32a93382177fcdfe67d73d0ad5dd548255d7c8a09e9f9d67166becd616ec1d8c650d30d766a42b24990ae
7
- data.tar.gz: '070838b8388668fa6c7ac73145c82dd0e825d61c83ea43e603789f1efd0383d3c57b147345f55b47d709f6a3786f475fc78fa2e1f5fd30213d6e691fcb6ba5ba'
6
+ metadata.gz: 8b187d024978cf9a7c22cc8f21e892dab50075c7eb2a605c45c7423cec186169e160d944e051d1e9c369222e373ee0e5ebd9effe217ca13f0d3edc7ec0e2875e
7
+ data.tar.gz: b990669e7aecbc09dcd90d89001ca35dd12fea964bbe1e8c29629b95f9a9bfe4fbb19cbcd683ab5b28575a7e00940aff087604e80f18c3d6c9a65b7bc658976b
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 1.14.0 (2017-12-19)
2
+
3
+ * Don't allow unlocking expired accounts when using account_expiration and lockout features (jeremyevans)
4
+
5
+ * Don't allow resetting passwords for expired accounts when using account_expiration and reset_password features (jeremyevans)
6
+
7
+ * Add change_password_notify feature for emailing when user uses change password feature (jeremyevans)
8
+
1
9
  === 1.13.0 (2017-11-21)
2
10
 
3
11
  * Add json_response_body(hash) configuration method to jwt feature (jeremyevans)
data/README.rdoc CHANGED
@@ -41,6 +41,7 @@ hashes by protecting access via database functions.
41
41
  * JWT (JSON API support for all other features)
42
42
  * Update Password Hash (when hash cost changes)
43
43
  * HTTP Basic Auth
44
+ * Change Password Notify
44
45
 
45
46
  == Resources
46
47
 
@@ -0,0 +1,24 @@
1
+ = Documentation for Change Password Notify Feature
2
+
3
+ The change password notify feature emails the user when their password
4
+ is changed using the change password feature.
5
+ auth_value_method :password_changed_email_subject, 'Password Changed'
6
+
7
+ auth_value_methods(
8
+ :password_changed_email_body
9
+ )
10
+ auth_methods(
11
+ :create_password_changed_email,
12
+ :send_password_changed_email
13
+ )
14
+
15
+
16
+ == Auth Value Methods
17
+
18
+ password_changed_email_subject :: Subject to use for the password changed emails
19
+ password_changed_email_body :: Body to use for the password changed emails
20
+
21
+ == Auth Methods
22
+
23
+ create_password_changed_email :: A Mail::Message for the password changed email to send.
24
+ send_password_changed_email :: Send the account unlock email.
@@ -0,0 +1,19 @@
1
+ = New Features
2
+
3
+ * A change_password_notify feature has been added, which emails the
4
+ user when the change_password feature is used to change their
5
+ password. This can alert the user when their password may have
6
+ been changed without their knowledge.
7
+
8
+ = Other Improvements
9
+
10
+ * When using the account_expiration feature with the reset_password
11
+ feature, resetting the passwords for expired accounts is no longer
12
+ allowed. Note that the previous behavior isn't considered a
13
+ security issue, because even after resetting their password,
14
+ expired accounts could not login.
15
+
16
+ * When using the account_expiration feature with the lockout feature,
17
+ unlocking expired accounts is no longer allowed. Note that the
18
+ previous behavior isn't considered a security issue, because even
19
+ after unlocking the account, expired accounts could not login.
@@ -71,6 +71,26 @@ module Rodauth
71
71
 
72
72
  private
73
73
 
74
+ def before_reset_password
75
+ check_account_expiration
76
+ super if defined?(super)
77
+ end
78
+
79
+ def before_reset_password_request
80
+ check_account_expiration
81
+ super if defined?(super)
82
+ end
83
+
84
+ def before_unlock_account
85
+ check_account_expiration
86
+ super if defined?(super)
87
+ end
88
+
89
+ def before_unlock_account_request
90
+ check_account_expiration
91
+ super if defined?(super)
92
+ end
93
+
74
94
  def after_close_account
75
95
  super if defined?(super)
76
96
  account_activity_ds(account_id).delete
@@ -0,0 +1,37 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Rodauth
4
+ Feature.define(:change_password_notify, :ChangePasswordNotify) do
5
+ depends :change_password, :email_base
6
+
7
+ auth_value_method :password_changed_email_subject, 'Password Changed'
8
+
9
+ auth_value_methods(
10
+ :password_changed_email_body
11
+ )
12
+ auth_methods(
13
+ :create_password_changed_email,
14
+ :send_password_changed_email
15
+ )
16
+
17
+ private
18
+
19
+ def send_password_changed_email
20
+ create_password_changed_email.deliver!
21
+ end
22
+
23
+ def create_password_changed_email
24
+ create_email(password_changed_email_subject, password_changed_email_body)
25
+ end
26
+
27
+ def password_changed_email_body
28
+ render('password-changed-email')
29
+ end
30
+
31
+ def after_change_password
32
+ super
33
+ send_password_changed_email
34
+ end
35
+ end
36
+ end
37
+
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Rodauth
4
- VERSION = '1.13.0'.freeze
4
+ VERSION = '1.14.0'.freeze
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -1,7 +1,7 @@
1
1
  require File.expand_path("spec_helper", File.dirname(__FILE__))
2
2
 
3
3
  describe 'Rodauth account expiration feature' do
4
- it "should force account expiration after x number of days" do
4
+ it "should force account expiration after x number of days since last login" do
5
5
  rodauth do
6
6
  enable :login, :logout, :account_expiration
7
7
  end
@@ -27,6 +27,141 @@ describe 'Rodauth account expiration feature' do
27
27
  end
28
28
  end
29
29
 
30
+ it "should not allow resetting of passwords for expired accounts" do
31
+ rodauth do
32
+ enable :login, :logout, :account_expiration, :reset_password
33
+ end
34
+ roda do |r|
35
+ r.rodauth
36
+ r.root{view :content=>rodauth.logged_in? ? "Logged In#{rodauth.last_account_login_at.strftime('%m%d%y')}" : "Not Logged"}
37
+ end
38
+
39
+ now = Time.now
40
+ login
41
+ page.body.must_include "Logged In#{now.strftime('%m%d%y')}"
42
+ logout
43
+
44
+ visit '/login'
45
+ click_link 'Forgot Password?'
46
+ fill_in 'Login', :with=>'foo@example.com'
47
+ click_button 'Request Password Reset'
48
+ link = email_link(/(\/reset-password\?key=.+)$/)
49
+
50
+ visit link
51
+ fill_in 'Password', :with=>'0123456'
52
+ fill_in 'Confirm Password', :with=>'0123456'
53
+ click_button 'Reset Password'
54
+ page.find('#notice_flash').text.must_equal "Your password has been reset"
55
+ page.current_path.must_equal '/'
56
+
57
+ visit '/login'
58
+ click_link 'Forgot Password?'
59
+ fill_in 'Login', :with=>'foo@example.com'
60
+ click_button 'Request Password Reset'
61
+ link = email_link(/(\/reset-password\?key=.+)$/)
62
+
63
+ DB[:account_activity_times].update(:last_login_at => Time.now - 181*86400)
64
+
65
+ visit link
66
+ page.title.must_equal 'Reset Password'
67
+ fill_in 'Password', :with=>'01234567'
68
+ fill_in 'Confirm Password', :with=>'01234567'
69
+ click_button 'Reset Password'
70
+ page.find('#error_flash').text.must_equal "You cannot log into this account as it has expired"
71
+ page.body.must_include 'Not Logged'
72
+ page.current_path.must_equal '/'
73
+
74
+ visit '/login'
75
+ click_link 'Forgot Password?'
76
+ fill_in 'Login', :with=>'foo@example.com'
77
+ click_button 'Request Password Reset'
78
+ page.find('#error_flash').text.must_equal "You cannot log into this account as it has expired"
79
+ page.body.must_include 'Not Logged'
80
+ page.current_path.must_equal '/'
81
+ end
82
+
83
+ it "should not allow account unlocks for expired accounts" do
84
+ rodauth do
85
+ enable :lockout, :account_expiration, :logout
86
+ max_invalid_logins 2
87
+ unlock_account_autologin? false
88
+ end
89
+ roda do |r|
90
+ r.rodauth
91
+ r.root{view :content=>(rodauth.logged_in? ? "Logged In" : "Not Logged")}
92
+ end
93
+
94
+ login
95
+ logout
96
+
97
+ visit '/login'
98
+ fill_in 'Login', :with=>'foo@example.com'
99
+ 3.times do
100
+ fill_in 'Password', :with=>'012345678910'
101
+ click_button 'Login'
102
+ end
103
+
104
+ page.body.must_include("This account is currently locked out")
105
+ click_button 'Request Account Unlock'
106
+ page.find('#notice_flash').text.must_equal 'An email has been sent to you with a link to unlock your account'
107
+ link = email_link(/(\/unlock-account\?key=.+)$/)
108
+
109
+ visit link
110
+ click_button 'Unlock Account'
111
+ page.find('#notice_flash').text.must_equal 'Your account has been unlocked'
112
+ page.body.must_include('Not Logged')
113
+
114
+ visit '/login'
115
+ fill_in 'Login', :with=>'foo@example.com'
116
+ 3.times do
117
+ fill_in 'Password', :with=>'012345678910'
118
+ click_button 'Login'
119
+ end
120
+
121
+ page.body.must_include("This account is currently locked out")
122
+ click_button 'Request Account Unlock'
123
+ page.find('#notice_flash').text.must_equal 'An email has been sent to you with a link to unlock your account'
124
+ link = email_link(/(\/unlock-account\?key=.+)$/)
125
+
126
+ DB[:account_activity_times].update(:last_login_at => Time.now - 181*86400)
127
+
128
+ visit link
129
+ click_button 'Unlock Account'
130
+ page.find('#error_flash').text.must_equal "You cannot log into this account as it has expired"
131
+ page.body.must_include 'Not Logged'
132
+ page.current_path.must_equal '/'
133
+ end
134
+
135
+ it "should not allow account unlock requests for expired accounts" do
136
+ rodauth do
137
+ enable :lockout, :account_expiration, :logout
138
+ max_invalid_logins 2
139
+ unlock_account_autologin? false
140
+ end
141
+ roda do |r|
142
+ r.rodauth
143
+ r.root{view :content=>(rodauth.logged_in? ? "Logged In" : "Not Logged")}
144
+ end
145
+
146
+ login
147
+ logout
148
+
149
+ visit '/login'
150
+ fill_in 'Login', :with=>'foo@example.com'
151
+ 3.times do
152
+ fill_in 'Password', :with=>'012345678910'
153
+ click_button 'Login'
154
+ end
155
+
156
+ DB[:account_activity_times].update(:last_login_at => Time.now - 181*86400)
157
+
158
+ page.body.must_include("This account is currently locked out")
159
+ click_button 'Request Account Unlock'
160
+ page.find('#error_flash').text.must_equal "You cannot log into this account as it has expired"
161
+ page.body.must_include 'Not Logged'
162
+ page.current_path.must_equal '/'
163
+ end
164
+
30
165
  it "should use last activity time if configured" do
31
166
  rodauth do
32
167
  enable :login, :logout, :account_expiration
@@ -0,0 +1,33 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe 'Rodauth change_password_notify feature' do
4
+ it "should email when using change password" do
5
+ rodauth do
6
+ enable :login, :logout, :change_password_notify
7
+ change_password_requires_password? false
8
+ end
9
+ roda do |r|
10
+ r.rodauth
11
+ r.root{view :content=>""}
12
+ end
13
+
14
+ login
15
+ page.current_path.must_equal '/'
16
+
17
+ visit '/change-password'
18
+ fill_in 'New Password', :with=>'0123456'
19
+ fill_in 'Confirm Password', :with=>'0123456'
20
+ click_button 'Change Password'
21
+ page.find('#notice_flash').text.must_equal "Your password has been changed"
22
+
23
+ page.current_path.must_equal '/'
24
+ msgs = Mail::TestMailer.deliveries
25
+ msgs.length.must_equal 1
26
+ msgs.first.to.first.must_equal 'foo@example.com'
27
+ msgs.first.body.to_s.must_equal <<EMAIL
28
+ Someone (hopefully you) has changed the password for the account
29
+ associated to this email address.
30
+ EMAIL
31
+ msgs.clear
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ Someone (hopefully you) has changed the password for the account
2
+ associated to this email address.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-21 00:00:00.000000000 Z
11
+ date: 2017-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -228,6 +228,7 @@ extra_rdoc_files:
228
228
  - doc/http_basic_auth.rdoc
229
229
  - doc/verify_login_change.rdoc
230
230
  - doc/internals.rdoc
231
+ - doc/change_password_notify.rdoc
231
232
  - doc/release_notes/1.0.0.txt
232
233
  - doc/release_notes/1.1.0.txt
233
234
  - doc/release_notes/1.2.0.txt
@@ -242,6 +243,7 @@ extra_rdoc_files:
242
243
  - doc/release_notes/1.11.0.txt
243
244
  - doc/release_notes/1.12.0.txt
244
245
  - doc/release_notes/1.13.0.txt
246
+ - doc/release_notes/1.14.0.txt
245
247
  files:
246
248
  - CHANGELOG
247
249
  - MIT-LICENSE
@@ -251,6 +253,7 @@ files:
251
253
  - doc/base.rdoc
252
254
  - doc/change_login.rdoc
253
255
  - doc/change_password.rdoc
256
+ - doc/change_password_notify.rdoc
254
257
  - doc/close_account.rdoc
255
258
  - doc/confirm_password.rdoc
256
259
  - doc/create_account.rdoc
@@ -274,6 +277,7 @@ files:
274
277
  - doc/release_notes/1.11.0.txt
275
278
  - doc/release_notes/1.12.0.txt
276
279
  - doc/release_notes/1.13.0.txt
280
+ - doc/release_notes/1.14.0.txt
277
281
  - doc/release_notes/1.2.0.txt
278
282
  - doc/release_notes/1.3.0.txt
279
283
  - doc/release_notes/1.4.0.txt
@@ -299,6 +303,7 @@ files:
299
303
  - lib/rodauth/features/base.rb
300
304
  - lib/rodauth/features/change_login.rb
301
305
  - lib/rodauth/features/change_password.rb
306
+ - lib/rodauth/features/change_password_notify.rb
302
307
  - lib/rodauth/features/close_account.rb
303
308
  - lib/rodauth/features/confirm_password.rb
304
309
  - lib/rodauth/features/create_account.rb
@@ -331,6 +336,7 @@ files:
331
336
  - spec/account_expiration_spec.rb
332
337
  - spec/all.rb
333
338
  - spec/change_login_spec.rb
339
+ - spec/change_password_notify_spec.rb
334
340
  - spec/change_password_spec.rb
335
341
  - spec/close_account_spec.rb
336
342
  - spec/confirm_password_spec.rb
@@ -377,6 +383,7 @@ files:
377
383
  - templates/otp-auth.str
378
384
  - templates/otp-disable.str
379
385
  - templates/otp-setup.str
386
+ - templates/password-changed-email.str
380
387
  - templates/password-confirm-field.str
381
388
  - templates/password-field.str
382
389
  - templates/recovery-auth.str
@@ -426,7 +433,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
433
  version: '0'
427
434
  requirements: []
428
435
  rubyforge_project:
429
- rubygems_version: 2.6.13
436
+ rubygems_version: 2.7.3
430
437
  signing_key:
431
438
  specification_version: 4
432
439
  summary: Authentication and Account Management Framework for Rack Applications