From 7c383618448d7d4387ce4e310a2abf81f2e7f2eb Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 18 Jan 2021 16:48:57 +0100 Subject: [PATCH] Fix OTP token type #863 --- CHANGELOG | 2 +- .../dialogs/SetOTPDialogFragment.kt | 45 +++++++++++++------ app/src/main/res/layout/fragment_set_otp.xml | 12 +++++ app/src/main/res/values/strings.xml | 1 + .../metadata/android/en-US/changelogs/56.txt | 2 +- .../metadata/android/fr-FR/changelogs/56.txt | 2 +- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 759d82cb5..49c5c2c76 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,5 @@ KeePassDX(2.9.12) - * + * Fix OTP token type #863 KeePassDX(2.9.11) * Add Keyfile XML version 2 (fix hex) #844 diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/SetOTPDialogFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/SetOTPDialogFragment.kt index ef50393fc..487cd52e1 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/SetOTPDialogFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/SetOTPDialogFragment.kt @@ -29,10 +29,7 @@ import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo -import android.widget.AdapterView -import android.widget.ArrayAdapter -import android.widget.EditText -import android.widget.Spinner +import android.widget.* import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import com.google.android.material.textfield.TextInputLayout @@ -57,6 +54,7 @@ class SetOTPDialogFragment : DialogFragment() { private var mOtpElement: OtpElement = OtpElement() + private var otpTypeMessage: TextView? = null private var otpTypeSpinner: Spinner? = null private var otpTokenTypeSpinner: Spinner? = null private var otpSecretContainer: TextInputLayout? = null @@ -74,6 +72,8 @@ class SetOTPDialogFragment : DialogFragment() { private var totpTokenTypeAdapter: ArrayAdapter? = null private var hotpTokenTypeAdapter: ArrayAdapter? = null private var otpAlgorithmAdapter: ArrayAdapter? = null + private var mHotpTokenTypeArray: Array? = null + private var mTotpTokenTypeArray: Array? = null private var mManualEvent = false private var mOnFocusChangeListener = View.OnFocusChangeListener { _, isFocus -> @@ -134,6 +134,7 @@ class SetOTPDialogFragment : DialogFragment() { activity?.let { activity -> val root = activity.layoutInflater.inflate(R.layout.fragment_set_otp, null) as ViewGroup? + otpTypeMessage = root?.findViewById(R.id.setup_otp_type_message) otpTypeSpinner = root?.findViewById(R.id.setup_otp_type) otpTokenTypeSpinner = root?.findViewById(R.id.setup_otp_token_type) otpSecretContainer = root?.findViewById(R.id.setup_otp_secret_label) @@ -183,23 +184,23 @@ class SetOTPDialogFragment : DialogFragment() { // HOTP / TOTP Type selection val otpTypeArray = OtpType.values() - otpTypeAdapter = ArrayAdapter(activity, + otpTypeAdapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, otpTypeArray).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } otpTypeSpinner?.adapter = otpTypeAdapter // Otp Token type selection - val hotpTokenTypeArray = OtpTokenType.getHotpTokenTypeValues() + mHotpTokenTypeArray = OtpTokenType.getHotpTokenTypeValues() hotpTokenTypeAdapter = ArrayAdapter(activity, - android.R.layout.simple_spinner_item, hotpTokenTypeArray).apply { + android.R.layout.simple_spinner_item, mHotpTokenTypeArray!!).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } // Proprietary only on closed and full version - val totpTokenTypeArray = OtpTokenType.getTotpTokenTypeValues( + mTotpTokenTypeArray = OtpTokenType.getTotpTokenTypeValues( BuildConfig.CLOSED_STORE && BuildConfig.FULL_VERSION) totpTokenTypeAdapter = ArrayAdapter(activity, - android.R.layout.simple_spinner_item, totpTokenTypeArray).apply { + android.R.layout.simple_spinner_item, mTotpTokenTypeArray!!).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } otpTokenTypeAdapter = hotpTokenTypeAdapter @@ -207,7 +208,7 @@ class SetOTPDialogFragment : DialogFragment() { // OTP Algorithm val otpAlgorithmArray = TokenCalculator.HashAlgorithm.values() - otpAlgorithmAdapter = ArrayAdapter(activity, + otpAlgorithmAdapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, otpAlgorithmArray).apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } @@ -372,24 +373,40 @@ class SetOTPDialogFragment : DialogFragment() { } private fun upgradeTokenType() { + val tokenType = mOtpElement.tokenType when (mOtpElement.type) { OtpType.HOTP -> { otpPeriodContainer?.visibility = View.GONE otpCounterContainer?.visibility = View.VISIBLE otpTokenTypeSpinner?.adapter = hotpTokenTypeAdapter - otpTokenTypeSpinner?.setSelection(OtpTokenType - .getHotpTokenTypeValues().indexOf(mOtpElement.tokenType)) + mHotpTokenTypeArray?.let { otpTokenTypeArray -> + defineOtpTokenTypeSpinner(otpTokenTypeArray, tokenType, OtpTokenType.RFC4226) + } } OtpType.TOTP -> { otpPeriodContainer?.visibility = View.VISIBLE otpCounterContainer?.visibility = View.GONE otpTokenTypeSpinner?.adapter = totpTokenTypeAdapter - otpTokenTypeSpinner?.setSelection(OtpTokenType - .getTotpTokenTypeValues().indexOf(mOtpElement.tokenType)) + mTotpTokenTypeArray?.let { otpTokenTypeArray -> + defineOtpTokenTypeSpinner(otpTokenTypeArray, tokenType, OtpTokenType.RFC6238) + } } } } + private fun defineOtpTokenTypeSpinner(otpTokenTypeArray: Array, + tokenType: OtpTokenType, + defaultTokenType: OtpTokenType) { + val formTokenType = if (otpTokenTypeArray.contains(tokenType)) { + otpTypeMessage?.visibility = View.GONE + tokenType + } else { + otpTypeMessage?.visibility = View.VISIBLE + defaultTokenType + } + otpTokenTypeSpinner?.setSelection(otpTokenTypeArray.indexOf(formTokenType)) + } + private fun upgradeParameters() { otpAlgorithmSpinner?.setSelection(TokenCalculator.HashAlgorithm.values() .indexOf(mOtpElement.algorithm)) diff --git a/app/src/main/res/layout/fragment_set_otp.xml b/app/src/main/res/layout/fragment_set_otp.xml index 6ffc6e9d3..c644902b1 100644 --- a/app/src/main/res/layout/fragment_set_otp.xml +++ b/app/src/main/res/layout/fragment_set_otp.xml @@ -29,6 +29,18 @@ android:layout_height="wrap_content" android:importantForAutofill="noExcludeDescendants" tools:targetApi="o"> + + + Counter must be between %1$d and %2$d. Period must be between %1$d and %2$d seconds. Token must contain %1$d to %2$d digits. + The existing OTP type is not recognized by this form, its validation may no longer correctly generate the token. This text does not match the requested item. Saving a new item is not allowed in a read-only database The field name already exists. diff --git a/fastlane/metadata/android/en-US/changelogs/56.txt b/fastlane/metadata/android/en-US/changelogs/56.txt index 42780ecb1..3a843ed42 100644 --- a/fastlane/metadata/android/en-US/changelogs/56.txt +++ b/fastlane/metadata/android/en-US/changelogs/56.txt @@ -1 +1 @@ - * \ No newline at end of file + * Fix OTP token type #863 \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/56.txt b/fastlane/metadata/android/fr-FR/changelogs/56.txt index 42780ecb1..ac3d72178 100644 --- a/fastlane/metadata/android/fr-FR/changelogs/56.txt +++ b/fastlane/metadata/android/fr-FR/changelogs/56.txt @@ -1 +1 @@ - * \ No newline at end of file + * Correction du type de token OTP #863 \ No newline at end of file