From b7b738c92b22658dc151bcb0e33925b0bc55ce8d Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Wed, 5 Mar 2025 11:29:13 +0100 Subject: [PATCH] Add cron job to cleanup exired oidc objects --- src/cron.js | 8 ++++++++ src/oidc.js | 24 ++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/cron.js b/src/cron.js index a6375eed9..2d264b90c 100644 --- a/src/cron.js +++ b/src/cron.js @@ -36,6 +36,7 @@ const appHealthMonitor = require('./apphealthmonitor.js'), janitor = require('./janitor.js'), mail = require('./mail.js'), network = require('./network.js'), + oidc = require('./oidc.js'), paths = require('./paths.js'), reverseProxy = require('./reverseproxy.js'), safe = require('safetydance'), @@ -56,6 +57,7 @@ const gJobs = { cleanupBackups: null, cleanupEventlog: null, cleanupTokens: null, + cleanupOidc: null, dockerVolumeCleaner: null, dynamicDns: null, schedulerSync: null, @@ -138,6 +140,12 @@ async function startJobs() { start: true }); + gJobs.cleanupOidc = CronJob.from({ + cronTime: '00 10 * * * *', // every hour ten minutes past + onTick: async () => await safe(oidc.cleanupExpired(), { debug }), + start: true + }); + gJobs.cleanupBackups = CronJob.from({ cronTime: DEFAULT_CLEANUP_BACKUPS_PATTERN, onTick: async () => await safe(backups.startCleanupTask(AuditSource.CRON), { debug }), diff --git a/src/oidc.js b/src/oidc.js index 7b8e62d5b..c18a01187 100644 --- a/src/oidc.js +++ b/src/oidc.js @@ -11,7 +11,9 @@ exports = module.exports = { getClient, delClient, updateClient, - listClients + listClients, + + cleanupExpired, }; const assert = require('assert'), @@ -217,6 +219,22 @@ async function getUserByAuthCode(authCode) { return await users.get(authData.payload.accountId); } +// This exposed to run on a cron job +async function cleanupExpired() { + debug('cleanupExpired'); + + const types = [ 'AuthorizationCode', 'AccessToken', 'Grant', 'Interaction', 'RefreshToken', 'Session' ]; + for (const type of types) { + load(type); + + for (const key in DATA_STORE[type]) { + if (!DATA_STORE[type][key].expiresAt || DATA_STORE[type][key].expiresAt < Date.now()) delete DATA_STORE[type][key]; + } + + save(type); + } +} + // ----------------------------- // Generic oidc node module data store model // ----------------------------- @@ -259,6 +277,8 @@ class CloudronAdapter { async upsert(id, payload, expiresIn) { debug(`[${this.name}] upsert: ${id}`); + const expiresAt = expiresIn ? new Date(Date.now() + (expiresIn * 1000)) : 0; + if (this.name === 'Client') { debug('upsert: this should not happen as it is stored in our db'); } else if (this.name === 'AccessToken' && (payload.clientId === tokens.ID_WEBADMIN || payload.clientId === tokens.ID_DEVELOPMENT)) { @@ -273,7 +293,7 @@ class CloudronAdapter { throw error; } } else { - DATA_STORE[this.name][id] = { id, expiresIn, payload, consumed: false }; + DATA_STORE[this.name][id] = { id, expiresAt, payload, consumed: false }; save(this.name); } }