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 @@ -54,17 +54,23 @@ std::string backupLogDataKey = DatabaseManager::generateBackupLogDataKey(); DatabaseManager::connectionManager->closeConnection(); - if (SQLiteUtils::fileExists(SQLiteQueryExecutor::sqliteFilePath) && - std::remove(SQLiteQueryExecutor::sqliteFilePath.c_str())) { + std::string sqliteFilePath = + DatabaseManager::connectionManager->getSQLiteFilePath(); + + if (SQLiteUtils::fileExists(sqliteFilePath) && + std::remove(sqliteFilePath.c_str())) { std::ostringstream errorStream; errorStream << "Failed to delete database file. Details: " << strerror(errno); Logger::log(errorStream.str()); throw std::system_error(errno, std::generic_category(), errorStream.str()); } - SQLiteQueryExecutor::backupDataKey = backupDataKey; - SQLiteQueryExecutor::backupLogDataKey = backupLogDataKey; + + DatabaseManager::connectionManager->setNewKeys( + backupDataKey, backupLogDataKey); + DatabaseManager::getQueryExecutor().migrate(); + DatabaseManager::connectionManager->initializeConnection(); PlatformSpecificTools::removeBackupDirectory(); CommMMKV::clearSensitiveData(); @@ -74,8 +80,6 @@ void DatabaseManager::initializeQueryExecutor(std::string &databasePath) { try { - DatabaseManager::connectionManager = - std::make_shared(); DatabaseManager::initializeSQLiteQueryExecutorProperties(databasePath); DatabaseManager::getQueryExecutor(); DatabaseManager::indicateQueryExecutorCreation(); @@ -159,9 +163,9 @@ backupLogDataKey = maybeBackupLogDataKey.value(); } - SQLiteQueryExecutor::sqliteFilePath = databasePath; - SQLiteQueryExecutor::backupDataKey = backupDataKey; - SQLiteQueryExecutor::backupLogDataKey = backupLogDataKey; + DatabaseManager::connectionManager = + std::make_shared( + databasePath, backupDataKey, backupLogDataKey); }); } @@ -180,11 +184,11 @@ void DatabaseManager::setUserDataKeys( const std::string &backupDataKey, const std::string &backupLogDataKey) { - if (SQLiteQueryExecutor::backupDataKey.empty()) { + if (DatabaseManager::connectionManager->getBackupDataKey().empty()) { throw std::runtime_error("backupDataKey is not set"); } - if (SQLiteQueryExecutor::backupLogDataKey.empty()) { + if (DatabaseManager::connectionManager->getBackupLogDataKey().empty()) { throw std::runtime_error("backupLogDataKey is not set"); } @@ -200,10 +204,10 @@ DatabaseManager::connectionManager->getConnection(), backupDataKey); CommSecureStore::set(CommSecureStore::backupDataKey, backupDataKey); - SQLiteQueryExecutor::backupDataKey = backupDataKey; - CommSecureStore::set(CommSecureStore::backupLogDataKey, backupLogDataKey); - SQLiteQueryExecutor::backupLogDataKey = backupLogDataKey; + + DatabaseManager::connectionManager->setNewKeys( + backupDataKey, backupLogDataKey); } void DatabaseManager::captureBackupLogs() { @@ -221,8 +225,8 @@ logID = "1"; } - bool newLogCreated = DatabaseManager::connectionManager->captureLogs( - backupID, logID, SQLiteQueryExecutor::backupLogDataKey); + bool newLogCreated = + DatabaseManager::connectionManager->captureLogs(backupID, logID); if (!newLogCreated) { return; } @@ -270,7 +274,8 @@ sqlite3 *backupDB; sqlite3_open(tempBackupPath.c_str(), &backupDB); - SQLiteUtils::setEncryptionKey(backupDB, SQLiteQueryExecutor::backupDataKey); + SQLiteUtils::setEncryptionKey( + backupDB, DatabaseManager::connectionManager->getBackupDataKey()); sqlite3_backup *backupObj = sqlite3_backup_init( backupDB, diff --git a/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.h b/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.h --- a/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.h +++ b/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.h @@ -6,6 +6,8 @@ class NativeSQLiteConnectionManager : public SQLiteConnectionManager { private: sqlite3_session *backupLogsSession; + std::string backupDataKey; + std::string backupLogDataKey; void attachSession(); void detachSession(); @@ -17,29 +19,28 @@ std::string encryptionKey); std::vector getAttachmentsFromLog(std::uint8_t *patchsetPtr, int patchsetSize); - void onDatabaseOpen(sqlite3 *db, std::string sqliteEncryptionKey) const; + void onDatabaseOpen(sqlite3 *db) const; public: - NativeSQLiteConnectionManager(); + NativeSQLiteConnectionManager( + std::string &databasePath, + std::string &backupDataKey, + std::string &backupLogDataKey); ~NativeSQLiteConnectionManager(); - sqlite3 *getEphemeralConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) const override; - void initializeConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) override; + sqlite3 *getEphemeralConnection() const override; + void initializeConnection() override; void closeConnection() override; - virtual void validateEncryption( - const std::string &sqliteFilePath, - const std::string &encryptionKey) override; + void validateEncryption() override; + std::string getBackupDataKey(); + std::string getBackupLogDataKey(); + void setNewKeys( + const std::string &backupDataKey, + const std::string &backupLogDataKey); void setLogsMonitoring(bool enabled); bool getLogsMonitoring(); - bool captureLogs( - std::string backupID, - std::string logID, - std::string encryptionKey); + bool captureLogs(std::string backupID, std::string logID); void restoreFromBackupLog(const std::vector &backupLog) override; }; diff --git a/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/NativeSQLiteConnectionManager.cpp @@ -180,8 +180,14 @@ return attachments; } -NativeSQLiteConnectionManager::NativeSQLiteConnectionManager() - : backupLogsSession(nullptr) { +NativeSQLiteConnectionManager::NativeSQLiteConnectionManager( + std::string &databasePath, + std::string &backupDataKey, + std::string &backupLogDataKey) + : SQLiteConnectionManager(databasePath), + backupLogsSession(nullptr), + backupDataKey(backupDataKey), + backupLogDataKey(backupLogDataKey) { } void NativeSQLiteConnectionManager::setLogsMonitoring(bool enabled) { @@ -198,28 +204,22 @@ return sqlite3session_enable(backupLogsSession, -1); } -void NativeSQLiteConnectionManager::onDatabaseOpen( - sqlite3 *db, - std::string sqliteEncryptionKey) const { - SQLiteUtils::setEncryptionKey(db, sqliteEncryptionKey); +void NativeSQLiteConnectionManager::onDatabaseOpen(sqlite3 *db) const { + SQLiteUtils::setEncryptionKey(db, this->backupDataKey); } -sqlite3 *NativeSQLiteConnectionManager::getEphemeralConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) const { - sqlite3 *db = this->createConnection(sqliteFilePath); - onDatabaseOpen(db, sqliteEncryptionKey); +sqlite3 *NativeSQLiteConnectionManager::getEphemeralConnection() const { + sqlite3 *db = this->createConnection(); + onDatabaseOpen(db); return db; } -void NativeSQLiteConnectionManager::initializeConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) { +void NativeSQLiteConnectionManager::initializeConnection() { if (this->dbConnection) { return; } - this->dbConnection = this->createConnection(sqliteFilePath); - onDatabaseOpen(getConnection(), sqliteEncryptionKey); + this->dbConnection = this->createConnection(); + onDatabaseOpen(getConnection()); attachSession(); setLogsMonitoring(false); } @@ -235,8 +235,7 @@ bool NativeSQLiteConnectionManager::captureLogs( std::string backupID, - std::string logID, - std::string encryptionKey) { + std::string logID) { int patchsetSize; std::uint8_t *patchsetPtr; int getPatchsetResult = sqlite3session_patchset( @@ -252,7 +251,8 @@ return false; } - persistLog(backupID, logID, patchsetPtr, patchsetSize, encryptionKey); + persistLog( + backupID, logID, patchsetPtr, patchsetSize, this->backupLogDataKey); sqlite3_free(patchsetPtr); // The session is not "zeroed" after capturing log. @@ -272,10 +272,31 @@ setLogsMonitoring(initialEnabledValue); } -void NativeSQLiteConnectionManager::validateEncryption( - const std::string &sqliteFilePath, - const std::string &encryptionKey) { - SQLiteUtils::validateEncryption(sqliteFilePath, encryptionKey); +void NativeSQLiteConnectionManager::setNewKeys( + const std::string &backupDataKey, + const std::string &backupLogDataKey) { + bool isConnectionInitialized = this->dbConnection; + if (isConnectionInitialized) { + this->closeConnection(); + } + + this->backupDataKey = backupDataKey; + this->backupLogDataKey = backupLogDataKey; + if (isConnectionInitialized) { + this->initializeConnection(); + } +} + +std::string NativeSQLiteConnectionManager::getBackupDataKey() { + return this->backupDataKey; +} + +std::string NativeSQLiteConnectionManager::getBackupLogDataKey() { + return this->backupLogDataKey; +} + +void NativeSQLiteConnectionManager::validateEncryption() { + SQLiteUtils::validateEncryption(this->sqliteFilePath, this->backupDataKey); } } // namespace comm diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.h @@ -6,12 +6,15 @@ #include #include +#include #include namespace comm { class SQLiteConnectionManager { protected: sqlite3 *dbConnection; + std::string sqliteFilePath; + static void handleSQLiteError( int errorCode, const std::string &errorMessagePrefix, @@ -19,31 +22,27 @@ void closeConnectionInternal(); // Shared implementation of creating a connection used by derived classes. - sqlite3 *createConnection(std::string sqliteFilePath) const; + sqlite3 *createConnection() const; public: - SQLiteConnectionManager(); + SQLiteConnectionManager(std::string sqliteFilePath); virtual ~SQLiteConnectionManager(); + std::string getSQLiteFilePath(); + // Creates a SQLite connection that is returned, but it is the caller's // responsibility to manage and close it. It is important to use this method, // not the `sqlite3` API, because creating a connection might be different // depending on the platform. Custom behaviour is implemented in derived // classes. - virtual sqlite3 *getEphemeralConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) const = 0; + virtual sqlite3 *getEphemeralConnection() const = 0; // Creates a SQLite connection that is cached and stored as an attribute. It // can be accessed using `getConnection` and closed using `closeConnection` - virtual void initializeConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) = 0; + virtual void initializeConnection() = 0; sqlite3 *getConnection() const; virtual void closeConnection() = 0; - virtual void validateEncryption( - const std::string &sqliteFilePath, - const std::string &encryptionKey) = 0; + virtual void validateEncryption() = 0; virtual void restoreFromBackupLog(const std::vector &backupLog); }; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteConnectionManager.cpp @@ -8,13 +8,18 @@ namespace comm { -SQLiteConnectionManager::SQLiteConnectionManager() : dbConnection(nullptr) { +SQLiteConnectionManager::SQLiteConnectionManager(std::string sqliteFilePath) + : dbConnection(nullptr), sqliteFilePath(sqliteFilePath) { } sqlite3 *SQLiteConnectionManager::getConnection() const { return dbConnection; } +std::string SQLiteConnectionManager::getSQLiteFilePath() { + return this->sqliteFilePath; +} + void SQLiteConnectionManager::handleSQLiteError( int errorCode, const std::string &errorMessagePrefix, @@ -27,10 +32,9 @@ } } -sqlite3 * -SQLiteConnectionManager::createConnection(std::string sqliteFilePath) const { +sqlite3 *SQLiteConnectionManager::createConnection() const { sqlite3 *dbConnection; - int connectResult = sqlite3_open(sqliteFilePath.c_str(), &dbConnection); + int connectResult = sqlite3_open(this->sqliteFilePath.c_str(), &dbConnection); handleSQLiteError(connectResult, "Failed to open database connection"); return dbConnection; } diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h @@ -35,10 +35,6 @@ const std::vector &tableNames) const; public: - static std::string sqliteFilePath; - static std::string backupDataKey; - static std::string backupLogDataKey; - #ifndef EMSCRIPTEN std::shared_ptr connectionManager; SQLiteQueryExecutor( diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp @@ -29,23 +29,15 @@ namespace comm { -std::string SQLiteQueryExecutor::sqliteFilePath; - -std::string SQLiteQueryExecutor::backupDataKey; - -std::string SQLiteQueryExecutor::backupLogDataKey; - void SQLiteQueryExecutor::migrate() const { - this->connectionManager->validateEncryption( - SQLiteQueryExecutor::sqliteFilePath, SQLiteQueryExecutor::backupDataKey); + this->connectionManager->validateEncryption(); std::stringstream db_path; - db_path << "db path: " << SQLiteQueryExecutor::sqliteFilePath.c_str() + db_path << "db path: " << this->connectionManager->getSQLiteFilePath() << std::endl; Logger::log(db_path.str()); - sqlite3 *db = this->connectionManager->getEphemeralConnection( - SQLiteQueryExecutor::sqliteFilePath, SQLiteQueryExecutor::backupDataKey); + sqlite3 *db = this->connectionManager->getEphemeralConnection(); auto db_version = SQLiteUtils::getDatabaseVersion(db); std::stringstream version_msg; @@ -74,8 +66,7 @@ std::shared_ptr connectionManager) : connectionManager(std::move(connectionManager)) { this->migrate(); - SQLiteQueryExecutor::connectionManager->initializeConnection( - SQLiteQueryExecutor::sqliteFilePath, SQLiteQueryExecutor::backupDataKey); + SQLiteQueryExecutor::connectionManager->initializeConnection(); std::string currentBackupID = this->getMetadata("backupID"); if (!ServicesUtils::fullBackupSupport || !currentBackupID.size()) { return; @@ -85,17 +76,15 @@ #else SQLiteQueryExecutor::SQLiteQueryExecutor(std::string sqliteFilePath) - : connectionManager(std::make_shared()) { - SQLiteQueryExecutor::sqliteFilePath = sqliteFilePath; + : connectionManager( + std::make_shared(sqliteFilePath)) { this->migrate(); - SQLiteQueryExecutor::connectionManager->initializeConnection( - SQLiteQueryExecutor::sqliteFilePath, SQLiteQueryExecutor::backupDataKey); + SQLiteQueryExecutor::connectionManager->initializeConnection(); } #endif sqlite3 *SQLiteQueryExecutor::getConnection() const { - this->connectionManager->initializeConnection( - SQLiteQueryExecutor::sqliteFilePath, SQLiteQueryExecutor::backupDataKey); + this->connectionManager->initializeConnection(); return this->connectionManager->getConnection(); } diff --git a/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.h b/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.h --- a/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.h +++ b/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.h @@ -6,18 +6,12 @@ class WebSQLiteConnectionManager : public SQLiteConnectionManager { public: - WebSQLiteConnectionManager(); + WebSQLiteConnectionManager(std::string sqliteFilePath); ~WebSQLiteConnectionManager(); - sqlite3 *getEphemeralConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) const override; - void initializeConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) override; + sqlite3 *getEphemeralConnection() const override; + void initializeConnection() override; void closeConnection() override; - virtual void validateEncryption( - const std::string &sqliteFilePath, - const std::string &encryptionKey) override; + virtual void validateEncryption() override; }; } // namespace comm diff --git a/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/WebSQLiteConnectionManager.cpp @@ -4,7 +4,9 @@ namespace comm { -WebSQLiteConnectionManager::WebSQLiteConnectionManager() { +WebSQLiteConnectionManager::WebSQLiteConnectionManager( + std::string sqliteFilePath) + : SQLiteConnectionManager(sqliteFilePath) { } WebSQLiteConnectionManager::~WebSQLiteConnectionManager() { @@ -14,30 +16,24 @@ SQLiteConnectionManager::closeConnectionInternal(); } -sqlite3 *WebSQLiteConnectionManager::getEphemeralConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) const { - return this->createConnection(sqliteFilePath); +sqlite3 *WebSQLiteConnectionManager::getEphemeralConnection() const { + return this->createConnection(); // We don't want to run `PRAGMA key = ...;` // on main web database. The context is here: // https://linear.app/comm/issue/ENG-6398/issues-with-sqlcipher-on-web } -void WebSQLiteConnectionManager::initializeConnection( - std::string sqliteFilePath, - std::string sqliteEncryptionKey) { +void WebSQLiteConnectionManager::initializeConnection() { if (this->dbConnection) { return; } - this->dbConnection = this->createConnection(sqliteFilePath); + this->dbConnection = this->createConnection(); // We don't want to run `PRAGMA key = ...;` // on main web database. The context is here: // https://linear.app/comm/issue/ENG-6398/issues-with-sqlcipher-on-web } -void WebSQLiteConnectionManager::validateEncryption( - const std::string &sqliteFilePath, - const std::string &encryptionKey) { +void WebSQLiteConnectionManager::validateEncryption() { // We don't want to run `PRAGMA key = ...;` // on main web database. The context is here: // https://linear.app/comm/issue/ENG-6398/issues-with-sqlcipher-on-web diff --git a/web/shared-worker/_generated/comm_query_executor.wasm b/web/shared-worker/_generated/comm_query_executor.wasm index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@