KemalIdentity::SQLite::SessionRepository
Inherits KemalIdentity::Sessions::Repository < Reference < Object
Sessions::Repository over auth_sessions, SQLite dialect.
On translating constraint failures
SQLite3::Exception#code reports CONSTRAINT for every constraint, not specifically for a
unique one, so every adapter here checks that broad code. On these tables the distinction
does not exist: the only constraints are primary keys and unique indexes, and both mean the
same thing to a caller — this row is already there. PostgreSQL's SQLSTATE is narrower,
which is why that adapter checks for 23505 exactly.
Constants
Constructors
accounts_table exists because auth_accounts is a reference implementation. An
application authenticating against its own users table joins against that instead and
still satisfies the same contract.
Instance methods
Stores a new session.
Raises KemalIdentity::InfrastructureError if record.token_digest is already present.
This is not defensive noise: auth_sessions.token_digest carries a unique index
precisely so that a digest collision is a loud database error rather than a silent
security failure in which two accounts share a session
(docs/03-data-model.md). An implementation that upserted here would convert that
error into exactly the failure the index exists to prevent.
Deletes rows whose absolute_expires_at is at or before before, returning the count.
Disk reclamation only. Correctness never depends on this having run: expiry is
evaluated on every read, which is the direct lesson of kemal-session issue #116, where
a timeout only marked a session for deletion at the next GC pass and a read could
refresh its access time before any expiry check, reviving it
(docs/02-security-model.md).
Deletes revoked rows whose revoked_at is at or before before, returning the count.
Separate from #delete_expired because a revoked session is not necessarily an expired
one: logging out at nine in the morning revokes a row whose absolute deadline is still
hours away, and that row is worth keeping for a while. It is the evidence behind "you
were signed out of this device", and deleting it the instant it is revoked throws away
the only record that the logout happened.
The retention window is the application's to choose. Disk reclamation either way — correctness never depends on this having run, because revocation is evaluated on read.
One indexed lookup with a join, returning session state and account status together — decision D7, identical in shape to the PostgreSQL adapter. An inner join, so a session pointing at an account that no longer exists resolves to nothing.
Marks one session revoked, returning false if it does not exist or was already revoked.
Already-revoked returns false rather than raising: logging out twice is not an error, and the caller learns whether it changed anything.
Revokes every live session for an account, optionally sparing one, and returns how many it revoked.
except_id is what makes "log out everywhere else" and "change password without
logging myself out" possible. Already-revoked sessions are not counted and not
re-stamped, so the count is the number of sessions actually ended.