quo_vadis 2.1.5 → 2.1.8
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 +17 -0
- data/README.md +2 -2
- data/app/models/quo_vadis/session.rb +1 -1
- data/app/views/quo_vadis/logs/index.html.erb +1 -1
- data/lib/quo_vadis/crypt.rb +12 -6
- data/lib/quo_vadis/model.rb +7 -3
- data/lib/quo_vadis/version.rb +1 -1
- data/test/integration/sessions_test.rb +1 -1
- data/test/models/crypt_test.rb +19 -0
- data/test/models/model_test.rb +10 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d11498bfa66e0397304c2d9a0f8ac504037f97beac4fd039fe6c8d0299696531
|
4
|
+
data.tar.gz: 2d1e267c7b55740c72087e297960ff6ececb1caee45a17eb588bf7e44ba64d31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4e7c7bb2996556b35b153c56916aef9834dcac2abea08ede8becc14e030d8f4ea1444f9286c1ca9b728c1a13c16d8d9b2e701255d57b769c7dc9abefa84a976
|
7
|
+
data.tar.gz: f466404a5ba44bfd506cbcd2fdc7b2f2d142ecab419363e3c368bb5eca67cfc78829afa698b8b0dc1cc76210b531a32a44c3bfdcd1ae709cf9eafe740861f089
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,23 @@
|
|
4
4
|
## HEAD
|
5
5
|
|
6
6
|
|
7
|
+
## 2.1.8 (18 June 2022)
|
8
|
+
|
9
|
+
* Extract convenience method for has authentication account.
|
10
|
+
* Only authenticating models react to email change.
|
11
|
+
|
12
|
+
|
13
|
+
## 2.1.7 (30 May 2022)
|
14
|
+
|
15
|
+
* Use SHA256 digest for encryption.
|
16
|
+
* Use <time> element in logs view.
|
17
|
+
|
18
|
+
|
19
|
+
## 2.1.6 (30 May 2022)
|
20
|
+
|
21
|
+
* Fix typo in session scope.
|
22
|
+
|
23
|
+
|
7
24
|
## 2.1.5 (27 May 2022)
|
8
25
|
|
9
26
|
* Order sessions list and display more information.
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Quo Vadis
|
2
2
|
|
3
|
-
Multifactor authentication for your Rails 6 app.
|
3
|
+
Multifactor authentication for your Rails 6 or Rails 7 app.
|
4
4
|
|
5
5
|
Designed in accordance with the [OWASP Application Security Verification Standard](https://owasp.org/www-project-application-security-verification-standard/) and relevant [OWASP Cheatsheets](https://cheatsheetseries.owasp.org).
|
6
6
|
|
@@ -537,6 +537,6 @@ If you don't want a specific flash message at all, give the key an empty value i
|
|
537
537
|
|
538
538
|
## Intellectual Property
|
539
539
|
|
540
|
-
Copyright 2011-
|
540
|
+
Copyright 2011-2022 Andrew Stewart (boss@airbladesoftware.com).
|
541
541
|
|
542
542
|
Released under the MIT licence.
|
@@ -12,7 +12,7 @@
|
|
12
12
|
<tbody>
|
13
13
|
<% @logs.each do |log| %>
|
14
14
|
<tr>
|
15
|
-
<td><%= log.created_at %></td>
|
15
|
+
<td><time datetime="<%= log.created_at.to_formatted_s(:iso8601) %>"><%= log.created_at.to_formatted_s('%-d %B %Y') %></time></td>
|
16
16
|
<td><%= QuoVadis.translate "log.action.#{log.action}" %></td>
|
17
17
|
<td><%= log.ip %></td>
|
18
18
|
<td><%= log.metadata.empty? ? '' : log.metadata.map {|k,v| "#{k}: #{v}"}.join(', ') %></td>
|
data/lib/quo_vadis/crypt.rb
CHANGED
@@ -8,7 +8,7 @@ module QuoVadis
|
|
8
8
|
return '' if value == ''
|
9
9
|
|
10
10
|
salt = SecureRandom.hex KEY_LENGTH
|
11
|
-
crypt = encryptor
|
11
|
+
crypt = encryptor salt
|
12
12
|
ciphertext = crypt.encrypt_and_sign value
|
13
13
|
[salt, ciphertext].join SEPARATOR
|
14
14
|
end
|
@@ -18,7 +18,7 @@ module QuoVadis
|
|
18
18
|
return '' if value == ''
|
19
19
|
|
20
20
|
salt, data = value.split SEPARATOR
|
21
|
-
crypt = encryptor
|
21
|
+
crypt = encryptor salt
|
22
22
|
crypt.decrypt_and_verify(data)
|
23
23
|
end
|
24
24
|
|
@@ -27,12 +27,18 @@ module QuoVadis
|
|
27
27
|
KEY_LENGTH = ActiveSupport::MessageEncryptor.key_len
|
28
28
|
SEPARATOR = '$$'
|
29
29
|
|
30
|
-
def self.encryptor(
|
31
|
-
|
30
|
+
def self.encryptor(salt)
|
31
|
+
key_sha256 = key salt, OpenSSL::Digest::SHA256
|
32
|
+
key_sha1 = key salt, OpenSSL::Digest::SHA1
|
33
|
+
ActiveSupport::MessageEncryptor.new(key_sha256).tap { |crypt|
|
34
|
+
crypt.rotate key_sha1
|
35
|
+
}
|
32
36
|
end
|
33
37
|
|
34
|
-
def self.key(salt)
|
35
|
-
ActiveSupport::KeyGenerator
|
38
|
+
def self.key(salt, hash_digest_class)
|
39
|
+
ActiveSupport::KeyGenerator
|
40
|
+
.new(secret, hash_digest_class: hash_digest_class)
|
41
|
+
.generate_key(salt, KEY_LENGTH)
|
36
42
|
end
|
37
43
|
|
38
44
|
def self.secret
|
data/lib/quo_vadis/model.rb
CHANGED
@@ -14,7 +14,7 @@ module QuoVadis
|
|
14
14
|
|
15
15
|
has_one :qv_account, as: :model, class_name: 'QuoVadis::Account', dependent: :destroy, autosave: true
|
16
16
|
|
17
|
-
before_validation :qv_copy_identifier_to_account, if:
|
17
|
+
before_validation :qv_copy_identifier_to_account, if: :has_authentication_account?
|
18
18
|
|
19
19
|
validate :qv_copy_password_errors, if: Proc.new { |m| m.qv_account&.password }
|
20
20
|
|
@@ -29,8 +29,8 @@ module QuoVadis
|
|
29
29
|
qv_account.identifier = send identifier
|
30
30
|
end
|
31
31
|
|
32
|
-
after_update :qv_log_email_change,
|
33
|
-
after_update :qv_notify_email_change, if: :saved_change_to_email?
|
32
|
+
after_update :qv_log_email_change, if: [:has_authentication_account?, :saved_change_to_email?]
|
33
|
+
after_update :qv_notify_email_change, if: [:has_authentication_account?, :saved_change_to_email?]
|
34
34
|
|
35
35
|
QuoVadis.register_model self.name, identifier
|
36
36
|
end
|
@@ -57,6 +57,10 @@ module QuoVadis
|
|
57
57
|
qv_account.revoke
|
58
58
|
end
|
59
59
|
|
60
|
+
def has_authentication_account?
|
61
|
+
!!qv_account
|
62
|
+
end
|
63
|
+
|
60
64
|
private
|
61
65
|
|
62
66
|
def qv_copy_password_errors
|
data/lib/quo_vadis/version.rb
CHANGED
@@ -54,7 +54,7 @@ class SessionsTest < IntegrationTest
|
|
54
54
|
phone.get quo_vadis.sessions_path
|
55
55
|
phone.assert_response :success
|
56
56
|
phone.assert_select 'td', 'This session'
|
57
|
-
phone.assert_select 'td
|
57
|
+
phone.assert_select 'td button[type=submit]', text: 'Log out', count: 1
|
58
58
|
|
59
59
|
# on phone, log out the desktop session
|
60
60
|
phone.delete quo_vadis.session_path(QuoVadis::Session.first.id)
|
data/test/models/crypt_test.rb
CHANGED
@@ -4,6 +4,13 @@ class CryptTest < ActiveSupport::TestCase
|
|
4
4
|
|
5
5
|
setup do
|
6
6
|
@crypt = QuoVadis::Crypt
|
7
|
+
|
8
|
+
@crypt_sha1 = Class.new(QuoVadis::Crypt) do
|
9
|
+
def self.encryptor(salt)
|
10
|
+
key_sha1 = key salt, OpenSSL::Digest::SHA1
|
11
|
+
ActiveSupport::MessageEncryptor.new key_sha1
|
12
|
+
end
|
13
|
+
end
|
7
14
|
end
|
8
15
|
|
9
16
|
test 'round trip' do
|
@@ -19,4 +26,16 @@ class CryptTest < ActiveSupport::TestCase
|
|
19
26
|
refute_equal ciphertext, @crypt.encrypt(plaintext)
|
20
27
|
end
|
21
28
|
|
29
|
+
test 'rotation' do
|
30
|
+
# This test only works if our test Rails contains this commit:
|
31
|
+
# https://github.com/rails/rails/commit/447e28347eb46e2ad5dc625de616152bd1b69a32
|
32
|
+
return unless ActiveSupport::KeyGenerator.respond_to? :hash_digest_class
|
33
|
+
|
34
|
+
plaintext = 'the quick brown fox'
|
35
|
+
# Encrypt with SHA1 digest
|
36
|
+
ciphertext_sha1 = @crypt_sha1.encrypt plaintext
|
37
|
+
# Ensure code can decrypt it.
|
38
|
+
assert_equal plaintext, @crypt.decrypt(ciphertext_sha1)
|
39
|
+
end
|
40
|
+
|
22
41
|
end
|
data/test/models/model_test.rb
CHANGED
@@ -66,4 +66,14 @@ class ModelTest < ActiveSupport::TestCase
|
|
66
66
|
u.update email: 'robert@example.com'
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
|
71
|
+
test 'does not notify or log on email change when no account' do
|
72
|
+
u = User.create! name: 'bob', email: 'bob@example.com'
|
73
|
+
assert_no_difference 'QuoVadis::Log.count' do
|
74
|
+
assert_no_enqueued_emails do
|
75
|
+
u.update email: 'robert@example.com'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
69
79
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quo_vadis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Stewart
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|