Allow adding digits and symbols in XkPasswd generator using mask-like values (#1023)
* - XkPasswordGeneratorDialogFragment: add symbol/number mask to allow appending numbers+symbols via a mask such as `ddds` which would generate random.password123!; position of `d` and `s` is not currently considered; only the count is relevant * - update CHANGELOG.md * - update CHANGELOG.md * - rename constants * Update CHANGELOG.md Co-authored-by: Harsh Shandilya <me@msfjarvis.dev> * - add missing marginTop * - add missing marginTop Co-authored-by: null <null> Co-authored-by: Harsh Shandilya <me@msfjarvis.dev> Co-authored-by: glowinthedark <glowinthedark> Co-authored-by: Harsh Shandilya <msfjarvis@gmail.com>
This commit is contained in:
parent
e2a372bc63
commit
82ae0a8629
7 changed files with 39 additions and 7 deletions
|
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
||||||
### Added
|
### Added
|
||||||
- Allow changing the branch used for Git operations
|
- Allow changing the branch used for Git operations
|
||||||
- Allow setting a subdirectory key when creating folders
|
- Allow setting a subdirectory key when creating folders
|
||||||
|
- Allow adding digits/symbols in XkPasswd generated passwords using a mask-like value (`dds` gives you two digits and a symbol, and so on)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
package com.zeapo.pwdstore.pwgenxkpwd
|
package com.zeapo.pwdstore.pwgenxkpwd
|
||||||
|
|
||||||
enum class CapsType {
|
enum class CapsType {
|
||||||
lowercase, UPPERCASE, TitleCase, Sentencecase, As_iS
|
lowercase, UPPERCASE, TitleCase, Sentence, As_iS
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ class PasswordBuilder(ctx: Context) {
|
||||||
private var maxWordLength = 9
|
private var maxWordLength = 9
|
||||||
private var minWordLength = 5
|
private var minWordLength = 5
|
||||||
private var separator = "."
|
private var separator = "."
|
||||||
private var capsType = CapsType.Sentencecase
|
private var capsType = CapsType.Sentence
|
||||||
private var prependDigits = 0
|
private var prependDigits = 0
|
||||||
private var numDigits = 0
|
private var numDigits = 0
|
||||||
private var isPrependWithSeparator = false
|
private var isPrependWithSeparator = false
|
||||||
|
@ -109,7 +109,7 @@ class PasswordBuilder(ctx: Context) {
|
||||||
val candidate = wordBank.secureRandomElement()
|
val candidate = wordBank.secureRandomElement()
|
||||||
val s = when (capsType) {
|
val s = when (capsType) {
|
||||||
CapsType.UPPERCASE -> candidate.toUpperCase(Locale.getDefault())
|
CapsType.UPPERCASE -> candidate.toUpperCase(Locale.getDefault())
|
||||||
CapsType.Sentencecase -> if (i == 0) candidate.capitalize(Locale.getDefault()) else candidate
|
CapsType.Sentence -> if (i == 0) candidate.capitalize(Locale.getDefault()) else candidate
|
||||||
CapsType.TitleCase -> candidate.capitalize(Locale.getDefault())
|
CapsType.TitleCase -> candidate.capitalize(Locale.getDefault())
|
||||||
CapsType.lowercase -> candidate.toLowerCase(Locale.getDefault())
|
CapsType.lowercase -> candidate.toLowerCase(Locale.getDefault())
|
||||||
CapsType.As_iS -> candidate
|
CapsType.As_iS -> candidate
|
||||||
|
|
|
@ -58,6 +58,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
||||||
binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS))
|
binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS))
|
||||||
|
|
||||||
binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR))
|
binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR))
|
||||||
|
binding.xkNumberSymbolMask.setText(prefs.getString(PREF_KEY_EXTRA_SYMBOLS_MASK, DEFAULT_EXTRA_SYMBOLS_MASK))
|
||||||
|
|
||||||
binding.xkPasswordText.typeface = monoTypeface
|
binding.xkPasswordText.typeface = monoTypeface
|
||||||
|
|
||||||
|
@ -92,6 +93,8 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
||||||
.setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH)
|
.setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH)
|
||||||
.setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH)
|
.setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH)
|
||||||
.setSeparator(binding.xkSeparator.text.toString())
|
.setSeparator(binding.xkSeparator.text.toString())
|
||||||
|
.appendNumbers(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_DIGIT })
|
||||||
|
.appendSymbols(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_SYMBOL })
|
||||||
.setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())).create()
|
.setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())).create()
|
||||||
} catch (e: PasswordGenerator.PasswordGeneratorException) {
|
} catch (e: PasswordGenerator.PasswordGeneratorException) {
|
||||||
Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show()
|
||||||
|
@ -105,6 +108,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
||||||
putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString())
|
putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString())
|
||||||
putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString())
|
putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString())
|
||||||
putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString())
|
putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString())
|
||||||
|
putString(PREF_KEY_EXTRA_SYMBOLS_MASK, binding.xkNumberSymbolMask.text.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +117,16 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
||||||
const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style"
|
const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style"
|
||||||
const val PREF_KEY_NUM_WORDS = "pref_key_num_words"
|
const val PREF_KEY_NUM_WORDS = "pref_key_num_words"
|
||||||
const val PREF_KEY_SEPARATOR = "pref_key_separator"
|
const val PREF_KEY_SEPARATOR = "pref_key_separator"
|
||||||
val DEFAULT_CAPS_STYLE = CapsType.Sentencecase.name
|
const val PREF_KEY_EXTRA_SYMBOLS_MASK = "pref_key_xkpwgen_extra_symbols_mask"
|
||||||
val DEFAULT_CAPS_INDEX = CapsType.Sentencecase.ordinal
|
val DEFAULT_CAPS_STYLE = CapsType.Sentence.name
|
||||||
|
val DEFAULT_CAPS_INDEX = CapsType.Sentence.ordinal
|
||||||
const val DEFAULT_NUMBER_OF_WORDS = "3"
|
const val DEFAULT_NUMBER_OF_WORDS = "3"
|
||||||
const val DEFAULT_WORD_SEPARATOR = "."
|
const val DEFAULT_WORD_SEPARATOR = "."
|
||||||
|
const val DEFAULT_EXTRA_SYMBOLS_MASK = "ds"
|
||||||
const val DEFAULT_MIN_WORD_LENGTH = 3
|
const val DEFAULT_MIN_WORD_LENGTH = 3
|
||||||
const val DEFAULT_MAX_WORD_LENGTH = 9
|
const val DEFAULT_MAX_WORD_LENGTH = 9
|
||||||
const val FALLBACK_ERROR_PASS = "42"
|
const val FALLBACK_ERROR_PASS = "42"
|
||||||
|
const val EXTRA_CHAR_PLACEHOLDER_DIGIT = 'd'
|
||||||
|
const val EXTRA_CHAR_PLACEHOLDER_SYMBOL = 's'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,28 @@
|
||||||
android:entries="@array/capitalization_type_values"
|
android:entries="@array/capitalization_type_values"
|
||||||
android:entryValues="@array/capitalization_type_values"
|
android:entryValues="@array/capitalization_type_values"
|
||||||
android:spinnerMode="dropdown"
|
android:spinnerMode="dropdown"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/total_words"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/separator" />
|
app:layout_constraintTop_toBottomOf="@id/total_words" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/xk_numbers_symbols_label"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/xkpwgen_extrachars_label"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/separator"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/separator"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/xkCapType">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/xk_number_symbol_mask"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints=""
|
||||||
|
android:inputType="text"
|
||||||
|
android:text="@string/xk_numbers_symbols_append_default" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<item>lowercase</item>
|
<item>lowercase</item>
|
||||||
<item>UPPERCASE</item>
|
<item>UPPERCASE</item>
|
||||||
<item>TitleCase</item>
|
<item>TitleCase</item>
|
||||||
<item>Sentencecase</item>
|
<item>Sentence</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="pwgen_provider_labels">
|
<string-array name="pwgen_provider_labels">
|
||||||
<item>Classic</item>
|
<item>Classic</item>
|
||||||
|
|
|
@ -390,4 +390,6 @@
|
||||||
<!-- GPG key selection in folder creation -->
|
<!-- GPG key selection in folder creation -->
|
||||||
<string name="folder_creation_err_file_exists">A file by that name already exists</string>
|
<string name="folder_creation_err_file_exists">A file by that name already exists</string>
|
||||||
<string name="folder_creation_err_folder_exists">A folder by that name already exists</string>
|
<string name="folder_creation_err_folder_exists">A folder by that name already exists</string>
|
||||||
|
<string name="xkpwgen_extrachars_label" >Digits/Symbols (d/s)</string>
|
||||||
|
<string name="xk_numbers_symbols_append_default">ds</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue