veri 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ac32f0c6d36a07d566aec8905648f0e27811876d52929ab1753f3109af5648b7
4
+ data.tar.gz: eaaec22fa0215df1896cf3baadf7b8ce5e7ff4ebcb61094443a020e54c63023c
5
+ SHA512:
6
+ metadata.gz: d75c20d2484660914c53ead2394f376bc915c45833bfe8b643b7e4964dc104c94d64747ce8be312bae24930e27216296060f1971a8356c9ec4c347372106c080
7
+ data.tar.gz: 4166c688264ac0cfa34866487a2ac572deb70972656c59fd724608841ea50d8b5436e64d70c7a45990302e4a8111cf0e47b103aff78075f0d792d05953c5a2b7
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.1.0
2
+
3
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 enjaku4 (https://github.com/enjaku4)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,315 @@
1
+ # Veri: Minimal Authentication Framework for Rails
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/veri.svg)](http://badge.fury.io/rb/veri)
4
+ [![Github Actions badge](https://github.com/brownboxdev/veri/actions/workflows/ci.yml/badge.svg)](https://github.com/brownboxdev/veri/actions/workflows/ci.yml)
5
+
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
+
8
+ **Key Features:**
9
+
10
+ - Cookie-based authentication with database-stored sessions
11
+ - Supports multiple password hashing algorithms (argon2, bcrypt, scrypt)
12
+ - Granular session management and control
13
+ - Flexible authentication callbacks
14
+ - No pre-defined business logic, no views, controllers, or mailers — just the essential methods
15
+ - Built-in return path handling
16
+
17
+ > ⚠️ **Development Notice**<br>
18
+ > Veri is functional but in early development. Breaking changes may occur in minor releases until v1.0!
19
+
20
+ ## Table of Contents
21
+
22
+ **Gem Usage:**
23
+ - [Installation](#installation)
24
+ - [Configuration](#configuration)
25
+ - [Password Management](#password-management)
26
+ - [Controller Integration](#controller-integration)
27
+ - [Authentication Sessions](#authentication-sessions)
28
+ - [View Helpers](#view-helpers)
29
+ - [Testing](#testing)
30
+
31
+ **Community Resources:**
32
+ - [Contributing](#contributing)
33
+ - [License](#license)
34
+ - [Code of Conduct](#code-of-conduct)
35
+
36
+ ## Installation
37
+
38
+ Add Veri to your Gemfile:
39
+
40
+ ```rb
41
+ gem "veri"
42
+ ```
43
+
44
+ Install the gem:
45
+
46
+ ```bash
47
+ bundle install
48
+ ```
49
+
50
+ Generate the migration for your user model (replace `users` with your user table name if different):
51
+
52
+ ```shell
53
+ # For standard integer IDs
54
+ rails generate veri:authentication users
55
+
56
+ # For UUID primary keys
57
+ rails generate veri:authentication users --uuid
58
+ ```
59
+
60
+ Run the migration:
61
+
62
+ ```shell
63
+ rails db:migrate
64
+ ```
65
+
66
+ ## Configuration
67
+
68
+ If customization is required, configure Veri in an initializer:
69
+
70
+ ```rb
71
+ # These are the default values; you can change them as needed
72
+ Veri.configure do |config|
73
+ config.hashing_algorithm = :argon2 # Password hashing algorithm (:argon2, :bcrypt, or :scrypt)
74
+ config.inactive_session_lifetime = nil # Session inactivity timeout (nil means sessions never expire due to inactivity)
75
+ config.total_session_lifetime = 14.days # Maximum session duration regardless of activity
76
+ config.user_model_name = "User" # Your user model name
77
+ end
78
+ ```
79
+
80
+ ## Password Management
81
+
82
+ Your user model is automatically extended with password management methods:
83
+
84
+ ```rb
85
+ # Set or update a password
86
+ user.update_password("new_password")
87
+
88
+ # Verify a password
89
+ user.verify_password("submitted_password")
90
+ ```
91
+
92
+ ## Controller Integration
93
+
94
+ ### Basic Setup
95
+
96
+ Include the authentication module and configure protection:
97
+
98
+ ```rb
99
+ class ApplicationController < ActionController::Base
100
+ include Veri::Authentication
101
+
102
+ with_authentication # Require authentication by default
103
+ end
104
+
105
+ class PicturesController < ApplicationController
106
+ skip_authentication only: [:index, :show] # Allow public access to index and show actions
107
+ end
108
+ ```
109
+
110
+ ### Authentication Methods
111
+
112
+ This is a simplified example of how to use Veri's authentication methods in your controllers:
113
+
114
+ ```rb
115
+ class SessionsController < ApplicationController
116
+ skip_authentication except: [:destroy]
117
+
118
+ def create
119
+ user = User.find_by(email: params[:email])
120
+
121
+ if user&.verify_password(params[:password])
122
+ log_in(user)
123
+ redirect_to return_path || dashboard_path
124
+ else
125
+ flash.now[:alert] = "Invalid credentials"
126
+ render :new, status: :unprocessable_entity
127
+ end
128
+ end
129
+
130
+ def destroy
131
+ log_out
132
+ redirect_to root_path
133
+ end
134
+ end
135
+ ```
136
+
137
+ Available methods:
138
+
139
+ - `current_user` - returns the authenticated user or `nil`
140
+ - `logged_in?` - returns `true` if user is authenticated
141
+ - `log_in(user)` - authenticates the user and creates a session
142
+ - `log_out` - terminates the current session
143
+ - `return_path` - returns the path the user was trying to access before authentication
144
+ - `current_session` - returns the current authentication session
145
+
146
+ ### Authentication Callbacks
147
+
148
+ Override these private methods to customize authentication behavior:
149
+
150
+ ```rb
151
+ class ApplicationController < ActionController::Base
152
+ include Veri::Authentication
153
+
154
+ with_authentication
155
+
156
+ # ...
157
+
158
+ private
159
+
160
+ # Called after successful login
161
+ def after_login(user)
162
+ Rails.logger.info "User #{user.id} logged in"
163
+ # Custom redirect logic, analytics, etc.
164
+ end
165
+
166
+ # Called after logout
167
+ def after_logout
168
+ Rails.logger.info "User logged out"
169
+ # Cleanup, analytics, etc.
170
+ end
171
+
172
+ # Customize unauthenticated user handling
173
+ def when_unauthenticated
174
+ # By default redirects back with a fallback to the root path if the request format is HTML,
175
+ # otherwise responds with 401 Unauthorized
176
+ redirect_to login_path
177
+ end
178
+ end
179
+ ```
180
+
181
+ ## Authentication Sessions
182
+
183
+ Veri stores authentication sessions in the database, enabling powerful session management:
184
+
185
+ ### Session Access
186
+
187
+ ```rb
188
+ # Get all sessions for a user
189
+ user.veri_sessions
190
+
191
+ # Get current session in controller
192
+ current_session
193
+ ```
194
+
195
+ ### Session Information
196
+
197
+ ```rb
198
+ session.info
199
+ # => {
200
+ # device: "Desktop",
201
+ # os: "macOS",
202
+ # browser: "Chrome",
203
+ # ip_address: "1.2.3.4",
204
+ # last_activity: "2023-10-01 12:00:00"
205
+ # }
206
+ ```
207
+
208
+ ### Session Status
209
+
210
+ ```rb
211
+ session.active? # Session is active (neither expired nor inactive)
212
+ session.inactive? # Session exceeded inactivity timeout
213
+ session.expired? # Session exceeded maximum lifetime
214
+ ```
215
+
216
+ ### Session Management
217
+
218
+ ```rb
219
+ # Terminate a specific session
220
+ session.terminate
221
+
222
+ # Terminate all sessions for a user
223
+ Veri::Session.terminate_all(user)
224
+
225
+ # Clean up expired/inactive sessions
226
+ Veri::Session.prune # All sessions
227
+ Veri::Session.prune(user) # Specific user's sessions
228
+ ```
229
+
230
+ ## View Helpers
231
+
232
+ Access authentication state in your views:
233
+
234
+ ```erb
235
+ <% if logged_in? %>
236
+ <p>Welcome, <%= current_user.name %>!</p>
237
+ <%= link_to "Logout", logout_path, method: :delete %>
238
+ <% else %>
239
+ <%= link_to "Login", login_path %>
240
+ <% end %>
241
+ ```
242
+
243
+ ## Testing
244
+
245
+ Veri doesn't provide test helpers, but you can easily create your own:
246
+
247
+ ### Request Specs (Recommended)
248
+
249
+ ```rb
250
+ module AuthenticationHelpers
251
+ def log_in(user)
252
+ password = "test_password"
253
+ user.update_password(password)
254
+ post login_path, params: { email: user.email, password: }
255
+ end
256
+
257
+ def log_out
258
+ delete logout_path
259
+ end
260
+ end
261
+
262
+ # In your spec_helper.rb
263
+ RSpec.configure do |config|
264
+ config.include AuthenticationHelpers, type: :request
265
+ end
266
+ ```
267
+
268
+ ### Controller Specs (Legacy)
269
+
270
+ ```rb
271
+ module AuthenticationHelpers
272
+ def log_in(user)
273
+ controller.log_in(user)
274
+ end
275
+
276
+ def log_out
277
+ controller.log_out
278
+ end
279
+ end
280
+
281
+ # In your spec_helper.rb
282
+ RSpec.configure do |config|
283
+ config.include AuthenticationHelpers, type: :controller
284
+ end
285
+ ```
286
+
287
+ ## Contributing
288
+
289
+ ### Getting Help
290
+ Have a question or need assistance? Open a discussion in our [discussions section](https://github.com/brownboxdev/veri/discussions) for:
291
+ - Usage questions
292
+ - Implementation guidance
293
+ - Feature suggestions
294
+
295
+ ### Reporting Issues
296
+ Found a bug? Please [create an issue](https://github.com/brownboxdev/veri/issues) with:
297
+ - A clear description of the problem
298
+ - Steps to reproduce the issue
299
+ - Your environment details (Rails version, Ruby version, etc.)
300
+
301
+ ### Contributing Code
302
+ Ready to contribute? You can:
303
+ - Fix bugs by submitting pull requests
304
+ - Improve documentation
305
+ - Add new features (please discuss first in our [discussions section](https://github.com/brownboxdev/veri/discussions))
306
+
307
+ Before contributing, please read the [contributing guidelines](https://github.com/brownboxdev/veri/blob/master/CONTRIBUTING.md)
308
+
309
+ ## License
310
+
311
+ The gem is available as open source under the terms of the [MIT License](https://github.com/brownboxdev/veri/blob/main/LICENSE.txt).
312
+
313
+ ## Code of Conduct
314
+
315
+ Everyone interacting in the Veri project is expected to follow the [code of conduct](https://github.com/brownboxdev/veri/blob/main/CODE_OF_CONDUCT.md).
@@ -0,0 +1,21 @@
1
+ require "rails/generators/migration"
2
+
3
+ module Veri
4
+ class AuthenticationGenerator < Rails::Generators::Base
5
+ include Rails::Generators::Migration
6
+
7
+ source_root File.expand_path("templates", __dir__)
8
+
9
+ argument :table_name, type: :string, required: true
10
+
11
+ class_option :uuid, type: :boolean, default: false, desc: "Use UUIDs as primary keys"
12
+
13
+ def create_migrations
14
+ migration_template "add_veri_authentication.rb.erb", "db/migrate/add_veri_authentication.rb"
15
+ end
16
+
17
+ def self.next_migration_number(_path)
18
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ class AddVeriAuthentication < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version.to_s %>]
2
+ def change
3
+ add_column <%= table_name.to_sym.inspect %>, :hashed_password, :text
4
+
5
+ create_table :veri_sessions<%= ", id: :uuid" if options[:uuid] %> do |t|
6
+ t.string :hashed_token, null: false, index: { unique: true }
7
+ t.datetime :expires_at, null: false
8
+ t.belongs_to :authenticatable, null: false, foreign_key: { to_table: <%= table_name.to_sym.inspect %> }, index: true<%= ", type: :uuid" if options[:uuid] %>
9
+ t.datetime :last_seen_at, null: false
10
+ t.string :ip_address
11
+ t.string :user_agent
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ require "active_support/core_ext/numeric/time"
2
+ require "dry-configurable"
3
+
4
+ module Veri
5
+ module Configuration
6
+ extend Dry::Configurable
7
+
8
+ module_function
9
+
10
+ setting :hashing_algorithm,
11
+ default: :argon2,
12
+ reader: true,
13
+ constructor: -> (value) { Veri::Inputs.process(value, as: :hashing_algorithm, error: Veri::ConfigurationError) }
14
+ setting :inactive_session_lifetime,
15
+ default: nil,
16
+ reader: true,
17
+ constructor: -> (value) { Veri::Inputs.process(value, as: :duration, optional: true, error: Veri::ConfigurationError) }
18
+ setting :total_session_lifetime,
19
+ default: 14.days,
20
+ reader: true,
21
+ constructor: -> (value) { Veri::Inputs.process(value, as: :duration, error: Veri::ConfigurationError) }
22
+ setting :user_model_name,
23
+ default: "User",
24
+ reader: true,
25
+ constructor: -> (value) { Veri::Inputs.process(value, as: :string, error: Veri::ConfigurationError) }
26
+
27
+ def hasher
28
+ case hashing_algorithm
29
+ when :argon2 then Veri::Password::Argon2
30
+ when :bcrypt then Veri::Password::BCrypt
31
+ when :scrypt then Veri::Password::SCrypt
32
+ else raise Veri::Error, "Invalid hashing algorithm: #{hashing_algorithm}"
33
+ end
34
+ end
35
+
36
+ def user_model
37
+ Veri::Inputs.process(user_model_name, as: :model, error: Veri::ConfigurationError)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,73 @@
1
+ module Veri
2
+ module Authentication
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include ActionController::Cookies unless self < ActionController::Cookies
7
+
8
+ helper_method(:current_user, :logged_in?) if respond_to?(:helper_method)
9
+ end
10
+
11
+ class_methods do
12
+ def with_authentication(options = {})
13
+ before_action :with_authentication, **options
14
+ rescue ArgumentError => e
15
+ raise Veri::InvalidArgumentError, e.message
16
+ end
17
+
18
+ def skip_authentication(options = {})
19
+ skip_before_action :with_authentication, **options
20
+ rescue ArgumentError => e
21
+ raise Veri::InvalidArgumentError, e.message
22
+ end
23
+ end
24
+
25
+ def current_user
26
+ @current_user ||= current_session&.authenticatable
27
+ end
28
+
29
+ def current_session
30
+ token = cookies.encrypted[:veri_token]
31
+ @current_session ||= token ? Session.find_by(hashed_token: Digest::SHA256.hexdigest(token)) : nil
32
+ end
33
+
34
+ def log_in(authenticatable)
35
+ token = Veri::Session.establish(Veri::Inputs.process(authenticatable, as: :authenticatable), request)
36
+ cookies.encrypted.permanent[:veri_token] = { value: token, httponly: true }
37
+ after_login
38
+ end
39
+
40
+ def log_out
41
+ current_session&.terminate
42
+ cookies.delete(:veri_token)
43
+ after_logout
44
+ end
45
+
46
+ def logged_in?
47
+ current_user.present?
48
+ end
49
+
50
+ def return_path
51
+ cookies.signed[:veri_return_path]
52
+ end
53
+
54
+ private
55
+
56
+ def with_authentication
57
+ current_session.update_info(request) and return if logged_in? && current_session.active?
58
+
59
+ current_session&.terminate
60
+
61
+ cookies.signed[:veri_return_path] = { value: request.fullpath, expires: 15.minutes.from_now } if request.get? && request.format.html?
62
+
63
+ when_unauthenticated
64
+ end
65
+
66
+ def when_unauthenticated
67
+ request.format.html? ? redirect_back(fallback_location: root_path) : head(:unauthorized)
68
+ end
69
+
70
+ def after_login = nil
71
+ def after_logout = nil
72
+ end
73
+ end
@@ -0,0 +1,27 @@
1
+ require "dry-types"
2
+
3
+ module Veri
4
+ module Inputs
5
+ extend self
6
+
7
+ include Dry.Types()
8
+
9
+ def process(value, as:, optional: false, error: Veri::InvalidArgumentError)
10
+ checker = send(as)
11
+ checker = checker.optional if optional
12
+
13
+ checker[value]
14
+ rescue Dry::Types::CoercionError => e
15
+ raise error, e.message
16
+ end
17
+
18
+ private
19
+
20
+ def hashing_algorithm = self::Strict::Symbol.enum(:argon2, :bcrypt, :scrypt)
21
+ def duration = self::Instance(ActiveSupport::Duration)
22
+ def string = self::Strict::String
23
+ def model = self::Strict::Class.constructor { _1.try(:safe_constantize) || _1 }.constrained(lt: ActiveRecord::Base)
24
+ def authenticatable = self::Instance(Veri::Configuration.user_model)
25
+ def request = self::Instance(ActionDispatch::Request)
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module Veri
2
+ module Authenticatable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ raise Veri::Error, "Veri::Authenticatable can only be included once" if defined?(@@included) && @@included != name
7
+
8
+ @@included = name
9
+
10
+ has_many :veri_sessions, class_name: "Veri::Session", foreign_key: :authenticatable_id, dependent: :destroy
11
+ end
12
+
13
+ def update_password(password)
14
+ update!(hashed_password: hasher.create(Veri::Inputs.process(password, as: :string)))
15
+ end
16
+
17
+ def verify_password(password)
18
+ hasher.verify(Veri::Inputs.process(password, as: :string), hashed_password)
19
+ end
20
+
21
+ private
22
+
23
+ def hasher = Veri::Configuration.hasher
24
+ end
25
+ end
@@ -0,0 +1,82 @@
1
+ require "user_agent_parser"
2
+
3
+ module Veri
4
+ class Session < ActiveRecord::Base
5
+ self.table_name = "veri_sessions"
6
+
7
+ belongs_to :authenticatable, class_name: Veri::Configuration.user_model_name # rubocop:disable Rails/ReflectionClassName
8
+
9
+ def active?
10
+ !expired? && !inactive?
11
+ end
12
+
13
+ def expired?
14
+ expires_at < Time.current
15
+ end
16
+
17
+ def inactive?
18
+ inactive_session_lifetime = Veri::Configuration.inactive_session_lifetime
19
+
20
+ return false unless inactive_session_lifetime
21
+
22
+ last_seen_at < Time.current - inactive_session_lifetime
23
+ end
24
+
25
+ alias terminate delete
26
+
27
+ def update_info(request)
28
+ processed_request = Veri::Inputs.process(request, as: :request, error: Veri::Error)
29
+
30
+ update!(
31
+ last_seen_at: Time.current,
32
+ ip_address: processed_request.remote_ip,
33
+ user_agent: processed_request.user_agent
34
+ )
35
+ end
36
+
37
+ def info
38
+ agent = UserAgentParser.parse(user_agent)
39
+
40
+ {
41
+ device: agent.device.to_s,
42
+ os: agent.os.to_s,
43
+ browser: agent.to_s,
44
+ ip_address:,
45
+ last_seen_at:
46
+ }
47
+ end
48
+
49
+ class << self
50
+ def establish(authenticatable, request)
51
+ token = SecureRandom.hex(32)
52
+ expires_at = Time.current + Veri::Configuration.total_session_lifetime
53
+
54
+ new(
55
+ hashed_token: Digest::SHA256.hexdigest(token),
56
+ expires_at:,
57
+ authenticatable: Veri::Inputs.process(authenticatable, as: :authenticatable, error: Veri::Error)
58
+ ).update_info(
59
+ Veri::Inputs.process(request, as: :request, error: Veri::Error)
60
+ )
61
+
62
+ token
63
+ end
64
+
65
+ def prune(authenticatable = nil)
66
+ processed_authenticatable = Veri::Inputs.process(authenticatable, as: :authenticatable, optional: true)
67
+ scope = processed_authenticatable ? where(authenticatable: processed_authenticatable) : all
68
+ to_be_pruned = scope.where(expires_at: ...Time.current)
69
+ if Veri::Configuration.inactive_session_lifetime
70
+ to_be_pruned = to_be_pruned.or(
71
+ scope.where(last_seen_at: ...(Time.current - Veri::Configuration.inactive_session_lifetime))
72
+ )
73
+ end
74
+ to_be_pruned.delete_all
75
+ end
76
+
77
+ def terminate_all(authenticatable)
78
+ Veri::Inputs.process(authenticatable, as: :authenticatable).veri_sessions.delete_all
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,17 @@
1
+ require "argon2"
2
+
3
+ module Veri
4
+ module Password
5
+ module Argon2
6
+ module_function
7
+
8
+ def create(password)
9
+ ::Argon2::Password.create(password)
10
+ end
11
+
12
+ def verify(password, hashed_password)
13
+ ::Argon2::Password.verify_password(password, hashed_password)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require "bcrypt"
2
+
3
+ module Veri
4
+ module Password
5
+ module BCrypt
6
+ module_function
7
+
8
+ def create(password)
9
+ ::BCrypt::Password.create(password)
10
+ end
11
+
12
+ def verify(password, hashed_password)
13
+ ::BCrypt::Password.new(hashed_password) == password
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require "scrypt"
2
+
3
+ module Veri
4
+ module Password
5
+ module SCrypt
6
+ module_function
7
+
8
+ def create(password)
9
+ ::SCrypt::Password.create(password)
10
+ end
11
+
12
+ def verify(password, hashed_password)
13
+ ::SCrypt::Password.new(hashed_password) == password
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ require "rails/railtie"
2
+
3
+ module Veri
4
+ class Railtie < Rails::Railtie
5
+ initializer "veri.to_prepare" do |app|
6
+ app.config.to_prepare do
7
+ user_model = Veri::Configuration.user_model
8
+ user_model.include Veri::Authenticatable unless user_model < Veri::Authenticatable
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Veri
2
+ VERSION = "0.1.0"
3
+ end
data/lib/veri.rb ADDED
@@ -0,0 +1,26 @@
1
+ require_relative "veri/version"
2
+
3
+ require "active_record"
4
+ require "active_support"
5
+
6
+ require_relative "veri/password/argon2"
7
+ require_relative "veri/password/bcrypt"
8
+ require_relative "veri/password/scrypt"
9
+
10
+ require_relative "veri/inputs"
11
+ require_relative "veri/configuration"
12
+
13
+ module Veri
14
+ class Error < StandardError; end
15
+ class ConfigurationError < Veri::Error; end
16
+ class InvalidArgumentError < Veri::Error; end
17
+
18
+ delegate :configure, to: Veri::Configuration
19
+ module_function :configure
20
+ end
21
+
22
+ require_relative "veri/models/session"
23
+ require_relative "veri/controllers/concerns/authentication"
24
+ require_relative "veri/models/concerns/authenticatable"
25
+
26
+ require_relative "veri/railtie"
data/veri.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ require_relative "lib/veri/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "veri"
5
+ spec.version = Veri::VERSION
6
+ spec.authors = ["enjaku4"]
7
+ spec.homepage = "https://github.com/brownboxdev/veri"
8
+ spec.metadata["homepage_uri"] = spec.homepage
9
+ spec.metadata["source_code_uri"] = spec.homepage
10
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
11
+ spec.metadata["rubygems_mfa_required"] = "true"
12
+ spec.summary = "Minimal cookie-based authentication library for Ruby on Rails"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 3.2", "< 3.5"
15
+
16
+ spec.files = [
17
+ "veri.gemspec", "README.md", "CHANGELOG.md", "LICENSE.txt"
18
+ ] + Dir.glob("lib/**/*")
19
+
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "argon2", "~> 2.0"
23
+ spec.add_dependency "bcrypt", "~> 3.0"
24
+ spec.add_dependency "dry-configurable", "~> 1.3"
25
+ spec.add_dependency "dry-types", "~> 1.8"
26
+ spec.add_dependency "rails", ">= 7.1", "< 8.1"
27
+ spec.add_dependency "scrypt", "~> 3.0"
28
+ spec.add_dependency "user_agent_parser", "~> 2.0"
29
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: veri
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - enjaku4
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: argon2
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bcrypt
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: dry-configurable
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: dry-types
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.8'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.8'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rails
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '7.1'
75
+ - - "<"
76
+ - !ruby/object:Gem::Version
77
+ version: '8.1'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '7.1'
85
+ - - "<"
86
+ - !ruby/object:Gem::Version
87
+ version: '8.1'
88
+ - !ruby/object:Gem::Dependency
89
+ name: scrypt
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.0'
95
+ type: :runtime
96
+ prerelease: false
97
+ version_requirements: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '3.0'
102
+ - !ruby/object:Gem::Dependency
103
+ name: user_agent_parser
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '2.0'
109
+ type: :runtime
110
+ prerelease: false
111
+ version_requirements: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '2.0'
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - CHANGELOG.md
121
+ - LICENSE.txt
122
+ - README.md
123
+ - lib/generators/veri/authentication_generator.rb
124
+ - lib/generators/veri/templates/add_veri_authentication.rb.erb
125
+ - lib/veri.rb
126
+ - lib/veri/configuration.rb
127
+ - lib/veri/controllers/concerns/authentication.rb
128
+ - lib/veri/inputs.rb
129
+ - lib/veri/models/concerns/authenticatable.rb
130
+ - lib/veri/models/session.rb
131
+ - lib/veri/password/argon2.rb
132
+ - lib/veri/password/bcrypt.rb
133
+ - lib/veri/password/scrypt.rb
134
+ - lib/veri/railtie.rb
135
+ - lib/veri/version.rb
136
+ - veri.gemspec
137
+ homepage: https://github.com/brownboxdev/veri
138
+ licenses:
139
+ - MIT
140
+ metadata:
141
+ homepage_uri: https://github.com/brownboxdev/veri
142
+ source_code_uri: https://github.com/brownboxdev/veri
143
+ changelog_uri: https://github.com/brownboxdev/veri/blob/main/CHANGELOG.md
144
+ rubygems_mfa_required: 'true'
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '3.2'
153
+ - - "<"
154
+ - !ruby/object:Gem::Version
155
+ version: '3.5'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubygems_version: 3.6.7
163
+ specification_version: 4
164
+ summary: Minimal cookie-based authentication library for Ruby on Rails
165
+ test_files: []