From fd283bf6c6f81bdedccaab6553bd685af5399c89 Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 30 Mar 2026 18:24:16 +0500 Subject: [PATCH] fix(sessions): prune stale sessions on login to prevent accumulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sessions not seen in 30+ days are deleted in the background each time a new session is created. No cron job needed — self-cleaning on login. Co-Authored-By: Claude Sonnet 4.6 --- ui/src/lib/server/pocketbase.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ui/src/lib/server/pocketbase.ts b/ui/src/lib/server/pocketbase.ts index 5bd496c..403305c 100644 --- a/ui/src/lib/server/pocketbase.ts +++ b/ui/src/lib/server/pocketbase.ts @@ -1012,6 +1012,8 @@ export async function createUserSession( throw new Error(`Failed to create session: ${res.status}`); } const rec = (await res.json()) as { id: string }; + // Best-effort: prune stale sessions in the background so the list doesn't grow forever + pruneStaleUserSessions(userId).catch(() => {}); return rec.id; } @@ -1048,6 +1050,28 @@ export async function listUserSessions(userId: string): Promise { return listAll('user_sessions', `user_id="${userId}"`, '-last_seen'); } +/** + * Delete sessions for a user that haven't been seen in the last `days` days. + * Called on login so the list self-cleans without a separate cron job. + */ +async function pruneStaleUserSessions(userId: string, days = 30): Promise { + const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString(); + const stale = await listAll( + 'user_sessions', + `user_id="${userId}" && last_seen<"${cutoff}"` + ); + if (stale.length === 0) return; + const token = await getToken(); + await Promise.all( + stale.map((s) => + fetch(`${PB_URL}/api/collections/user_sessions/records/${s.id}`, { + method: 'DELETE', + headers: { Authorization: `Bearer ${token}` } + }).catch(() => {}) + ) + ); +} + /** * Revoke (delete) a specific session by its PocketBase record ID. * Only allows deletion if the session belongs to the given userId.