Initial commit

This commit is contained in:
2026-05-18 13:17:28 -04:00
committed by GitHub
commit 16fadfd529
91 changed files with 3321 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
end
+16
View File
@@ -0,0 +1,16 @@
class BlacklistedToken < ApplicationRecord
belongs_to :user
validates :jti, presence: true, uniqueness: true
validates :exp, presence: true
# check if a token is blacklisted
def self.blacklisted?(jti)
exists?(jti: jti)
end
# cleanup expired tokens (run this via a scheduled job)
def self.cleanup_expired
where("exp < ?", Time.current).delete_all
end
end
View File
+30
View File
@@ -0,0 +1,30 @@
class RefreshToken < ApplicationRecord
belongs_to :user
validates :token, presence: true, uniqueness: true
validates :expires_at, presence: true
before_validation :generate_token, on: :create
# check if token is still active (not revoked and not expired)
def active?
!revoked && expires_at > Time.current
end
# revoke this token
def revoke!
update!(revoked: true)
end
# generate a secure random token
def generate_token
self.token ||= SecureRandom.urlsafe_base64(32)
self.expires_at ||= 7.days.from_now
end
# cleanup expired or old revoked tokens (run via scheduled job)
# deletes tokens that are either expired OR (revoked AND old)
def self.cleanup_old_tokens
where("expires_at < ? OR (revoked = ? AND created_at < ?)", 30.days.ago, true, 30.days.ago).delete_all
end
end
+17
View File
@@ -0,0 +1,17 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :recoverable, :rememberable, :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:validatable
# associations
has_many :blacklisted_tokens, dependent: :destroy
has_many :refresh_tokens, dependent: :destroy
# role-based authorization
enum :role, { user: 0, admin: 1, moderator: 2 }
# validations so your db doesn't turn into a trash can
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, presence: true, length: { minimum: 6 }, if: -> { new_record? || !password.nil? }
end