mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add color for special password chars #454
This commit is contained in:
@@ -36,7 +36,7 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
||||
import com.kunzisoft.keepass.model.MainCredential
|
||||
import com.kunzisoft.keepass.utils.PasswordEntropy
|
||||
import com.kunzisoft.keepass.password.PasswordEntropy
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
import com.kunzisoft.keepass.view.KeyFileSelectionView
|
||||
import com.kunzisoft.keepass.view.PasswordView
|
||||
|
||||
@@ -60,6 +60,11 @@ object TemplateField {
|
||||
const val LABEL_SECURE_NOTE = "Secure Note"
|
||||
const val LABEL_MEMBERSHIP = "Membership"
|
||||
|
||||
fun isStandardPasswordName(context: Context, name: String): Boolean {
|
||||
return name.equals(LABEL_PASSWORD, true)
|
||||
|| name == getLocalizedName(context, LABEL_PASSWORD)
|
||||
}
|
||||
|
||||
fun isStandardFieldName(name: String): Boolean {
|
||||
return arrayOf(
|
||||
LABEL_TITLE,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.utils
|
||||
package com.kunzisoft.keepass.password
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
@@ -20,6 +20,13 @@
|
||||
package com.kunzisoft.keepass.password
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.StyleSpan
|
||||
import com.kunzisoft.keepass.R
|
||||
import java.security.SecureRandom
|
||||
import java.util.*
|
||||
@@ -215,28 +222,6 @@ class PasswordGenerator(private val resources: Resources) {
|
||||
}
|
||||
}
|
||||
|
||||
// From KeePassXC code https://github.com/keepassxreboot/keepassxc/pull/538
|
||||
private fun extendedChars(): String {
|
||||
val charSet = StringBuilder()
|
||||
// [U+0080, U+009F] are C1 control characters,
|
||||
// U+00A0 is non-breaking space
|
||||
run {
|
||||
var ch = '\u00A1'
|
||||
while (ch <= '\u00AC') {
|
||||
charSet.append(ch)
|
||||
++ch
|
||||
}
|
||||
}
|
||||
// U+00AD is soft hyphen (format character)
|
||||
var ch = '\u00AE'
|
||||
while (ch < '\u00FF') {
|
||||
charSet.append(ch)
|
||||
++ch
|
||||
}
|
||||
charSet.append('\u00FF')
|
||||
return charSet.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
private const val LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz"
|
||||
@@ -247,5 +232,80 @@ class PasswordGenerator(private val resources: Resources) {
|
||||
private const val SPECIAL_CHARS = "!\"#$%&'*+,./:;=?@\\^`"
|
||||
private const val BRACKET_CHARS = "[]{}()<>"
|
||||
private const val AMBIGUOUS_CHARS = "iI|lLoO01"
|
||||
|
||||
// From KeePassXC code https://github.com/keepassxreboot/keepassxc/pull/538
|
||||
private fun extendedChars(): String {
|
||||
val charSet = StringBuilder()
|
||||
// [U+0080, U+009F] are C1 control characters,
|
||||
// U+00A0 is non-breaking space
|
||||
run {
|
||||
var ch = '\u00A1'
|
||||
while (ch <= '\u00AC') {
|
||||
charSet.append(ch)
|
||||
++ch
|
||||
}
|
||||
}
|
||||
// U+00AD is soft hyphen (format character)
|
||||
var ch = '\u00AE'
|
||||
while (ch < '\u00FF') {
|
||||
charSet.append(ch)
|
||||
++ch
|
||||
}
|
||||
charSet.append('\u00FF')
|
||||
return charSet.toString()
|
||||
}
|
||||
|
||||
fun getColorizedPassword(password: String): Spannable {
|
||||
val coloredString = SpannableStringBuilder()
|
||||
if (password.isNotEmpty()) {
|
||||
password.forEach {
|
||||
when {
|
||||
UPPERCASE_CHARS.contains(it)||
|
||||
LOWERCASE_CHARS.contains(it) -> {
|
||||
coloredString.append(it)
|
||||
}
|
||||
DIGIT_CHARS.contains(it) -> {
|
||||
// RED
|
||||
coloredString.append(colorizeChar(it, Color.rgb(224, 56, 56)))
|
||||
}
|
||||
SPECIAL_CHARS.contains(it) -> {
|
||||
// Blue
|
||||
coloredString.append(colorizeChar(it, Color.rgb(66, 132, 237)))
|
||||
}
|
||||
MINUS_CHAR.contains(it)||
|
||||
UNDERLINE_CHAR.contains(it)||
|
||||
BRACKET_CHARS.contains(it) -> {
|
||||
// Purple
|
||||
coloredString.append(colorizeChar(it, Color.rgb(141, 34, 191)))
|
||||
}
|
||||
extendedChars().contains(it) -> {
|
||||
// Green
|
||||
coloredString.append(colorizeChar(it, Color.rgb(44, 181, 50)))
|
||||
}
|
||||
else -> {
|
||||
coloredString.append(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
coloredString.setSpan(
|
||||
StyleSpan(Typeface.BOLD),
|
||||
0,
|
||||
password.length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
return coloredString
|
||||
}
|
||||
|
||||
private fun colorizeChar(char: Char, color: Int): Spannable {
|
||||
val spannableColorChar = SpannableString(char.toString())
|
||||
spannableColorChar.setSpan(
|
||||
ForegroundColorSpan(color),
|
||||
0,
|
||||
1,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
return spannableColorChar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ import android.widget.TextView
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.utils.PasswordEntropy
|
||||
import com.kunzisoft.keepass.password.PasswordGenerator
|
||||
import com.kunzisoft.keepass.password.PasswordEntropy
|
||||
|
||||
class PasswordView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@@ -118,7 +119,7 @@ class PasswordView @JvmOverloads constructor(context: Context,
|
||||
return passwordText.text.toString()
|
||||
}
|
||||
set(value) {
|
||||
passwordText.text = value
|
||||
passwordText.text = PasswordGenerator.getColorizedPassword(value)
|
||||
getEntropyStrength(value)
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import androidx.core.view.isVisible
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.password.PasswordGenerator
|
||||
|
||||
class TextEditFieldView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@@ -123,7 +125,10 @@ class TextEditFieldView @JvmOverloads constructor(context: Context,
|
||||
return valueView.text?.toString() ?: ""
|
||||
}
|
||||
set(value) {
|
||||
valueView.setText(value)
|
||||
if (TemplateField.isStandardPasswordName(context, label))
|
||||
valueView.setText(PasswordGenerator.getColorizedPassword(value))
|
||||
else
|
||||
valueView.setText(value)
|
||||
}
|
||||
|
||||
override var default: String = ""
|
||||
|
||||
@@ -36,7 +36,9 @@ import androidx.core.text.util.LinkifyCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.model.EntryInfo.Companion.APPLICATION_ID_FIELD_NAME
|
||||
import com.kunzisoft.keepass.password.PasswordGenerator
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
|
||||
|
||||
@@ -191,7 +193,10 @@ class TextFieldView @JvmOverloads constructor(context: Context,
|
||||
return valueView.text.toString()
|
||||
}
|
||||
set(value) {
|
||||
valueView.text = value
|
||||
if (TemplateField.isStandardPasswordName(context, label))
|
||||
valueView.text = PasswordGenerator.getColorizedPassword(value)
|
||||
else
|
||||
valueView.text = value
|
||||
changeProtectedValueParameters()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user