KemalIdentity::Postgres::AccountRepository
Inherits KemalIdentity::Accounts::Repository < Reference < Object
Accounts::Repository over the reference auth_accounts table.
A reference implementation, not a requirement. An application that already has
users.email and users.password_digest implements the contract over that table and
never creates auth_accounts at all — that distinction is the difference between
"adoptable incrementally" and "rewrite your user model first"
(docs/03-data-model.md). This class exists so there is something to point at, and so the
contract has a second implementation keeping the in-memory double honest.
Constants
Every column the contract needs, named explicitly rather than SELECT *: a column added
to the table later must not silently change what this reads.
Constructors
Instance methods
Increments auth_version and returns the new value, or nil if no such account
exists.
Invalidates every session for the account without enumerating rows: each session
stores the auth_version it was minted under, and a mismatch fails the session on its
next read. Used on password change and MFA recovery, alongside explicit revocation
rather than instead of it (docs/02-security-model.md).
Also the answer for a change to the account's tenant, which is the one authorization
input a session copies: without a bump or an explicit revocation, sessions that already
exist keep the tenant they were minted with until they expire
(Sessions::Record#tenant_id).
The tenant_id IS NULL case is split out rather than folded into one clever predicate.
tenant_id = NULL matches nothing in SQL — it is not false, it is unknown — so the
single-tenant lookup has to say IS NULL explicitly. Writing the obvious parameterised
query instead returns no rows for every single-tenant application, and the contract spec
has a named example for it.
Records that this account's address has been proved, and returns false if no such account exists.
Idempotent: confirming twice is not an error, and the second call moves the timestamp forward rather than refusing. A user who clicks a link twice has not done anything wrong.
Replaces the stored digest and scheme, and moves updated_at to at.
This is the lazy-rehash write: a successful login against a digest at an outdated cost
rehashes at the current one, so old digests disappear as people sign in and nobody is
forced through a password reset (docs/06-roadmap.md).
Returns false if no such account exists. Does not revoke sessions — a rehash of the same password is not a credential change, and revoking here would log everyone out of the application that just upgraded its cost.