Delete all backups (if possible) when user generates a new recovery code
This commit is contained in:
parent
395cc4c899
commit
4271fd6005
5 changed files with 31 additions and 3 deletions
|
@ -44,7 +44,7 @@ class App : Application() {
|
||||||
factory { AppListRetriever(this@App, get(), get(), get()) }
|
factory { AppListRetriever(this@App, get(), get(), get()) }
|
||||||
|
|
||||||
viewModel { SettingsViewModel(this@App, get(), get(), get(), get(), get()) }
|
viewModel { SettingsViewModel(this@App, get(), get(), get(), get(), get()) }
|
||||||
viewModel { RecoveryCodeViewModel(this@App, get(), get()) }
|
viewModel { RecoveryCodeViewModel(this@App, get(), get(), get()) }
|
||||||
viewModel { BackupStorageViewModel(this@App, get(), get(), get()) }
|
viewModel { BackupStorageViewModel(this@App, get(), get(), get()) }
|
||||||
viewModel { RestoreStorageViewModel(this@App, get(), get()) }
|
viewModel { RestoreStorageViewModel(this@App, get(), get()) }
|
||||||
viewModel { RestoreViewModel(this@App, get(), get(), get(), get(), get()) }
|
viewModel { RestoreViewModel(this@App, get(), get(), get(), get(), get()) }
|
||||||
|
|
|
@ -44,6 +44,11 @@ internal class DocumentsProviderBackupPlugin(
|
||||||
storage.currentFullBackupDir ?: throw IOException()
|
storage.currentFullBackupDir ?: throw IOException()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override suspend fun deleteAllBackups() {
|
||||||
|
storage.rootBackupDir?.deleteContents(context)
|
||||||
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override suspend fun getMetadataOutputStream(): OutputStream {
|
override suspend fun getMetadataOutputStream(): OutputStream {
|
||||||
val setDir = storage.getSetDir() ?: throw IOException()
|
val setDir = storage.getSetDir() ?: throw IOException()
|
||||||
|
|
|
@ -25,6 +25,12 @@ interface BackupPlugin {
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
suspend fun initializeDevice()
|
suspend fun initializeDevice()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all existing [RestoreSet]s from the storage medium.
|
||||||
|
*/
|
||||||
|
@Throws(IOException::class)
|
||||||
|
suspend fun deleteAllBackups()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [OutputStream] for writing backup metadata.
|
* Returns an [OutputStream] for writing backup metadata.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -190,6 +190,7 @@ class RecoveryCodeInputFragment : Fragment() {
|
||||||
|
|
||||||
private val regenRequest = registerForActivityResult(StartActivityForResult()) {
|
private val regenRequest = registerForActivityResult(StartActivityForResult()) {
|
||||||
if (it.resultCode == RESULT_OK) {
|
if (it.resultCode == RESULT_OK) {
|
||||||
|
viewModel.deleteAllBackup()
|
||||||
parentFragmentManager.popBackStack()
|
parentFragmentManager.popBackStack()
|
||||||
Snackbar.make(requireView(), R.string.recovery_code_recreated, Snackbar.LENGTH_LONG)
|
Snackbar.make(requireView(), R.string.recovery_code_recreated, Snackbar.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
|
@ -203,7 +204,6 @@ class RecoveryCodeInputFragment : Fragment() {
|
||||||
.setMessage(R.string.recovery_code_verification_new_dialog_message)
|
.setMessage(R.string.recovery_code_verification_new_dialog_message)
|
||||||
.setPositiveButton(R.string.recovery_code_verification_generate_new) { dialog, _ ->
|
.setPositiveButton(R.string.recovery_code_verification_generate_new) { dialog, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
// TODO try to delete backups
|
|
||||||
val i = Intent(requireContext(), RecoveryCodeActivity::class.java)
|
val i = Intent(requireContext(), RecoveryCodeActivity::class.java)
|
||||||
regenRequest.launch(i)
|
regenRequest.launch(i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package com.stevesoltys.seedvault.ui.recoverycode
|
package com.stevesoltys.seedvault.ui.recoverycode
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import com.stevesoltys.seedvault.App
|
import com.stevesoltys.seedvault.App
|
||||||
import com.stevesoltys.seedvault.crypto.Crypto
|
import com.stevesoltys.seedvault.crypto.Crypto
|
||||||
import com.stevesoltys.seedvault.crypto.KeyManager
|
import com.stevesoltys.seedvault.crypto.KeyManager
|
||||||
|
import com.stevesoltys.seedvault.transport.backup.BackupPlugin
|
||||||
import com.stevesoltys.seedvault.ui.LiveEvent
|
import com.stevesoltys.seedvault.ui.LiveEvent
|
||||||
import com.stevesoltys.seedvault.ui.MutableLiveEvent
|
import com.stevesoltys.seedvault.ui.MutableLiveEvent
|
||||||
import io.github.novacrypto.bip39.JavaxPBKDF2WithHmacSHA512
|
import io.github.novacrypto.bip39.JavaxPBKDF2WithHmacSHA512
|
||||||
|
@ -16,6 +18,10 @@ import io.github.novacrypto.bip39.Validation.UnexpectedWhiteSpaceException
|
||||||
import io.github.novacrypto.bip39.Validation.WordNotFoundException
|
import io.github.novacrypto.bip39.Validation.WordNotFoundException
|
||||||
import io.github.novacrypto.bip39.Words
|
import io.github.novacrypto.bip39.Words
|
||||||
import io.github.novacrypto.bip39.wordlists.English
|
import io.github.novacrypto.bip39.wordlists.English
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.IOException
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
@ -25,7 +31,8 @@ internal const val WORD_LIST_SIZE = 2048
|
||||||
class RecoveryCodeViewModel(
|
class RecoveryCodeViewModel(
|
||||||
app: App,
|
app: App,
|
||||||
private val crypto: Crypto,
|
private val crypto: Crypto,
|
||||||
private val keyManager: KeyManager
|
private val keyManager: KeyManager,
|
||||||
|
private val backupPlugin: BackupPlugin
|
||||||
) : AndroidViewModel(app) {
|
) : AndroidViewModel(app) {
|
||||||
|
|
||||||
internal val wordList: List<CharSequence> by lazy {
|
internal val wordList: List<CharSequence> by lazy {
|
||||||
|
@ -69,4 +76,14 @@ class RecoveryCodeViewModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deleteAllBackup() {
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
backupPlugin.deleteAllBackups()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e("RecoveryCodeViewModel", "Error deleting backups", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue