textmachine/platform/internal/pgstore/identity.sql.go

334 lines
8.2 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: identity.sql
package pgstore
import (
"context"
"time"
)
const createIdentity = `-- name: CreateIdentity :execrows
insert into identities (provider, subject, user_id, email, email_verified, created_at, last_login_at)
values ($1, $2, $3, $4,
$5, $6, $6)
on conflict (provider, subject) do nothing
`
type CreateIdentityParams struct {
Provider string
Subject string
UserID string
Email *string
EmailVerified bool
Now time.Time
}
// `do nothing` rather than a bare insert: two first logins of one brand-new identity can race, and
// the loser must see the row the winner inserted rather than a unique violation.
func (q *Queries) CreateIdentity(ctx context.Context, arg CreateIdentityParams) (int64, error) {
result, err := q.db.Exec(ctx, createIdentity,
arg.Provider,
arg.Subject,
arg.UserID,
arg.Email,
arg.EmailVerified,
arg.Now,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const createUser = `-- name: CreateUser :exec
insert into users (id, email, created_at)
values ($1, $2, $3)
`
type CreateUserParams struct {
ID string
Email *string
CreatedAt time.Time
}
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error {
_, err := q.db.Exec(ctx, createUser, arg.ID, arg.Email, arg.CreatedAt)
return err
}
const deleteExpiredLoginStates = `-- name: DeleteExpiredLoginStates :execrows
delete from auth_states where expires_at <= $1
`
func (q *Queries) DeleteExpiredLoginStates(ctx context.Context, now time.Time) (int64, error) {
result, err := q.db.Exec(ctx, deleteExpiredLoginStates, now)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const deleteOldLoginEvents = `-- name: DeleteOldLoginEvents :execrows
delete from login_events where at < $1
`
// /auth/callback writes a row on every refusal and needs no credential to do it, so a journal that
// only grows is a liability rather than an audit.
func (q *Queries) DeleteOldLoginEvents(ctx context.Context, before time.Time) (int64, error) {
result, err := q.db.Exec(ctx, deleteOldLoginEvents, before)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const lockIdentity = `-- name: LockIdentity :one
select user_id from identities
where provider = $1 and subject = $2 for update
`
type LockIdentityParams struct {
Provider string
Subject string
}
func (q *Queries) LockIdentity(ctx context.Context, arg LockIdentityParams) (string, error) {
row := q.db.QueryRow(ctx, lockIdentity, arg.Provider, arg.Subject)
var user_id string
err := row.Scan(&user_id)
return user_id, err
}
const putLoginState = `-- name: PutLoginState :exec
insert into auth_states (state_sha256, provider, issuer, nonce, code_verifier, return_to, start_id, created_at, expires_at)
values ($1, $2, $3, $4,
$5, $6, $7, $8,
$9)
`
type PutLoginStateParams struct {
StateSha256 []byte
Provider string
Issuer string
Nonce string
CodeVerifier string
ReturnTo string
StartID string
CreatedAt time.Time
ExpiresAt time.Time
}
// Identity, login states and the login journal.
func (q *Queries) PutLoginState(ctx context.Context, arg PutLoginStateParams) error {
_, err := q.db.Exec(ctx, putLoginState,
arg.StateSha256,
arg.Provider,
arg.Issuer,
arg.Nonce,
arg.CodeVerifier,
arg.ReturnTo,
arg.StartID,
arg.CreatedAt,
arg.ExpiresAt,
)
return err
}
const recentLogins = `-- name: RecentLogins :many
select provider, outcome, reason, ip_prefix, client, at
from login_events where user_id = $1::text order by at desc limit $2::bigint
`
type RecentLoginsParams struct {
UserID string
Lim int64
}
type RecentLoginsRow struct {
Provider string
Outcome string
Reason string
IpPrefix string
Client string
At time.Time
}
func (q *Queries) RecentLogins(ctx context.Context, arg RecentLoginsParams) ([]RecentLoginsRow, error) {
rows, err := q.db.Query(ctx, recentLogins, arg.UserID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
var items []RecentLoginsRow
for rows.Next() {
var i RecentLoginsRow
if err := rows.Scan(
&i.Provider,
&i.Outcome,
&i.Reason,
&i.IpPrefix,
&i.Client,
&i.At,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const recordLogin = `-- name: RecordLogin :exec
insert into login_events (user_id, provider, outcome, reason, ip_prefix, client, at)
values ($1, $2, $3, $4,
$5, $6, $7)
`
type RecordLoginParams struct {
UserID *string
Provider string
Outcome string
Reason string
IpPrefix string
Client string
At time.Time
}
func (q *Queries) RecordLogin(ctx context.Context, arg RecordLoginParams) error {
_, err := q.db.Exec(ctx, recordLogin,
arg.UserID,
arg.Provider,
arg.Outcome,
arg.Reason,
arg.IpPrefix,
arg.Client,
arg.At,
)
return err
}
const refreshAccountEmail = `-- name: RefreshAccountEmail :exec
update users set email = $1::text where id = $2
`
type RefreshAccountEmailParams struct {
Email string
ID string
}
// The cast keeps the parameter non-null: users.email IS nullable, but this path is reached only for
// a VERIFIED, non-empty address, and a *string here would invite a nil the branch cannot produce.
func (q *Queries) RefreshAccountEmail(ctx context.Context, arg RefreshAccountEmailParams) error {
_, err := q.db.Exec(ctx, refreshAccountEmail, arg.Email, arg.ID)
return err
}
const refreshIdentity = `-- name: RefreshIdentity :exec
update identities set email = $1, email_verified = $2,
last_login_at = $3
where provider = $4 and subject = $5
`
type RefreshIdentityParams struct {
Email *string
EmailVerified bool
Now time.Time
Provider string
Subject string
}
// The address is refreshed only when the provider says it is verified — an unverified one is kept
// on the identity and never promoted to the account.
func (q *Queries) RefreshIdentity(ctx context.Context, arg RefreshIdentityParams) error {
_, err := q.db.Exec(ctx, refreshIdentity,
arg.Email,
arg.EmailVerified,
arg.Now,
arg.Provider,
arg.Subject,
)
return err
}
const revokeUserSessions = `-- name: RevokeUserSessions :execrows
update sessions set revoked_at = $1::timestamptz
where user_id = $2 and revoked_at is null
`
type RevokeUserSessionsParams struct {
Now time.Time
UserID string
}
func (q *Queries) RevokeUserSessions(ctx context.Context, arg RevokeUserSessionsParams) (int64, error) {
result, err := q.db.Exec(ctx, revokeUserSessions, arg.Now, arg.UserID)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const takeLoginState = `-- name: TakeLoginState :one
delete from auth_states
where state_sha256 = $1 and expires_at > $2
returning provider, issuer, nonce, code_verifier, return_to, start_id, created_at, expires_at
`
type TakeLoginStateParams struct {
StateSha256 []byte
Now time.Time
}
type TakeLoginStateRow struct {
Provider string
Issuer string
Nonce string
CodeVerifier string
ReturnTo string
StartID string
CreatedAt time.Time
ExpiresAt time.Time
}
// Deleting and returning in ONE statement is what makes it single-use under concurrency: a second
// callback with the same state deletes nothing and gets nothing, with no window between the check
// and the removal.
func (q *Queries) TakeLoginState(ctx context.Context, arg TakeLoginStateParams) (TakeLoginStateRow, error) {
row := q.db.QueryRow(ctx, takeLoginState, arg.StateSha256, arg.Now)
var i TakeLoginStateRow
err := row.Scan(
&i.Provider,
&i.Issuer,
&i.Nonce,
&i.CodeVerifier,
&i.ReturnTo,
&i.StartID,
&i.CreatedAt,
&i.ExpiresAt,
)
return i, err
}
const userByIdentity = `-- name: UserByIdentity :one
select user_id from identities
where provider = $1 and subject = $2
`
type UserByIdentityParams struct {
Provider string
Subject string
}
// Resolves a provider's subject to the account it belongs to, WITHOUT creating one.
func (q *Queries) UserByIdentity(ctx context.Context, arg UserByIdentityParams) (string, error) {
row := q.db.QueryRow(ctx, userByIdentity, arg.Provider, arg.Subject)
var user_id string
err := row.Scan(&user_id)
return user_id, err
}