Skip to content

Commit 8c27ef4

Browse files
core/data: Fix encrypted DB cross-platform compatibility (#698)
Configure SQLCipher v4 cipher mode on Web WASM to match Desktop JVM and Android encryption format, enabling cross-platform encrypted backup portability. The Web WASM platform was using sqlite3mc's default cipher, which is incompatible with the SQLCipher v4 cipher used by the Desktop JVM (sqlite-jdbc-crypt) and Android (SafeRoom/SQLCipher). Changes: - WebDatabaseHolder: Set PRAGMA cipher='sqlcipher' and PRAGMA legacy=4 before PRAGMA key when opening encrypted DBs - WebSafeRepo: Set cipher parameters before PRAGMA rekey when encrypting an unencrypted database Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 6b221ab commit 8c27ef4

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

core/data/db-sqldelight/src/wasmJsMain/kotlin/com/softartdev/notedelight/db/WebDatabaseHolder.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ class WebDatabaseHolder(private val key: String? = null) : SqlDelightDbHolder {
1515
override val noteQueries: NoteQueries = noteDb.noteQueries
1616

1717
/**
18-
* Sets the encryption key on the database connection.
18+
* Configures SQLCipher v4 compatibility and sets the encryption key.
1919
* Must be called BEFORE any other SQL operations (including createSchema).
20-
* This sends PRAGMA key as the first statement to the worker.
20+
*
21+
* Uses `cipher=sqlcipher` with `legacy=4` to match the Desktop JVM and Android
22+
* encryption format, enabling cross-platform encrypted backup portability.
2123
*/
2224
suspend fun applyKey() {
2325
if (!key.isNullOrEmpty()) {
2426
val escapedKey = key.replace("'", "''")
25-
logger.d { "Setting encryption key on database" }
27+
logger.d { "Configuring SQLCipher v4 and setting encryption key" }
28+
driver.execute(null, "PRAGMA cipher = 'sqlcipher'", 0, null).await()
29+
driver.execute(null, "PRAGMA legacy = 4", 0, null).await()
2630
driver.execute(null, "PRAGMA key = '$escapedKey'", 0, null).await()
2731
}
2832
}

core/data/db-sqldelight/src/wasmJsMain/kotlin/com/softartdev/notedelight/repository/WebSafeRepo.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class WebSafeRepo(private val coroutineDispatchers: CoroutineDispatchers) : Safe
7676
logger.d { "Encrypting database" }
7777
val holder = dbHolder ?: buildDbIfNeed()
7878
val escapedKey = newPass.toString().replace("'", "''")
79-
// On an unencrypted database, PRAGMA rekey encrypts it in-place
79+
holder.driver.execute(null, "PRAGMA cipher = 'sqlcipher'", 0, null).await()
80+
holder.driver.execute(null, "PRAGMA legacy = 4", 0, null).await()
8081
holder.driver.execute(null, "PRAGMA rekey = '$escapedKey'", 0, null).await()
8182
logger.d { "PRAGMA rekey executed, closing and reopening with key" }
8283
closeDatabase()

0 commit comments

Comments
 (0)