Documentation
¶
Overview ¶
Package sqlstore implements store.Store on top of bun, for SQLite and PostgreSQL. Schema changes are versioned goose migrations (see migrate.go).
Index ¶
- Constants
- func HasEncryptedBodyValues(ctx context.Context, driver, dsn string) (bool, error)
- func HasEncryptedValues(ctx context.Context, driver, dsn string) (bool, error)
- func ParseKey(text string) ([]byte, error)
- func Provision(ctx context.Context, o ProvisionOptions) error
- func SequentialUserIDsForTests()
- func SetSequentialUserIDsForTests(on bool)
- type BodyRekeyStats
- type BodyStore
- func (s *BodyStore) BodyStats(ctx context.Context) (store.BodyStats, error)
- func (s *BodyStore) BodyUserIDs(ctx context.Context) ([]int64, error)
- func (s *BodyStore) BodyVersion(ctx context.Context, userID int64) (int64, error)
- func (b *BodyStore) Close() error
- func (s *BodyStore) CreateDexaScan(ctx context.Context, d *models.DexaScan) error
- func (s *BodyStore) DeleteDexaScan(ctx context.Context, userID, id int64) error
- func (s *BodyStore) DeleteScaleReading(ctx context.Context, userID, id int64) error
- func (s *BodyStore) DeleteScaleReadings(ctx context.Context, userID int64, ids []int64) (int, error)
- func (s *BodyStore) DeleteUserBodyData(ctx context.Context, userID int64) error
- func (b *BodyStore) HasEncryptedValues(ctx context.Context) (bool, error)
- func (b *BodyStore) HasPending(ctx context.Context) (bool, error)
- func (s *BodyStore) ListDexaScans(ctx context.Context, userID int64) ([]models.DexaScan, error)
- func (s *BodyStore) ListDexaScansPage(ctx context.Context, userID int64, f store.ListFilter) ([]models.DexaScan, *store.Cursor, error)
- func (s *BodyStore) ListScaleReadings(ctx context.Context, userID int64) ([]models.ScaleReading, error)
- func (s *BodyStore) ListScaleReadingsPage(ctx context.Context, userID int64, f store.ListFilter) ([]models.ScaleReading, *store.Cursor, error)
- func (b *BodyStore) MaxConns() int
- func (b *BodyStore) Migrate(ctx context.Context) ([]*goose.MigrationResult, error)
- func (b *BodyStore) Ping(ctx context.Context) error
- func (b *BodyStore) Rekey(ctx context.Context, dryRun bool) (BodyRekeyStats, error)
- func (s *BodyStore) ScaleReadingsForReconcile(ctx context.Context, userID int64, f store.ListFilter, source string, ...) ([]models.ScaleReading, error)
- func (b *BodyStore) SchemaVersion(ctx context.Context) (int64, error)
- func (s *BodyStore) UpsertScaleReadings(ctx context.Context, userID int64, rs []models.ScaleReading) (int, error)
- type Cipher
- type CopyStats
- type Option
- type ProvisionOptions
- type RekeyStats
- type Store
- func (s *Store) AddAuditEvent(ctx context.Context, e *models.AuditEvent) error
- func (s *Store) AddPasskey(ctx context.Context, p models.Passkey) error
- func (s *Store) CancelJob(ctx context.Context, publicID string, userID int64, at time.Time) (models.Job, error)
- func (s *Store) CancelJobs(ctx context.Context, userID int64, kinds []string, at time.Time) error
- func (s *Store) ClearFailures(ctx context.Context, key string) error
- func (s *Store) Close() error
- func (s *Store) CompleteJob(ctx context.Context, publicID, tokenHash string, c models.Completion, ...) (models.Job, error)
- func (s *Store) CompletePasswordReset(ctx context.Context, tokenHash, passwordHash string) (int64, error)
- func (s *Store) ConfirmTOTP(ctx context.Context, userID, step int64) error
- func (s *Store) CountFailures(ctx context.Context, key string, since time.Time) (int, error)
- func (s *Store) CountRecoveryCodes(ctx context.Context, userID int64) (int, error)
- func (s *Store) CreateAccessToken(ctx context.Context, t *models.AccessToken) error
- func (s *Store) CreatePasswordReset(ctx context.Context, tokenHash string, userID int64, createdBy *int64, ...) error
- func (s *Store) CreateSession(ctx context.Context, tokenHash string, userID int64, method string, ...) error
- func (s *Store) CreateUser(ctx context.Context, username string) (models.User, error)
- func (s *Store) CreateUserWithIdentity(ctx context.Context, username, email string, id models.Identity) (models.User, error)
- func (s *Store) DeleteAccessToken(ctx context.Context, userID, id int64) error
- func (s *Store) DeleteAuthProvider(ctx context.Context, slug string) error
- func (s *Store) DeleteIdentity(ctx context.Context, userID int64, provider string) error
- func (s *Store) DeleteIntegration(ctx context.Context, userID int64, provider string) error
- func (s *Store) DeleteJobSchedule(ctx context.Context, userID int64, kind string) error
- func (s *Store) DeletePasskey(ctx context.Context, userID int64, credentialID string) error
- func (s *Store) DeletePasswordResets(ctx context.Context, userID int64) error
- func (s *Store) DeleteSession(ctx context.Context, tokenHash string) error
- func (s *Store) DeleteSetting(ctx context.Context, name string) error
- func (s *Store) DeleteTOTP(ctx context.Context, userID int64) error
- func (s *Store) DeleteUser(ctx context.Context, userID int64) error
- func (s *Store) DeleteUserAccessTokens(ctx context.Context, userID int64) error
- func (s *Store) DeleteUserSessions(ctx context.Context, userID int64) error
- func (s *Store) EnqueueJob(ctx context.Context, n models.NewJob) (models.Job, bool, error)
- func (s *Store) EnsurePasskeyHandle(ctx context.Context, userID int64) (string, error)
- func (s *Store) ExecForTests(ctx context.Context, query string, args ...any) error
- func (s *Store) ExpireQueuedJobs(ctx context.Context, at time.Time) (int64, error)
- func (s *Store) GetAuthProvider(ctx context.Context, slug string) (models.AuthProvider, error)
- func (s *Store) GetIdentity(ctx context.Context, provider, subject string) (models.Identity, error)
- func (s *Store) GetIntegration(ctx context.Context, userID int64, provider string) ([]byte, error)
- func (s *Store) GetJob(ctx context.Context, publicID string) (models.Job, error)
- func (s *Store) GetJobSchedule(ctx context.Context, userID int64, kind string) (models.JobSchedule, error)
- func (s *Store) GetSession(ctx context.Context, tokenHash string) (models.Session, error)
- func (s *Store) GetSetting(ctx context.Context, name string) (string, error)
- func (s *Store) GetTOTP(ctx context.Context, userID int64) (models.TOTP, error)
- func (s *Store) GetUser(ctx context.Context, id int64) (models.User, error)
- func (s *Store) GetUserByEmail(ctx context.Context, email string) (models.User, error)
- func (s *Store) HasPending(ctx context.Context) (bool, error)
- func (s *Store) HasUsers(ctx context.Context) (bool, error)
- func (s *Store) HeartbeatJob(ctx context.Context, publicID, tokenHash string, extend time.Duration, ...) (cancel bool, err error)
- func (s *Store) IdentityProviders(ctx context.Context) (map[int64][]string, error)
- func (s *Store) JobStats(ctx context.Context, failedSince time.Time) ([]models.JobKindStats, error)
- func (s *Store) LastFinishedStates(ctx context.Context, kind string, n int, since time.Time) ([]string, error)
- func (s *Store) LeaseJob(ctx context.Context, req models.LeaseRequest, at time.Time) (models.Job, bool, error)
- func (s *Store) ListAccessTokens(ctx context.Context, userID int64) ([]models.AccessToken, error)
- func (s *Store) ListAuditEvents(ctx context.Context, f store.AuditFilter) ([]models.AuditEvent, error)
- func (s *Store) ListAuthProviders(ctx context.Context) ([]models.AuthProvider, error)
- func (s *Store) ListJobSchedules(ctx context.Context, kind string) ([]models.JobSchedule, error)
- func (s *Store) ListJobs(ctx context.Context, f models.JobFilter) ([]models.Job, error)
- func (s *Store) ListPasskeys(ctx context.Context, userID int64) ([]models.Passkey, error)
- func (s *Store) ListUserIdentities(ctx context.Context, userID int64) ([]models.Identity, error)
- func (s *Store) ListUsers(ctx context.Context) ([]models.User, error)
- func (s *Store) ListUsersWithIntegration(ctx context.Context, provider string) ([]int64, error)
- func (s *Store) ListWorkers(ctx context.Context, since time.Time) ([]models.WorkerInstance, error)
- func (s *Store) MaxConns() int
- func (s *Store) Migrate(ctx context.Context) ([]*goose.MigrationResult, error)
- func (s *Store) MigrateDown(ctx context.Context) (*goose.MigrationResult, error)
- func (s *Store) MigrateTo(ctx context.Context, version int64) ([]*goose.MigrationResult, error)
- func (s *Store) MigrationStatus(ctx context.Context) ([]*goose.MigrationStatus, error)
- func (s *Store) NonceSeen(ctx context.Context, nonce string) (bool, error)
- func (s *Store) PasswordResetUser(ctx context.Context, tokenHash string) (models.User, error)
- func (s *Store) Ping(ctx context.Context) error
- func (s *Store) PurgeAuditEvents(ctx context.Context, before time.Time) (int64, error)
- func (s *Store) PurgeFailures(ctx context.Context, before time.Time) (int64, error)
- func (s *Store) PurgeJobs(ctx context.Context, before time.Time) (int64, error)
- func (s *Store) PurgeNonces(ctx context.Context, before time.Time) (int64, error)
- func (s *Store) PurgeWorkers(ctx context.Context, before time.Time) (int64, error)
- func (s *Store) PutAuthProvider(ctx context.Context, p models.AuthProvider) error
- func (s *Store) PutIdentity(ctx context.Context, id models.Identity) error
- func (s *Store) PutIntegration(ctx context.Context, userID int64, provider string, data []byte) error
- func (s *Store) PutJobSchedule(ctx context.Context, j models.JobSchedule) error
- func (s *Store) PutPendingTOTP(ctx context.Context, userID int64, secret string) error
- func (s *Store) PutSetting(ctx context.Context, name, value string) error
- func (s *Store) ReapExpiredLeases(ctx context.Context, at time.Time, backoff func(models.Job) time.Duration) ([]models.Job, error)
- func (s *Store) RecordFailure(ctx context.Context, key string, at time.Time) error
- func (s *Store) Rekey(ctx context.Context, dryRun bool) (RekeyStats, error)
- func (s *Store) ReleaseJob(ctx context.Context, publicID, tokenHash string, at time.Time) error
- func (s *Store) RenamePasskey(ctx context.Context, userID int64, credentialID, name string) error
- func (s *Store) ReplaceRecoveryCodes(ctx context.Context, userID int64, hashes []string) error
- func (s *Store) RunningJob(ctx context.Context, publicID, tokenHash string) (models.Job, error)
- func (s *Store) SchemaVersion(ctx context.Context) (int64, error)
- func (s *Store) SetUserJobPriority(ctx context.Context, userID int64, priority int) error
- func (s *Store) SetUserRole(ctx context.Context, userID int64, role string) error
- func (s *Store) SetUserStrengthLevelAuto(ctx context.Context, userID int64, enabled bool) error
- func (s *Store) SetUserStrengthLevelBulk(ctx context.Context, userID int64, enabled bool) error
- func (s *Store) SettingsGeneration(ctx context.Context) (int64, error)
- func (s *Store) Stats(ctx context.Context) (store.Stats, error)
- func (s *Store) TouchWorker(ctx context.Context, id string, kinds []string, version string, at time.Time) error
- func (s *Store) TwoFactorUsers(ctx context.Context) (map[int64]bool, error)
- func (s *Store) UpdatePasskeyUse(ctx context.Context, credentialID, credential string, signCount uint32) error
- func (s *Store) UpdateUserHiddenColumns(ctx context.Context, userID int64, keys []string) error
- func (s *Store) UpdateUserProfile(ctx context.Context, userID int64, username, firstName, lastName, email string, ...) error
- func (s *Store) UpdateUserSettings(ctx context.Context, userID int64, athleteDefault bool, ranking []string) error
- func (s *Store) UpdateUserTimezone(ctx context.Context, userID int64, timezone string) error
- func (s *Store) UseNonce(ctx context.Context, nonce string, expires time.Time) (bool, error)
- func (s *Store) UseRecoveryCode(ctx context.Context, userID int64, hash string) (bool, error)
- func (s *Store) UseTOTPStep(ctx context.Context, userID, step int64) (bool, error)
- func (s *Store) UserByPasskeyHandle(ctx context.Context, handle string) (models.User, error)
- func (s *Store) UserBySession(ctx context.Context, tokenHash string) (models.User, error)
- func (s *Store) UserByTokenHash(ctx context.Context, tokenHash string) (models.User, error)
- func (s *Store) UserProviders(ctx context.Context, userID int64) ([]string, error)
Constants ¶
const ( ProvisionAppRole = "dexafix" // the api's role; owns the database ProvisionBodyRole = "dexafix_body" // the body service's role; owns the schema "body" only ProvisionDatabase = "dexafix" ProvisionBodySchema = "body" )
The names Provision creates. They are fixed: the connection strings that deploy init writes and the body service's search_path refer to them.
const ( DriverSQLite = "sqlite" DriverPostgres = "postgres" )
Supported database drivers.
const KeySize = 32
KeySize is the length of an encryption key in bytes (AES-256).
Variables ¶
This section is empty.
Functions ¶
func HasEncryptedBodyValues ¶
HasEncryptedBodyValues is HasEncryptedValues for a database that holds only the body domain.
func HasEncryptedValues ¶
HasEncryptedValues reports whether the database already holds encrypted values, without migrating it. A database that does not exist yet, or has no tables, holds none. The serve command uses it to avoid inventing a new key for data that depends on an old one.
func Provision ¶
func Provision(ctx context.Context, o ProvisionOptions) error
Provision makes the PostgreSQL roles, the database and the body schema the recommended deployment runs on, so that no service runs as a superuser and a leak of one cannot read the other's data:
dexafix owns the database, has no rights in the schema "body" dexafix_body owns the schema "body" and can use nothing else
It can be run again and again: what exists is kept and the passwords are set again, so a changed password file takes effect at the next run. It never drops anything.
func SequentialUserIDsForTests ¶
func SequentialUserIDsForTests()
SequentialUserIDsForTests makes new users get the ids 1, 2, 3... instead of random ones. Call it from TestMain of a test binary, never from production code: random ids are a defence.
func SetSequentialUserIDsForTests ¶
func SetSequentialUserIDsForTests(on bool)
SetSequentialUserIDsForTests turns the sequential ids of SequentialUserIDsForTests on or off, for the test that wants random ids in a binary that otherwise uses counted ones.
Types ¶
type BodyRekeyStats ¶
type BodyRekeyStats struct {
Changed int // rows re-encrypted
Current int // rows already under the current key
}
BodyRekeyStats counts what Rekey changed (or, in a dry run, would change) in the body data.
type BodyStore ¶
type BodyStore struct {
// contains filtered or unexported fields
}
BodyStore is the body domain: a user's scale readings and DEXA scans, and the counter of their changes. It has its own migrations (migrations/body, with a version table of its own), its own key check and a cipher of its own, so it can live in a database of its own, in the process of the body service. Inside a Store it shares the connection pool of the main database.
func OpenBody ¶
OpenBody opens a database that holds only the body domain, for the body service. The cipher option (WithCipher) is a master key: the body key derives from it, so a body process may share the key file of the main backend, or have one of its own. WithoutMigrate and RequireMigrated work as for Open.
func (*BodyStore) BodyUserIDs ¶
BodyUserIDs lists the users that have a scan, a reading or a counter.
func (*BodyStore) BodyVersion ¶
BodyVersion returns the number of changes to the user's scans and readings so far.
func (*BodyStore) Close ¶
Close closes the connection pool when this store opened it. Inside a Store it does nothing: the Store closes the pool.
func (*BodyStore) CreateDexaScan ¶
func (*BodyStore) DeleteDexaScan ¶
func (*BodyStore) DeleteScaleReading ¶
func (*BodyStore) DeleteScaleReadings ¶ added in v0.0.2
func (*BodyStore) DeleteUserBodyData ¶
DeleteUserBodyData removes the user's scans, readings and counter.
func (*BodyStore) HasEncryptedValues ¶
HasEncryptedValues reports whether the body data holds encrypted rows.
func (*BodyStore) HasPending ¶
HasPending reports whether the body domain has unapplied migrations.
func (*BodyStore) ListDexaScans ¶
func (*BodyStore) ListDexaScansPage ¶
func (*BodyStore) ListScaleReadings ¶
func (*BodyStore) ListScaleReadingsPage ¶
func (*BodyStore) Rekey ¶
Rekey re-encrypts every row with the current body key and writes the new check value, in one transaction: it completes or leaves the data untouched. Rows already under the current key are skipped, so a run can be repeated. With dryRun nothing is written.
func (*BodyStore) ScaleReadingsForReconcile ¶ added in v0.0.2
func (*BodyStore) SchemaVersion ¶
SchemaVersion is the applied migration version of the body domain (0 = none).
func (*BodyStore) UpsertScaleReadings ¶
type Cipher ¶
type Cipher struct {
// contains filtered or unexported fields
}
Cipher encrypts sensitive columns with AES-256-GCM. It seals with the current key and opens values made by the current key or by any previous one.
type CopyStats ¶
type CopyStats struct {
Users int
DexaScans int
ScaleReads int
Integrations int
Identities int
AccessTokens int
Settings int
Providers int
AuditEvents int
}
CopyStats reports how many rows Copy transferred per table.
type Option ¶
type Option func(*openConfig)
Option customises Open.
func RequireMigrated ¶
func RequireMigrated() Option
RequireMigrated fails Open when there are pending migrations instead of applying them.
func WithCipher ¶
WithCipher encrypts sensitive columns: provider secrets, integration tokens, server settings and e-mail addresses. Values stored before it was enabled are encrypted when the store opens.
func WithoutBody ¶
func WithoutBody() Option
WithoutBody opens the main database without the body domain (scans and readings): its tables are not created or migrated, and the BodyStore methods are not available. For a backend that calls a body service of its own.
func WithoutMigrate ¶
func WithoutMigrate() Option
WithoutMigrate opens the database without touching the schema (used by the db management commands).
type ProvisionOptions ¶
ProvisionOptions are what Provision needs. AdminDSN is a superuser's connection string (to any database, usually "postgres"); the two passwords are the ones the application roles get.
type RekeyStats ¶
type RekeyStats struct {
Emails int // user e-mail addresses re-encrypted
Integrations int
Settings int
Providers int
TOTP int // two-step verification secrets re-encrypted
Jobs int // queued or running worker jobs re-encrypted
Body int // scale readings and DEXA scans re-encrypted
Lookups int // e-mail lookup hashes recomputed
Current int // encrypted values already under the current key
}
RekeyStats counts what Rekey changed (or, in a dry run, would change). Current counts values that were already sealed with the current key and are left alone.
func (RekeyStats) Changed ¶
func (r RekeyStats) Changed() int
Changed is the number of values that were or would be rewritten.
type Store ¶
type Store struct {
// BodyStore is the body domain (scans and readings) on the same connection pool, or nil when
// the store was opened WithoutBody: then another process holds that data. Its methods are
// promoted, so a combined process and the tests use one value for both domains; the main
// backend only sees the store.Store interface, which does not have them.
*BodyStore
// contains filtered or unexported fields
}
Store is a bun backed store.Store.
func (*Store) AddAuditEvent ¶
func (*Store) AddPasskey ¶
AddPasskey stores a new credential. A credential id belongs to one user: a second registration of the same authenticator credential fails with ErrExists.
func (*Store) CancelJob ¶
func (s *Store) CancelJob(ctx context.Context, publicID string, userID int64, at time.Time) (models.Job, error)
CancelJob cancels a queued job at once and asks the worker of a running one to stop. userID limits it to that user's jobs (0: any). A job that already ended is returned as it is.
func (*Store) CancelJobs ¶
CancelJobs cancels the active jobs of a user and kinds (for example when a login is removed).
func (*Store) CompleteJob ¶
func (s *Store) CompleteJob(ctx context.Context, publicID, tokenHash string, c models.Completion, at time.Time) (models.Job, error)
CompleteJob ends the attempt as the worker reports it. An OutcomeRetry requeues the job for c.RetryAt unless it ran out of attempts (it then fails for good) or was canceled. It fails with ErrLeaseLost when the job is no longer running under this token, which also makes a second completion of the same attempt harmless.
func (*Store) CompletePasswordReset ¶
func (s *Store) CompletePasswordReset(ctx context.Context, tokenHash, passwordHash string) (int64, error)
CompletePasswordReset uses a live link: in one transaction it deletes the user's links, sets the password and signs the user out everywhere (sessions and access tokens), so a link can be used once and a changed password never leaves old sessions alive. It returns the user id, or ErrNotFound when the link is unknown or expired.
func (*Store) ConfirmTOTP ¶
ConfirmTOTP turns a pending setup into a confirmed one. step is the code step the user proved the secret with; it becomes the replay guard. It fails with ErrNotFound without a pending setup.
func (*Store) CountFailures ¶
func (*Store) CountRecoveryCodes ¶
CountRecoveryCodes is the number of recovery codes the user has left.
func (*Store) CreateAccessToken ¶
func (*Store) CreatePasswordReset ¶
func (s *Store) CreatePasswordReset(ctx context.Context, tokenHash string, userID int64, createdBy *int64, expires time.Time) error
CreatePasswordReset stores a reset link for the user. A user has at most one live link: the others, and every expired link, are removed first. createdBy is the administrator who made it, nil when the user asked for it.
func (*Store) CreateSession ¶
func (*Store) CreateUser ¶
func (*Store) CreateUserWithIdentity ¶
func (s *Store) CreateUserWithIdentity(ctx context.Context, username, email string, id models.Identity) (models.User, error)
CreateUserWithIdentity creates a user together with a way to sign in.
func (*Store) DeleteAccessToken ¶
func (*Store) DeleteAuthProvider ¶
func (*Store) DeleteIdentity ¶
func (*Store) DeleteIntegration ¶
func (*Store) DeleteJobSchedule ¶
DeleteJobSchedule forgets a schedule, which also resumes one that was paused.
func (*Store) DeletePasskey ¶
func (*Store) DeletePasswordResets ¶
DeletePasswordResets removes the user's outstanding reset links, for example after the password or the e-mail address changed.
func (*Store) DeleteSession ¶
func (*Store) DeleteTOTP ¶
DeleteTOTP removes the setup and the recovery codes. It succeeds when there is none.
func (*Store) DeleteUser ¶
DeleteUser removes the user and, with them, the IP addresses in the audit events about them. The events themselves stay, without a reference to the person (ON DELETE SET NULL).
func (*Store) DeleteUserAccessTokens ¶
func (*Store) DeleteUserSessions ¶
func (*Store) EnqueueJob ¶
EnqueueJob queues a job. When the job has a DedupeKey and one with that key is already queued or running, nothing is added and that job is returned with created false.
func (*Store) EnsurePasskeyHandle ¶
EnsurePasskeyHandle returns the random user handle that identifies the user to their passkeys, creating it the first time. It is 64 random bytes and says nothing about the person.
func (*Store) ExecForTests ¶
ExecForTests runs one statement for a test that has to break the database on purpose, such as renaming a table so that every query on it fails. Never call it from production code.
func (*Store) ExpireQueuedJobs ¶
ExpireQueuedJobs ends queued jobs that were not started before their expiry.
func (*Store) GetAuthProvider ¶
func (*Store) GetIdentity ¶
func (*Store) GetIntegration ¶
func (*Store) GetJobSchedule ¶
func (s *Store) GetJobSchedule(ctx context.Context, userID int64, kind string) (models.JobSchedule, error)
GetJobSchedule returns what the scheduler remembers about a user and kind, or ErrNotFound.
func (*Store) GetSession ¶
func (*Store) GetSetting ¶
func (*Store) GetTOTP ¶
GetTOTP returns the user's one-time password setup, confirmed or not, or ErrNotFound.
func (*Store) GetUserByEmail ¶
func (*Store) HasPending ¶
HasPending reports whether there are unapplied migrations, in the main database or the body domain.
func (*Store) HeartbeatJob ¶
func (s *Store) HeartbeatJob(ctx context.Context, publicID, tokenHash string, extend time.Duration, progress *string, at time.Time) (cancel bool, err error)
HeartbeatJob extends the lease of a running job and stores its progress (nil leaves it). It fails with ErrLeaseLost when the token is not the leaseholder's, or the lease or the job's hard deadline has passed: the job then belongs to the reaper. cancel tells the worker to stop.
func (*Store) IdentityProviders ¶
func (*Store) JobStats ¶
JobStats counts the jobs of every kind that are waiting or running, and those that failed since a time.
func (*Store) LastFinishedStates ¶
func (s *Store) LastFinishedStates(ctx context.Context, kind string, n int, since time.Time) ([]string, error)
LastFinishedStates returns the states of the latest n jobs of a kind that succeeded or failed since a time, newest first. The backend watches it to notice that a provider keeps failing.
func (*Store) LeaseJob ¶
func (s *Store) LeaseJob(ctx context.Context, req models.LeaseRequest, at time.Time) (models.Job, bool, error)
LeaseJob hands the best waiting job to a worker, or reports that there is none. The order is: administrators' jobs first, then the user's priority (higher first), then jobs somebody waits for, then the oldest. Role and priority are read now, so a change applies to jobs already queued. MaxRunning is checked when leasing, so it can be exceeded by the number of leases that happen at the very same moment; the lease itself is exact.
func (*Store) ListAccessTokens ¶
func (*Store) ListAuditEvents ¶
func (s *Store) ListAuditEvents(ctx context.Context, f store.AuditFilter) ([]models.AuditEvent, error)
func (*Store) ListAuthProviders ¶
func (*Store) ListJobSchedules ¶
func (*Store) ListPasskeys ¶
func (*Store) ListUserIdentities ¶
func (*Store) ListUsersWithIntegration ¶
ListUsersWithIntegration returns the ids of users who have stored data for a provider.
func (*Store) ListWorkers ¶
ListWorkers returns the workers seen since a time, newest first.
func (*Store) MaxConns ¶
MaxConns is the size of the connection pool. A server uses it to keep one class of requests from taking every connection.
func (*Store) Migrate ¶
Migrate applies all pending migrations: the main database's, then the body domain's when this store has one (they have separate migration sets and version tables).
func (*Store) MigrateDown ¶
MigrateDown rolls back the most recently applied migration.
func (*Store) MigrateTo ¶
MigrateTo migrates up or down until the database is at the given version (0 = empty).
func (*Store) MigrationStatus ¶
MigrationStatus lists every known migration and whether it has been applied.
func (*Store) PasswordResetUser ¶
PasswordResetUser returns the user a live reset link belongs to, or ErrNotFound.
func (*Store) Ping ¶
Ping checks that the database answers. It is defined here and not promoted from the BodyStore, which is nil in a store opened WithoutBody.
func (*Store) PurgeAuditEvents ¶
func (*Store) PurgeFailures ¶
func (*Store) PurgeNonces ¶
func (*Store) PurgeWorkers ¶
PurgeWorkers forgets workers not seen since the cutoff.
func (*Store) PutAuthProvider ¶
func (*Store) PutIdentity ¶
func (*Store) PutIntegration ¶
func (*Store) PutJobSchedule ¶
func (*Store) PutPendingTOTP ¶
PutPendingTOTP starts (or restarts) the setup with a new secret. The setup counts only after ConfirmTOTP, and starting again discards an earlier, unconfirmed secret. A confirmed setup is never replaced: it fails with ErrExists.
func (*Store) PutSetting ¶
func (*Store) ReapExpiredLeases ¶
func (s *Store) ReapExpiredLeases(ctx context.Context, at time.Time, backoff func(models.Job) time.Duration) ([]models.Job, error)
ReapExpiredLeases deals with running jobs whose lease or hard deadline has passed, because the worker died, hung or lost the network: each such attempt counts as failed, and the job is requeued after backoff(job) or, when it has no attempts left, ended. It returns the jobs it changed.
func (*Store) RecordFailure ¶
func (*Store) Rekey ¶
Rekey re-encrypts every encrypted value with the current key, recomputes the e-mail lookup hashes (they derive from the key) and writes the new key check value, all in one transaction: it completes or leaves the database untouched. Values already sealed with the current key are skipped, so a run can be repeated. Any value that no configured key can open fails the whole run. With dryRun nothing is written and the result reports what would change.
func (*Store) ReleaseJob ¶
ReleaseJob gives a job back without counting the attempt, for a worker that is shutting down.
func (*Store) RenamePasskey ¶
func (*Store) ReplaceRecoveryCodes ¶
ReplaceRecoveryCodes stores the hashes of a new set of recovery codes and drops the old set.
func (*Store) RunningJob ¶
RunningJob returns a job that is running under this lease token, or ErrLeaseLost. It changes nothing; the backend uses it to find out whose call it is serving.
func (*Store) SchemaVersion ¶
SchemaVersion returns the currently applied migration version (0 = none).
func (*Store) SetUserJobPriority ¶
SetUserJobPriority sets the priority (1-100) that orders a user's jobs among other users'.
func (*Store) SetUserRole ¶
func (*Store) SetUserStrengthLevelAuto ¶
SetUserStrengthLevelAuto allows or forbids automatic Strength Level sync for a user. Forbidding it deletes the stored login in the same transaction.
func (*Store) SetUserStrengthLevelBulk ¶
SetUserStrengthLevelBulk allows or forbids the multi-day sync for a user who may sync.
func (*Store) SettingsGeneration ¶
SettingsGeneration returns a number that grows whenever a setting is written or deleted.
func (*Store) TouchWorker ¶
func (s *Store) TouchWorker(ctx context.Context, id string, kinds []string, version string, at time.Time) error
TouchWorker records that a worker process asked for work.
func (*Store) TwoFactorUsers ¶
TwoFactorUsers returns the ids of the users who have confirmed two-step verification.
func (*Store) UpdatePasskeyUse ¶
func (s *Store) UpdatePasskeyUse(ctx context.Context, credentialID, credential string, signCount uint32) error
UpdatePasskeyUse records a sign-in: the new counter, the refreshed credential JSON (flags such as backup state can change) and the time.
func (*Store) UpdateUserHiddenColumns ¶
UpdateUserHiddenColumns stores which daily table columns the user has hidden.
func (*Store) UpdateUserProfile ¶
func (*Store) UpdateUserSettings ¶
func (s *Store) UpdateUserSettings(ctx context.Context, userID int64, athleteDefault bool, ranking []string) error
UpdateUserSettings stores the athlete-mode default and the method accuracy ranking.
func (*Store) UpdateUserTimezone ¶
func (*Store) UseNonce ¶
UseNonce claims nonce until expires. The insert only succeeds, or takes over an expired row, when nobody holds it, so two processes racing for the same value cannot both win.
func (*Store) UseRecoveryCode ¶
UseRecoveryCode deletes the code with this hash and reports whether the user had it.
func (*Store) UseTOTPStep ¶
UseTOTPStep records step as used and reports whether it was fresh. It is one conditional update, so of two requests presenting the same code only one wins.