mirror of
https://github.com/PhilKes/NotallyX.git
synced 2025-06-28 20:29:54 +00:00
Merge pull request #588 from PhilKes/fix/backup-on-save-decrypt
Fix decrypting database on auto-save backup if biometric lock is enabled
This commit is contained in:
commit
402baf8056
3 changed files with 32 additions and 13 deletions
|
@ -89,7 +89,7 @@ import net.lingala.zip4j.model.enums.EncryptionMethod
|
||||||
private const val TAG = "ExportExtensions"
|
private const val TAG = "ExportExtensions"
|
||||||
private const val NOTIFICATION_CHANNEL_ID = "AutoBackups"
|
private const val NOTIFICATION_CHANNEL_ID = "AutoBackups"
|
||||||
private const val NOTIFICATION_ID = 123412
|
private const val NOTIFICATION_ID = 123412
|
||||||
private const val NOTALLYX_BACKUP_LOGS_FILE = "notallyx-backup-logs"
|
private const val NOTALLYX_BACKUP_LOGS_FILE = "notallyx-backup-logs.txt"
|
||||||
private const val OUTPUT_DATA_BACKUP_URI = "backupUri"
|
private const val OUTPUT_DATA_BACKUP_URI = "backupUri"
|
||||||
|
|
||||||
const val AUTO_BACKUP_WORK_NAME = "com.philkes.notallyx.AutoBackupWork"
|
const val AUTO_BACKUP_WORK_NAME = "com.philkes.notallyx.AutoBackupWork"
|
||||||
|
@ -174,7 +174,7 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN
|
||||||
backupFile = folder.createFile(MIME_TYPE_ZIP, ON_SAVE_BACKUP_FILE)
|
backupFile = folder.createFile(MIME_TYPE_ZIP, ON_SAVE_BACKUP_FILE)
|
||||||
exportAsZip(backupFile!!.uri, password = password)
|
exportAsZip(backupFile!!.uri, password = password)
|
||||||
} else {
|
} else {
|
||||||
NotallyDatabase.getDatabase(this, observePreferences = false).value.checkpoint()
|
val (_, file) = copyDatabase()
|
||||||
val files =
|
val files =
|
||||||
with(savedNote) {
|
with(savedNote) {
|
||||||
images.map {
|
images.map {
|
||||||
|
@ -192,10 +192,7 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN
|
||||||
audios.map {
|
audios.map {
|
||||||
BackupFile(SUBFOLDER_AUDIOS, File(getExternalAudioDirectory(), it.name))
|
BackupFile(SUBFOLDER_AUDIOS, File(getExternalAudioDirectory(), it.name))
|
||||||
} +
|
} +
|
||||||
BackupFile(
|
BackupFile(null, file)
|
||||||
null,
|
|
||||||
NotallyDatabase.getCurrentDatabaseFile(this@autoBackupOnSave),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
exportToZip(backupFile.uri, files, password)
|
exportToZip(backupFile.uri, files, password)
|
||||||
|
@ -417,7 +414,7 @@ fun ContextWrapper.copyDatabase(): Pair<NotallyDatabase, File> {
|
||||||
val cipher = getInitializedCipherForDecryption(iv = preferences.iv.value!!)
|
val cipher = getInitializedCipherForDecryption(iv = preferences.iv.value!!)
|
||||||
val passphrase = cipher.doFinal(preferences.databaseEncryptionKey.value)
|
val passphrase = cipher.doFinal(preferences.databaseEncryptionKey.value)
|
||||||
val decryptedFile = File(cacheDir, DATABASE_NAME)
|
val decryptedFile = File(cacheDir, DATABASE_NAME)
|
||||||
decryptDatabase(this, passphrase, decryptedFile, databaseFile)
|
decryptDatabase(this, passphrase, databaseFile, decryptedFile)
|
||||||
Pair(database, decryptedFile)
|
Pair(database, decryptedFile)
|
||||||
} else {
|
} else {
|
||||||
val dbFile = File(cacheDir, DATABASE_NAME)
|
val dbFile = File(cacheDir, DATABASE_NAME)
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.philkes.notallyx.data.model.parseToColorString
|
||||||
import com.philkes.notallyx.presentation.getQuantityString
|
import com.philkes.notallyx.presentation.getQuantityString
|
||||||
import com.philkes.notallyx.presentation.showToast
|
import com.philkes.notallyx.presentation.showToast
|
||||||
import com.philkes.notallyx.presentation.viewmodel.NotallyModel.FileType
|
import com.philkes.notallyx.presentation.viewmodel.NotallyModel.FileType
|
||||||
|
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
|
||||||
import com.philkes.notallyx.utils.FileError
|
import com.philkes.notallyx.utils.FileError
|
||||||
import com.philkes.notallyx.utils.SUBFOLDER_AUDIOS
|
import com.philkes.notallyx.utils.SUBFOLDER_AUDIOS
|
||||||
import com.philkes.notallyx.utils.SUBFOLDER_FILES
|
import com.philkes.notallyx.utils.SUBFOLDER_FILES
|
||||||
|
@ -44,6 +45,8 @@ import com.philkes.notallyx.utils.log
|
||||||
import com.philkes.notallyx.utils.mimeTypeToFileExtension
|
import com.philkes.notallyx.utils.mimeTypeToFileExtension
|
||||||
import com.philkes.notallyx.utils.rename
|
import com.philkes.notallyx.utils.rename
|
||||||
import com.philkes.notallyx.utils.scheduleNoteReminders
|
import com.philkes.notallyx.utils.scheduleNoteReminders
|
||||||
|
import com.philkes.notallyx.utils.security.SQLCipherUtils
|
||||||
|
import com.philkes.notallyx.utils.security.decryptDatabase
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
@ -86,12 +89,31 @@ suspend fun ContextWrapper.importZip(
|
||||||
NotallyDatabase.DATABASE_NAME,
|
NotallyDatabase.DATABASE_NAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
val database =
|
var dbFile = File(databaseFolder, NotallyDatabase.DATABASE_NAME)
|
||||||
SQLiteDatabase.openDatabase(
|
val state = SQLCipherUtils.getDatabaseState(dbFile)
|
||||||
File(databaseFolder, NotallyDatabase.DATABASE_NAME).path,
|
if (state == SQLCipherUtils.State.ENCRYPTED) {
|
||||||
null,
|
val fallbackEncryptionKey =
|
||||||
SQLiteDatabase.OPEN_READONLY,
|
NotallyXPreferences.getInstance(this@importZip)
|
||||||
|
.fallbackDatabaseEncryptionKey
|
||||||
|
.value
|
||||||
|
if (fallbackEncryptionKey != null) {
|
||||||
|
val dbFileDecrypted =
|
||||||
|
File(databaseFolder, "${NotallyDatabase.DATABASE_NAME}-decrypted")
|
||||||
|
decryptDatabase(
|
||||||
|
this@importZip,
|
||||||
|
fallbackEncryptionKey,
|
||||||
|
dbFile,
|
||||||
|
dbFileDecrypted,
|
||||||
)
|
)
|
||||||
|
dbFile = dbFileDecrypted
|
||||||
|
} else {
|
||||||
|
throw IllegalArgumentException(
|
||||||
|
"Backup contains encrypted database and 'fallbackDatabaseEncryptionKey' has no value!"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val database =
|
||||||
|
SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READONLY)
|
||||||
|
|
||||||
val labelCursor = database.query("Label", null, null, null, null, null, null)
|
val labelCursor = database.query("Label", null, null, null, null, null, null)
|
||||||
val baseNoteCursor = database.query("BaseNote", null, null, null, null, null, null)
|
val baseNoteCursor = database.query("BaseNote", null, null, null, null, null, null)
|
||||||
|
|
|
@ -37,8 +37,8 @@ fun decryptDatabase(context: ContextWrapper, passphrase: ByteArray) {
|
||||||
fun decryptDatabase(
|
fun decryptDatabase(
|
||||||
context: Context,
|
context: Context,
|
||||||
passphrase: ByteArray,
|
passphrase: ByteArray,
|
||||||
decryptedFile: File,
|
|
||||||
databaseFile: File,
|
databaseFile: File,
|
||||||
|
decryptedFile: File,
|
||||||
) {
|
) {
|
||||||
val state = SQLCipherUtils.getDatabaseState(databaseFile)
|
val state = SQLCipherUtils.getDatabaseState(databaseFile)
|
||||||
if (state == SQLCipherUtils.State.ENCRYPTED) {
|
if (state == SQLCipherUtils.State.ENCRYPTED) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue