better password processing, master password to setup wizard
This commit is contained in:
parent
8cc51abae9
commit
d2c9f13932
11 changed files with 148 additions and 27 deletions
|
@ -322,7 +322,9 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
if (preference != null) {
|
if (preference != null) {
|
||||||
if (preference.key == resourceHelper.gs(R.string.key_master_password)) {
|
if (preference.key == resourceHelper.gs(R.string.key_master_password)) {
|
||||||
passwordCheck.setPassword(context, R.string.master_password, R.string.key_master_password)
|
passwordCheck.queryPassword(context, R.string.current_master_password, R.string.key_master_password, {
|
||||||
|
passwordCheck.setPassword(context, R.string.master_password, R.string.key_master_password)
|
||||||
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (preference.key == resourceHelper.gs(R.string.key_settings_password)) {
|
if (preference.key == resourceHelper.gs(R.string.key_settings_password)) {
|
||||||
|
|
|
@ -165,6 +165,7 @@ interface AppComponent : AndroidInjector<MainApp> {
|
||||||
fun injectSWButton(swButton: SWButton)
|
fun injectSWButton(swButton: SWButton)
|
||||||
fun injectSWEditNumberWithUnits(swEditNumberWithUnits: SWEditNumberWithUnits)
|
fun injectSWEditNumberWithUnits(swEditNumberWithUnits: SWEditNumberWithUnits)
|
||||||
fun injectSWEditString(swEditString: SWEditString)
|
fun injectSWEditString(swEditString: SWEditString)
|
||||||
|
fun injectSWEditEncryptedPassword(swSWEditEncryptedPassword: SWEditEncryptedPassword)
|
||||||
fun injectSWEditUrl(swEditUrl: SWEditUrl)
|
fun injectSWEditUrl(swEditUrl: SWEditUrl)
|
||||||
fun injectSWFragment(swFragment: SWFragment)
|
fun injectSWFragment(swFragment: SWFragment)
|
||||||
fun injectSSWHtmlLink(swHtmlLink: SWHtmlLink)
|
fun injectSSWHtmlLink(swHtmlLink: SWHtmlLink)
|
||||||
|
|
|
@ -246,6 +246,7 @@ open class AppModule {
|
||||||
@ContributesAndroidInjector fun swButtonInjector(): SWButton
|
@ContributesAndroidInjector fun swButtonInjector(): SWButton
|
||||||
@ContributesAndroidInjector fun swEditNumberWithUnitsInjector(): SWEditNumberWithUnits
|
@ContributesAndroidInjector fun swEditNumberWithUnitsInjector(): SWEditNumberWithUnits
|
||||||
@ContributesAndroidInjector fun swEditStringInjector(): SWEditString
|
@ContributesAndroidInjector fun swEditStringInjector(): SWEditString
|
||||||
|
@ContributesAndroidInjector fun swEditEncryptedPasswordInjector(): SWEditEncryptedPassword
|
||||||
@ContributesAndroidInjector fun swEditUrlInjector(): SWEditUrl
|
@ContributesAndroidInjector fun swEditUrlInjector(): SWEditUrl
|
||||||
@ContributesAndroidInjector fun swFragmentInjector(): SWFragment
|
@ContributesAndroidInjector fun swFragmentInjector(): SWFragment
|
||||||
@ContributesAndroidInjector fun swHtmlLinkInjector(): SWHtmlLink
|
@ContributesAndroidInjector fun swHtmlLinkInjector(): SWHtmlLink
|
||||||
|
|
|
@ -33,6 +33,7 @@ import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||||
import info.nightscout.androidaps.setupwizard.elements.*
|
import info.nightscout.androidaps.setupwizard.elements.*
|
||||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||||
import info.nightscout.androidaps.utils.AndroidPermission
|
import info.nightscout.androidaps.utils.AndroidPermission
|
||||||
|
import info.nightscout.androidaps.utils.CryptoUtil
|
||||||
import info.nightscout.androidaps.utils.LocaleHelper.update
|
import info.nightscout.androidaps.utils.LocaleHelper.update
|
||||||
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
||||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
||||||
|
@ -60,7 +61,8 @@ class SWDefinition @Inject constructor(
|
||||||
private val nsProfilePlugin: NSProfilePlugin,
|
private val nsProfilePlugin: NSProfilePlugin,
|
||||||
private val protectionCheck: ProtectionCheck,
|
private val protectionCheck: ProtectionCheck,
|
||||||
private val importExportPrefs: ImportExportPrefs,
|
private val importExportPrefs: ImportExportPrefs,
|
||||||
private val androidPermission: AndroidPermission
|
private val androidPermission: AndroidPermission,
|
||||||
|
private val cryptoUtil: CryptoUtil
|
||||||
) {
|
) {
|
||||||
|
|
||||||
lateinit var activity: AppCompatActivity
|
lateinit var activity: AppCompatActivity
|
||||||
|
@ -203,9 +205,18 @@ class SWDefinition @Inject constructor(
|
||||||
.add(SWInfotext(injector)
|
.add(SWInfotext(injector)
|
||||||
.label(R.string.patient_name_summary))
|
.label(R.string.patient_name_summary))
|
||||||
.add(SWEditString(injector)
|
.add(SWEditString(injector)
|
||||||
.validator(SWTextValidator { text: String -> text.length > 0 })
|
.validator(SWTextValidator(String::isNotEmpty))
|
||||||
.preferenceId(R.string.key_patient_name)
|
.preferenceId(R.string.key_patient_name))
|
||||||
.updateDelay(5))
|
private val screenMasterPassword = SWScreen(injector, R.string.master_password)
|
||||||
|
.skippable(false)
|
||||||
|
.add(SWInfotext(injector)
|
||||||
|
.label(R.string.master_password))
|
||||||
|
.add(SWEditEncryptedPassword(injector, cryptoUtil)
|
||||||
|
.preferenceId(R.string.key_master_password))
|
||||||
|
.add(SWBreak(injector))
|
||||||
|
.add(SWInfotext(injector)
|
||||||
|
.label(R.string.master_password_summary))
|
||||||
|
.validator(SWValidator { !cryptoUtil.checkPassword("", sp.getString(R.string.key_master_password, "")) })
|
||||||
private val screenAge = SWScreen(injector, R.string.patientage)
|
private val screenAge = SWScreen(injector, R.string.patientage)
|
||||||
.skippable(false)
|
.skippable(false)
|
||||||
.add(SWBreak(injector))
|
.add(SWBreak(injector))
|
||||||
|
@ -393,6 +404,7 @@ class SWDefinition @Inject constructor(
|
||||||
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
||||||
.add(screenPermissionBt)
|
.add(screenPermissionBt)
|
||||||
.add(screenPermissionStore)
|
.add(screenPermissionStore)
|
||||||
|
.add(screenMasterPassword)
|
||||||
.add(screenImport)
|
.add(screenImport)
|
||||||
.add(screenUnits)
|
.add(screenUnits)
|
||||||
.add(displaySettings)
|
.add(displaySettings)
|
||||||
|
@ -420,6 +432,7 @@ class SWDefinition @Inject constructor(
|
||||||
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
||||||
.add(screenPermissionBt)
|
.add(screenPermissionBt)
|
||||||
.add(screenPermissionStore)
|
.add(screenPermissionStore)
|
||||||
|
.add(screenMasterPassword)
|
||||||
.add(screenImport)
|
.add(screenImport)
|
||||||
.add(screenUnits)
|
.add(screenUnits)
|
||||||
.add(displaySettings)
|
.add(displaySettings)
|
||||||
|
@ -442,6 +455,7 @@ class SWDefinition @Inject constructor(
|
||||||
.add(screenEula)
|
.add(screenEula)
|
||||||
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
.add(if (isRunningTest()) null else screenPermissionBattery) // cannot mock ask battery optimization
|
||||||
.add(screenPermissionStore)
|
.add(screenPermissionStore)
|
||||||
|
.add(screenMasterPassword)
|
||||||
.add(screenImport)
|
.add(screenImport)
|
||||||
.add(screenUnits)
|
.add(screenUnits)
|
||||||
.add(displaySettings)
|
.add(displaySettings)
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package info.nightscout.androidaps.setupwizard.elements
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.InputType
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.setupwizard.SWTextValidator
|
||||||
|
import info.nightscout.androidaps.utils.CryptoUtil
|
||||||
|
|
||||||
|
class SWEditEncryptedPassword(injector: HasAndroidInjector, private val cryptoUtil: CryptoUtil) : SWItem(injector, Type.STRING) {
|
||||||
|
|
||||||
|
private var validator: SWTextValidator = SWTextValidator(String::isNotEmpty)
|
||||||
|
private var updateDelay = 0L
|
||||||
|
|
||||||
|
override fun generateDialog(layout: LinearLayout) {
|
||||||
|
val context = layout.context
|
||||||
|
val l = TextView(context)
|
||||||
|
l.id = View.generateViewId()
|
||||||
|
label?.let { l.setText(it) }
|
||||||
|
l.setTypeface(l.typeface, Typeface.BOLD)
|
||||||
|
layout.addView(l)
|
||||||
|
val c = TextView(context)
|
||||||
|
c.id = View.generateViewId()
|
||||||
|
comment?.let { c.setText(it) }
|
||||||
|
c.setTypeface(c.typeface, Typeface.ITALIC)
|
||||||
|
layout.addView(c)
|
||||||
|
val editText = EditText(context)
|
||||||
|
editText.id = View.generateViewId()
|
||||||
|
editText.inputType = InputType.TYPE_CLASS_TEXT
|
||||||
|
editText.maxLines = 1
|
||||||
|
editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
layout.addView(editText)
|
||||||
|
|
||||||
|
val c2 = TextView(context)
|
||||||
|
c2.id = View.generateViewId()
|
||||||
|
c2.setText(R.string.confirm)
|
||||||
|
layout.addView(c2)
|
||||||
|
|
||||||
|
val editText2 = EditText(context)
|
||||||
|
editText2.id = View.generateViewId()
|
||||||
|
editText2.inputType = InputType.TYPE_CLASS_TEXT
|
||||||
|
editText2.maxLines = 1
|
||||||
|
editText2.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
layout.addView(editText2)
|
||||||
|
|
||||||
|
super.generateDialog(layout)
|
||||||
|
val watcher = object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
sp.remove(preferenceId)
|
||||||
|
scheduleChange(updateDelay)
|
||||||
|
if (validator.isValid(editText.text.toString()) && validator.isValid(editText2.text.toString()) && editText.text.toString() == editText2.text.toString())
|
||||||
|
save(s.toString(), updateDelay)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable) {}
|
||||||
|
}
|
||||||
|
editText.addTextChangedListener(watcher)
|
||||||
|
editText2.addTextChangedListener(watcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun preferenceId(preferenceId: Int): SWEditEncryptedPassword {
|
||||||
|
this.preferenceId = preferenceId
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validator(validator: SWTextValidator): SWEditEncryptedPassword {
|
||||||
|
this.validator = validator
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun save(value: String, updateDelay: Long) {
|
||||||
|
sp.putString(preferenceId, cryptoUtil.hashPassword(value))
|
||||||
|
scheduleChange(updateDelay)
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledFuture
|
import java.util.concurrent.ScheduledFuture
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
@ -20,7 +21,7 @@ open class SWItem(val injector: HasAndroidInjector, var type: Type) {
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var rxBus: RxBusWrapper
|
@Inject lateinit var rxBus: RxBusWrapper
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var sp: info.nightscout.androidaps.utils.sharedPreferences.SP
|
@Inject lateinit var sp: SP
|
||||||
|
|
||||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||||
private var scheduledEventPost: ScheduledFuture<*>? = null
|
private var scheduledEventPost: ScheduledFuture<*>? = null
|
||||||
|
@ -55,7 +56,7 @@ open class SWItem(val injector: HasAndroidInjector, var type: Type) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun save(value: String, updateDelay: Long) {
|
open fun save(value: String, updateDelay: Long) {
|
||||||
sp.putString(preferenceId, value)
|
sp.putString(preferenceId, value)
|
||||||
scheduleChange(updateDelay)
|
scheduleChange(updateDelay)
|
||||||
}
|
}
|
||||||
|
@ -69,7 +70,7 @@ open class SWItem(val injector: HasAndroidInjector, var type: Type) {
|
||||||
open fun generateDialog(layout: LinearLayout) {}
|
open fun generateDialog(layout: LinearLayout) {}
|
||||||
open fun processVisibility() {}
|
open fun processVisibility() {}
|
||||||
|
|
||||||
private fun scheduleChange(updateDelay: Long) {
|
fun scheduleChange(updateDelay: Long) {
|
||||||
class PostRunnable : Runnable {
|
class PostRunnable : Runnable {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
aapsLogger.debug(LTag.CORE, "Firing EventPreferenceChange")
|
aapsLogger.debug(LTag.CORE, "Firing EventPreferenceChange")
|
||||||
|
|
|
@ -8,7 +8,7 @@ import info.nightscout.androidaps.utils.ToastUtils
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
object BiometricCheck {
|
object BiometricCheck {
|
||||||
fun biometricPrompt(activity: FragmentActivity, title: Int, ok: Runnable?, cancel: Runnable? = null, fail: Runnable? = null) {
|
fun biometricPrompt(activity: FragmentActivity, title: Int, ok: Runnable?, cancel: Runnable? = null, fail: Runnable? = null, passwordCheck: PasswordCheck) {
|
||||||
val executor = Executors.newSingleThreadExecutor()
|
val executor = Executors.newSingleThreadExecutor()
|
||||||
|
|
||||||
val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() {
|
val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() {
|
||||||
|
@ -23,15 +23,19 @@ object BiometricCheck {
|
||||||
BiometricConstants.ERROR_LOCKOUT_PERMANENT,
|
BiometricConstants.ERROR_LOCKOUT_PERMANENT,
|
||||||
BiometricConstants.ERROR_USER_CANCELED -> {
|
BiometricConstants.ERROR_USER_CANCELED -> {
|
||||||
ToastUtils.showToastInUiThread(activity.baseContext, errString.toString())
|
ToastUtils.showToastInUiThread(activity.baseContext, errString.toString())
|
||||||
fail?.run()
|
// fallback to master password
|
||||||
|
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() })
|
||||||
}
|
}
|
||||||
|
|
||||||
BiometricConstants.ERROR_NEGATIVE_BUTTON ->
|
BiometricConstants.ERROR_NEGATIVE_BUTTON ->
|
||||||
cancel?.run()
|
cancel?.run()
|
||||||
|
|
||||||
BiometricConstants.ERROR_NO_DEVICE_CREDENTIAL ->
|
BiometricConstants.ERROR_NO_DEVICE_CREDENTIAL -> {
|
||||||
// call ok, because it's not possible to bypass it when biometrics is setup, hw not present and no pin set
|
ToastUtils.showToastInUiThread(activity.baseContext, errString.toString())
|
||||||
ok?.run()
|
// no pin set
|
||||||
|
// fallback to master password
|
||||||
|
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() })
|
||||||
|
}
|
||||||
|
|
||||||
BiometricConstants.ERROR_NO_SPACE,
|
BiometricConstants.ERROR_NO_SPACE,
|
||||||
BiometricConstants.ERROR_HW_UNAVAILABLE,
|
BiometricConstants.ERROR_HW_UNAVAILABLE,
|
||||||
|
|
|
@ -16,19 +16,19 @@ import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
// since androidx.autofill.HintConstants are not available
|
// since androidx.autofill.HintConstants are not available
|
||||||
val AUTOFILL_HINT_NEW_PASSWORD = "newPassword"
|
const val AUTOFILL_HINT_NEW_PASSWORD = "newPassword"
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PasswordCheck @Inject constructor(
|
class PasswordCheck @Inject constructor(
|
||||||
val sp: SP,
|
val sp: SP,
|
||||||
val cryptoUtil: CryptoUtil
|
private val cryptoUtil: CryptoUtil
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
fun queryPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, ok: ( (String) -> Unit)?, cancel: (()->Unit)? = null, fail: (()->Unit)? = null) {
|
fun queryPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, ok: ((String) -> Unit)?, cancel: (() -> Unit)? = null, fail: (() -> Unit)? = null) {
|
||||||
val password = sp.getString(preference, "")
|
val password = sp.getString(preference, "")
|
||||||
if (password == "") {
|
if (password == "") {
|
||||||
ok?.invoke("")
|
ok?.invoke("")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,11 @@ class PasswordCheck @Inject constructor(
|
||||||
val alertDialogBuilder = AlertDialogHelper.Builder(context)
|
val alertDialogBuilder = AlertDialogHelper.Builder(context)
|
||||||
alertDialogBuilder.setView(promptsView)
|
alertDialogBuilder.setView(promptsView)
|
||||||
|
|
||||||
val userInput = promptsView.findViewById<View>(R.id.passwordprompt_pass) as EditText
|
val userInput = promptsView.findViewById<View>(R.id.password_prompt_pass) as EditText
|
||||||
|
val userInput2 = promptsView.findViewById<View>(R.id.password_prompt_pass_confirm) as EditText
|
||||||
|
|
||||||
|
userInput2.visibility = View.GONE
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val autoFillHintPasswordKind = context.getString(preference)
|
val autoFillHintPasswordKind = context.getString(preference)
|
||||||
userInput.setAutofillHints(View.AUTOFILL_HINT_PASSWORD, "aaps_${autoFillHintPasswordKind}")
|
userInput.setAutofillHints(View.AUTOFILL_HINT_PASSWORD, "aaps_${autoFillHintPasswordKind}")
|
||||||
|
@ -64,12 +68,13 @@ class PasswordCheck @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
fun setPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, ok: ( (String) -> Unit)? = null, cancel: (()->Unit)? = null, clear: (()->Unit)? = null) {
|
fun setPassword(context: Context, @StringRes labelId: Int, @StringRes preference: Int, ok: ((String) -> Unit)? = null, cancel: (() -> Unit)? = null, clear: (() -> Unit)? = null) {
|
||||||
val promptsView = LayoutInflater.from(context).inflate(R.layout.passwordprompt, null)
|
val promptsView = LayoutInflater.from(context).inflate(R.layout.passwordprompt, null)
|
||||||
val alertDialogBuilder = AlertDialogHelper.Builder(context)
|
val alertDialogBuilder = AlertDialogHelper.Builder(context)
|
||||||
alertDialogBuilder.setView(promptsView)
|
alertDialogBuilder.setView(promptsView)
|
||||||
|
|
||||||
val userInput = promptsView.findViewById<View>(R.id.passwordprompt_pass) as EditText
|
val userInput = promptsView.findViewById<View>(R.id.password_prompt_pass) as EditText
|
||||||
|
val userInput2 = promptsView.findViewById<View>(R.id.password_prompt_pass_confirm) as EditText
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val autoFillHintPasswordKind = context.getString(preference)
|
val autoFillHintPasswordKind = context.getString(preference)
|
||||||
|
@ -82,7 +87,10 @@ class PasswordCheck @Inject constructor(
|
||||||
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, context.getString(labelId), R.drawable.ic_header_key))
|
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, context.getString(labelId), R.drawable.ic_header_key))
|
||||||
.setPositiveButton(context.getString(R.string.ok)) { _, _ ->
|
.setPositiveButton(context.getString(R.string.ok)) { _, _ ->
|
||||||
val enteredPassword = userInput.text.toString()
|
val enteredPassword = userInput.text.toString()
|
||||||
if (enteredPassword.isNotEmpty()) {
|
val enteredPassword2 = userInput2.text.toString()
|
||||||
|
if (enteredPassword != enteredPassword2) {
|
||||||
|
ToastUtils.errorToast(context, context.getString(R.string.passwords_dont_match))
|
||||||
|
} else if (enteredPassword.isNotEmpty()) {
|
||||||
sp.putString(preference, cryptoUtil.hashPassword(enteredPassword))
|
sp.putString(preference, cryptoUtil.hashPassword(enteredPassword))
|
||||||
ToastUtils.okToast(context, context.getString(R.string.password_set))
|
ToastUtils.okToast(context, context.getString(R.string.password_set))
|
||||||
ok?.invoke(enteredPassword)
|
ok?.invoke(enteredPassword)
|
||||||
|
|
|
@ -56,7 +56,7 @@ class ProtectionCheck @Inject constructor(
|
||||||
ProtectionType.NONE ->
|
ProtectionType.NONE ->
|
||||||
ok?.run()
|
ok?.run()
|
||||||
ProtectionType.BIOMETRIC ->
|
ProtectionType.BIOMETRIC ->
|
||||||
BiometricCheck.biometricPrompt(activity, titleResourceIDs[protection.ordinal], ok, cancel, fail)
|
BiometricCheck.biometricPrompt(activity, titleResourceIDs[protection.ordinal], ok, cancel, fail, passwordCheck)
|
||||||
ProtectionType.MASTER_PASSWORD ->
|
ProtectionType.MASTER_PASSWORD ->
|
||||||
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() })
|
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() })
|
||||||
ProtectionType.CUSTOM_PASSWORD ->
|
ProtectionType.CUSTOM_PASSWORD ->
|
||||||
|
|
|
@ -3,18 +3,23 @@
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="10dp" >
|
android:padding="10dp">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/passwordprompt_pass"
|
android:id="@+id/password_prompt_pass"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/password_hint"
|
android:hint="@string/password_hint"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword">
|
||||||
>
|
|
||||||
|
|
||||||
<requestFocus />
|
<requestFocus />
|
||||||
|
|
||||||
</EditText>
|
</EditText>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/password_prompt_pass_confirm"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/password_hint"
|
||||||
|
android:inputType="textPassword"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1805,4 +1805,7 @@
|
||||||
<string name="key_graphconfig" translatable="false">graphconfig</string>
|
<string name="key_graphconfig" translatable="false">graphconfig</string>
|
||||||
<string name="authorizationfailed">Authorization failed</string>
|
<string name="authorizationfailed">Authorization failed</string>
|
||||||
<string name="overview_show_absinsulin">Absolute insulin</string>
|
<string name="overview_show_absinsulin">Absolute insulin</string>
|
||||||
|
<string name="master_password_summary">Master password is used for backup encryption and to override security in application. Remember it or store on a safe place.</string>
|
||||||
|
<string name="passwords_dont_match">Passwords don\'t match</string>
|
||||||
|
<string name="current_master_password">Current master password</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue