rodauth 1.19.1 → 1.20.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.
- checksums.yaml +4 -4
- data/CHANGELOG +72 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +100 -7
- data/doc/base.rdoc +25 -0
- data/doc/email_auth.rdoc +1 -1
- data/doc/email_base.rdoc +5 -1
- data/doc/internals.rdoc +2 -2
- data/doc/jwt_refresh.rdoc +35 -0
- data/doc/lockout.rdoc +3 -0
- data/doc/login_password_requirements_base.rdoc +4 -1
- data/doc/otp.rdoc +22 -39
- data/doc/recovery_codes.rdoc +15 -28
- data/doc/release_notes/1.20.0.txt +175 -0
- data/doc/remember.rdoc +3 -0
- data/doc/reset_password.rdoc +2 -1
- data/doc/single_session.rdoc +3 -0
- data/doc/verify_account.rdoc +4 -3
- data/doc/verify_login_change.rdoc +1 -1
- data/lib/rodauth.rb +33 -4
- data/lib/rodauth/features/base.rb +93 -10
- data/lib/rodauth/features/change_login.rb +1 -1
- data/lib/rodauth/features/confirm_password.rb +1 -1
- data/lib/rodauth/features/create_account.rb +2 -2
- data/lib/rodauth/features/disallow_password_reuse.rb +5 -3
- data/lib/rodauth/features/email_auth.rb +4 -2
- data/lib/rodauth/features/email_base.rb +12 -6
- data/lib/rodauth/features/jwt.rb +9 -0
- data/lib/rodauth/features/jwt_refresh.rb +142 -0
- data/lib/rodauth/features/lockout.rb +8 -4
- data/lib/rodauth/features/login_password_requirements_base.rb +1 -0
- data/lib/rodauth/features/otp.rb +63 -6
- data/lib/rodauth/features/recovery_codes.rb +1 -0
- data/lib/rodauth/features/remember.rb +20 -2
- data/lib/rodauth/features/reset_password.rb +5 -2
- data/lib/rodauth/features/single_session.rb +15 -2
- data/lib/rodauth/features/verify_account.rb +11 -6
- data/lib/rodauth/features/verify_login_change.rb +5 -3
- data/lib/rodauth/version.rb +2 -2
- data/spec/disallow_password_reuse_spec.rb +115 -28
- data/spec/email_auth_spec.rb +2 -2
- data/spec/jwt_refresh_spec.rb +256 -0
- data/spec/lockout_spec.rb +4 -4
- data/spec/login_spec.rb +52 -11
- data/spec/migrate/001_tables.rb +10 -0
- data/spec/migrate_travis/001_tables.rb +8 -0
- data/spec/remember_spec.rb +27 -0
- data/spec/reset_password_spec.rb +2 -2
- data/spec/rodauth_spec.rb +25 -1
- data/spec/single_session_spec.rb +20 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/two_factor_spec.rb +57 -3
- data/spec/verify_account_spec.rb +18 -1
- data/spec/verify_login_change_spec.rb +2 -2
- data/templates/add-recovery-codes.str +1 -1
- data/templates/change-password.str +2 -2
- data/templates/login-confirm-field.str +2 -2
- data/templates/login-field.str +2 -2
- data/templates/otp-auth-code-field.str +2 -2
- data/templates/otp-setup.str +4 -3
- data/templates/password-confirm-field.str +2 -2
- data/templates/password-field.str +2 -2
- data/templates/recovery-auth.str +2 -2
- data/templates/reset-password-request.str +1 -1
- data/templates/sms-code-field.str +2 -2
- data/templates/sms-setup.str +2 -2
- data/templates/unlock-account-request.str +1 -1
- data/templates/unlock-account.str +1 -1
- data/templates/verify-account-resend.str +1 -1
- metadata +15 -5
data/spec/verify_account_spec.rb
CHANGED
@@ -3,10 +3,14 @@ require File.expand_path("spec_helper", File.dirname(__FILE__))
|
|
3
3
|
describe 'Rodauth verify_account feature' do
|
4
4
|
it "should support verifying accounts" do
|
5
5
|
last_sent_column = nil
|
6
|
+
secret = nil
|
7
|
+
allow_raw_token = false
|
6
8
|
rodauth do
|
7
9
|
enable :login, :create_account, :verify_account
|
8
10
|
verify_account_autologin? false
|
9
11
|
verify_account_email_last_sent_column{last_sent_column}
|
12
|
+
hmac_secret{secret}
|
13
|
+
allow_raw_email_token?{allow_raw_token}
|
10
14
|
end
|
11
15
|
roda do |r|
|
12
16
|
r.rodauth
|
@@ -73,8 +77,13 @@ describe 'Rodauth verify_account feature' do
|
|
73
77
|
|
74
78
|
link = email_link(/(\/verify-account\?key=.+)$/, 'foo@example2.com')
|
75
79
|
visit link[0...-1]
|
76
|
-
page.find('#error_flash').text.must_equal "invalid verify account key"
|
80
|
+
page.find('#error_flash').text.must_equal "There was an error verifying your account: invalid verify account key"
|
77
81
|
|
82
|
+
secret = SecureRandom.random_bytes(32)
|
83
|
+
visit link
|
84
|
+
page.find('#error_flash').text.must_equal "There was an error verifying your account: invalid verify account key"
|
85
|
+
|
86
|
+
allow_raw_token = true
|
78
87
|
visit link
|
79
88
|
click_button 'Verify Account'
|
80
89
|
page.find('#notice_flash').text.must_equal "Your account has been verified"
|
@@ -87,11 +96,13 @@ describe 'Rodauth verify_account feature' do
|
|
87
96
|
|
88
97
|
[false, true].each do |ph|
|
89
98
|
it "should support setting passwords when verifying accounts #{'with account_password_hash_column' if ph}" do
|
99
|
+
initial_secret = secret = SecureRandom.random_bytes(32)
|
90
100
|
rodauth do
|
91
101
|
enable :login, :create_account, :verify_account
|
92
102
|
account_password_hash_column :ph if ph
|
93
103
|
verify_account_autologin? false
|
94
104
|
verify_account_set_password? true
|
105
|
+
hmac_secret{secret}
|
95
106
|
end
|
96
107
|
roda do |r|
|
97
108
|
r.rodauth
|
@@ -105,6 +116,12 @@ describe 'Rodauth verify_account feature' do
|
|
105
116
|
page.find('#notice_flash').text.must_equal "An email has been sent to you with a link to verify your account"
|
106
117
|
|
107
118
|
link = email_link(/(\/verify-account\?key=.+)$/, 'foo@example2.com')
|
119
|
+
|
120
|
+
secret = SecureRandom.random_bytes(32)
|
121
|
+
visit link
|
122
|
+
page.find('#error_flash').text.must_equal "There was an error verifying your account: invalid verify account key"
|
123
|
+
|
124
|
+
secret = initial_secret
|
108
125
|
visit link
|
109
126
|
fill_in 'Password', :with=>'0123456789'
|
110
127
|
fill_in 'Confirm Password', :with=>'012345678'
|
@@ -36,7 +36,7 @@ describe 'Rodauth verify_login_change feature' do
|
|
36
36
|
logout
|
37
37
|
|
38
38
|
visit link
|
39
|
-
page.find('#error_flash').text.must_equal "invalid verify login change key"
|
39
|
+
page.find('#error_flash').text.must_equal "There was an error verifying your login change: invalid verify login change key"
|
40
40
|
|
41
41
|
visit new_link
|
42
42
|
page.title.must_equal 'Verify Login Change'
|
@@ -128,7 +128,7 @@ describe 'Rodauth verify_login_change feature' do
|
|
128
128
|
page.current_path.must_equal '/login'
|
129
129
|
|
130
130
|
visit link
|
131
|
-
page.find('#error_flash').text.must_equal "invalid verify login change key"
|
131
|
+
page.find('#error_flash').text.must_equal "There was an error verifying your login change: invalid verify login change key"
|
132
132
|
end
|
133
133
|
|
134
134
|
it "should handle uniqueness errors raised when inserting verify login change entry" do
|
@@ -1,2 +1,2 @@
|
|
1
1
|
<pre id="recovery-codes">#{rodauth.recovery_codes.map{|s| h s}.join("\n\n")}</pre>
|
2
|
-
#{"
|
2
|
+
#{"#{rodauth.add_recovery_codes_heading}#{rodauth.render('recovery-codes')}" if rodauth.can_add_recovery_codes?}
|
@@ -3,9 +3,9 @@
|
|
3
3
|
#{rodauth.csrf_tag}
|
4
4
|
#{rodauth.render('password-field') if rodauth.change_password_requires_password?}
|
5
5
|
<div class="form-group">
|
6
|
-
<label class="col-sm-2 control-label" for="new-password">#{rodauth.new_password_label}</label>
|
6
|
+
<label class="col-sm-2 control-label" for="new-password">#{rodauth.new_password_label}#{rodauth.input_field_label_suffix}</label>
|
7
7
|
<div class="col-sm-10">
|
8
|
-
|
8
|
+
#{rodauth.input_field_string(rodauth.new_password_param, 'new-password', :type => 'password')}
|
9
9
|
</div>
|
10
10
|
</div>
|
11
11
|
#{rodauth.render('password-confirm-field') if rodauth.require_password_confirmation?}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-2 control-label" for="login-confirm">#{rodauth.login_confirm_label}</label>
|
2
|
+
<label class="col-sm-2 control-label" for="login-confirm">#{rodauth.login_confirm_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-10">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.login_confirm_param, 'login-confirm', :type=>rodauth.login_input_type)}
|
5
5
|
</div>
|
6
6
|
</div>
|
data/templates/login-field.str
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-2 control-label" for="login">#{rodauth.login_label}</label>
|
2
|
+
<label class="col-sm-2 control-label" for="login">#{rodauth.login_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-10">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.login_param, 'login', :type=>rodauth.login_input_type)}
|
5
5
|
</div>
|
6
6
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-4 control-label" for="otp-auth-code">#{rodauth.otp_auth_label}</label>
|
2
|
+
<label class="col-sm-4 control-label" for="otp-auth-code">#{rodauth.otp_auth_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-3">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.otp_auth_param, 'otp-auth-code', :value=>'', :attr=>'autocomplete="off"' )}
|
5
5
|
</div>
|
6
6
|
</div>
|
data/templates/otp-setup.str
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
<form method="post" class="rodauth form-horizontal" role="form" id="otp-setup-form">
|
2
2
|
#{rodauth.otp_setup_additional_form_tags}
|
3
|
-
<input type="hidden" id="otp-key" name="#{rodauth.otp_setup_param}" value="#{rodauth.
|
3
|
+
<input type="hidden" id="otp-key" name="#{rodauth.otp_setup_param}" value="#{rodauth.otp_user_key}" />
|
4
|
+
#{"<input type=\"hidden\" id=\"otp-hmac-secret\" name=\"#{rodauth.otp_setup_raw_param}\" value=\"#{rodauth.otp_key}\" />" if rodauth.otp_keys_use_hmac?}
|
4
5
|
#{rodauth.csrf_tag}
|
5
6
|
<div class="form-group">
|
6
|
-
<p
|
7
|
-
<p
|
7
|
+
<p>#{rodauth.otp_secret_label}: #{rodauth.otp_user_key}</p>
|
8
|
+
<p>#{rodauth.otp_provisioning_uri_label}: #{rodauth.otp_provisioning_uri}</p>
|
8
9
|
</div>
|
9
10
|
|
10
11
|
<div class="row">
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-2 control-label" for="password-confirm">#{rodauth.password_confirm_label}</label>
|
2
|
+
<label class="col-sm-2 control-label" for="password-confirm">#{rodauth.password_confirm_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-10">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.password_confirm_param, 'password-confirm', :type => 'password')}
|
5
5
|
</div>
|
6
6
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-2 control-label" for="password">#{rodauth.password_label}</label>
|
2
|
+
<label class="col-sm-2 control-label" for="password">#{rodauth.password_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-10">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.password_param, 'password', :type => 'password')}
|
5
5
|
</div>
|
6
6
|
</div>
|
data/templates/recovery-auth.str
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
#{rodauth.recovery_auth_additional_form_tags}
|
3
3
|
#{rodauth.csrf_tag}
|
4
4
|
<div class="form-group">
|
5
|
-
<label class="col-sm-2 control-label" for="recovery_code">#{rodauth.recovery_codes_label}</label>
|
5
|
+
<label class="col-sm-2 control-label" for="recovery_code">#{rodauth.recovery_codes_label}#{rodauth.input_field_label_suffix}</label>
|
6
6
|
<div class="col-sm-10">
|
7
|
-
|
7
|
+
#{rodauth.input_field_string(rodauth.recovery_codes_param, 'recovery_code', :value => '')}
|
8
8
|
</div>
|
9
9
|
</div>
|
10
10
|
#{rodauth.button(rodauth.recovery_auth_button)}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<form action="#{rodauth.prefix}/#{rodauth.reset_password_request_route}" method="post" class="rodauth form-horizontal" role="form" id="reset-password-request-form">
|
2
2
|
#{rodauth.reset_password_request_additional_form_tags}
|
3
3
|
#{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.reset_password_request_route}")}
|
4
|
-
|
4
|
+
#{rodauth.reset_password_explanatory_text}
|
5
5
|
#{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
|
6
6
|
#{rodauth.button(rodauth.reset_password_request_button)}
|
7
7
|
</form>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="form-group">
|
2
|
-
<label class="col-sm-3 control-label" for="sms-code">#{rodauth.sms_code_label}</label>
|
2
|
+
<label class="col-sm-3 control-label" for="sms-code">#{rodauth.sms_code_label}#{rodauth.input_field_label_suffix}</label>
|
3
3
|
<div class="col-sm-3">
|
4
|
-
|
4
|
+
#{rodauth.input_field_string(rodauth.sms_code_param, 'sms-code', :value => '')}
|
5
5
|
</div>
|
6
6
|
</div>
|
data/templates/sms-setup.str
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
#{rodauth.csrf_tag}
|
4
4
|
#{rodauth.render('password-field') if rodauth.two_factor_modifications_require_password?}
|
5
5
|
<div class="form-group">
|
6
|
-
<label class="col-sm-2 control-label" for="sms-phone">#{rodauth.sms_phone_label}</label>
|
6
|
+
<label class="col-sm-2 control-label" for="sms-phone">#{rodauth.sms_phone_label}#{rodauth.input_field_label_suffix}</label>
|
7
7
|
<div class="col-sm-3">
|
8
|
-
|
8
|
+
#{rodauth.input_field_string(rodauth.sms_phone_param, 'sms-phone')}
|
9
9
|
</div>
|
10
10
|
</div>
|
11
11
|
#{rodauth.button(rodauth.sms_setup_button)}
|
@@ -2,6 +2,6 @@
|
|
2
2
|
#{rodauth.unlock_account_request_additional_form_tags}
|
3
3
|
#{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.unlock_account_request_route}")}
|
4
4
|
<input type="hidden" name="#{rodauth.login_param}" value="#{h rodauth.param(rodauth.login_param)}"/>
|
5
|
-
|
5
|
+
#{rodauth.unlock_account_request_explanatory_text}
|
6
6
|
<input type="submit" class="btn btn-primary inline" value="#{rodauth.unlock_account_request_button}"/>
|
7
7
|
</form>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<form method="post" class="rodauth form-horizontal" role="form" id="unlock-account-form">
|
2
2
|
#{rodauth.unlock_account_additional_form_tags}
|
3
3
|
#{rodauth.csrf_tag}
|
4
|
-
|
4
|
+
#{rodauth.unlock_account_explanatory_text}
|
5
5
|
#{rodauth.render('password-field') if rodauth.unlock_account_requires_password?}
|
6
6
|
#{rodauth.button(rodauth.unlock_account_button)}
|
7
7
|
</form>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<form action="#{rodauth.prefix}/#{rodauth.verify_account_resend_route}" method="post" class="rodauth form-horizontal" role="form" id="verify-account-resend-form">
|
2
2
|
#{rodauth.verify_account_resend_additional_form_tags}
|
3
3
|
#{rodauth.csrf_tag("#{rodauth.prefix}/#{rodauth.verify_account_resend_route}")}
|
4
|
-
|
4
|
+
#{rodauth.verify_account_resend_explanatory_text}
|
5
5
|
#{(login = rodauth.param_or_nil(rodauth.login_param)) ? "<input type=\"hidden\" name=\"#{rodauth.login_param}\" value=\"#{h login}\"/>" : rodauth.render('login-field')}
|
6
6
|
#{rodauth.button(rodauth.verify_account_resend_button)}
|
7
7
|
</form>
|
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.
|
4
|
+
version: 1.20.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:
|
11
|
+
date: 2019-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -229,6 +229,7 @@ extra_rdoc_files:
|
|
229
229
|
- doc/update_password_hash.rdoc
|
230
230
|
- doc/verify_account.rdoc
|
231
231
|
- doc/email_auth.rdoc
|
232
|
+
- doc/jwt_refresh.rdoc
|
232
233
|
- doc/verify_account_grace_period.rdoc
|
233
234
|
- doc/verify_login_change.rdoc
|
234
235
|
- doc/release_notes/1.17.0.txt
|
@@ -251,6 +252,7 @@ extra_rdoc_files:
|
|
251
252
|
- doc/release_notes/1.9.0.txt
|
252
253
|
- doc/release_notes/1.18.0.txt
|
253
254
|
- doc/release_notes/1.19.0.txt
|
255
|
+
- doc/release_notes/1.20.0.txt
|
254
256
|
files:
|
255
257
|
- CHANGELOG
|
256
258
|
- MIT-LICENSE
|
@@ -272,6 +274,7 @@ files:
|
|
272
274
|
- doc/http_basic_auth.rdoc
|
273
275
|
- doc/internals.rdoc
|
274
276
|
- doc/jwt.rdoc
|
277
|
+
- doc/jwt_refresh.rdoc
|
275
278
|
- doc/lockout.rdoc
|
276
279
|
- doc/login.rdoc
|
277
280
|
- doc/login_password_requirements_base.rdoc
|
@@ -294,6 +297,7 @@ files:
|
|
294
297
|
- doc/release_notes/1.18.0.txt
|
295
298
|
- doc/release_notes/1.19.0.txt
|
296
299
|
- doc/release_notes/1.2.0.txt
|
300
|
+
- doc/release_notes/1.20.0.txt
|
297
301
|
- doc/release_notes/1.3.0.txt
|
298
302
|
- doc/release_notes/1.4.0.txt
|
299
303
|
- doc/release_notes/1.5.0.txt
|
@@ -328,6 +332,7 @@ files:
|
|
328
332
|
- lib/rodauth/features/email_base.rb
|
329
333
|
- lib/rodauth/features/http_basic_auth.rb
|
330
334
|
- lib/rodauth/features/jwt.rb
|
335
|
+
- lib/rodauth/features/jwt_refresh.rb
|
331
336
|
- lib/rodauth/features/lockout.rb
|
332
337
|
- lib/rodauth/features/login.rb
|
333
338
|
- lib/rodauth/features/login_password_requirements_base.rb
|
@@ -362,6 +367,7 @@ files:
|
|
362
367
|
- spec/disallow_password_reuse_spec.rb
|
363
368
|
- spec/email_auth_spec.rb
|
364
369
|
- spec/http_basic_auth_spec.rb
|
370
|
+
- spec/jwt_refresh_spec.rb
|
365
371
|
- spec/jwt_spec.rb
|
366
372
|
- spec/lockout_spec.rb
|
367
373
|
- spec/login_spec.rb
|
@@ -432,7 +438,12 @@ files:
|
|
432
438
|
homepage: https://github.com/jeremyevans/rodauth
|
433
439
|
licenses:
|
434
440
|
- MIT
|
435
|
-
metadata:
|
441
|
+
metadata:
|
442
|
+
bug_tracker_uri: https://github.com/jeremyevans/rodauth/issues
|
443
|
+
changelog_uri: http://rodauth.jeremyevans.net/rdoc/files/CHANGELOG.html
|
444
|
+
documentation_uri: http://rodauth.jeremyevans.net/documentation.html
|
445
|
+
mailing_list_uri: https://groups.google.com/forum/#!forum/rodauth
|
446
|
+
source_code_uri: https://github.com/jeremyevans/rodauth
|
436
447
|
post_install_message:
|
437
448
|
rdoc_options:
|
438
449
|
- "--quiet"
|
@@ -455,8 +466,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
455
466
|
- !ruby/object:Gem::Version
|
456
467
|
version: '0'
|
457
468
|
requirements: []
|
458
|
-
|
459
|
-
rubygems_version: 2.7.6
|
469
|
+
rubygems_version: 3.0.3
|
460
470
|
signing_key:
|
461
471
|
specification_version: 4
|
462
472
|
summary: Authentication and Account Management Framework for Rack Applications
|