diff --git a/keyserver/src/cron/cron.js b/keyserver/src/cron/cron.js --- a/keyserver/src/cron/cron.js +++ b/keyserver/src/cron/cron.js @@ -23,6 +23,9 @@ import { deleteInaccessibleThreads } from '../deleters/thread-deleters.js'; import { deleteExpiredUpdates } from '../deleters/update-deleters.js'; import { deleteUnassignedUploads } from '../deleters/upload-deleters.js'; +import { fetchKeyserverOlmAccount } from '../fetchers/olm-account-fetcher.js'; +import { updateOlmAccount } from '../updaters/olm-account-updater.js'; +import { validateAccountPrekey } from '../utils/olm-utils.js'; if (cluster.isMaster) { schedule.scheduleJob( @@ -90,4 +93,38 @@ } }, ); + + schedule.scheduleJob( + '0 0 * * *', // every day at midnight in the keyserver's timezone + async () => { + try { + const [ + { picklingKey: primaryPicklingKey, account: primaryAccount }, + { + picklingKey: notificationsPicklingKey, + account: notificationsAccount, + }, + ] = await Promise.all([ + fetchKeyserverOlmAccount('primary'), + fetchKeyserverOlmAccount('notifications'), + ]); + + await Promise.all([ + validateAccountPrekey(primaryAccount), + validateAccountPrekey(notificationsAccount), + ]); + + await Promise.all([ + updateOlmAccount(primaryAccount, primaryPicklingKey, true), + updateOlmAccount( + notificationsAccount, + notificationsPicklingKey, + false, + ), + ]); + } catch (e) { + console.warn('encountered error while trying to validate prekeys', e); + } + }, + ); } diff --git a/keyserver/src/utils/olm-utils.js b/keyserver/src/utils/olm-utils.js --- a/keyserver/src/utils/olm-utils.js +++ b/keyserver/src/utils/olm-utils.js @@ -48,4 +48,36 @@ return cachedOLMUtility; } -export { createPickledOlmAccount, getOlmUtility, unpicklePickledOlmAccount }; +async function validateAccountPrekey(account: OlmAccount): Promise { + const prekey = JSON.parse(account.prekey()); + + const hasPrekey = Object.keys(prekey.curve25519).length !== 0; + const prekeyPublished = account.last_prekey_publish_time() !== 0; + + const currentDate = new Date(); + const lastPrekeyPublishDate = new Date(account.last_prekey_publish_time()); + + if ( + !hasPrekey || + (prekeyPublished && + currentDate.getMonth() - lastPrekeyPublishDate.getMonth() > 0) + ) { + // If there is no prekey or the current prekey is older than month + // we need to generate new one. + account.generate_prekey(); + } + + if ( + prekeyPublished && + (currentDate - lastPrekeyPublishDate) / 3600000 >= 24 + ) { + account.forget_old_prekey(); + } +} + +export { + createPickledOlmAccount, + getOlmUtility, + unpicklePickledOlmAccount, + validateAccountPrekey, +};