import { env } from "@homarr/auth/env"; import { NEVER } from "@homarr/cron-jobs-core/expressions"; import { db, eq, inArray } from "@homarr/db"; import { sessions, users } from "@homarr/db/schema"; import { supportedAuthProviders } from "@homarr/definitions"; import { logger } from "@homarr/log"; import { createCronJob } from "../lib"; /** * Deletes sessions for users that have inactive auth providers. * Sessions from other providers are deleted so they can no longer be used. */ export const sessionCleanupJob = createCronJob("sessionCleanup", NEVER, { runOnStart: true, }).withCallback(async () => { const currentAuthProviders = env.AUTH_PROVIDERS; const inactiveAuthProviders = supportedAuthProviders.filter((provider) => !currentAuthProviders.includes(provider)); const subQuery = db .select({ id: users.id }) .from(users) .where(inArray(users.provider, inactiveAuthProviders)) .as("sq"); const sessionsWithInactiveProviders = await db .select({ userId: sessions.userId }) .from(sessions) .rightJoin(subQuery, eq(sessions.userId, subQuery.id)); const userIds = sessionsWithInactiveProviders.map(({ userId }) => userId).filter((value) => value !== null); await db.delete(sessions).where(inArray(sessions.userId, userIds)); if (sessionsWithInactiveProviders.length > 0) { logger.info(`Deleted sessions for inactive providers count=${userIds.length}`); } else { logger.debug("No sessions to delete"); } });