Split up validating, verifying and storing of recovery code
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
index fdd8c1e..8211a01 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeInputFragment.kt
@@ -30,7 +30,7 @@
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.util.Locale
-internal const val ARG_FOR_NEW_CODE = "forVerifyingNewCode"
+internal const val ARG_FOR_NEW_CODE = "forStoringNewCode"
class RecoveryCodeInputFragment : Fragment() {
@@ -57,7 +57,7 @@
/**
* True if this is for verifying a new recovery code, false for verifying an existing one.
*/
- private var forVerifyingNewCode: Boolean = true
+ private var forStoringNewCode: Boolean = true
override fun onCreateView(
inflater: LayoutInflater,
@@ -85,7 +85,7 @@
wordList = v.findViewById(R.id.wordList)
arguments?.getBoolean(ARG_FOR_NEW_CODE, true)?.let {
- forVerifyingNewCode = it
+ forStoringNewCode = it
}
return v
@@ -116,14 +116,14 @@
editText.setAdapter(adapter)
}
doneButton.setOnClickListener { done() }
- newCodeButton.visibility = if (forVerifyingNewCode) GONE else VISIBLE
+ newCodeButton.visibility = if (forStoringNewCode) GONE else VISIBLE
newCodeButton.setOnClickListener { generateNewCode() }
viewModel.existingCodeChecked.observeEvent(viewLifecycleOwner,
LiveEventHandler { verified -> onExistingCodeChecked(verified) }
)
- if (forVerifyingNewCode && isDebugBuild() && !viewModel.isRestore) debugPreFill()
+ if (forStoringNewCode && isDebugBuild() && !viewModel.isRestore) debugPreFill()
}
private fun getInput(): List<CharSequence> = ArrayList<String>(WORD_NUM).apply {
@@ -134,11 +134,18 @@
val input = getInput()
if (!allFilledOut(input)) return
try {
- viewModel.validateAndContinue(input, forVerifyingNewCode)
+ viewModel.validateCode(input)
} catch (e: ChecksumException) {
Toast.makeText(context, R.string.recovery_code_error_checksum_word, LENGTH_LONG).show()
+ return
} catch (e: InvalidWordException) {
showWrongWordError(input)
+ return
+ }
+ if (forStoringNewCode) {
+ viewModel.storeNewCode(input)
+ } else {
+ viewModel.verifyExistingCode(input)
}
}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeViewModel.kt
index 3eb3329..d851ea9 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeViewModel.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/recoverycode/RecoveryCodeViewModel.kt
@@ -57,23 +57,37 @@
internal var isRestore: Boolean = false
@Throws(InvalidWordException::class, ChecksumException::class)
- fun validateAndContinue(input: List<CharSequence>, forVerifyingNewCode: Boolean) {
+ fun validateCode(input: List<CharSequence>): Mnemonics.MnemonicCode {
val code = Mnemonics.MnemonicCode(input.toMnemonicChars())
try {
code.validate()
} catch (e: WordCountException) {
throw AssertionError(e)
}
- val seed = code.toSeed()
- if (forVerifyingNewCode) {
- keyManager.storeBackupKey(seed)
- keyManager.storeMainKey(seed)
- mRecoveryCodeSaved.setEvent(true)
- } else {
- val verified = crypto.verifyBackupKey(seed)
- if (verified && !keyManager.hasMainKey()) keyManager.storeMainKey(seed)
- mExistingCodeChecked.setEvent(verified)
- }
+ return code
+ }
+
+ /**
+ * Verifies existing recovery code and returns result via [existingCodeChecked].
+ */
+ fun verifyExistingCode(input: List<CharSequence>) {
+ // we validate the code again, just in case
+ val seed = validateCode(input).toSeed()
+ val verified = crypto.verifyBackupKey(seed)
+ // store main key at this opportunity if it is still missing
+ if (verified && !keyManager.hasMainKey()) keyManager.storeMainKey(seed)
+ mExistingCodeChecked.setEvent(verified)
+ }
+
+ /**
+ * Stores a new recovery code and returns result via [recoveryCodeSaved].
+ */
+ fun storeNewCode(input: List<CharSequence>) {
+ // we validate the code again, just in case
+ val seed = validateCode(input).toSeed()
+ keyManager.storeBackupKey(seed)
+ keyManager.storeMainKey(seed)
+ mRecoveryCodeSaved.setEvent(true)
}
/**