From 80c0152d46892043143ab2d074401dc6a2b6fdb4 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Sun, 16 May 2021 23:19:45 +0200 Subject: [PATCH] Change credit card implementation --- .../keepass/activities/EntryActivity.kt | 4 +- .../activities/fragments/EntryEditFragment.kt | 23 ++- .../keepass/autofill/AutofillHelper.kt | 123 +++++++-------- .../keepass/database/element/DateInstant.kt | 24 ++- .../database/element/template/Template.kt | 11 +- .../element/template/TemplateEngine.kt | 7 +- .../element/template/TemplatesFields.kt} | 8 +- .../com/kunzisoft/keepass/model/CreditCard.kt | 22 +-- .../com/kunzisoft/keepass/model/EntryInfo.kt | 11 +- .../keepass/view/EntryContentsView.kt | 4 +- .../res/layout/entry_cc_details_dialog.xml | 143 ------------------ app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 14 files changed, 117 insertions(+), 266 deletions(-) rename app/src/main/java/com/kunzisoft/keepass/{model/TemplatesCustomFields.kt => database/element/template/TemplatesFields.kt} (89%) delete mode 100644 app/src/main/res/layout/entry_cc_details_dialog.xml diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt index 77f0ed52d..f4170a4ca 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt @@ -49,7 +49,7 @@ import com.kunzisoft.keepass.database.element.Entry import com.kunzisoft.keepass.database.element.node.NodeId import com.kunzisoft.keepass.education.EntryActivityEducation import com.kunzisoft.keepass.magikeyboard.MagikIME -import com.kunzisoft.keepass.model.TemplatesCustomFields +import com.kunzisoft.keepass.database.element.template.TemplatesFields import com.kunzisoft.keepass.model.EntryAttachmentState import com.kunzisoft.keepass.model.StreamDirection import com.kunzisoft.keepass.otp.OtpEntryFields @@ -334,7 +334,7 @@ class EntryActivity : LockingActivity() { clipboardHelper?.timeoutCopyToClipboard( value.toString(), getString(R.string.copy_field, - TemplatesCustomFields.getLocalizedName(applicationContext, field.name)) + TemplatesFields.getLocalizedName(applicationContext, field.name)) ) } } else { diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/EntryEditFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/EntryEditFragment.kt index 455a2dee2..2b375052d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/EntryEditFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/EntryEditFragment.kt @@ -41,19 +41,16 @@ import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.DateInstant import com.kunzisoft.keepass.database.element.icon.IconImage import com.kunzisoft.keepass.database.element.security.ProtectedString -import com.kunzisoft.keepass.database.element.template.Template -import com.kunzisoft.keepass.database.element.template.TemplateAttribute -import com.kunzisoft.keepass.database.element.template.TemplateAttributeAction -import com.kunzisoft.keepass.database.element.template.TemplateAttributeType +import com.kunzisoft.keepass.database.element.template.* import com.kunzisoft.keepass.education.EntryEditActivityEducation import com.kunzisoft.keepass.icons.IconDrawableFactory import com.kunzisoft.keepass.model.* -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_EXPIRATION -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_NOTES -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_PASSWORD -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_TITLE -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_URL -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_USERNAME +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_EXPIRATION +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_NOTES +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_PASSWORD +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_TITLE +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_URL +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_USERNAME import com.kunzisoft.keepass.otp.OtpEntryFields import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.view.* @@ -352,7 +349,7 @@ class EntryEditFragment : StylishFragment() { // Add an action icon if needed return context?.let { EntryEditFieldView(it).apply { - label = TemplatesCustomFields.getLocalizedName(context, field.name) + label = TemplatesFields.getLocalizedName(context, field.name) setProtection(field.protectedValue.isProtected, mHideProtectedValue) setValue(field.protectedValue.toString(), when (templateAttribute.type) { TemplateAttributeType.MULTILINE -> EntryEditFieldView.TextType.MULTI_LINE @@ -385,7 +382,7 @@ class EntryEditFragment : StylishFragment() { field: Field): View? { return context?.let { DateTimeView(it).apply { - label = TemplatesCustomFields.getLocalizedName(context, field.name) + label = TemplatesFields.getLocalizedName(context, field.name) try { val value = field.protectedValue.toString() activation = value.trim().isNotEmpty() @@ -525,7 +522,7 @@ class EntryEditFragment : StylishFragment() { private data class FieldId(var viewId: Int, var protected: Boolean) private fun isStandardFieldName(name: String): Boolean { - return TemplatesCustomFields.isStandardFieldName(name) + return TemplatesFields.isStandardFieldName(name) } private fun containsCustomFieldName(name: String): Boolean { diff --git a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt index 085a2a0f1..69be1cec2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt @@ -48,7 +48,7 @@ import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.icon.IconImage import com.kunzisoft.keepass.model.EntryInfo import com.kunzisoft.keepass.model.SearchInfo -import com.kunzisoft.keepass.model.TemplatesCustomFields +import com.kunzisoft.keepass.database.element.template.TemplatesFields import com.kunzisoft.keepass.settings.AutofillSettingsActivity import com.kunzisoft.keepass.settings.PreferencesUtil import java.util.* @@ -121,80 +121,71 @@ object AutofillHelper { builder.setValue(passwordId, AutofillValue.forText(entryInfo.password)) } + if (entryInfo.expires) { + // get month (month in database entry is stored as String in the format MM) + val month = entryInfo.expiryTime.getMonthInt() + // get year (year in database entry is stored as String in the format YY) + val year = entryInfo.expiryTime.getYearInt() + + struct.ccExpDateId?.let { + if (struct.isWebView) { + // set date string as defined in https://html.spec.whatwg.org + val dateString = "$year\u002D$month" + builder.setValue(it, AutofillValue.forText(dateString)) + } else { + val calendar = Calendar.getInstance() + calendar.clear() + calendar[Calendar.YEAR] = year + // Month value is 0-based. e.g., 0 for January + calendar[Calendar.MONTH] = month - 1 + val date = calendar.timeInMillis + builder.setValue(it, AutofillValue.forDate(date)) + } + } + struct.ccExpDateMonthId?.let { + if (struct.isWebView) { + builder.setValue(it, AutofillValue.forText(month.toString())) + } else { + if (struct.ccExpMonthOptions != null) { + // index starts at 0 + builder.setValue(it, AutofillValue.forList(month - 1)) + } else { + builder.setValue(it, AutofillValue.forText(month.toString())) + } + } + } + struct.ccExpDateYearId?.let { + var autofillValue: AutofillValue? = null + + struct.ccExpYearOptions?.let { options -> + var yearIndex = options.indexOf(year.toString().substring(0, 2)) + + if (yearIndex == -1) { + yearIndex = options.indexOf(year.toString()) + } + if (yearIndex != -1) { + autofillValue = AutofillValue.forList(yearIndex) + builder.setValue(it, autofillValue) + } + } + + if (autofillValue == null) { + builder.setValue(it, AutofillValue.forText(year.toString())) + } + } + } for (field in entryInfo.customFields) { - if (field.name == TemplatesCustomFields.CREDIT_CARD_CARDHOLDER) { + if (field.name == TemplatesFields.CREDIT_CARD_CARDHOLDER) { struct.ccNameId?.let { ccNameId -> builder.setValue(ccNameId, AutofillValue.forText(field.protectedValue.stringValue)) } } - if (field.name == TemplatesCustomFields.CREDIT_CARD_NUMBER) { + if (field.name == TemplatesFields.CREDIT_CARD_NUMBER) { struct.ccnId?.let { ccnId -> builder.setValue(ccnId, AutofillValue.forText(field.protectedValue.stringValue)) } } - if (field.name == TemplatesCustomFields.CREDIT_CARD_EXPIRATION) { - // the database stores the expiration month and year as a String - // of length four in the format MMYY - if (field.protectedValue.stringValue.length != 4) continue - - // get month (month in database entry is stored as String in the format MM) - val monthString = field.protectedValue.stringValue.substring(0, 2) - val month = monthString.toIntOrNull() ?: 0 - if (month < 1 || month > 12) continue - - // get year (year in database entry is stored as String in the format YY) - val yearString = field.protectedValue.stringValue.substring(2, 4) - val year = "20$yearString".toIntOrNull() ?: 0 - if (year == 0) continue - - struct.ccExpDateId?.let { - if (struct.isWebView) { - // set date string as defined in https://html.spec.whatwg.org - val dateString = "20$yearString\u002D$monthString" - builder.setValue(it, AutofillValue.forText(dateString)) - } else { - val calendar = Calendar.getInstance() - calendar.clear() - calendar[Calendar.YEAR] = year - // Month value is 0-based. e.g., 0 for January - calendar[Calendar.MONTH] = month - 1 - val date = calendar.timeInMillis - builder.setValue(it, AutofillValue.forDate(date)) - } - } - struct.ccExpDateMonthId?.let { - if (struct.isWebView) { - builder.setValue(it, AutofillValue.forText(monthString)) - } else { - if (struct.ccExpMonthOptions != null) { - // index starts at 0 - builder.setValue(it, AutofillValue.forList(month - 1)) - } else { - builder.setValue(it, AutofillValue.forText(monthString)) - } - } - } - struct.ccExpDateYearId?.let { - var autofillValue: AutofillValue? = null - - struct.ccExpYearOptions?.let { options -> - var yearIndex = options.indexOf(yearString) - - if (yearIndex == -1) { - yearIndex = options.indexOf("20$yearString") - } - if (yearIndex != -1) { - autofillValue = AutofillValue.forList(yearIndex) - builder.setValue(it, autofillValue) - } - } - - if (autofillValue == null) { - builder.setValue(it, AutofillValue.forText("20$yearString")) - } - } - } - if (field.name == TemplatesCustomFields.CREDIT_CARD_CVV) { + if (field.name == TemplatesFields.CREDIT_CARD_CVV) { struct.cvvId?.let { cvvId -> builder.setValue(cvvId, AutofillValue.forText(field.protectedValue.stringValue)) } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/DateInstant.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/DateInstant.kt index 50953f42d..ee7e9d079 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/DateInstant.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/DateInstant.kt @@ -91,6 +91,14 @@ class DateInstant : Parcelable { } } + fun getMonthInt(): Int { + return Companion.getMonthInt(jDate) + } + + fun getYearInt(): Int { + return Companion.getYearInt(jDate) + } + override fun toString(): String { return when (type) { Type.DATE -> dateFormat.format(jDate) @@ -173,11 +181,21 @@ class DateInstant : Parcelable { } + fun getMonthInt(date: Date): Int { + val dateFormat = SimpleDateFormat("MM", Locale.ENGLISH) + return dateFormat.format(date).toInt() + } + + fun getYearInt(date: Date): Int { + val dateFormat = SimpleDateFormat("yyyy", Locale.ENGLISH) + return dateFormat.format(date).toInt() + } + fun getDateTimeString(resources: Resources, date: Date): String { return java.text.DateFormat.getDateTimeInstance( - java.text.DateFormat.MEDIUM, - java.text.DateFormat.SHORT, - ConfigurationCompat.getLocales(resources.configuration)[0]) + java.text.DateFormat.MEDIUM, + java.text.DateFormat.SHORT, + ConfigurationCompat.getLocales(resources.configuration)[0]) .format(date) } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/template/Template.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/template/Template.kt index fe8cb2144..efbcd20e9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/template/Template.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/template/Template.kt @@ -23,12 +23,11 @@ import android.os.ParcelUuid import android.os.Parcelable import com.kunzisoft.keepass.database.element.database.DatabaseVersioned import com.kunzisoft.keepass.database.element.icon.IconImage -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_EXPIRATION -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_NOTES -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_PASSWORD -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_TITLE -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_URL -import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_USERNAME +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_EXPIRATION +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_NOTES +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_PASSWORD +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_URL +import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_USERNAME import java.util.* import kotlin.collections.ArrayList diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplateEngine.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplateEngine.kt index 9788d7f45..311a379d7 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplateEngine.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplateEngine.kt @@ -73,7 +73,11 @@ class TemplateEngine(private val databaseKDBX: DatabaseKDBX) { try { val attributeName = key.substring(TEMPLATE_ATTRIBUTE_TITLE_PREFIX.length) val attribute = getOrRetrieveAttributeFromName(attributes, attributeName) - attribute.attribute.label = value.stringValue + var referenceLabel = value.stringValue + if (referenceLabel.equals(TEMPLATE_ATTRIBUTE_TITLE_EXPIRATION, true)) { + referenceLabel = TemplatesFields.STANDARD_EXPIRATION + } + attribute.attribute.label = referenceLabel } catch (e: Exception) { Log.e(TAG, "Unable to retrieve template position", e) } @@ -154,6 +158,7 @@ class TemplateEngine(private val databaseKDBX: DatabaseKDBX) { private const val TEMPLATE_ENTRY_UUID = "_etm_template_uuid" private const val TEMPLATE_ATTRIBUTE_POSITION_PREFIX = "_etm_position" private const val TEMPLATE_ATTRIBUTE_TITLE_PREFIX = "_etm_title" + private const val TEMPLATE_ATTRIBUTE_TITLE_EXPIRATION = "@exp_date" private const val TEMPLATE_ATTRIBUTE_TYPE_PREFIX = "_etm_type" private const val TEMPLATE_ATTRIBUTE_TYPE_PROTECTED = "Protected" private const val TEMPLATE_ATTRIBUTE_TYPE_INLINE = "Inline" diff --git a/app/src/main/java/com/kunzisoft/keepass/model/TemplatesCustomFields.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplatesFields.kt similarity index 89% rename from app/src/main/java/com/kunzisoft/keepass/model/TemplatesCustomFields.kt rename to app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplatesFields.kt index 53bc61269..f0d72389b 100644 --- a/app/src/main/java/com/kunzisoft/keepass/model/TemplatesCustomFields.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/template/TemplatesFields.kt @@ -1,9 +1,9 @@ -package com.kunzisoft.keepass.model +package com.kunzisoft.keepass.database.element.template import android.content.Context import com.kunzisoft.keepass.R -object TemplatesCustomFields { +object TemplatesFields { const val STANDARD_TITLE = "title" const val STANDARD_USERNAME = "username" @@ -14,7 +14,6 @@ object TemplatesCustomFields { const val CREDIT_CARD_CARDHOLDER = "Card holder" const val CREDIT_CARD_NUMBER = "Number" - const val CREDIT_CARD_EXPIRATION = "@exp_date" const val CREDIT_CARD_CVV = "CVV" private const val CREDIT_CARD_PIN = "PIN" @@ -42,9 +41,10 @@ object TemplatesCustomFields { CREDIT_CARD_CARDHOLDER -> context.getString(R.string.credit_card_cardholder) CREDIT_CARD_NUMBER -> context.getString(R.string.credit_card_number) - CREDIT_CARD_EXPIRATION -> context.getString(R.string.credit_card_expiration) CREDIT_CARD_CVV -> context.getString(R.string.credit_card_security_code) CREDIT_CARD_PIN -> context.getString(R.string.credit_card_pin) + + // TODO Others translations else -> fieldName } } diff --git a/app/src/main/java/com/kunzisoft/keepass/model/CreditCard.kt b/app/src/main/java/com/kunzisoft/keepass/model/CreditCard.kt index 5a6d875e0..a238642e6 100644 --- a/app/src/main/java/com/kunzisoft/keepass/model/CreditCard.kt +++ b/app/src/main/java/com/kunzisoft/keepass/model/CreditCard.kt @@ -3,8 +3,10 @@ package com.kunzisoft.keepass.model import android.os.Parcel import android.os.Parcelable -data class CreditCard(val cardholder: String?, val number: String?, - val expiration: String?, val cvv: String?) : Parcelable { +data class CreditCard(val cardholder: String?, + val number: String?, + val expiration: String?, + val cvv: String?) : Parcelable { constructor(parcel: Parcel) : this( parcel.readString(), @@ -20,22 +22,6 @@ data class CreditCard(val cardholder: String?, val number: String?, parcel.writeString(cvv) } - fun getExpirationMonth(): String { - return if (expiration?.length == 4) { - expiration.substring(0, 2) - } else { - "" - } - } - - fun getExpirationYear(): String { - return if (expiration?.length == 4) { - expiration.substring(2, 4) - } else { - "" - } - } - override fun describeContents(): Int { return 0 } diff --git a/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt b/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt index 402256fc1..adef8507f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt +++ b/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt @@ -24,6 +24,7 @@ import android.os.Parcelable import com.kunzisoft.keepass.database.element.Attachment import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.security.ProtectedString +import com.kunzisoft.keepass.database.element.template.TemplatesFields import com.kunzisoft.keepass.otp.OtpElement import com.kunzisoft.keepass.otp.OtpEntryFields import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD @@ -166,19 +167,19 @@ class EntryInfo : NodeInfo { creditCard?.let { cc -> cc.cardholder?.let { val v = ProtectedString(false, it) - addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_CARDHOLDER, v)) + addUniqueField(Field(TemplatesFields.CREDIT_CARD_CARDHOLDER, v)) } cc.expiration?.let { - val v = ProtectedString(false, it) - addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_EXPIRATION, v)) + expires = true + // TODO Expiration expiryTime = it } cc.number?.let { val v = ProtectedString(false, it) - addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_NUMBER, v)) + addUniqueField(Field(TemplatesFields.CREDIT_CARD_NUMBER, v)) } cc.cvv?.let { val v = ProtectedString(true, it) - addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_CVV, v)) + addUniqueField(Field(TemplatesFields.CREDIT_CARD_CVV, v)) } } } diff --git a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt index a3714b30d..688028b33 100644 --- a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt +++ b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt @@ -42,7 +42,7 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString import com.kunzisoft.keepass.utils.UuidUtil import com.kunzisoft.keepass.model.EntryAttachmentState import com.kunzisoft.keepass.model.StreamDirection -import com.kunzisoft.keepass.model.TemplatesCustomFields +import com.kunzisoft.keepass.database.element.template.TemplatesFields import com.kunzisoft.keepass.otp.OtpElement import com.kunzisoft.keepass.otp.OtpType import com.kunzisoft.keepass.settings.PreferencesUtil @@ -313,7 +313,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context, onCopyButtonClickListener: OnClickListener?) { extraFieldsListView.addView(EntryFieldView(context).apply { - setLabel(TemplatesCustomFields.getLocalizedName(context, title)) + setLabel(TemplatesFields.getLocalizedName(context, title)) setValue(value.toString(), value.isProtected) setAutoLink() activateCopyButton(allowCopy) diff --git a/app/src/main/res/layout/entry_cc_details_dialog.xml b/app/src/main/res/layout/entry_cc_details_dialog.xml deleted file mode 100644 index 2c0f7220f..000000000 --- a/app/src/main/res/layout/entry_cc_details_dialog.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a2cd52b29..8d0da01ec 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -371,7 +371,6 @@ Algorithmus Karteninhaber Nummer - Gültig bis Prüfnummer OTP Ungültiges OTP-Geheimnis. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d5105e8a7..d0fd76f0c 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -371,7 +371,6 @@ Algorithme Titulaire de la carte Numéros - Expiration CVV PIN OTP diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7514f17ee..38a0311ed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -101,7 +101,6 @@ Algorithm Cardholder Number - Expiration CVV PIN OTP