aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-08-08 13:06:26 +0530
committerGitHub <noreply@github.com>2021-08-08 13:06:26 +0530
commit1738364d2fdb3c4069d55516ea623d49dcebfd48 (patch)
tree5dd397147b872ec62db00b935ca536216c50e6ae
parent1b54e679b7b6eaf2955c45d4223426650d197461 (diff)
Make password generator parameter changes reactive (#1480)
* Make XkPassword generator reactive * Handle empty strings * Make password generator reactive * Sync changelog for 1.13.5 release * Add to changelog
-rw-r--r--CHANGELOG.md12
-rw-r--r--app/build.gradle.kts1
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt22
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt34
-rw-r--r--gradle/libs.versions.toml2
5 files changed, 61 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66a756f1..bedec617 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -30,11 +30,17 @@ All notable changes to this project will be documented in this file.
- Using the `git://` protocol in the server URL now presents an explicit discouragement rather than a generic error
- Encrypted data is no longer ASCII armored, bringing it in line with `pass`
- Removed Bromite from supported Autofill browsers, since they [disable Android autofill](https://github.com/bromite/bromite/blob/master/FAQ.md#does-bromite-support-the-android-autofill-framework).
+- Changing password generator parameters now automatically updates the password without needing to press the 'Generate' button again
-## [1.13.4] - 2021-03-20
+## [1.13.5] - 2021-07-28
### Fixed
+- When prompted to select a GPG key during onboarding, the app would crash if the user did not make a selection in OpenKeychain
+- Certain apps had incorrect Autofill hints which would crash the app
+
+## [1.13.4] - 2021-03-20
+
- Fix support for ECDSA SSH keys and support AES-GCM
- Fix a couple issues with Autofill
@@ -448,7 +454,9 @@ All notable changes to this project will be documented in this file.
- Fix elements overlapping.
-[Unreleased]: https://github.com/android-password-store/Android-Password-Store/compare/v1.13.4...HEAD
+[Unreleased]: https://github.com/android-password-store/Android-Password-Store/compare/v1.13.5...release-1.13
+
+[1.13.5]: https://github.com/android-password-store/Android-Password-Store/compare/v1.13.4...v1.13.5
[1.13.4]: https://github.com/android-password-store/Android-Password-Store/compare/v1.13.3...v1.13.4
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 4ae3136e..0ca522f7 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -102,6 +102,7 @@ dependencies {
implementation(libs.thirdparty.bouncycastle)
implementation(libs.thirdparty.eddsa)
implementation(libs.thirdparty.fastscroll)
+ implementation(libs.thirdparty.flowbinding.android)
implementation(libs.thirdparty.jgit) {
exclude(group = "org.apache.httpcomponents", module = "httpclient")
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
index 4820521f..ab51cc4e 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
@@ -17,6 +17,7 @@ import androidx.appcompat.widget.AppCompatTextView
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
+import androidx.lifecycle.lifecycleScope
import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -28,7 +29,14 @@ import dev.msfjarvis.aps.util.pwgen.PasswordGenerator.generate
import dev.msfjarvis.aps.util.pwgen.PasswordGenerator.setPrefs
import dev.msfjarvis.aps.util.pwgen.PasswordOption
import dev.msfjarvis.aps.util.settings.PreferenceKeys
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
+import reactivecircus.flowbinding.android.widget.afterTextChanges
+import reactivecircus.flowbinding.android.widget.checkedChanges
+@OptIn(ExperimentalCoroutinesApi::class)
class PasswordGeneratorDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -49,9 +57,21 @@ class PasswordGeneratorDialogFragment : DialogFragment() {
binding.lowercase.isChecked = !prefs.getBoolean(PasswordOption.NoLowercaseLetters.key, false)
binding.ambiguous.isChecked = !prefs.getBoolean(PasswordOption.NoAmbiguousCharacters.key, false)
binding.pronounceable.isChecked = !prefs.getBoolean(PasswordOption.FullyRandom.key, true)
-
binding.lengthNumber.setText(prefs.getInt(PreferenceKeys.LENGTH, 20).toString())
binding.passwordText.typeface = monoTypeface
+
+ merge(
+ binding.numerals.checkedChanges().skipInitialValue(),
+ binding.symbols.checkedChanges().skipInitialValue(),
+ binding.uppercase.checkedChanges().skipInitialValue(),
+ binding.lowercase.checkedChanges().skipInitialValue(),
+ binding.ambiguous.checkedChanges().skipInitialValue(),
+ binding.pronounceable.checkedChanges().skipInitialValue(),
+ binding.lengthNumber.afterTextChanges().skipInitialValue(),
+ )
+ .onEach { generate(binding.passwordText) }
+ .launchIn(lifecycleScope)
+
return builder
.run {
setTitle(R.string.pwgen_title)
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt
index ad252975..645ab9ba 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/XkPasswordGeneratorDialogFragment.kt
@@ -15,6 +15,7 @@ import androidx.core.content.edit
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
+import androidx.lifecycle.lifecycleScope
import com.github.ajalt.timberkt.Timber.tag
import com.github.michaelbull.result.fold
import com.github.michaelbull.result.getOr
@@ -26,8 +27,14 @@ import dev.msfjarvis.aps.ui.crypto.PasswordCreationActivity
import dev.msfjarvis.aps.util.extensions.getString
import dev.msfjarvis.aps.util.pwgenxkpwd.CapsType
import dev.msfjarvis.aps.util.pwgenxkpwd.PasswordBuilder
-
-/** A placeholder fragment containing a simple view. */
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
+import reactivecircus.flowbinding.android.widget.afterTextChanges
+import reactivecircus.flowbinding.android.widget.selectionEvents
+
+@OptIn(ExperimentalCoroutinesApi::class)
class XkPasswordGeneratorDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -69,21 +76,34 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
val dialog = builder.setTitle(this.resources.getString(R.string.xkpwgen_title)).create()
+ // make parameter changes reactive and automatically update passwords
+ merge(
+ binding.xkSeparator.afterTextChanges().skipInitialValue(),
+ binding.xkCapType.selectionEvents().skipInitialValue(),
+ binding.xkNumWords.afterTextChanges().skipInitialValue(),
+ binding.xkNumberSymbolMask.afterTextChanges().skipInitialValue(),
+ )
+ .onEach { updatePassword(binding, prefs) }
+ .launchIn(lifecycleScope)
+
dialog.setOnShowListener {
- setPreferences(binding, prefs)
- makeAndSetPassword(binding)
+ updatePassword(binding, prefs)
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener {
- setPreferences(binding, prefs)
- makeAndSetPassword(binding)
+ updatePassword(binding, prefs)
}
}
return dialog
}
+ private fun updatePassword(binding: FragmentXkpwgenBinding, prefs: SharedPreferences) {
+ setPreferences(binding, prefs)
+ makeAndSetPassword(binding)
+ }
+
private fun makeAndSetPassword(binding: FragmentXkpwgenBinding) {
PasswordBuilder(requireContext())
- .setNumberOfWords(Integer.valueOf(binding.xkNumWords.text.toString()))
+ .setNumberOfWords(binding.xkNumWords.text.toString().ifBlank { "0" }.toInt())
.setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH)
.setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH)
.setSeparator(binding.xkSeparator.text.toString())
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 223ea9a2..32837d4a 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,6 +5,7 @@ androidx_test = "1.4.0"
compose = "1.1.0-alpha01"
composeSnapshot = "-"
coroutines = "1.5.1"
+flowbinding = "1.2.0"
hilt = "2.38.1"
kotlin = "1.5.21"
lifecycle = "2.4.0-alpha03"
@@ -69,6 +70,7 @@ thirdparty-bouncycastle = "org.bouncycastle:bcprov-jdk15on:1.69"
thirdparty-commons_codec = "commons-codec:commons-codec:1.14"
thirdparty-eddsa = "net.i2p.crypto:eddsa:0.3.0"
thirdparty-fastscroll = "me.zhanghai.android.fastscroll:library:1.1.7"
+thirdparty-flowbinding-android = { module = "io.github.reactivecircus.flowbinding:flowbinding-android", version.ref = "flowbinding" }
thirdparty-jgit = "org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r"
thirdparty-kotlinResult = "com.michael-bull.kotlin-result:kotlin-result:1.1.12"
thirdparty-leakcanary = "com.squareup.leakcanary:leakcanary-android:2.7"