Page MenuHomePhabricator

D7797.id26405.diff
No OneTemporary

D7797.id26405.diff

diff --git a/keyserver/src/updaters/olm-session-updater.js b/keyserver/src/updaters/olm-session-updater.js
new file mode 100644
--- /dev/null
+++ b/keyserver/src/updaters/olm-session-updater.js
@@ -0,0 +1,83 @@
+// @flow
+import type { EncryptResult } from '@commapp/olm';
+
+import { ServerError } from 'lib/utils/errors.js';
+import sleep from 'lib/utils/sleep.js';
+
+import { fetchOlmAccount } from './olm-account-updater.js';
+import { SQL, dbQuery } from '../database/database.js';
+import { unpickleOlmSession } from '../utils/olm-utils.js';
+
+const maxOlmSessionUpdateRetriesCount = 5;
+const olmSessionUpdateRetryDelay = 100;
+
+async function encryptAndUpdateOlmSession(
+ cookieID: string,
+ olmSessionType: 'content' | 'notifications',
+ messagesToEncrypt: $ReadOnlyArray<string>,
+): Promise<$ReadOnlyArray<EncryptResult>> {
+ const isContent = olmSessionType === 'content';
+ const { picklingKey } = await fetchOlmAccount(olmSessionType);
+
+ let retriesLeft = maxOlmSessionUpdateRetriesCount;
+
+ while (retriesLeft > 0) {
+ const [olmSessionResult] = await dbQuery(
+ SQL`
+ SELECT version, pickled_olm_session FROM olm_sessions
+ WHERE cookie_id = ${cookieID} AND is_content = ${isContent}
+ `,
+ );
+
+ if (olmSessionResult.length === 0) {
+ throw new ServerError('missing_olm_session');
+ }
+
+ const [{ version, pickled_olm_session: pickledSession }] = olmSessionResult;
+ const session = await unpickleOlmSession(pickledSession, picklingKey);
+
+ const encryptedMessages = [];
+ for (const message of messagesToEncrypt) {
+ encryptedMessages.push(session.encrypt(message));
+ }
+
+ const updatedSession = session.pickle(picklingKey);
+
+ const [transactionResult] = await dbQuery(
+ SQL`
+ START TRANSACTION;
+
+ SELECT version INTO @currentVersion
+ FROM olm_sessions
+ WHERE cookie_id = ${cookieID} AND is_content = ${isContent}
+ FOR UPDATE;
+
+ UPDATE olm_sessions
+ SET
+ pickled_olm_session = ${updatedSession},
+ version = ${version} + 1
+ WHERE version = ${version} AND is_content = ${isContent}
+ AND cookie_id = ${cookieID};
+
+ COMMIT;
+
+ SELECT @currentVersion AS versionOnUpdateAttempt;
+ `,
+ { multipleStatements: true },
+ );
+
+ const selectResult = transactionResult.pop();
+ const [{ versionOnUpdateAttempt }] = selectResult;
+
+ if (version === versionOnUpdateAttempt) {
+ return encryptedMessages;
+ }
+
+ retriesLeft = retriesLeft - 1;
+ await sleep(olmSessionUpdateRetryDelay);
+ }
+
+ throw new ServerError('max_olm_account_update_retry_exceeded');
+}
+
+export { encryptAndUpdateOlmSession };

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 11:17 PM (18 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2609237
Default Alt Text
D7797.id26405.diff (2 KB)

Event Timeline