veri 2.0.2 → 2.0.3

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: c9b0db1fbb87c0a3b25d47f2142cab1b9143a0ba7751a05c1676ca6e3b4b6ee3
4
- data.tar.gz: 600d600760a3c0af2fddfece43322193be1ae4255eae0dd1c22d4099a083cb7b
3
+ metadata.gz: 90c72152f71aea2555de8f7788b356e8b957d94df73a0bfc826ee79b1087fed7
4
+ data.tar.gz: f552a61efc8b704a9065bca3d785dcb8cd4046299ee94e05dc0cb08b381511e4
5
5
  SHA512:
6
- metadata.gz: aaf5ec5aced9ddec1c42367df39be9e4322d3b1b3946bb473bfaee3f668d6fea55d78b48f3f1f0fa1acb8ee4588de8039d054730d3b913ab8036def74054d858
7
- data.tar.gz: b188516f09afc341584f4460d5caa0e552c94e54dfe3a4bc3fe7a4cddb592acbb8c4957092e4763e88bd1be34ebc122934b40876bd2fc23e87d3b207b5fb2479
6
+ metadata.gz: 1947901336055c81c82f36c18c6abdeadc76d6d1ce47564de69bd83cb98a75d14e433276df5be08c24506277571121d81eaf6c3c0805c5d1041f8d9272821d31
7
+ data.tar.gz: eb186110a8816965a3ae0c7f396fdd8b0fd212ce281602139268e55cf466e3ad7589e0838383840e629c2b6259ab027c1beb343b5f4338b778717a3b5670eaae
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## v2.0.3
2
+
3
+ ### Bugs
4
+
5
+ - Fixed authentication raising `NameError` when the configured user model is not named `User`
6
+ - Fixed Rails commands failing when the configured user model class does not exist yet
7
+ - Fixed expired and inactive sessions still appearing as logged in on pages that don't require authentication
8
+ - Fixed locking a user not terminating their sessions until their next request
9
+ - Fixed password verification raising an error for users who have no password set
10
+ - Fixed cross-tenant shapeshifting not working
11
+
12
+ ### Misc
13
+
14
+ - The hashing algorithm can now be changed without breaking existing passwords
15
+
1
16
  ## v2.0.2
2
17
 
3
18
  ### Misc
data/README.md CHANGED
@@ -81,6 +81,8 @@ Veri.configure do |config|
81
81
  end
82
82
  ```
83
83
 
84
+ The hashing algorithm can be changed at any time: existing passwords are verified with the algorithm they were hashed with and are automatically re-hashed with the configured algorithm on the next successful login.
85
+
84
86
  ## Password Management
85
87
 
86
88
  Your user model is automatically extended with password management methods:
@@ -408,6 +410,8 @@ session.shapeshift(user, tenant: company)
408
410
  session.true_tenant
409
411
  ```
410
412
 
413
+ The `tenant:` argument always becomes the session's tenant: omitting it means no tenant. In a multi-tenant application, always pass it explicitly.
414
+
411
415
  All other session methods work the same way in multi-tenant applications as in single-tenant applications. However, `to_true_identity` will restore both the original user and tenant.
412
416
 
413
417
  ### Orphaned Sessions
@@ -502,24 +506,26 @@ end
502
506
  ## Getting Help and Contributing
503
507
 
504
508
  ### Getting Help
