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)
     }
 
     /**