diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp @@ -30,6 +30,10 @@ } void DatabaseManager::clearSensitiveData() { + comm::CommSecureStore commSecureStore{}; + commSecureStore.set(commSecureStore.userID, ""); + commSecureStore.set(commSecureStore.deviceID, ""); + commSecureStore.set(commSecureStore.commServicesAccessToken, ""); SQLiteQueryExecutor::clearSensitiveData(); NotificationsCryptoModule::clearSensitiveData(); DatabaseManager::setDatabaseStatusAsWorkable(); 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 @@ -95,6 +95,16 @@ jsi::String backupID) override; virtual jsi::Value generateRandomString(jsi::Runtime &rt, double size) override; + virtual jsi::Value setCommServicesAuthMetadata( + jsi::Runtime &rt, + jsi::String userID, + jsi::String deviceID, + jsi::String accessToken) override; + virtual jsi::Value getCommServicesAuthMetadata(jsi::Runtime &rt) override; + virtual jsi::Value setCommServicesAccessToken( + jsi::Runtime &rt, + jsi::String accessToken) override; + virtual jsi::Value clearCommServicesAccessToken(jsi::Runtime &rt) override; public: CommCoreModule(std::shared_ptr jsInvoker); 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 @@ -957,4 +957,153 @@ }); } +jsi::Value CommCoreModule::setCommServicesAuthMetadata( + jsi::Runtime &rt, + jsi::String userID, + jsi::String deviceID, + jsi::String accessToken) { + auto userIDStr{userID.utf8(rt)}; + auto deviceIDStr{deviceID.utf8(rt)}; + auto accessTokenStr{accessToken.utf8(rt)}; + return createPromiseAsJSIValue( + rt, + [this, userIDStr, deviceIDStr, accessTokenStr]( + jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = + [this, promise, userIDStr, deviceIDStr, accessTokenStr]() { + std::string error; + try { + this->secureStore.set(this->secureStore.userID, userIDStr); + this->secureStore.set(this->secureStore.deviceID, deviceIDStr); + this->secureStore.set( + this->secureStore.commServicesAccessToken, accessTokenStr); + } catch (const std::exception &e) { + error = e.what(); + } + this->jsInvoker_->invokeAsync([error, promise]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRunCancellable( + job, promise, this->jsInvoker_); + }); +} + +jsi::Value CommCoreModule::getCommServicesAuthMetadata(jsi::Runtime &rt) { + return createPromiseAsJSIValue( + rt, [this](jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [this, &innerRt, promise]() { + std::string error; + std::string userID; + std::string deviceID; + std::string accessToken; + try { + folly::Optional userIDOpt = + this->secureStore.get(this->secureStore.userID); + if (userIDOpt.hasValue()) { + userID = userIDOpt.value(); + } + folly::Optional deviceIDOpt = + this->secureStore.get(this->secureStore.deviceID); + if (deviceIDOpt.hasValue()) { + deviceID = deviceIDOpt.value(); + } + folly::Optional accessTokenOpt = this->secureStore.get( + this->secureStore.commServicesAccessToken); + if (accessTokenOpt.hasValue()) { + accessToken = accessTokenOpt.value(); + } + } catch (const std::exception &e) { + error = e.what(); + } + this->jsInvoker_->invokeAsync( + [&innerRt, error, userID, deviceID, accessToken, promise]() { + if (error.size()) { + promise->reject(error); + } else { + auto authMetadata = jsi::Object(innerRt); + if (!userID.empty()) { + authMetadata.setProperty( + innerRt, + "userID", + jsi::String::createFromUtf8(innerRt, userID)); + } + if (!deviceID.empty()) { + authMetadata.setProperty( + innerRt, + "deviceID", + jsi::String::createFromUtf8(innerRt, deviceID)); + } + if (!accessToken.empty()) { + authMetadata.setProperty( + innerRt, + "accessToken", + jsi::String::createFromUtf8(innerRt, accessToken)); + } + promise->resolve(std::move(authMetadata)); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRunCancellable( + job, promise, this->jsInvoker_); + }); +} + +jsi::Value CommCoreModule::setCommServicesAccessToken( + jsi::Runtime &rt, + jsi::String accessToken) { + auto accessTokenStr{accessToken.utf8(rt)}; + return createPromiseAsJSIValue( + rt, + [this, accessTokenStr]( + jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [this, promise, accessTokenStr]() { + std::string error; + try { + this->secureStore.set( + this->secureStore.commServicesAccessToken, accessTokenStr); + } catch (const std::exception &e) { + error = e.what(); + } + this->jsInvoker_->invokeAsync([error, promise]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRunCancellable( + job, promise, this->jsInvoker_); + }); +} + +jsi::Value CommCoreModule::clearCommServicesAccessToken(jsi::Runtime &rt) { + return createPromiseAsJSIValue( + rt, [this](jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [this, promise]() { + std::string error; + try { + this->secureStore.set( + this->secureStore.commServicesAccessToken, ""); + } catch (const std::exception &e) { + error = e.what(); + } + this->jsInvoker_->invokeAsync([error, promise]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRunCancellable( + job, promise, this->jsInvoker_); + }); +} + } // namespace comm diff --git a/native/cpp/CommonCpp/Tools/CommSecureStore.h b/native/cpp/CommonCpp/Tools/CommSecureStore.h --- a/native/cpp/CommonCpp/Tools/CommSecureStore.h +++ b/native/cpp/CommonCpp/Tools/CommSecureStore.h @@ -10,6 +10,9 @@ public: void set(const std::string key, const std::string value) const; folly::Optional get(const std::string key) const; + const std::string commServicesAccessToken = "accessToken"; + const std::string userID = "userID"; + const std::string deviceID = "deviceID"; }; } // namespace comm 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 @@ -119,6 +119,18 @@ static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateRandomString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->generateRandomString(rt, args[0].asNumber()); } +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setCommServicesAuthMetadata(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setCommServicesAuthMetadata(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt)); +} +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getCommServicesAuthMetadata(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getCommServicesAuthMetadata(rt); +} +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setCommServicesAccessToken(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->setCommServicesAccessToken(rt, args[0].asString(rt)); +} +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_clearCommServicesAccessToken(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->clearCommServicesAccessToken(rt); +} CommCoreModuleSchemaCxxSpecJSI::CommCoreModuleSchemaCxxSpecJSI(std::shared_ptr jsInvoker) : TurboModule("CommTurboModule", jsInvoker) { @@ -156,6 +168,10 @@ methodMap_["reportDBOperationsFailure"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_reportDBOperationsFailure}; methodMap_["computeBackupKey"] = MethodMetadata {2, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_computeBackupKey}; methodMap_["generateRandomString"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateRandomString}; + methodMap_["setCommServicesAuthMetadata"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setCommServicesAuthMetadata}; + methodMap_["getCommServicesAuthMetadata"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getCommServicesAuthMetadata}; + methodMap_["setCommServicesAccessToken"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setCommServicesAccessToken}; + methodMap_["clearCommServicesAccessToken"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_clearCommServicesAccessToken}; } 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 @@ -54,6 +54,10 @@ virtual void reportDBOperationsFailure(jsi::Runtime &rt) = 0; virtual jsi::Value computeBackupKey(jsi::Runtime &rt, jsi::String password, jsi::String backupID) = 0; virtual jsi::Value generateRandomString(jsi::Runtime &rt, double size) = 0; + virtual jsi::Value setCommServicesAuthMetadata(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken) = 0; + virtual jsi::Value getCommServicesAuthMetadata(jsi::Runtime &rt) = 0; + virtual jsi::Value setCommServicesAccessToken(jsi::Runtime &rt, jsi::String accessToken) = 0; + virtual jsi::Value clearCommServicesAccessToken(jsi::Runtime &rt) = 0; }; @@ -347,6 +351,38 @@ return bridging::callFromJs( rt, &T::generateRandomString, jsInvoker_, instance_, std::move(size)); } + jsi::Value setCommServicesAuthMetadata(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken) override { + static_assert( + bridging::getParameterCount(&T::setCommServicesAuthMetadata) == 4, + "Expected setCommServicesAuthMetadata(...) to have 4 parameters"); + + return bridging::callFromJs( + rt, &T::setCommServicesAuthMetadata, jsInvoker_, instance_, std::move(userID), std::move(deviceID), std::move(accessToken)); + } + jsi::Value getCommServicesAuthMetadata(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getCommServicesAuthMetadata) == 1, + "Expected getCommServicesAuthMetadata(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getCommServicesAuthMetadata, jsInvoker_, instance_); + } + jsi::Value setCommServicesAccessToken(jsi::Runtime &rt, jsi::String accessToken) override { + static_assert( + bridging::getParameterCount(&T::setCommServicesAccessToken) == 2, + "Expected setCommServicesAccessToken(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::setCommServicesAccessToken, jsInvoker_, instance_, std::move(accessToken)); + } + jsi::Value clearCommServicesAccessToken(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::clearCommServicesAccessToken) == 1, + "Expected clearCommServicesAccessToken(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::clearCommServicesAccessToken, jsInvoker_, instance_); + } private: T *instance_; diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -34,6 +34,12 @@ +notifPrekeySignature: string, }; +type CommServicesAuthMetadata = { + +userID?: ?string, + +deviceID?: ?string, + +commServicesAccessToken?: ?string, +}; + interface Spec extends TurboModule { +getDraft: (key: string) => Promise; +updateDraft: (key: string, text: string) => Promise; @@ -92,6 +98,14 @@ +reportDBOperationsFailure: () => void; +computeBackupKey: (password: string, backupID: string) => Promise; +generateRandomString: (size: number) => Promise; + +setCommServicesAuthMetadata: ( + userID: string, + deviceID: string, + accessToken: string, + ) => Promise; + +getCommServicesAuthMetadata: () => Promise; + +setCommServicesAccessToken: (accessToken: string) => Promise; + +clearCommServicesAccessToken: () => Promise; } export interface CoreModuleSpec extends Spec {