509
+
505
510
  Have a question or need assistance? Open a discussion in the [discussions section](https://github.com/enjaku4/veri/discussions) for:
511
+
506
512
  - Usage questions
507
513
  - Implementation guidance
508
- - Feature suggestions
514
+ - Open-ended ideas or suggestions
515
+
516
+ ### Issues
517
+
518
+ [Issues](https://github.com/enjaku4/veri/issues) track bugs, planned features, and other work. When reporting a bug, please include:
509
519
 
510
- ### Reporting Issues
511
- Found a bug? Please [create an issue](https://github.com/enjaku4/veri/issues) with:
512
520
  - A clear description of the problem
513
521
  - Steps to reproduce the issue
514
- - Your environment details (Rails version, Ruby version, etc.)
522
+ - Your environment details (Rails and Ruby versions, OS, etc.)
515
523
 
516
524
  ### Contributing Code
517
- Ready to contribute? You can:
518
- - Fix bugs by submitting pull requests
519
- - Improve documentation
520
- - Add new features (please discuss first in the [discussions section](https://github.com/enjaku4/veri/discussions))
521
525
 
522
- Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/veri/blob/main/CONTRIBUTING.md)
526
+ Any open issue is free to pick up or discuss. Check the [project board](https://github.com/users/enjaku4/projects/13) or [issues tab](https://github.com/enjaku4/veri/issues).
527
+
528
+ Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/veri/blob/main/CONTRIBUTING.md).
523
529
 
524
530
  ## License
525
531
 
@@ -531,6 +537,6 @@ Everyone interacting in the Veri project is expected to follow the [code of cond
531
537
 
532
538
  ## Old Versions
533
539
 
534
- Only the latest major version is supported. Older versions are obsolete and not maintained, but their READMEs are available here for reference:
540
+ Only the latest major version is actively maintained. READMEs for older versions are available here for reference:
535
541
 
536
542
  [v1.x.x](https://github.com/enjaku4/veri/blob/9c188e16a703141b7cd89dd31d5cd49a557f143d/README.md)
@@ -1,5 +1,3 @@
1
- require "zlib"
2
-
3
1
  module Veri
4
2
  module Authentication
5
3
  extend ActiveSupport::Concern
@@ -29,9 +27,9 @@ module Veri
29
27
  end
30
28
 
31
29
  def current_session
32
- token = cookies.encrypted["#{auth_cookie_prefix}_token"]
30
+ token = cookies.encrypted["veri_token"]
33
31
 
34
- @current_session ||= Session.lookup(token, resolved_tenant)
32
+ @current_session ||= Session.find_active(token, resolved_tenant)
35
33
  end
36
34
 
37
35
  def log_in(authenticatable)
@@ -44,13 +42,15 @@ module Veri
44
42
 
45
43
  token = Veri::Session.establish(processed_authenticatable, request, resolved_tenant)
46
44
 
47
- cookies.encrypted.permanent["#{auth_cookie_prefix}_token"] = { value: token, httponly: true }
45
+ cookies.encrypted.permanent["veri_token"] = { value: token, httponly: true, secure: request.ssl? }
46
+ reset_memoization
48
47
  true
49
48
  end
50
49
 
51
50
  def log_out
52
51
  current_session&.terminate
53
- cookies.delete("#{auth_cookie_prefix}_token")
52
+ cookies.delete("veri_token")
53
+ reset_memoization
54
54
  end
55
55
 
56
56
  def logged_in?
@@ -58,7 +58,7 @@ module Veri
58
58
  end
59
59
 
60
60
  def return_path
61
- cookies.signed["#{auth_cookie_prefix}_return_path"]
61
+ cookies.signed["veri_return_path"]
62
62
  end
63
63
 
64
64
  def shapeshifter?
@@ -68,20 +68,14 @@ module Veri
68
68
  private
69
69
 
70
70
  def with_authentication
71
- if logged_in? && current_session.active?
72
- if current_user.locked?
73
- log_out
74
- when_unauthenticated
75
- else
76
- current_session.update_info(request)
77
- end
78
-
71
+ if logged_in? && !current_user.locked?
72
+ current_session.update_info(request)
79
73
  return
80
74
  end
81
75
 
82
76
  log_out
83
77
 
84
- cookies.signed["#{auth_cookie_prefix}_return_path"] = { value: request.fullpath, expires: 15.minutes.from_now } if request.get? && request.format.html?
78
+ cookies.signed["veri_return_path"] = { value: request.fullpath, expires: 15.minutes.from_now } if request.get? && request.format.html?
85
79
 
86
80
  when_unauthenticated
87
81
  end
@@ -100,8 +94,8 @@ module Veri
100
94
  ).resolve
101
95
  end
102
96
 
103
- def auth_cookie_prefix
104
- @auth_cookie_prefix ||= "auth_#{Zlib.crc32(Marshal.dump(resolved_tenant))}"
97
+ def reset_memoization
98
+ @current_user = @current_session = nil
105
99
  end
106
100
  end
107
101
  end
@@ -23,14 +23,26 @@ module Veri
23
23
  end
24
24
 
25
25
  def verify_password(password)
26
- hasher.verify(
27
- Veri::Inputs::NonEmptyString.new(password, message: "Expected a non-empty string, got `#{password.inspect}`").process,
28
- hashed_password
29
- )
26
+ processed_password = Veri::Inputs::NonEmptyString.new(password, message: "Expected a non-empty string, got `#{password.inspect}`").process
27
+
28
+ return false if hashed_password.blank?
29
+
30
+ stored_hasher = Veri::Configuration::HASHERS.values.find { _1.match?(hashed_password) }
31
+
32
+ raise Veri::Error, "Unrecognized password hash format" unless stored_hasher
33
+
34
+ return false unless stored_hasher.verify(processed_password, hashed_password)
35
+
36
+ update_column(:hashed_password, hasher.create(processed_password)) unless stored_hasher == hasher
37
+
38
+ true
30
39
  end
31
40
 
32
41
  def lock!
33
- update!(locked: true, locked_at: Time.current)
42
+ transaction do
43
+ update!(locked: true, locked_at: Time.current)
44
+ sessions.terminate_all
45
+ end
34
46
  end
35
47
 
36
48
  def unlock!
@@ -5,8 +5,6 @@ module Veri
5
5
  class Session < ActiveRecord::Base
6
6
  self.table_name = "veri_sessions"
7
7
 
8
- belongs_to :authenticatable, class_name: Veri::Configuration.user_model_name
9
- belongs_to :original_authenticatable, class_name: Veri::Configuration.user_model_name, optional: true
10
8
  belongs_to :tenant, polymorphic: true, optional: true
11
9
  belongs_to :original_tenant, polymorphic: true, optional: true
12
10
 
@@ -128,10 +126,12 @@ module Veri
128
126
 
129
127
  alias terminate_all delete_all
130
128
 
131
- def lookup(token, resolved_tenant)
129
+ def find_active(token, resolved_tenant)
132
130
  return nil if token.blank?
133
131
 
134
- find_by(hashed_token: digest_token(token), **resolved_tenant)
132
+ session = find_by(hashed_token: digest_token(token), **resolved_tenant)
133
+
134
+ session&.active? ? session : nil
135
135
  end
136
136
 
137
137
  private
@@ -12,6 +12,10 @@ module Veri
12
12
  def verify(password, hashed_password)
13
13
  ::Argon2::Password.verify_password(password, hashed_password)
14
14
  end
15
+
16
+ def match?(hashed_password)
17
+ hashed_password.start_with?("$argon2")
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -12,6 +12,10 @@ module Veri
12
12
  def verify(password, hashed_password)
13
13
  ::BCrypt::Password.new(hashed_password) == password
14
14
  end
15
+
16
+ def match?(hashed_password)
17
+ hashed_password.start_with?("$2")
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -42,6 +42,10 @@ module Veri
42
42
 
43
43
  OpenSSL.fixed_length_secure_compare(recalculated_hash, hash)
44
44
  end
45
+
46
+ def match?(hashed_password)
47
+ hashed_password.start_with?("#{DIGEST}$")
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -12,6 +12,10 @@ module Veri
12
12
  def verify(password, hashed_password)
13
13
  ::SCrypt::Password.new(hashed_password) == password
14
14
  end
15
+
16
+ def match?(hashed_password)
17
+ hashed_password.match?(/\A\h+\$\h+\$\h+\$/)
18
+ end
15
19
  end
16
20
  end
17
21
  end
data/lib/veri/railtie.rb CHANGED
@@ -22,8 +22,16 @@ module Veri
22
22
  end
23
23
  end
24
24
 
25
- user_model = Veri::Configuration.user_model
26
- user_model.include Veri::Authenticatable unless user_model < Veri::Authenticatable
25
+ begin
26
+ user_model = Veri::Configuration.user_model
27
+ user_model.include Veri::Authenticatable unless user_model < Veri::Authenticatable
28
+ rescue Veri::ConfigurationError
29
+ raise if Veri::Railtie.server_running?
30
+ end
31
+
32
+ Veri::Session.belongs_to :authenticatable, class_name: Veri::Configuration.user_model_name
33
+ Veri::Session.belongs_to :original_authenticatable, class_name: Veri::Configuration.user_model_name,
34
+ optional: true
27
35
  end
28
36
  end
29
37
 
data/lib/veri/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Veri
2
- VERSION = "2.0.2".freeze
2
+ VERSION = "2.0.3".freeze
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: veri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - enjaku4
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-03-28 00:00:00.000000000 Z
10
+ date: 2026-07-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: argon2