diff --git a/keyserver/src/database/migration-config.js b/keyserver/src/database/migration-config.js --- a/keyserver/src/database/migration-config.js +++ b/keyserver/src/database/migration-config.js @@ -23,6 +23,7 @@ createPickledOlmAccount, publishPrekeysToIdentity, } from '../utils/olm-utils.js'; +import type { PickledOlmAccount } from '../utils/olm-utils.js'; import { synchronizeInviteLinksWithBlobs } from '../utils/synchronize-invite-links-with-blobs.js'; const botViewer = createScriptViewer(bots.commbot.userID); @@ -844,6 +845,13 @@ const [pickledContentAccount, pickledNotificationsAccount] = await Promise.all([createPickledOlmAccount(), createPickledOlmAccount()]); + await saveNewOlmAccounts(pickledContentAccount, pickledNotificationsAccount); +} + +async function saveNewOlmAccounts( + pickledContentAccount: PickledOlmAccount, + pickledNotificationsAccount: PickledOlmAccount, +) { await dbQuery( SQL` INSERT INTO olm_accounts (is_content, version, @@ -869,4 +877,9 @@ return !!process.env.COMM_DATABASE_HOST; } -export { migrations, newDatabaseVersion, createOlmAccounts }; +export { + migrations, + newDatabaseVersion, + createOlmAccounts, + saveNewOlmAccounts, +}; diff --git a/keyserver/src/database/setup-db.js b/keyserver/src/database/setup-db.js --- a/keyserver/src/database/setup-db.js +++ b/keyserver/src/database/setup-db.js @@ -12,18 +12,30 @@ import { updateDBVersion } from '../database/db-version.js'; import { newDatabaseVersion, - createOlmAccounts, + saveNewOlmAccounts, } from '../database/migration-config.js'; import { createScriptViewer } from '../session/scripts.js'; import { ensureUserCredentials } from '../user/checks.js'; -import { thisKeyserverAdmin } from '../user/identity.js'; -import { verifyUserLoggedIn } from '../user/login.js'; +import { thisKeyserverAdmin, saveIdentityInfo } from '../user/identity.js'; +import { verifyUserLoggedInWithoutDB } from '../user/login.js'; +import { createPickledOlmAccount } from '../utils/olm-utils.js'; async function setupDB() { + const [pickledContentAccount, pickledNotificationsAccount] = + await Promise.all([createPickledOlmAccount(), createPickledOlmAccount()]); + + const { + identityInfo, + pickledContentAccount: contentAccount, + pickledNotificationsAccount: notificationsAccount, + } = await verifyUserLoggedInWithoutDB( + pickledContentAccount, + pickledNotificationsAccount, + ); await ensureUserCredentials(); await createTables(); - await createOlmAccounts(); - await verifyUserLoggedIn(); + await saveNewOlmAccounts(contentAccount, notificationsAccount); + await saveIdentityInfo(identityInfo); await createUsers(); await createThreads(); await setUpMetadataTable(); diff --git a/keyserver/src/user/login.js b/keyserver/src/user/login.js --- a/keyserver/src/user/login.js +++ b/keyserver/src/user/login.js @@ -19,6 +19,8 @@ } from './identity.js'; import { getMessageForException } from '../responders/utils.js'; import { fetchCallUpdateOlmAccount } from '../updaters/olm-account-updater.js'; +import { unpickleOlmAccount } from '../utils/olm-utils.js'; +import type { PickledOlmAccount } from '../utils/olm-utils.js'; // After register or login is successful function markKeysAsPublished(account: OlmAccount) { @@ -69,6 +71,62 @@ return identityInfo; } +async function unpickleAndUseCallback( + pickledOlmAccount: PickledOlmAccount, + callback: (account: OlmAccount, picklingKey: string) => Promise | T, +): Promise<{ result: T, pickledOlmAccount: PickledOlmAccount }> { + const { picklingKey, pickledAccount } = pickledOlmAccount; + + const account = await unpickleOlmAccount({ + picklingKey, + pickledAccount, + }); + let result; + try { + result = await callback(account, picklingKey); + } catch (e) { + throw new ServerError(getMessageForException(e) ?? 'unknown_error'); + } + const updatedAccount = account.pickle(picklingKey); + + return { + result, + pickledOlmAccount: { ...pickledOlmAccount, pickledAccount: updatedAccount }, + }; +} + +async function verifyUserLoggedInWithoutDB( + pickledContentAccount: PickledOlmAccount, + pickledNotificationsAccount: PickledOlmAccount, +): Promise<{ + identityInfo: IdentityInfo, + pickledContentAccount: PickledOlmAccount, + pickledNotificationsAccount: PickledOlmAccount, +}> { + const userInfo = await getUserCredentials(); + + const identityInfo = await registerOrLogInBase( + userInfo, + async callback => { + const { result, pickledOlmAccount } = await unpickleAndUseCallback( + pickledContentAccount, + callback, + ); + pickledContentAccount = pickledOlmAccount; + return result; + }, + async callback => { + const { result, pickledOlmAccount } = await unpickleAndUseCallback( + pickledNotificationsAccount, + callback, + ); + pickledNotificationsAccount = pickledOlmAccount; + return result; + }, + ); + return { identityInfo, pickledContentAccount, pickledNotificationsAccount }; +} + async function registerOrLogIn( userInfo: UserCredentials, ): Promise { @@ -197,4 +255,4 @@ } } -export { verifyUserLoggedIn }; +export { verifyUserLoggedIn, verifyUserLoggedInWithoutDB }; 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 @@ -25,7 +25,7 @@ } from '../updaters/olm-account-updater.js'; import { verifyUserLoggedIn } from '../user/login.js'; -type PickledOlmAccount = { +export type PickledOlmAccount = { +picklingKey: string, +pickledAccount: string, };