Rewrites the internal/db/queries comments to rule 32 and regenerates dbq, whose doc comments and embedded SQL carry them. The bugs behind the tiered mixes, the md5 order seed, the score bands and the round-robin arms are restated as the constraint each one enforces; counts from one library and stale cross-references are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.7 KiB
SQL
61 lines
2.7 KiB
SQL
-- name: InsertSession :one
|
|
-- created_ip and last_ip start equal: at issue time the origin IS the current
|
|
-- location. They diverge as the session is used from elsewhere, which is what
|
|
-- makes a stolen token visible in the active-sessions surface.
|
|
INSERT INTO sessions (user_id, token_hash, user_agent, created_ip, last_ip)
|
|
VALUES ($1, $2, $3, sqlc.arg(ip), sqlc.arg(ip))
|
|
RETURNING *;
|
|
|
|
-- name: GetSessionByTokenHash :one
|
|
-- Expired sessions are invisible here, so they fail auth the moment they
|
|
-- lapse rather than whenever the GC sweep next runs. Two limits:
|
|
-- idle 30 days — a token nobody has used in a month is abandoned, and
|
|
-- matches the web cookie's lifetime;
|
|
-- absolute 1 year — even a token in daily use is re-issued yearly, so a
|
|
-- stolen one that is being used quietly does not live
|
|
-- forever.
|
|
-- Keep in step with ListSessionsForUser and GcDeleteExpiredSessions.
|
|
SELECT * FROM sessions
|
|
WHERE token_hash = $1
|
|
AND last_seen_at > now() - interval '30 days'
|
|
AND created_at > now() - interval '365 days';
|
|
|
|
-- name: TouchSessionLastSeen :exec
|
|
UPDATE sessions SET last_seen_at = now(), last_ip = $2 WHERE id = $1;
|
|
|
|
-- name: ListSessionsForUser :many
|
|
-- Most-recently-active first: the row a user is most likely to act on is the
|
|
-- one that moved last, and an unfamiliar entry at the top is the alarm.
|
|
-- Expired rows are left out: they no longer authenticate, so listing them
|
|
-- as active would be wrong. Same limits as GetSessionByTokenHash.
|
|
SELECT * FROM sessions
|
|
WHERE user_id = $1
|
|
AND last_seen_at > now() - interval '30 days'
|
|
AND created_at > now() - interval '365 days'
|
|
ORDER BY last_seen_at DESC;
|
|
|
|
-- name: DeleteSession :exec
|
|
DELETE FROM sessions WHERE id = $1;
|
|
|
|
-- name: DeleteSessionByTokenHash :exec
|
|
DELETE FROM sessions WHERE token_hash = $1;
|
|
|
|
-- name: DeleteSessionForUser :execrows
|
|
-- Scoped by user_id, not just id: household data is per-user. Keyed on the
|
|
-- id alone, any
|
|
-- household member could revoke another member's session by guessing a uuid.
|
|
-- execrows lets the handler answer 404 rather than a false 204 when the row
|
|
-- isn't theirs.
|
|
DELETE FROM sessions WHERE id = $1 AND user_id = $2;
|
|
|
|
-- name: DeleteOtherSessionsForUser :execrows
|
|
-- "Log out everywhere else." Excludes the caller's own session so the action
|
|
-- doesn't log them out of the page they just used to invoke it.
|
|
DELETE FROM sessions WHERE user_id = $1 AND id <> $2;
|
|
|
|
-- name: DeleteSessionsForUser :execrows
|
|
-- Every session the user has, the caller's included. A password reset uses
|
|
-- it: whoever forgot the password is not signed in anywhere they trust, and
|
|
-- whoever may have learned it must be signed out everywhere.
|
|
DELETE FROM sessions WHERE user_id = $1;
|