diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt index 0cd8ae95a..fa3ebaab0 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt @@ -212,10 +212,7 @@ class EntryEditActivity : LockingActivity(), true } R.id.menu_add_otp -> { - // Retrieve the current otpElement if exists - // and open the dialog to set up the OTP - SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel) - .show(supportFragmentManager, "addOTPDialog") + setupOTP() true } else -> true @@ -315,6 +312,13 @@ class EntryEditActivity : LockingActivity(), entryEditContentsView?.addEmptyCustomField() } + private fun setupOTP() { + // Retrieve the current otpElement if exists + // and open the dialog to set up the OTP + SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel) + .show(supportFragmentManager, "addOTPDialog") + } + /** * Saves the new entry or update an existing entry in the database */ @@ -372,12 +376,10 @@ class EntryEditActivity : LockingActivity(), } private fun performedNextEducation(entryEditActivityEducation: EntryEditActivityEducation) { - val passwordView: View? = null// TODO entryEditContentsView?.generatePasswordView - val addNewFieldView: View? = null // TODO entryEditContentsView?.addNewFieldButton - - val generatePasswordEducationPerformed = passwordView != null + val passwordGeneratorView: View? = entryEditAddToolBar?.findViewById(R.id.menu_generate_password) + val generatePasswordEducationPerformed = passwordGeneratorView != null && entryEditActivityEducation.checkAndPerformedGeneratePasswordEducation( - passwordView, + passwordGeneratorView, { openPasswordGenerator() }, @@ -386,14 +388,28 @@ class EntryEditActivity : LockingActivity(), } ) if (!generatePasswordEducationPerformed) { - // entryNewFieldEducationPerformed - mNewEntry != null && mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty() + val addNewFieldView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_field) + val addNewFieldEducationPerformed = mNewEntry != null + && mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty() && addNewFieldView != null && addNewFieldView.visibility == View.VISIBLE && entryEditActivityEducation.checkAndPerformedEntryNewFieldEducation( addNewFieldView, { addNewCustomField() - }) + }, + { + performedNextEducation(entryEditActivityEducation) + } + ) + if (!addNewFieldEducationPerformed) { + val setupOtpView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_otp) + setupOtpView != null && setupOtpView.visibility == View.VISIBLE + && entryEditActivityEducation.checkAndPerformedSetUpOTPEducation( + setupOtpView, + { + setupOTP() + }) + } } } diff --git a/app/src/main/java/com/kunzisoft/keepass/education/Education.kt b/app/src/main/java/com/kunzisoft/keepass/education/Education.kt index 5dd88173b..4de51a2c6 100644 --- a/app/src/main/java/com/kunzisoft/keepass/education/Education.kt +++ b/app/src/main/java/com/kunzisoft/keepass/education/Education.kt @@ -94,7 +94,8 @@ open class Education(val activity: Activity) { R.string.education_copy_username_key, R.string.education_entry_edit_key, R.string.education_password_generator_key, - R.string.education_entry_new_field_key) + R.string.education_entry_new_field_key, + R.string.education_setup_OTP_key) /** @@ -271,6 +272,18 @@ open class Education(val activity: Activity) { context.resources.getBoolean(R.bool.education_entry_new_field_default)) } + /** + * Determines whether the explanatory view to setup OTP has already been displayed. + * + * @param context The context to open the SharedPreferences + * @return boolean value of education_setup_OTP_key key + */ + fun isEducationSetupOTPPerformed(context: Context): Boolean { + val prefs = getEducationSharedPreferences(context) + return prefs.getBoolean(context.getString(R.string.education_setup_OTP_key), + context.resources.getBoolean(R.bool.education_setup_OTP_default)) + } + /** * Defines if the reset education preference has been reclicked * diff --git a/app/src/main/java/com/kunzisoft/keepass/education/EntryEditActivityEducation.kt b/app/src/main/java/com/kunzisoft/keepass/education/EntryEditActivityEducation.kt index c6f77a47e..b7d1f01ef 100644 --- a/app/src/main/java/com/kunzisoft/keepass/education/EntryEditActivityEducation.kt +++ b/app/src/main/java/com/kunzisoft/keepass/education/EntryEditActivityEducation.kt @@ -37,7 +37,7 @@ class EntryEditActivityEducation(activity: Activity) activity.getString(R.string.education_generate_password_title), activity.getString(R.string.education_generate_password_summary)) .textColorInt(Color.WHITE) - .tintTarget(false) + .tintTarget(true) .cancelable(true), object : TapTargetView.Listener() { override fun onTargetClick(view: TapTargetView) { @@ -66,7 +66,7 @@ class EntryEditActivityEducation(activity: Activity) activity.getString(R.string.education_entry_new_field_title), activity.getString(R.string.education_entry_new_field_summary)) .textColorInt(Color.WHITE) - .tintTarget(false) + .tintTarget(true) .cancelable(true), object : TapTargetView.Listener() { override fun onTargetClick(view: TapTargetView) { @@ -82,4 +82,33 @@ class EntryEditActivityEducation(activity: Activity) }, R.string.education_entry_new_field_key) } + + /** + * Check and display learning views + * Displays the explanation to setup OTP + */ + fun checkAndPerformedSetUpOTPEducation(educationView: View, + onEducationViewClick: ((TapTargetView?) -> Unit)? = null, + onOuterViewClick: ((TapTargetView?) -> Unit)? = null): Boolean { + return checkAndPerformedEducation(!isEducationSetupOTPPerformed(activity), + TapTarget.forView(educationView, + activity.getString(R.string.education_setup_OTP_title), + activity.getString(R.string.education_setup_OTP_summary)) + .textColorInt(Color.WHITE) + .tintTarget(true) + .cancelable(true), + object : TapTargetView.Listener() { + override fun onTargetClick(view: TapTargetView) { + super.onTargetClick(view) + onEducationViewClick?.invoke(view) + } + + override fun onOuterCircleClick(view: TapTargetView?) { + super.onOuterCircleClick(view) + view?.dismiss(false) + onOuterViewClick?.invoke(view) + } + }, + R.string.education_setup_OTP_key) + } } \ No newline at end of file diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 6d623b39d..0f44c87e2 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -236,6 +236,8 @@ false education_entry_new_field_key false + education_setup_OTP_key + false education_screen_reclicked_key false diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 320125a72..83913cd9f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -400,10 +400,12 @@ Link your password to your scanned biometric to quickly unlock your database. Edit the entry Edit your entry with custom fields. Pool data can be referenced between different entry fields. - Create a strong password for your entry. + Create a strong password Generate a strong password to associate with your entry, easily define it according to the criteria of the form and don\'t forget secure password. Add custom fields Register an additional field, add a value and optionally protect it. + Setup OTP + Setup One-Time Password management (HOTP / TOTP) to generate a token requested for Two-factor authentication (2FA). Unlock your database Enter the password and/or keyfile to unlock your database.\n\nBackup your database file in a safe place after each change. Write protect your database