veri 2.0.1 → 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 +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +42 -18
- data/lib/veri/configuration.rb +1 -1
- data/lib/veri/controllers/concerns/authentication.rb +12 -18
- data/lib/veri/models/concerns/authenticatable.rb +17 -5
- data/lib/veri/models/session.rb +4 -4
- data/lib/veri/password/argon2.rb +4 -0
- data/lib/veri/password/bcrypt.rb +4 -0
- data/lib/veri/password/pbkdf2.rb +4 -0
- data/lib/veri/password/scrypt.rb +4 -0
- data/lib/veri/railtie.rb +10 -2
- data/lib/veri/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90c72152f71aea2555de8f7788b356e8b957d94df73a0bfc826ee79b1087fed7
|
|
4
|
+
data.tar.gz: f552a61efc8b704a9065bca3d785dcb8cd4046299ee94e05dc0cb08b381511e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1947901336055c81c82f36c18c6abdeadc76d6d1ce47564de69bd83cb98a75d14e433276df5be08c24506277571121d81eaf6c3c0805c5d1041f8d9272821d31
|
|
7
|
+
data.tar.gz: eb186110a8816965a3ae0c7f396fdd8b0fd212ce281602139268e55cf466e3ad7589e0838383840e629c2b6259ab027c1beb343b5f4338b778717a3b5670eaae
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
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
|
+
|
|
16
|
+
## v2.0.2
|
|
17
|
+
|
|
18
|
+
### Misc
|
|
19
|
+
|
|
20
|
+
- Clarified error message for non-existent user model
|
|
21
|
+
|
|
1
22
|
## v2.0.1
|
|
2
23
|
|
|
3
24
|
### Misc
|
data/README.md
CHANGED
|
@@ -70,13 +70,19 @@ Configure Veri in an initializer if customization is needed:
|
|
|
70
70
|
```rb
|
|
71
71
|
# These are the default values; you can change them as needed
|
|
72
72
|
Veri.configure do |config|
|
|
73
|
-
|
|
74
|
-
config.
|
|
75
|
-
|
|
76
|
-
config.
|
|
73
|
+
# Password hashing algorithm (:argon2, :bcrypt, :pbkdf2, or :scrypt)
|
|
74
|
+
config.hashing_algorithm = :argon2
|
|
75
|
+
# Session inactivity timeout (nil means sessions never expire due to inactivity)
|
|
76
|
+
config.inactive_session_lifetime = nil
|
|
77
|
+
# Maximum session duration regardless of activity
|
|
78
|
+
config.total_session_lifetime = 14.days
|
|
79
|
+
# Your user model name
|
|
80
|
+
config.user_model_name = "User"
|
|
77
81
|
end
|
|
78
82
|
```
|
|
79
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
|
+
|
|
80
86
|
## Password Management
|
|
81
87
|
|
|
82
88
|
Your user model is automatically extended with password management methods:
|
|
@@ -88,6 +94,12 @@ user.update_password("password")
|
|
|
88
94
|
# Verify a password
|
|
89
95
|
user.verify_password("password")
|
|
90
96
|
```
|
|
97
|
+
Changing a password does not automatically terminate existing sessions. If you want to invalidate the user's sessions after a password change, do so explicitly:
|
|
98
|
+
|
|
99
|
+
```rb
|
|
100
|
+
user.update_password(new_password)
|
|
101
|
+
user.sessions.terminate_all
|
|
102
|
+
```
|
|
91
103
|
|
|
92
104
|
## Controller Integration
|
|
93
105
|
|
|
@@ -99,11 +111,13 @@ Include the authentication module in your controllers and configure protection:
|
|
|
99
111
|
class ApplicationController < ActionController::Base
|
|
100
112
|
include Veri::Authentication
|
|
101
113
|
|
|
102
|
-
|
|
114
|
+
# Require authentication by default
|
|
115
|
+
with_authentication
|
|
103
116
|
end
|
|
104
117
|
|
|
105
118
|
class PicturesController < ApplicationController
|
|
106
|
-
|
|
119
|
+
# Allow public access to index and show actions
|
|
120
|
+
skip_authentication only: [:index, :show]
|
|
107
121
|
end
|
|
108
122
|
```
|
|
109
123
|
|
|
@@ -161,7 +175,7 @@ current_user
|
|
|
161
175
|
# Returns true if user is authenticated
|
|
162
176
|
logged_in?
|
|
163
177
|
|
|
164
|
-
# Authenticates user
|
|
178
|
+
# Authenticates user, returns true on success or false if account is locked
|
|
165
179
|
log_in(user)
|
|
166
180
|
|
|
167
181
|
# Terminates current session
|
|
@@ -396,6 +410,8 @@ session.shapeshift(user, tenant: company)
|
|
|
396
410
|
session.true_tenant
|
|
397
411
|
```
|
|
398
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
|
+
|
|
399
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.
|
|
400
416
|
|
|
401
417
|
### Orphaned Sessions
|
|
@@ -408,6 +424,12 @@ To clean up orphaned sessions, use:
|
|
|
408
424
|
Veri::Session.prune
|
|
409
425
|
```
|
|
410
426
|
|
|
427
|
+
Or, for a specific user:
|
|
428
|
+
|
|
429
|
+
```rb
|
|
430
|
+
user.sessions.prune
|
|
431
|
+
```
|
|
432
|
+
|
|
411
433
|
### Tenant Migrations
|
|
412
434
|
|
|
413
435
|
When you rename or remove models used as tenants, you need to update Veri's stored data accordingly. Use these irreversible data migrations:
|
|
@@ -484,24 +506,26 @@ end
|
|
|
484
506
|
## Getting Help and Contributing
|
|
485
507
|
|
|
486
508
|
### Getting Help
|
|
487
|
-
|
|
509
|
+
|
|
510
|
+
Have a question or need assistance? Open a discussion in the [discussions section](https://github.com/enjaku4/veri/discussions) for:
|
|
511
|
+
|
|
488
512
|
- Usage questions
|
|
489
513
|
- Implementation guidance
|
|
490
|
-
-
|
|
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:
|
|
491
519
|
|
|
492
|
-
### Reporting Issues
|
|
493
|
-
Found a bug? Please [create an issue](https://github.com/enjaku4/veri/issues) with:
|
|
494
520
|
- A clear description of the problem
|
|
495
521
|
- Steps to reproduce the issue
|
|
496
|
-
- Your environment details (Rails
|
|
522
|
+
- Your environment details (Rails and Ruby versions, OS, etc.)
|
|
497
523
|
|
|
498
524
|
### Contributing Code
|
|
499
|
-
Ready to contribute? You can:
|
|
500
|
-
- Fix bugs by submitting pull requests
|
|
501
|
-
- Improve documentation
|
|
502
|
-
- Add new features (please discuss first in our [discussions section](https://github.com/enjaku4/veri/discussions))
|
|
503
525
|
|
|
504
|
-
|
|
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).
|
|
505
529
|
|
|
506
530
|
## License
|
|
507
531
|
|
|
@@ -513,6 +537,6 @@ Everyone interacting in the Veri project is expected to follow the [code of cond
|
|
|
513
537
|
|
|
514
538
|
## Old Versions
|
|
515
539
|
|
|
516
|
-
Only the latest major version is
|
|
540
|
+
Only the latest major version is actively maintained. READMEs for older versions are available here for reference:
|
|
517
541
|
|
|
518
542
|
[v1.x.x](https://github.com/enjaku4/veri/blob/9c188e16a703141b7cd89dd31d5cd49a557f143d/README.md)
|
data/lib/veri/configuration.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Veri
|
|
|
66
66
|
Veri::Inputs::Model.new(
|
|
67
67
|
user_model_name,
|
|
68
68
|
error: Veri::ConfigurationError,
|
|
69
|
-
message: "Invalid user model name `#{user_model_name}`,
|
|
69
|
+
message: "Invalid user model name `#{user_model_name}`, model does not exist"
|
|
70
70
|
).process
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -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["
|
|
30
|
+
token = cookies.encrypted["veri_token"]
|
|
33
31
|
|
|
34
|
-
@current_session ||= Session.
|
|
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["
|
|
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("
|
|
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["
|
|
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? &&
|
|
72
|
-
|
|
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["
|
|
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
|
|
104
|
-
@
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
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!
|
data/lib/veri/models/session.rb
CHANGED
|
@@ -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
|
|
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
|
data/lib/veri/password/argon2.rb
CHANGED
data/lib/veri/password/bcrypt.rb
CHANGED
data/lib/veri/password/pbkdf2.rb
CHANGED
data/lib/veri/password/scrypt.rb
CHANGED
data/lib/veri/railtie.rb
CHANGED
|
@@ -22,8 +22,16 @@ module Veri
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
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
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.
|
|
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-
|
|
10
|
+
date: 2026-07-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: argon2
|
|
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
147
147
|
- !ruby/object:Gem::Version
|
|
148
148
|
version: '0'
|
|
149
149
|
requirements: []
|
|
150
|
-
rubygems_version:
|
|
150
|
+
rubygems_version: 4.0.3
|
|
151
151
|
specification_version: 4
|
|
152
152
|
summary: Minimal cookie-based authentication library for Ruby on Rails
|
|
153
153
|
test_files: []
|