Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3346504
D12129.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D12129.diff
View Options
diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -146,6 +146,11 @@
+initializeCryptoAccount: () => Promise<void>,
+getUserPublicKey: () => Promise<ClientPublicKeys>,
+encrypt: (content: string, deviceID: string) => Promise<EncryptedData>,
+ +encryptAndPersist: (
+ content: string,
+ deviceID: string,
+ messageID: string,
+ ) => Promise<EncryptedData>,
+decrypt: (encryptedData: EncryptedData, deviceID: string) => Promise<string>,
+decryptSequentialAndPersist: (
encryptedData: EncryptedData,
diff --git a/lib/utils/__mocks__/config.js b/lib/utils/__mocks__/config.js
--- a/lib/utils/__mocks__/config.js
+++ b/lib/utils/__mocks__/config.js
@@ -16,6 +16,7 @@
initializeCryptoAccount: jest.fn(),
getUserPublicKey: jest.fn(),
encrypt: jest.fn(),
+ encryptAndPersist: jest.fn(),
decrypt: jest.fn(),
decryptSequentialAndPersist: jest.fn(),
contentInboundSessionCreator: jest.fn(),
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
@@ -129,6 +129,11 @@
bool overwrite) override;
virtual jsi::Value
encrypt(jsi::Runtime &rt, jsi::String message, jsi::String deviceID) override;
+ virtual jsi::Value encryptAndPersist(
+ jsi::Runtime &rt,
+ jsi::String message,
+ jsi::String deviceID,
+ jsi::String messageID) override;
virtual jsi::Value decrypt(
jsi::Runtime &rt,
jsi::Object encryptedDataJSI,
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -1389,6 +1389,86 @@
});
}
+jsi::Value CommCoreModule::encryptAndPersist(
+ jsi::Runtime &rt,
+ jsi::String message,
+ jsi::String deviceID,
+ jsi::String messageID) {
+ auto messageCpp{message.utf8(rt)};
+ auto deviceIDCpp{deviceID.utf8(rt)};
+ auto messageIDCpp{messageID.utf8(rt)};
+ return createPromiseAsJSIValue(
+ rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
+ taskType job = [=, &innerRt]() {
+ std::string error;
+ crypto::EncryptedData encryptedMessage;
+ try {
+ encryptedMessage =
+ contentCryptoModule->encrypt(deviceIDCpp, messageCpp);
+
+ std::string storedSecretKey =
+ getAccountDataKey(secureStoreAccountDataKey);
+ crypto::Persist newContentPersist =
+ this->contentCryptoModule->storeAsB64(storedSecretKey);
+
+ std::promise<void> persistencePromise;
+ std::future<void> persistenceFuture =
+ persistencePromise.get_future();
+ GlobalDBSingleton::instance.scheduleOrRunCancellable(
+ [=, &persistencePromise]() {
+ try {
+
+ folly::dynamic jsonObject = folly::dynamic::object;
+ std::string messageStr(
+ encryptedMessage.message.begin(),
+ encryptedMessage.message.end());
+ jsonObject["message"] = messageStr;
+ jsonObject["messageType"] = encryptedMessage.messageType;
+ std::string ciphertext = folly::toJson(jsonObject);
+
+ DatabaseManager::getQueryExecutor().beginTransaction();
+ DatabaseManager::getQueryExecutor()
+ .setCiphertextForOutboundP2PMessage(
+ messageIDCpp, deviceIDCpp, ciphertext);
+ DatabaseManager::getQueryExecutor().storeOlmPersistData(
+ DatabaseManager::getQueryExecutor()
+ .getContentAccountID(),
+ newContentPersist);
+ DatabaseManager::getQueryExecutor().commitTransaction();
+ persistencePromise.set_value();
+ } catch (std::system_error &e) {
+ DatabaseManager::getQueryExecutor().rollbackTransaction();
+ persistencePromise.set_exception(
+ std::make_exception_ptr(e));
+ }
+ });
+ persistenceFuture.get();
+
+ } catch (const std::exception &e) {
+ error = e.what();
+ }
+ this->jsInvoker_->invokeAsync([=, &innerRt]() {
+ if (error.size()) {
+ promise->reject(error);
+ return;
+ }
+ auto encryptedDataJSI = jsi::Object(innerRt);
+ auto message = std::string{
+ encryptedMessage.message.begin(),
+ encryptedMessage.message.end()};
+ auto messageJSI = jsi::String::createFromUtf8(innerRt, message);
+ encryptedDataJSI.setProperty(innerRt, "message", messageJSI);
+ encryptedDataJSI.setProperty(
+ innerRt,
+ "messageType",
+ static_cast<int>(encryptedMessage.messageType));
+ promise->resolve(std::move(encryptedDataJSI));
+ });
+ };
+ this->cryptoThread->scheduleTask(job);
+ });
+}
+
jsi::Value CommCoreModule::decrypt(
jsi::Runtime &rt,
jsi::Object encryptedDataJSI,
diff --git a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
--- a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
+++ b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp
@@ -87,6 +87,9 @@
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_encrypt(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->encrypt(rt, args[0].asString(rt), args[1].asString(rt));
}
+static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_encryptAndPersist(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+ return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->encryptAndPersist(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt));
+}
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_decrypt(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->decrypt(rt, args[0].asObject(rt), args[1].asString(rt));
}
@@ -226,6 +229,7 @@
methodMap_["initializeContentOutboundSession"] = MethodMetadata {5, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeContentOutboundSession};
methodMap_["initializeContentInboundSession"] = MethodMetadata {5, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeContentInboundSession};
methodMap_["encrypt"] = MethodMetadata {2, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_encrypt};
+ methodMap_["encryptAndPersist"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_encryptAndPersist};
methodMap_["decrypt"] = MethodMetadata {2, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_decrypt};
methodMap_["decryptSequentialAndPersist"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_decryptSequentialAndPersist};
methodMap_["signMessage"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_signMessage};
diff --git a/native/cpp/CommonCpp/_generated/commJSI.h b/native/cpp/CommonCpp/_generated/commJSI.h
--- a/native/cpp/CommonCpp/_generated/commJSI.h
+++ b/native/cpp/CommonCpp/_generated/commJSI.h
@@ -44,6 +44,7 @@
virtual jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String deviceID) = 0;
virtual jsi::Value initializeContentInboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::Object encryptedContent, jsi::String deviceID, double sessionVersion, bool overwrite) = 0;
virtual jsi::Value encrypt(jsi::Runtime &rt, jsi::String message, jsi::String deviceID) = 0;
+ virtual jsi::Value encryptAndPersist(jsi::Runtime &rt, jsi::String message, jsi::String deviceID, jsi::String messageID) = 0;
virtual jsi::Value decrypt(jsi::Runtime &rt, jsi::Object encryptedData, jsi::String deviceID) = 0;
virtual jsi::Value decryptSequentialAndPersist(jsi::Runtime &rt, jsi::Object encryptedData, jsi::String deviceID, jsi::String messageID) = 0;
virtual jsi::Value signMessage(jsi::Runtime &rt, jsi::String message) = 0;
@@ -293,6 +294,14 @@
return bridging::callFromJs<jsi::Value>(
rt, &T::encrypt, jsInvoker_, instance_, std::move(message), std::move(deviceID));
}
+ jsi::Value encryptAndPersist(jsi::Runtime &rt, jsi::String message, jsi::String deviceID, jsi::String messageID) override {
+ static_assert(
+ bridging::getParameterCount(&T::encryptAndPersist) == 4,
+ "Expected encryptAndPersist(...) to have 4 parameters");
+
+ return bridging::callFromJs<jsi::Value>(
+ rt, &T::encryptAndPersist, jsInvoker_, instance_, std::move(message), std::move(deviceID), std::move(messageID));
+ }
jsi::Value decrypt(jsi::Runtime &rt, jsi::Object encryptedData, jsi::String deviceID) override {
static_assert(
bridging::getParameterCount(&T::decrypt) == 3,
diff --git a/native/crypto/olm-api.js b/native/crypto/olm-api.js
--- a/native/crypto/olm-api.js
+++ b/native/crypto/olm-api.js
@@ -20,6 +20,7 @@
},
getUserPublicKey: commCoreModule.getUserPublicKey,
encrypt: commCoreModule.encrypt,
+ encryptAndPersist: commCoreModule.encryptAndPersist,
decrypt: commCoreModule.decrypt,
decryptSequentialAndPersist: commCoreModule.decryptSequentialAndPersist,
async contentInboundSessionCreator(
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -92,6 +92,11 @@
overwrite: boolean,
) => Promise<string>;
+encrypt: (message: string, deviceID: string) => Promise<EncryptedData>;
+ +encryptAndPersist: (
+ message: string,
+ deviceID: string,
+ messageID: string,
+ ) => Promise<EncryptedData>;
+decrypt: (encryptedData: Object, deviceID: string) => Promise<string>;
+decryptSequentialAndPersist: (
encryptedData: Object,
diff --git a/web/crypto/olm-api.js b/web/crypto/olm-api.js
--- a/web/crypto/olm-api.js
+++ b/web/crypto/olm-api.js
@@ -45,6 +45,7 @@
},
getUserPublicKey: proxyToWorker('getUserPublicKey'),
encrypt: proxyToWorker('encrypt'),
+ encryptAndPersist: proxyToWorker('encryptAndPersist'),
decrypt: proxyToWorker('decrypt'),
decryptSequentialAndPersist: proxyToWorker('decryptSequentialAndPersist'),
contentInboundSessionCreator: proxyToWorker('contentInboundSessionCreator'),
diff --git a/web/shared-worker/worker/worker-crypto.js b/web/shared-worker/worker/worker-crypto.js
--- a/web/shared-worker/worker/worker-crypto.js
+++ b/web/shared-worker/worker/worker-crypto.js
@@ -443,6 +443,50 @@
messageType: encryptedContent.type,
};
},
+ async encryptAndPersist(
+ content: string,
+ deviceID: string,
+ messageID: string,
+ ): Promise<EncryptedData> {
+ if (!cryptoStore) {
+ throw new Error('Crypto account not initialized');
+ }
+ const olmSession = cryptoStore.contentSessions[deviceID];
+ if (!olmSession) {
+ throw new Error(`No session for deviceID: ${deviceID}`);
+ }
+
+ const encryptedContent = olmSession.session.encrypt(content);
+
+ const sqliteQueryExecutor = getSQLiteQueryExecutor();
+ const dbModule = getDBModule();
+ if (!sqliteQueryExecutor || !dbModule) {
+ throw new Error(
+ "Couldn't persist crypto store because database is not initialized",
+ );
+ }
+
+ const result: EncryptedData = {
+ message: encryptedContent.body,
+ messageType: encryptedContent.type,
+ };
+
+ sqliteQueryExecutor.beginTransaction();
+ try {
+ sqliteQueryExecutor.setCiphertextForOutboundP2PMessage(
+ messageID,
+ deviceID,
+ JSON.stringify(result),
+ );
+ persistCryptoStore(true);
+ sqliteQueryExecutor.commitTransaction();
+ } catch (e) {
+ sqliteQueryExecutor.rollbackTransaction();
+ throw e;
+ }
+
+ return result;
+ },
async decrypt(
encryptedData: EncryptedData,
deviceID: string,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 23, 8:57 AM (14 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2569966
Default Alt Text
D12129.diff (12 KB)
Attached To
Mode
D12129: [web][native] implement encrypting and persisting OutboundP2PMessage's content in the same SQLite transaction as persisting `olm` session
Attached
Detach File
Event Timeline
Log In to Comment