admin: list accounts that have no active sessions

The Accounts tab (readStore.ListAccounts) inner-joined the authorizations
aggregate, so any account with zero authorization rows was silently hidden -
accounts that never finished login, had all sessions revoked, or were frozen
then unfrozen. CountAccounts and SearchAccounts already LEFT JOIN, so the count
and search disagreed with the list.

Switch ListAccounts to LEFT JOIN auth and COALESCE the null last_active_at /
device_count (sessionless accounts sort last), matching SearchAccounts.
This commit is contained in:
Astra 2026-09-09 14:56:10 +01:00
parent 2014c98386
commit 5a89a83caf
2 changed files with 46 additions and 5 deletions

View file

@ -872,19 +872,22 @@ WITH auth AS (
SELECT u.id, u.phone, u.username, u.first_name, u.last_name, u.created_at, u.updated_at,
COALESCE(r.frozen, false), COALESCE(r.reason, ''), u.verified, u.scam, u.fake,
COALESCE(EXTRACT(EPOCH FROM u.premium_expires_at), 0)::bigint,
COALESCE(auth.last_active_at, u.created_at), COALESCE(auth.device_count, 0),
COALESCE(auth.last_active_at, '0001-01-01 00:00:00+00'::timestamptz), COALESCE(auth.device_count, 0)::int,
COALESCE(NULLIF(u.username, ''), p.username_lower, '') AS display_username,
COALESCE(ap.login_email, ''),
`+accountCollectibleUsernamesColumn+` AS collectibles
FROM users u
-- LEFT JOIN, not JOIN: an account with no authorizations (never finished login,
-- all sessions revoked, frozen-then-unfrozen) must still appear here, matching
-- CountAccounts and SearchAccounts.
LEFT JOIN auth ON auth.user_id = u.id
LEFT JOIN account_restrictions r ON r.user_id = u.id
LEFT JOIN peer_usernames p ON p.peer_type = 'user' AND p.peer_id = u.id AND p.editable
LEFT JOIN account_passwords ap ON ap.user_id = u.id
WHERE NOT u.is_bot
AND NOT (u.id = ANY($4::bigint[]))
AND ($1::bigint = 0 OR (COALESCE(auth.last_active_at, u.created_at), u.id) < (to_timestamp(($1::double precision) / 1000000.0), $2::bigint))
ORDER BY COALESCE(auth.last_active_at, u.created_at) DESC, u.id DESC
AND ($1::bigint = 0 OR (COALESCE(auth.last_active_at, '0001-01-01 00:00:00+00'::timestamptz), u.id) < (to_timestamp(($1::double precision) / 1000000.0), $2::bigint))
ORDER BY COALESCE(auth.last_active_at, '0001-01-01 00:00:00+00'::timestamptz) DESC, u.id DESC
LIMIT $3`, beforeActiveUS, beforeID, limit+1, domain.SystemUserIDs())
if err != nil {
return nil, false, fmt.Errorf("list accounts: %w", err)