Documentation
¶
Overview ¶
Package memory is the in-process Repository driver. It backs both fast unit tests (no gRPC, no docker) and local-development runs where a full EntDB stack is overkill.
All operations are mutex-protected so tests using t.Parallel() are race-free. The driver keeps the same surface as the EntDB-backed driver — service.Repository plus a no-op service.DB — so the driver-selection helper in internal/repo/driver.go can hand it back from Build like any other backend.
Index ¶
- type Repo
- func (r *Repo) ConsumeEmailLoginCode(_ context.Context, email string, atMs int64) (*service.EmailLoginCodeRecord, error)
- func (r *Repo) ConsumeMagicLinkToken(_ context.Context, tokenHash string, atMs int64) (*service.MagicLinkTokenRecord, error)
- func (r *Repo) ConsumeOAuthOneTimeCode(_ context.Context, codeHash string, atMs int64) (*service.OAuthOneTimeCodeRecord, error)
- func (r *Repo) ConsumePhoneVerificationCode(_ context.Context, userID string, atMs int64) (*service.PhoneVerificationCodeRecord, error)
- func (r *Repo) ConsumeQrLoginSession(_ context.Context, nodeID string, atMs int64) error
- func (r *Repo) ConsumeRefreshTokenByHash(_ context.Context, hash string, atMs int64) error
- func (r *Repo) CountEmailChangeTokens() int
- func (r *Repo) CountEmailVerificationTokens() int
- func (r *Repo) CountLoginChallenges() int
- func (r *Repo) CountPasskeyChallenges() int
- func (r *Repo) CountPasswordResetTokens() int
- func (r *Repo) CountRefreshTokensForUser(userID string) int
- func (r *Repo) CreateEmailChangeToken(_ context.Context, t *service.EmailChangeToken) error
- func (r *Repo) CreateEmailVerificationToken(_ context.Context, t *service.EmailVerificationToken) error
- func (r *Repo) CreateIdentityVerification(_ context.Context, rec *service.IdentityVerificationRecord) error
- func (r *Repo) CreateLoginChallenge(_ context.Context, rec *service.LoginChallengeRecord) (string, error)
- func (r *Repo) CreateMagicLinkToken(_ context.Context, rec *service.MagicLinkTokenRecord) (string, error)
- func (r *Repo) CreateOAuthIdentity(_ context.Context, oi *service.OAuthIdentity) error
- func (r *Repo) CreateOAuthOneTimeCode(_ context.Context, rec *service.OAuthOneTimeCodeRecord) (string, error)
- func (r *Repo) CreatePasskeyChallenge(_ context.Context, rec *service.PasskeyChallengeRecord) (string, error)
- func (r *Repo) CreatePasskeyCredential(_ context.Context, rec *service.PasskeyCredRecord) (string, error)
- func (r *Repo) CreatePasswordResetToken(_ context.Context, t *service.PasswordResetToken) error
- func (r *Repo) CreateQrLoginSession(_ context.Context, rec *service.QrLoginSessionRecord) (string, error)
- func (r *Repo) CreateRecoveryCode(_ context.Context, rec *service.RecoveryCodeRecord) (string, error)
- func (r *Repo) CreateRefreshToken(_ context.Context, rec *service.RefreshTokenRecord) (string, error)
- func (r *Repo) CreateSession(_ context.Context, s *service.SessionRecord) (string, error)
- func (r *Repo) CreateTotpCredential(_ context.Context, rec *service.TotpCredRecord) (string, error)
- func (r *Repo) CreateUser(_ context.Context, u *service.User) (string, error)
- func (r *Repo) DeleteExpiredEmailChangeTokens(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredEmailLoginCodes(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredEmailVerificationTokens(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredInvitations(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredLoginChallenges(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredMagicLinkTokens(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredOAuthOneTimeCodes(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredPasswordResetTokens(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredPhoneVerificationCodes(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredQrLoginSessions(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteExpiredWebAuthnChallenges(_ context.Context, beforeMs int64, limit int) error
- func (r *Repo) DeleteLoginChallenge(_ context.Context, nodeID string) error
- func (r *Repo) DeletePasskeyChallenge(_ context.Context, nodeID string) error
- func (r *Repo) DeleteRecoveryCodesForUser(_ context.Context, userID string) error
- func (r *Repo) DeleteRefreshToken(_ context.Context, nodeID string) error
- func (r *Repo) DeleteRefreshTokensForUser(_ context.Context, userID string) error
- func (r *Repo) DeleteTotpCredential(_ context.Context, nodeID string) error
- func (r *Repo) DeleteTotpCredentialsForUser(_ context.Context, userID string) error
- func (r *Repo) DeleteUser(_ context.Context, userID string) error
- func (r *Repo) ExecuteAtomic(context.Context, string, string, []sdk.Operation) (*sdk.CommitResult, error)
- func (r *Repo) FindEmailChangeTokenByHash(_ context.Context, hash string) (*service.EmailChangeToken, error)
- func (r *Repo) FindEmailLoginCodeByEmail(_ context.Context, email string) (*service.EmailLoginCodeRecord, error)
- func (r *Repo) FindEmailVerificationTokenByHash(_ context.Context, hash string) (*service.EmailVerificationToken, error)
- func (r *Repo) FindInvitationByHash(_ context.Context, tokenHash string) (*service.InvitationRecord, error)
- func (r *Repo) FindPasswordResetTokenByHash(_ context.Context, hash string) (*service.PasswordResetToken, error)
- func (r *Repo) FindPhoneVerificationCodeByUser(_ context.Context, userID string) (*service.PhoneVerificationCodeRecord, error)
- func (r *Repo) FindQrLoginSession(_ context.Context, sessionID string) (*service.QrLoginSessionRecord, error)
- func (r *Repo) FindRecoveryCodeByHash(_ context.Context, userID, hash string) (*service.RecoveryCodeRecord, error)
- func (r *Repo) FindRefreshTokenByHash(_ context.Context, hash string) (*service.RefreshTokenRecord, error)
- func (r *Repo) FindRefreshTokenByHashIncludingConsumed(_ context.Context, hash string) (*service.RefreshTokenRecord, error)
- func (r *Repo) FindUserByEmail(_ context.Context, email string) (*service.User, error)
- func (r *Repo) FindUserByProviderID(_ context.Context, provider, providerUserID string) (*service.User, error)
- func (r *Repo) GetEdgesFrom(context.Context, string, string, string, int) ([]*sdk.Edge, error)
- func (r *Repo) GetEdgesTo(context.Context, string, string, string, int) ([]*sdk.Edge, error)
- func (r *Repo) GetIdentityVerification(_ context.Context, verificationID string) (*service.IdentityVerificationRecord, error)
- func (r *Repo) GetLatestIdentityVerificationForUser(_ context.Context, userID string) (*service.IdentityVerificationRecord, error)
- func (r *Repo) GetLoginChallengeByChallengeID(_ context.Context, challengeID string) (*service.LoginChallengeRecord, error)
- func (r *Repo) GetNode(context.Context, string, string, int, string) (*sdk.Node, error)
- func (r *Repo) GetPasskeyChallenge(_ context.Context, nodeID string) (*service.PasskeyChallengeRecord, error)
- func (r *Repo) GetPasskeyCredentialByCredID(_ context.Context, credentialID string) (*service.PasskeyCredRecord, error)
- func (r *Repo) GetSessionBySid(_ context.Context, sid string) (*service.SessionRecord, error)
- func (r *Repo) GetTotpCredential(_ context.Context, userID string) (*service.TotpCredRecord, error)
- func (r *Repo) GetUser(_ context.Context, userID string) (*service.User, error)
- func (r *Repo) IncrementEmailLoginCodeAttempts(_ context.Context, nodeID string) error
- func (r *Repo) IncrementFailedLoginCount(_ context.Context, userID string) (int32, error)
- func (r *Repo) IncrementPhoneVerificationCodeAttempts(_ context.Context, nodeID string) error
- func (r *Repo) ListOAuthIdentitiesForUser(_ context.Context, userID string) ([]*service.OAuthIdentity, error)
- func (r *Repo) ListPasskeyCredentials(_ context.Context, userID string) ([]*service.PasskeyCredRecord, error)
- func (r *Repo) MarkEmailChangeTokenConsumed(_ context.Context, id string, atMs int64) error
- func (r *Repo) MarkEmailVerificationTokenConsumed(_ context.Context, id string, atMs int64) error
- func (r *Repo) MarkPasswordResetTokenConsumed(_ context.Context, id string, atMs int64) error
- func (r *Repo) QueryNodes(context.Context, string, string, int, map[string]any) ([]*sdk.Node, error)
- func (r *Repo) RegisterUserInTenant(_ context.Context, _, _, _, _, _ string) error
- func (r *Repo) ResetFailedLoginCount(_ context.Context, userID string) error
- func (r *Repo) RevokeSession(_ context.Context, sid string, atMs int64) error
- func (r *Repo) RevokeSessionsForUser(_ context.Context, userID string, atMs int64) error
- func (r *Repo) SearchNodes(context.Context, string, string, int, string) ([]*sdk.Node, error)
- func (r *Repo) SetUserEmailVerified(_ context.Context, userID string, atMs int64) error
- func (r *Repo) SetUserIDVVerified(_ context.Context, userID string, atMs int64) error
- func (r *Repo) SetUserLockedUntil(_ context.Context, userID string, lockedUntilMs int64) error
- func (r *Repo) SetUserPhoneVerified(_ context.Context, userID, phoneNumber string, atMs int64) error
- func (r *Repo) UpdateIdentityVerificationStatus(_ context.Context, verificationID, status, rejectionReason string, ...) error
- func (r *Repo) UpdateInvitation(_ context.Context, nodeID string, fields map[string]any) error
- func (r *Repo) UpdatePasskeyCredential(_ context.Context, nodeID string, fields map[string]any) error
- func (r *Repo) UpdateQrLoginSession(_ context.Context, nodeID string, fields map[string]any) error
- func (r *Repo) UpdateRecoveryCode(_ context.Context, nodeID string, fields map[string]any) error
- func (r *Repo) UpdateTotpCredential(_ context.Context, nodeID string, fields map[string]any) error
- func (r *Repo) UpdateUser(_ context.Context, userID string, fields map[string]any) error
- func (r *Repo) UpdateUserEmail(_ context.Context, userID, newEmail string, atMs int64) error
- func (r *Repo) UpsertEmailLoginCode(_ context.Context, rec *service.EmailLoginCodeRecord) (string, error)
- func (r *Repo) UpsertPhoneVerificationCode(_ context.Context, rec *service.PhoneVerificationCodeRecord) (string, error)
- func (r *Repo) WithProject(projectID string) service.Repository
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo is the in-memory implementation of service.Repository.
Project isolation (ADR-0002): each Repo instance owns an independent set of data-plane maps, so two projects share no rows and uniqueness (e.g. email) is per-project, mirroring the postgres `WHERE project_id = $1` boundary and the entdb per-project SDK partition. WithProject returns the sibling Repo for a given project, lazily created and memoised in a shared registry so repeated lookups of the same project reuse one store.
func New ¶
func New() *Repo
New returns an empty Repo bound to the boot-default project (the empty project id). Data written without an explicit project scope lands here; WithProject derives isolated siblings for other projects.
func (*Repo) ConsumeEmailLoginCode ¶ added in v0.11.0
func (r *Repo) ConsumeEmailLoginCode(_ context.Context, email string, atMs int64) (*service.EmailLoginCodeRecord, error)
ConsumeEmailLoginCode atomically marks the email's unconsumed, unexpired code consumed and returns it. Any second caller, an expired code, or a missing code returns ErrEmailLoginCodeInvalid.
func (*Repo) ConsumeMagicLinkToken ¶ added in v0.11.0
func (r *Repo) ConsumeMagicLinkToken(_ context.Context, tokenHash string, atMs int64) (*service.MagicLinkTokenRecord, error)
ConsumeMagicLinkToken atomically marks an unconsumed, unexpired token consumed and returns it. A replay, an expired token, or a missing token returns ErrMagicLinkInvalid.
func (*Repo) ConsumeOAuthOneTimeCode ¶ added in v0.9.0
func (r *Repo) ConsumeOAuthOneTimeCode(_ context.Context, codeHash string, atMs int64) (*service.OAuthOneTimeCodeRecord, error)
ConsumeOAuthOneTimeCode atomically marks an unconsumed, unexpired code consumed and returns its record. The mutex held across read+check+write makes this CAS trivially correct for the in-process driver: any second caller (or an expired code) returns ErrOAuthCodeInvalid.
func (*Repo) ConsumePhoneVerificationCode ¶ added in v0.14.0
func (r *Repo) ConsumePhoneVerificationCode(_ context.Context, userID string, atMs int64) (*service.PhoneVerificationCodeRecord, error)
ConsumePhoneVerificationCode atomically marks the user's unconsumed, unexpired code consumed and returns it. Any second caller, an expired code, or a missing code returns ErrPhoneCodeInvalid.
func (*Repo) ConsumeQrLoginSession ¶ added in v0.7.2
ConsumeQrLoginSession atomically transitions an approved session to consumed. The mutex held across read+check+write makes this CAS trivially correct for the in-process driver: any second caller sees status != "approved" and returns ErrQrLoginNotPending.
func (*Repo) ConsumeRefreshTokenByHash ¶
ConsumeRefreshTokenByHash atomically marks the row consumed. Returns service.ErrUnauthenticated if the row is missing or already consumed, so concurrent rotations resolve to exactly one winner.
func (*Repo) CountEmailChangeTokens ¶ added in v0.8.0
CountEmailChangeTokens is a test helper; see CountPasswordResetTokens.
func (*Repo) CountEmailVerificationTokens ¶ added in v0.8.0
CountEmailVerificationTokens is a test helper; see CountPasswordResetTokens.
func (*Repo) CountLoginChallenges ¶ added in v0.8.0
CountLoginChallenges is a test helper; see CountPasswordResetTokens.
func (*Repo) CountPasskeyChallenges ¶ added in v0.8.0
CountPasskeyChallenges is a test helper; see CountPasswordResetTokens.
func (*Repo) CountPasswordResetTokens ¶ added in v0.8.0
CountPasswordResetTokens is a test helper used by the sweeper regression to infer "rows deleted" from "rows still present" after the v1.14.0 contract dropped the row-count return.
func (*Repo) CountRefreshTokensForUser ¶
CountRefreshTokensForUser is a test helper for assertions about session count.
func (*Repo) CreateEmailChangeToken ¶
func (*Repo) CreateEmailVerificationToken ¶
func (*Repo) CreateIdentityVerification ¶ added in v0.4.0
func (*Repo) CreateLoginChallenge ¶
func (*Repo) CreateMagicLinkToken ¶ added in v0.11.0
func (*Repo) CreateOAuthIdentity ¶
func (*Repo) CreateOAuthOneTimeCode ¶ added in v0.9.0
func (*Repo) CreatePasskeyChallenge ¶
func (*Repo) CreatePasskeyCredential ¶
func (*Repo) CreatePasswordResetToken ¶
func (*Repo) CreateQrLoginSession ¶
func (*Repo) CreateRecoveryCode ¶
func (*Repo) CreateRefreshToken ¶
func (*Repo) CreateSession ¶ added in v0.8.0
func (*Repo) CreateTotpCredential ¶
func (*Repo) CreateUser ¶
func (*Repo) DeleteExpiredEmailChangeTokens ¶ added in v0.7.1
func (*Repo) DeleteExpiredEmailLoginCodes ¶ added in v0.11.0
func (*Repo) DeleteExpiredEmailVerificationTokens ¶ added in v0.7.1
func (*Repo) DeleteExpiredInvitations ¶ added in v0.15.0
func (*Repo) DeleteExpiredLoginChallenges ¶ added in v0.7.1
func (*Repo) DeleteExpiredMagicLinkTokens ¶ added in v0.11.0
func (*Repo) DeleteExpiredOAuthOneTimeCodes ¶ added in v0.9.0
func (*Repo) DeleteExpiredPasswordResetTokens ¶ added in v0.7.1
func (*Repo) DeleteExpiredPhoneVerificationCodes ¶ added in v0.14.0
func (*Repo) DeleteExpiredQrLoginSessions ¶ added in v0.15.0
func (*Repo) DeleteExpiredWebAuthnChallenges ¶ added in v0.7.1
func (*Repo) DeleteLoginChallenge ¶
func (*Repo) DeletePasskeyChallenge ¶
func (*Repo) DeleteRecoveryCodesForUser ¶
func (*Repo) DeleteRefreshToken ¶
func (*Repo) DeleteRefreshTokensForUser ¶
func (*Repo) DeleteTotpCredential ¶
func (*Repo) DeleteTotpCredentialsForUser ¶
func (*Repo) DeleteUser ¶ added in v0.13.0
DeleteUser physically removes the user and every user-owned row. It is idempotent (a missing user is a no-op). The email-keyed login codes / magic-link tokens are intentionally left untouched (they carry no user_id and are short-lived pre-account artifacts); the audit store has no in-memory equivalent so nothing to retain. The phone-verification codes are user-keyed and durable, so they are drained here like the other user-owned types.
func (*Repo) ExecuteAtomic ¶
func (*Repo) FindEmailChangeTokenByHash ¶
func (*Repo) FindEmailLoginCodeByEmail ¶ added in v0.11.0
func (*Repo) FindEmailVerificationTokenByHash ¶
func (*Repo) FindInvitationByHash ¶
func (*Repo) FindPasswordResetTokenByHash ¶
func (*Repo) FindPhoneVerificationCodeByUser ¶ added in v0.14.0
func (*Repo) FindQrLoginSession ¶
func (*Repo) FindRecoveryCodeByHash ¶
func (*Repo) FindRefreshTokenByHash ¶
func (*Repo) FindRefreshTokenByHashIncludingConsumed ¶
func (*Repo) FindUserByEmail ¶
func (*Repo) FindUserByProviderID ¶
func (*Repo) GetEdgesFrom ¶
func (*Repo) GetEdgesTo ¶
func (*Repo) GetIdentityVerification ¶ added in v0.4.0
func (*Repo) GetLatestIdentityVerificationForUser ¶ added in v0.4.0
func (*Repo) GetLoginChallengeByChallengeID ¶
func (*Repo) GetPasskeyChallenge ¶
func (*Repo) GetPasskeyCredentialByCredID ¶
func (*Repo) GetSessionBySid ¶ added in v0.8.0
func (*Repo) GetTotpCredential ¶
func (*Repo) IncrementEmailLoginCodeAttempts ¶ added in v0.11.0
func (*Repo) IncrementFailedLoginCount ¶
func (*Repo) IncrementPhoneVerificationCodeAttempts ¶ added in v0.14.0
func (*Repo) ListOAuthIdentitiesForUser ¶
func (*Repo) ListPasskeyCredentials ¶
func (*Repo) MarkEmailChangeTokenConsumed ¶
func (*Repo) MarkEmailVerificationTokenConsumed ¶
func (*Repo) MarkPasswordResetTokenConsumed ¶
func (*Repo) QueryNodes ¶
func (*Repo) RegisterUserInTenant ¶ added in v0.7.1
RegisterUserInTenant is a no-op on the in-memory driver. The in-memory store bypasses the EntDB two-tier model entirely, so there is no global registry / tenant-membership to enforce.
func (*Repo) ResetFailedLoginCount ¶
func (*Repo) RevokeSession ¶ added in v0.8.0
RevokeSession is idempotent: a no-op if the session does not exist or is already revoked. Concurrent revoke calls converge on the same final state rather than racing each other into failure.
func (*Repo) RevokeSessionsForUser ¶ added in v0.8.0
RevokeSessionsForUser revokes every active session for the user. Existing revoked rows are left alone so the original revoke timestamp survives.
func (*Repo) SearchNodes ¶
func (*Repo) SetUserEmailVerified ¶
func (*Repo) SetUserIDVVerified ¶ added in v0.4.2
func (*Repo) SetUserLockedUntil ¶
func (*Repo) SetUserPhoneVerified ¶ added in v0.14.0
func (*Repo) UpdateIdentityVerificationStatus ¶ added in v0.4.0
func (*Repo) UpdateInvitation ¶
func (*Repo) UpdatePasskeyCredential ¶
func (*Repo) UpdateQrLoginSession ¶
func (*Repo) UpdateRecoveryCode ¶
func (*Repo) UpdateTotpCredential ¶
func (*Repo) UpdateUser ¶
func (*Repo) UpdateUserEmail ¶
func (*Repo) UpsertEmailLoginCode ¶ added in v0.11.0
func (r *Repo) UpsertEmailLoginCode(_ context.Context, rec *service.EmailLoginCodeRecord) (string, error)
UpsertEmailLoginCode replaces any existing code for the email so at most one is live per address. Keyed by email (the unique field).
func (*Repo) UpsertPhoneVerificationCode ¶ added in v0.14.0
func (r *Repo) UpsertPhoneVerificationCode(_ context.Context, rec *service.PhoneVerificationCodeRecord) (string, error)
UpsertPhoneVerificationCode replaces any existing code for the user so at most one is live per user. Keyed by user_id.
func (*Repo) WithProject ¶ added in v1.0.0
func (r *Repo) WithProject(projectID string) service.Repository
WithProject returns the Repo bound to projectID, mirroring the postgres `WHERE project_id = $1` boundary and the entdb per-project SDK partition (ADR-0002). Each project gets a fully independent store, so two projects never see each other's rows and a unique key (email) is scoped per project. The sibling is memoised so repeated calls for one project return the same store; passing this Repo's own project id returns itself.