veri 0.4.0 → 1.0.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.md +14 -0
- data/README.md +33 -14
- data/lib/veri/configuration.rb +1 -0
- data/lib/veri/inputs/hashing_algorithm.rb +1 -1
- data/lib/veri/models/session.rb +4 -12
- data/lib/veri/password/pbkdf2.rb +47 -0
- data/lib/veri/railtie.rb +7 -1
- data/lib/veri/version.rb +1 -1
- data/lib/veri.rb +1 -0
- data/veri.gemspec +2 -2
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4434399cb0f0e3081ff2ccb8e72df12623e74f6f2cd43f318d50ae483845be6
|
4
|
+
data.tar.gz: 194dec0866793d8f2bc906d2830f8c9a4fb37e7d8a5c7f5c58bec7d0631abc51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e5dbe8a582d077ef157f8c16d3ec5c21ac24b501e323ed4bf11f577fe436900dffdc1a40814011c78f969962c97ca0b931cd5684253578ecb4804b994016dca
|
7
|
+
data.tar.gz: ba78fb8d71fd4dffdb527add9759f56d84ca9772535897d356f4a4a9f1302f149d3533355e8a86a518b09f179c638313dcdf2b9932c82fd7e8a427457a1b3111
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## v1.0.0
|
2
|
+
|
3
|
+
### Breaking
|
4
|
+
|
5
|
+
- Dropped support for Rails 7.1
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
- Added support for pbkdf2 password hashing algorithm
|
10
|
+
|
11
|
+
### Bugs
|
12
|
+
|
13
|
+
- Fixed error raised on Rails console commands when the database was not yet set up
|
14
|
+
|
1
15
|
## v0.4.0
|
2
16
|
|
3
17
|
### Breaking
|
data/README.md
CHANGED
@@ -1,23 +1,20 @@
|
|
1
1
|
# Veri: Minimal Authentication Framework for Rails
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/veri)
|
4
|
-
[](https://github.com/enjaku4/veri/actions/workflows/ci.yml)
|
5
5
|
|
6
6
|
Veri is a cookie-based authentication library for Ruby on Rails that provides essential authentication building blocks without imposing business logic. Unlike full-featured solutions, Veri gives you complete control over your authentication flow while handling the complex underlying mechanics of secure password storage and session management.
|
7
7
|
|
8
8
|
**Key Features:**
|
9
9
|
|
10
10
|
- Cookie-based authentication with database-stored sessions
|
11
|
-
- Multiple password hashing algorithms (argon2, bcrypt, scrypt)
|
11
|
+
- Multiple password hashing algorithms (argon2, bcrypt, pbkdf2, scrypt)
|
12
12
|
- Granular session management and control
|
13
13
|
- Return path handling
|
14
14
|
- User impersonation feature
|
15
15
|
- Account lockout functionality
|
16
16
|
- Multi-tenancy support
|
17
17
|
|
18
|
-
> ⚠️ **Development Notice**<br>
|
19
|
-
> Veri is functional but in early development. Breaking changes may occur in minor releases until v1.0!
|
20
|
-
|
21
18
|
## Table of Contents
|
22
19
|
|
23
20
|
**Gem Usage:**
|
@@ -73,7 +70,7 @@ If customization is required, configure Veri in an initializer:
|
|
73
70
|
```rb
|
74
71
|
# These are the default values; you can change them as needed
|
75
72
|
Veri.configure do |config|
|
76
|
-
config.hashing_algorithm = :argon2 # Password hashing algorithm (:argon2, :bcrypt, or :scrypt)
|
73
|
+
config.hashing_algorithm = :argon2 # Password hashing algorithm (:argon2, :bcrypt, :pbkdf2, or :scrypt)
|
77
74
|
config.inactive_session_lifetime = nil # Session inactivity timeout (nil means sessions never expire due to inactivity)
|
78
75
|
config.total_session_lifetime = 14.days # Maximum session duration regardless of activity
|
79
76
|
config.user_model_name = "User" # Your user model name
|
@@ -115,6 +112,22 @@ end
|
|
115
112
|
This is a simplified example of how to use Veri's authentication methods:
|
116
113
|
|
117
114
|
```rb
|
115
|
+
class RegistrationsController < ApplicationController
|
116
|
+
skip_authentication
|
117
|
+
|
118
|
+
def create
|
119
|
+
user = User.new(user_params)
|
120
|
+
|
121
|
+
if user.valid?
|
122
|
+
user.update_password(user_params[:password])
|
123
|
+
log_in(user)
|
124
|
+
redirect_to dashboard_path
|
125
|
+
else
|
126
|
+
render :new, status: :unprocessable_content
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
118
131
|
class SessionsController < ApplicationController
|
119
132
|
skip_authentication except: [:destroy]
|
120
133
|
|
@@ -126,7 +139,7 @@ class SessionsController < ApplicationController
|
|
126
139
|
redirect_to return_path || dashboard_path
|
127
140
|
else
|
128
141
|
flash.now[:alert] = "Invalid credentials"
|
129
|
-
render :new, status: :
|
142
|
+
render :new, status: :unprocessable_content
|
130
143
|
end
|
131
144
|
end
|
132
145
|
|
@@ -288,8 +301,14 @@ session.terminate
|
|
288
301
|
# Terminate all sessions
|
289
302
|
Veri::Session.terminate_all
|
290
303
|
|
291
|
-
#
|
304
|
+
# Terminate all sessions for a specific user
|
305
|
+
user.sessions.terminate_all
|
306
|
+
|
307
|
+
# Clean up expired/inactive sessions, and sessions with deleted tenant
|
292
308
|
Veri::Session.prune
|
309
|
+
|
310
|
+
# Clean up expired/inactive sessions for a specific user
|
311
|
+
user.sessions.prune
|
293
312
|
```
|
294
313
|
|
295
314
|
## Account Lockout
|
@@ -426,13 +445,13 @@ end
|
|
426
445
|
## Getting Help and Contributing
|
427
446
|
|
428
447
|
### Getting Help
|
429
|
-
Have a question or need assistance? Open a discussion in our [discussions section](https://github.com/
|
448
|
+
Have a question or need assistance? Open a discussion in our [discussions section](https://github.com/enjaku4/veri/discussions) for:
|
430
449
|
- Usage questions
|
431
450
|
- Implementation guidance
|
432
451
|
- Feature suggestions
|
433
452
|
|
434
453
|
### Reporting Issues
|
435
|
-
Found a bug? Please [create an issue](https://github.com/
|
454
|
+
Found a bug? Please [create an issue](https://github.com/enjaku4/veri/issues) with:
|
436
455
|
- A clear description of the problem
|
437
456
|
- Steps to reproduce the issue
|
438
457
|
- Your environment details (Rails version, Ruby version, etc.)
|
@@ -441,14 +460,14 @@ Found a bug? Please [create an issue](https://github.com/brownboxdev/veri/issues
|
|
441
460
|
Ready to contribute? You can:
|
442
461
|
- Fix bugs by submitting pull requests
|
443
462
|
- Improve documentation
|
444
|
-
- Add new features (please discuss first in our [discussions section](https://github.com/
|
463
|
+
- Add new features (please discuss first in our [discussions section](https://github.com/enjaku4/veri/discussions))
|
445
464
|
|
446
|
-
Before contributing, please read the [contributing guidelines](https://github.com/
|
465
|
+
Before contributing, please read the [contributing guidelines](https://github.com/enjaku4/veri/blob/main/CONTRIBUTING.md)
|
447
466
|
|
448
467
|
## License
|
449
468
|
|
450
|
-
The gem is available as open source under the terms of the [MIT License](https://github.com/
|
469
|
+
The gem is available as open source under the terms of the [MIT License](https://github.com/enjaku4/veri/blob/main/LICENSE.txt).
|
451
470
|
|
452
471
|
## Code of Conduct
|
453
472
|
|
454
|
-
Everyone interacting in the Veri project is expected to follow the [code of conduct](https://github.com/
|
473
|
+
Everyone interacting in the Veri project is expected to follow the [code of conduct](https://github.com/enjaku4/veri/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/veri/configuration.rb
CHANGED
data/lib/veri/models/session.rb
CHANGED
@@ -100,23 +100,15 @@ module Veri
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def prune
|
103
|
-
|
103
|
+
expired.or(inactive).delete_all
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
expired_scope = expired_scope.or(where(last_seen_at: ...inactive_cutoff))
|
108
|
-
end
|
109
|
-
|
110
|
-
expired_scope.delete_all
|
111
|
-
|
112
|
-
ids = where.not(tenant_id: nil).includes(:tenant).filter_map do |session|
|
113
|
-
session.tenant
|
114
|
-
nil
|
105
|
+
orphaned_tenant_sessions = where.not(tenant_id: nil).includes(:tenant).filter_map do |session|
|
106
|
+
!session.tenant
|
115
107
|
rescue ActiveRecord::RecordNotFound
|
116
108
|
session.id
|
117
109
|
end
|
118
110
|
|
119
|
-
where(id:
|
111
|
+
where(id: orphaned_tenant_sessions).delete_all if orphaned_tenant_sessions.any?
|
120
112
|
end
|
121
113
|
|
122
114
|
alias terminate_all delete_all
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "openssl"
|
2
|
+
require "base64"
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
module Veri
|
6
|
+
module Password
|
7
|
+
module Pbkdf2
|
8
|
+
module_function
|
9
|
+
|
10
|
+
ITERATIONS = 210_000
|
11
|
+
SALT_BYTES = 64
|
12
|
+
HASH_BYTES = 64
|
13
|
+
DIGEST = "sha512"
|
14
|
+
|
15
|
+
def create(password)
|
16
|
+
salt = SecureRandom.random_bytes(SALT_BYTES)
|
17
|
+
hash = OpenSSL::KDF.pbkdf2_hmac(
|
18
|
+
password,
|
19
|
+
salt:,
|
20
|
+
iterations: ITERATIONS,
|
21
|
+
length: HASH_BYTES,
|
22
|
+
hash: DIGEST
|
23
|
+
)
|
24
|
+
|
25
|
+
"#{DIGEST}$#{ITERATIONS}$#{HASH_BYTES}$#{Base64.strict_encode64(salt)}$#{Base64.strict_encode64(hash)}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def verify(password, hashed_password)
|
29
|
+
parts = hashed_password.split("$")
|
30
|
+
digest, iterations, hash_bytes, encoded_salt, encoded_hash = parts[0], parts[1], parts[2], parts[3], parts[4]
|
31
|
+
|
32
|
+
salt = Base64.strict_decode64(encoded_salt)
|
33
|
+
hash = Base64.strict_decode64(encoded_hash)
|
34
|
+
|
35
|
+
recalculated_hash = OpenSSL::KDF.pbkdf2_hmac(
|
36
|
+
password,
|
37
|
+
salt:,
|
38
|
+
iterations: iterations.to_i,
|
39
|
+
length: hash_bytes.to_i,
|
40
|
+
hash: digest
|
41
|
+
)
|
42
|
+
|
43
|
+
OpenSSL.fixed_length_secure_compare(recalculated_hash, hash)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/veri/railtie.rb
CHANGED
@@ -2,9 +2,15 @@ require "rails/railtie"
|
|
2
2
|
|
3
3
|
module Veri
|
4
4
|
class Railtie < Rails::Railtie
|
5
|
+
def self.table_exists?
|
6
|
+
ActiveRecord::Base.connection.data_source_exists?("veri_sessions")
|
7
|
+
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
5
11
|
initializer "veri.to_prepare" do |app|
|
6
12
|
app.config.to_prepare do
|
7
|
-
if
|
13
|
+
if Veri::Railtie.table_exists?
|
8
14
|
Veri::Session.where.not(tenant_id: nil).distinct.pluck(:tenant_type).each do |tenant_class|
|
9
15
|
tenant_class.constantize
|
10
16
|
rescue NameError => e
|
data/lib/veri/version.rb
CHANGED
data/lib/veri.rb
CHANGED
data/veri.gemspec
CHANGED
@@ -4,7 +4,7 @@ Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = "veri"
|
5
5
|
spec.version = Veri::VERSION
|
6
6
|
spec.authors = ["enjaku4"]
|
7
|
-
spec.homepage = "https://github.com/
|
7
|
+
spec.homepage = "https://github.com/enjaku4/veri"
|
8
8
|
spec.metadata["homepage_uri"] = spec.homepage
|
9
9
|
spec.metadata["source_code_uri"] = spec.homepage
|
10
10
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "bcrypt", "~> 3.0"
|
24
24
|
spec.add_dependency "dry-configurable", "~> 1.1"
|
25
25
|
spec.add_dependency "dry-types", "~> 1.7"
|
26
|
-
spec.add_dependency "rails", ">= 7.
|
26
|
+
spec.add_dependency "rails", ">= 7.2", "< 8.1"
|
27
27
|
spec.add_dependency "scrypt", "~> 3.0"
|
28
28
|
spec.add_dependency "user_agent_parser", "~> 2.0"
|
29
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: veri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- enjaku4
|
@@ -71,7 +71,7 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '7.
|
74
|
+
version: '7.2'
|
75
75
|
- - "<"
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '8.1'
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
requirements:
|
82
82
|
- - ">="
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: '7.
|
84
|
+
version: '7.2'
|
85
85
|
- - "<"
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '8.1'
|
@@ -137,17 +137,18 @@ files:
|
|
137
137
|
- lib/veri/models/session.rb
|
138
138
|
- lib/veri/password/argon2.rb
|
139
139
|
- lib/veri/password/bcrypt.rb
|
140
|
+
- lib/veri/password/pbkdf2.rb
|
140
141
|
- lib/veri/password/scrypt.rb
|
141
142
|
- lib/veri/railtie.rb
|
142
143
|
- lib/veri/version.rb
|
143
144
|
- veri.gemspec
|
144
|
-
homepage: https://github.com/
|
145
|
+
homepage: https://github.com/enjaku4/veri
|
145
146
|
licenses:
|
146
147
|
- MIT
|
147
148
|
metadata:
|
148
|
-
homepage_uri: https://github.com/
|
149
|
-
source_code_uri: https://github.com/
|
150
|
-
changelog_uri: https://github.com/
|
149
|
+
homepage_uri: https://github.com/enjaku4/veri
|
150
|
+
source_code_uri: https://github.com/enjaku4/veri
|
151
|
+
changelog_uri: https://github.com/enjaku4/veri/blob/main/CHANGELOG.md
|
151
152
|
rubygems_mfa_required: 'true'
|
152
153
|
rdoc_options: []
|
153
154
|
require_paths:
|
@@ -166,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
167
|
- !ruby/object:Gem::Version
|
167
168
|
version: '0'
|
168
169
|
requirements: []
|
169
|
-
rubygems_version: 3.
|
170
|
+
rubygems_version: 3.7.1
|
170
171
|
specification_version: 4
|
171
172
|
summary: Minimal cookie-based authentication library for Ruby on Rails
|
172
173
|
test_files: []
|