Bug 1413120 - [Form Autofill] Accept credit card numbers with hyphens. r=ralin draft
authorLuke Chang <lchang@mozilla.com>
Tue, 07 Nov 2017 20:07:32 +0800
changeset 698839 1e54a2296f7b254d304dec8cfa0f29d7b8d8d39f
parent 698828 612c48e5fb771b03e28bf5e5212f7687702736ad
child 698888 fe5c71e20599f3139ed30e39a1d31635e6566392
push id89367
push userbmo:lchang@mozilla.com
push dateThu, 16 Nov 2017 04:18:13 +0000
reviewersralin
bugs1413120
milestone59.0a1
Bug 1413120 - [Form Autofill] Accept credit card numbers with hyphens. r=ralin MozReview-Commit-ID: BFomE2mTG84
browser/extensions/formautofill/FormAutofillUtils.jsm
browser/extensions/formautofill/ProfileStorage.jsm
browser/extensions/formautofill/test/unit/test_transformFields.js
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -95,21 +95,27 @@ this.FormAutofillUtils = {
   isAddressField(fieldName) {
     return !!this._fieldNameInfo[fieldName] && !this.isCreditCardField(fieldName);
   },
 
   isCreditCardField(fieldName) {
     return this._fieldNameInfo[fieldName] == "creditCard";
   },
 
-  isCCNumber(ccNumber) {
+  normalizeCCNumber(ccNumber) {
+    ccNumber = ccNumber.replace(/[-\s]/g, "");
+
     // Based on the information on wiki[1], the shortest valid length should be
     // 12 digits(Maestro).
     // [1] https://en.wikipedia.org/wiki/Payment_card_number
-    return ccNumber ? ccNumber.replace(/\s/g, "").match(/^\d{12,}$/) : false;
+    return ccNumber.match(/^\d{12,}$/) ? ccNumber : null;
+  },
+
+  isCCNumber(ccNumber) {
+    return !!this.normalizeCCNumber(ccNumber);
   },
 
   getCategoryFromFieldName(fieldName) {
     return this._fieldNameInfo[fieldName];
   },
 
   getCategoriesFromFieldNames(fieldNames) {
     let categories = new Set();
--- a/browser/extensions/formautofill/ProfileStorage.jsm
+++ b/browser/extensions/formautofill/ProfileStorage.jsm
@@ -1518,38 +1518,38 @@ class CreditCards extends AutofillRecord
       } else {
         creditCard["cc-exp"] = "";
       }
       hasNewComputedFields = true;
     }
 
     // Encrypt credit card number
     if (!("cc-number-encrypted" in creditCard)) {
-      let ccNumber = (creditCard["cc-number"] || "").replace(/\s/g, "");
-      if (FormAutofillUtils.isCCNumber(ccNumber)) {
+      if ("cc-number" in creditCard) {
+        let ccNumber = creditCard["cc-number"];
         creditCard["cc-number"] = this._getMaskedCCNumber(ccNumber);
         creditCard["cc-number-encrypted"] = MasterPassword.encryptSync(ccNumber);
       } else {
-        delete creditCard["cc-number"];
         creditCard["cc-number-encrypted"] = "";
       }
     }
 
     return hasNewComputedFields;
   }
 
   _stripComputedFields(creditCard) {
     if (creditCard["cc-number-encrypted"]) {
       creditCard["cc-number"] = MasterPassword.decryptSync(creditCard["cc-number-encrypted"]);
     }
     super._stripComputedFields(creditCard);
   }
 
   _normalizeFields(creditCard) {
     this._normalizeCCName(creditCard);
+    this._normalizeCCNumber(creditCard);
     this._normalizeCCExpirationDate(creditCard);
   }
 
   _normalizeCCName(creditCard) {
     if (creditCard["cc-given-name"] || creditCard["cc-additional-name"] || creditCard["cc-family-name"]) {
       if (!creditCard["cc-name"]) {
         creditCard["cc-name"] = FormAutofillNameUtils.joinNameParts({
           given: creditCard["cc-given-name"],
@@ -1559,16 +1559,25 @@ class CreditCards extends AutofillRecord
       }
 
       delete creditCard["cc-given-name"];
       delete creditCard["cc-additional-name"];
       delete creditCard["cc-family-name"];
     }
   }
 
+  _normalizeCCNumber(creditCard) {
+    if (creditCard["cc-number"]) {
+      creditCard["cc-number"] = FormAutofillUtils.normalizeCCNumber(creditCard["cc-number"]);
+      if (!creditCard["cc-number"]) {
+        delete creditCard["cc-number"];
+      }
+    }
+  }
+
   _normalizeCCExpirationDate(creditCard) {
     if (creditCard["cc-exp-month"]) {
       let expMonth = parseInt(creditCard["cc-exp-month"], 10);
       if (isNaN(expMonth) || expMonth < 1 || expMonth > 12) {
         delete creditCard["cc-exp-month"];
       } else {
         creditCard["cc-exp-month"] = expMonth;
       }
--- a/browser/extensions/formautofill/test/unit/test_transformFields.js
+++ b/browser/extensions/formautofill/test/unit/test_transformFields.js
@@ -562,16 +562,45 @@ const CREDIT_CARD_NORMALIZE_TESTCASES = 
       "cc-given-name": "John",
       "cc-family-name": "Doe",
     },
     expectedResult: {
       "cc-name": "John Doe",
     },
   },
 
+  // Card Number
+  {
+    description: "Regular number",
+    creditCard: {
+      "cc-number": "1234123412341234",
+    },
+    expectedResult: {
+      "cc-number": "1234123412341234",
+    },
+  },
+  {
+    description: "Number with spaces",
+    creditCard: {
+      "cc-number": "1234 1234  1234 1234",
+    },
+    expectedResult: {
+      "cc-number": "1234123412341234",
+    },
+  },
+  {
+    description: "Number with hyphens",
+    creditCard: {
+      "cc-number": "1234-1234-1234-1234",
+    },
+    expectedResult: {
+      "cc-number": "1234123412341234",
+    },
+  },
+
   // Expiration Date
   {
     description: "Has \"cc-exp\" formatted \"yyyy-mm\"",
     creditCard: {
       "cc-exp": "2022-12",
     },
     expectedResult: {
       "cc-exp-month": 12,