quo_vadis 2.2.4 → 2.2.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d059bd573146f59fff8f4fff1ef953c4da0bff83b07125efafadfd40334a9a8
4
- data.tar.gz: 744bd5ac56082016453309608721c76e37dcb8827f1c7111102d8a0d06961608
3
+ metadata.gz: 793c8183dd6e61c69255ca9e13a9726949591cbc4e3dda9890fb213848819dea
4
+ data.tar.gz: a01e34b058359d91dac594c617a2c55550f16f2e607a9b254f2087eab9eadc10
5
5
  SHA512:
6
- metadata.gz: 746819329e2b544e00ca92ccf75cd5293f58160da3243db0c0d6b9dba6d70fde94e59492fd2d73387e20d5f60487dbb98f56eb8c618573215a6b9efd027b4442
7
- data.tar.gz: caf55aa31161fe96980ab58b2a3d477202e03b80fa2a4a684477bfb6f3aef4c4033ff670b03f2d434cbda45ff4bc23291d288b196440f372545c1eaccd89732f
6
+ metadata.gz: b5c29de9d14f2d2d14e4fcefa04379b0135c5720b27df6d3762c30503e121cb811f1e0248a76d589580931f953367c04f810d286df15204abe2c52b2df1c82cb
7
+ data.tar.gz: 9afd5eb09d2b91db1a5c3023e2c2b4fccd545231b39188fa95acebab677549dc642a657797b8c2e59b83b00595ce21083ffeadf0be2f4c17aa09e64496a9a672
data/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@
4
4
  ## HEAD
5
5
 
6
6
 
7
+ ## 2.2.6 (17 November 2025)
8
+
9
+ * Make permitting of password updates explicit.
10
+ * Feature-detect method rather than module for normalisation.
11
+
12
+
13
+ ## 2.2.5 (14 April 2025)
14
+
15
+ * Normalise identifier value for lookup.
16
+ * Tweak summary of project.
17
+
18
+
7
19
  ## 2.2.4 (25 June 2024)
8
20
 
9
21
  * Add logged-{in, out} routing constraints.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Quo Vadis
2
2
 
3
- Multifactor authentication for your Rails app (Rails 7 and Rails 6).
3
+ Multifactor authentication for your Rails app (backwards-compatible to Rails 6).
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
 
@@ -59,6 +59,8 @@ Finally, copy the example views across:
59
59
  rails generate quo_vadis:install
60
60
  ```
61
61
 
62
+ You may find that you need to eager load your code in development so that your model's / models' `#authenticates` call(s) executes straightaway. This method registers your model(s) with QuoVadis, which needs to happen before you can do any authentication-related things such as reset your password.
63
+
62
64
 
63
65
  ## Usage
64
66
 
@@ -7,12 +7,14 @@ module QuoVadis
7
7
  has_secure_password
8
8
 
9
9
  validates_length_of :password, minimum: QuoVadis.password_minimum_length, allow_blank: true
10
- validate :password_updated_legitimately, on: :update
10
+ validate :permitted_update, on: :update
11
11
 
12
12
  attr_accessor :new_password
13
13
 
14
14
 
15
15
  def change(current_plaintext, new_plaintext, new_plaintext_confirmation)
16
+ permit_password_update
17
+
16
18
  unless authenticate current_plaintext
17
19
  errors.add :password, :incorrect
18
20
  return false
@@ -38,6 +40,8 @@ module QuoVadis
38
40
 
39
41
 
40
42
  def reset(new_plaintext, new_plaintext_confirmation)
43
+ permit_password_update
44
+
41
45
  # has_secure_password ignores empty passwords ("") on update so reject them here.
42
46
  if new_plaintext.empty?
43
47
  errors.add :password, :blank
@@ -56,18 +60,19 @@ module QuoVadis
56
60
 
57
61
  private
58
62
 
59
- def password_updated_legitimately
60
- return unless password_digest_changed?
63
+ def permit_password_update
64
+ @permit_password_update = true
65
+ end
61
66
 
62
- unless change_or_reset_called?
63
- errors.add :password, 'must be updated via #change or #reset'
64
- end
67
+ def permit_password_update?
68
+ @permit_password_update
65
69
  end
66
70
 
67
- def change_or_reset_called?
68
- caller_locations.any? { |loc|
69
- ['change', 'reset'].include?(loc.label) && Pathname.new(loc.path).basename.to_s == 'password.rb'
70
- }
71
+ def permitted_update
72
+ return unless password_digest_changed?
73
+ return if permit_password_update?
74
+
75
+ errors.add :password, 'must be updated via #change or #reset'
71
76
  end
72
77
  end
73
78
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module QuoVadis
4
- VERSION = '2.2.4'
4
+ VERSION = '2.2.6'
5
5
  end
data/lib/quo_vadis.rb CHANGED
@@ -51,7 +51,12 @@ module QuoVadis
51
51
 
52
52
  def identifier_value_in_params(params)
53
53
  identifier = detect_identifier params.keys
54
- params[identifier]
54
+ value = params[identifier]
55
+
56
+ return value unless ApplicationRecord.respond_to? :normalize_value_for
57
+
58
+ klass = model_of(identifier.to_sym).constantize
59
+ klass.normalize_value_for(identifier.to_sym, value)
55
60
  end
56
61
 
57
62
  # model - string class name, e.g. 'User'
@@ -94,10 +99,16 @@ module QuoVadis
94
99
 
95
100
  private
96
101
 
102
+ # key - model name, e.g. "User"
103
+ # value - identifier, e.g. :email
97
104
  def models
