// 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 }