-- 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 (rule #47). 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;