98
105
  @models ||= {}
99
106
  end
100
107
 
108
+ def model_of(identifier)
109
+ models.rassoc(identifier).first
110
+ end
111
+
101
112
  def detect_identifier(candidates)
102
113
  (identifiers.map(&:to_s) & candidates.map(&:to_s)).first
103
114
  end
data/quo_vadis.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['Andy Stewart']
9
9
  spec.email = ['boss@airbladesoftware.com']
10
10
 
11
- spec.summary = 'Multifactor authentication for Rails 6 and 7.'
11
+ spec.summary = 'Multifactor authentication for Rails.'
12
12
  spec.homepage = 'https://github.com/airblade/quo_vadis'
13
13
  spec.license = 'MIT'
14
14
 
@@ -2,5 +2,7 @@ class User < ApplicationRecord
2
2
  validates :name, presence: true
3
3
  validates :email, presence: true, uniqueness: {case_sensitive: false}
4
4
 
5
+ normalizes :email, with: -> { _1.strip.downcase }
6
+
5
7
  authenticates
6
8
  end
@@ -17,7 +17,7 @@ class AccountTest < ActiveSupport::TestCase
17
17
  p = Person.create! username: 'bob', email: 'bob@example.com', password: 'secretsecret'
18
18
  assert_enqueued_email_with QuoVadis::Mailer,
19
19
  :identifier_change_notification,
20
- args: {email: 'bob@example.com', identifier: 'username', ip: nil, timestamp: Time.now} do
20
+ params: {email: 'bob@example.com', identifier: 'username', ip: nil, timestamp: Time.now} do
21
21
  assert_enqueued_emails 1 do
22
22
  p.update username: 'robert@example.com'
23
23
  end
@@ -30,7 +30,7 @@ class AccountTest < ActiveSupport::TestCase
30
30
  u = User.create! name: 'bob', email: 'bob@example.com', password: '123456789abc'
31
31
  assert_enqueued_email_with QuoVadis::Mailer,
32
32
  :email_change_notification,
33
- args: {email: 'bob@example.com', ip: nil, timestamp: Time.now} do
33
+ params: {email: 'bob@example.com', ip: nil, timestamp: Time.now} do
34
34
  assert_enqueued_emails 1 do
35
35
  u.update email: 'robert@example.com'
36
36
  end
@@ -29,14 +29,15 @@ class ModelTest < ActiveSupport::TestCase
29
29
 
30
30
 
31
31
  test 'copies model identifier to account' do
32
- email = 'bob@example.com'
32
+ email = ' Bob@example.com '
33
33
  u = User.create! name: 'bob', email: email, password: '123456789abc'
34
- assert_equal email, u.qv_account.identifier
34
+ # email is normalized
35
+ assert_equal "bob@example.com", u.qv_account.identifier
35
36
 
36
- email = 'b@foo.com'
37
+ email = 'b@FOO.com '
37
38
  u.update email: email
38
39
  u.qv_account.reload
39
- assert_equal email, u.qv_account.identifier
40
+ assert_equal "b@foo.com", u.qv_account.identifier
40
41
 
41
42
  u.update name: nil, email: 'xyz' # nil name is invalid
42
43
  u.qv_account.reload
@@ -62,7 +63,7 @@ class ModelTest < ActiveSupport::TestCase
62
63
  u = User.create! name: 'bob', email: 'bob@example.com', password: '123456789abc'
63
64
  assert_enqueued_email_with QuoVadis::Mailer,
64
65
  :email_change_notification,
65
- args: {email: 'bob@example.com', ip: nil, timestamp: Time.now} do
66
+ params: {email: 'bob@example.com', ip: nil, timestamp: Time.now} do
66
67
  u.update email: 'robert@example.com'
67
68
  end
68
69
  end
@@ -35,9 +35,9 @@ class QuoVadisTest < ActiveSupport::TestCase
35
35
 
36
36
 
37
37
  test 'find_account_by_identifier_in_params' do
38
- u = User.create! name: 'bob', email: 'bob@example.com', password: '123456789abc'
38
+ u = User.create! name: 'bob', email: ' Bob@example.com ', password: '123456789abc'
39
39
  assert_equal u.qv_account,
40
- QuoVadis.find_account_by_identifier_in_params({'foo' => 'bar', 'email' => 'bob@example.com', 'commit' => 'Save'})
40
+ QuoVadis.find_account_by_identifier_in_params({'foo' => 'bar', 'email' => ' BOB@example.com ', 'commit' => 'Save'})
41
41
  end
42
42
 
43
43
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quo_vadis
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.4
4
+ version: 2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Stewart
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -66,7 +65,6 @@ dependencies:
66
65
  - - "~>"
67
66
  - !ruby/object:Gem::Version
68
67
  version: '2.0'
69
- description:
70
68
  email:
71
69
  - boss@airbladesoftware.com
72
70
  executables: []
@@ -206,7 +204,6 @@ homepage: https://github.com/airblade/quo_vadis
206
204
  licenses:
207
205
  - MIT
208
206
  metadata: {}
209
- post_install_message:
210
207
  rdoc_options: []
211
208
  require_paths:
212
209
  - lib
@@ -221,8 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
218
  - !ruby/object:Gem::Version
222
219
  version: '0'
223
220
  requirements: []
224
- rubygems_version: 3.5.11
225
- signing_key:
221
+ rubygems_version: 3.7.2
226
222
  specification_version: 4
227
- summary: Multifactor authentication for Rails 6 and 7.
223
+ summary: Multifactor authentication for Rails.
228
224
  test_files: []