clients icon indicating copy to clipboard operation
clients copied to clipboard

[PS-1660] Fix autofill of expiration date input for bank cards

Open chenaski opened this issue 3 years ago • 4 comments

Type of change

- [X] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

The issue was found using this acquiring service.

Expiration date input looks like:

<input
  id="ExpireDate"
  class="text-field__input"
  autocomplete="cc-exp"
  type="tel"
  name="ExpireDate"
  data-i18n="[placeholder]fld.placeholder.expdate"
  value=""
  size="4"
  data-tdata="[has]params.expiremonth.visible==1;"
  maxlength="5"
  placeholder="ММ / ГГ"
/>

The problem was the incorrect identification of the input format. The input with placeholder="ММ / ГГ" got a value in YYYY-MM format, which is fallback in case when required format was not identified. It happened because ММ in the placeholder value had Russian characters, but the actual constant has English ones. The upper case characters look quite similar: MM and ММ, but the lower case are not: mm and мм.

After implementing the fix, I tested it on the site where the issue was initially found. I hope this won't cause the backward compatibility issues because the current check contains a mix of English and Russian characters, and most likely it never worked.

chenaski avatar Oct 12 '22 15:10 chenaski

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Oct 12 '22 15:10 CLAassistant

Thank you for your contribution! We've added this to our internal Community PR board for review. ID: PS-1660

bitwarden-bot avatar Oct 12 '22 15:10 bitwarden-bot

Hi @chenaski and thank you for your contribution.

Are there any other sites you could give us to test and verify your changes? It's been hard to find sites that have the desired CC fields. Googling even with Google Translate hasn't been great. From what I can tell, is that paysec.by is a payment provider which can be embedded into sites (similar to Paypal)?

djsmith85 avatar Dec 19 '22 15:12 djsmith85

Yes, it's just a third-party site with a form for card details.

I know only one site. But there you need to have a Belarusian phone number starting with +375. And, unfortunately, I haven't found any services that could provide a temporary phone number for this country.

I verified extension after this fix locally, it worked fine. Below I leave full HTML of the form, I think this should be enough for testing.

Full HTML of the form
<div class="form-container-fixed">
  <div class="subtitle lock">
    <span class="productive-heading-01 text-01" data-i18n="title.cardpay"
      >Оплата картой</span
    >
  </div>

  <div id="ErrorBlock" style="display: none"></div>
  <div class="form-row-top ui_01 text_01">
    <div id="cardName" class="card-name">
      <img class="card-name-default" src="/page/reseller_2/img/icon-bank.svg" />
    </div>
    <div id="CardType" class="card-type"></div>
  </div>
  <form
    method="post"
    name="form1"
    id="form1"
    data-matomo-name="js_cardpay"
    novalidate="novalidate"
  >
    <div id="CardForm" class="form-card-data-wrapper">
      <div class="form-row">
        <div id="cellCardNumber" class="text-field">
          <input
            id="CardNumber"
            class="text-field__input"
            autocomplete="cc-number"
            type="tel"
            value=""
            name="ACTIONPARAM_ID_17"
            maxlength="23"
            data-tdata="[has]params.cardnumber.visible==1;[maxlength]params.cardnumber.maxlength;"
            data-i18n="[placeholder]fld.placeholder.cardnumber"
            placeholder="0000 0000 0000 0000"
          />
          <span class="cardmask">••••&nbsp;&nbsp;•••• </span>
          <label class="text-field__label" data-i18n="fld.cardnumber"
            >Номер карты</label
          >
        </div>
      </div>
      <div class="form-row">
        <div id="cellExpireDate" class="text-field">
          <input
            id="ExpireDate"
            class="text-field__input"
            autocomplete="cc-exp"
            type="tel"
            name="ExpireDate"
            data-i18n="[placeholder]fld.placeholder.expdate"
            value=""
            size="4"
            data-tdata="[has]params.expiremonth.visible==1;"
            maxlength="5"
            placeholder="ММ / ГГ"
          />
          <label class="text-field__label" data-i18n="fld.cardexpire"
            >Срок</label
          >
          <input
            type="hidden"
            id="ExpireMonth"
            name="ACTIONPARAM_ID_22"
            value=""
          />
          <input
            type="hidden"
            id="ExpireYear"
            name="ACTIONPARAM_ID_23"
            value=""
          />
          <span id="pictExpireDate" class="text-field_icon"></span>
        </div>
        <div id="cellCVC2" class="text-field">
          <input
            id="CVC2"
            class="text-field__input"
            type="tel"
            name="ACTIONPARAM_ID_18"
            data-i18n="[placeholder]fld.placeholder.cvc"
            value=""
            maxlength="4"
            data-tdata="[has]params.cvc2.visible==1"
            placeholder="000"
          />
          <label class="text-field__label" data-i18n="fld.cvc2">CVC-код</label>
          <span
            id="pictCVC2"
            class="tooltip text-field_icon icon-CVC2"
            data-tooltip="tooltip.cvc"
            data-style="tooltip-cvc"
          >
            <label class="tooltip-cvc" aria-role="tooltip"
              >3 цифры на обороте карты</label
            ></span
          >
        </div>
      </div>
    </div>
    <div id="InfoBlock" class="helper-text-01 text-05 hide">test</div>
    <div id="ValidatorFormErrors" class="helper-text-01 text-error hide">
      <span id="ValidatorFormErrorsText"></span>
    </div>
    <div id="ValidatorErrors" class="helper-text-01 text-error hide">
      <span id="ValidatorErrorsText"></span>
    </div>
    <!-- checkbox -->
    <div id="addCardToOneClick" style="display: none">
      <div class="checkbox">
        <input
          type="hidden"
          id="Operation_ID"
          value="149123877"
          data-tdata="[value]operation.id"
        />
        <input
          type="hidden"
          id="addCardToOneClickH"
          name="addCardToOneClick"
          value="1"
        />
        <label class="checkbox-container body-short-01 text-01"
          ><span data-i18n="oneclick.savecard"
            >Запомнить карту для будущих покупок</span
          >
          <input
            id="addCardToOneClickCHK"
            type="checkbox"
            name="addCardToOneClickCHK"
            checked="checked"
            value="1"
            onchange="if(this.checked){ $('#addCardToOneClickH').val(1)} else {$('#addCardToOneClickH').val(0)}"
          />
          <span class="checkmark"></span>
        </label>
        <span
          id="pictCardToOneClick"
          class="text-field_icon icon-help tooltip"
          data-tooltip="tooltip.oneclick"
        >
          <label class="tooltipBubble" aria-role="tooltip"
            >Сохраните карту, чтобы не вводить ее данные заново при каждой
            оплате. Данные хранятся в зашифрованном виде, никто другой не сможет
            ими воспользоваться.</label
          ></span
        >
      </div>
    </div>
    <!-- Спасибо -->
    <div id="thanks_info" class="spasibo" style="display: none">
      <div id="declinebonus" style="display: none">
        <div class="checkbox">
          <label class="checkbox-container body-short-01 text-01"
            ><span>Отказаться от списания бонусов Спасибо</span>
            <input
              id="declinebonusClickCHK"
              type="checkbox"
              name="declinebonusClickCHK"
              value="0"
            />
            <span class="checkmark"></span>
          </label>
        </div>
      </div>
      <div id="BlockSpasibo">
        <div class="form-check mb-2">
          <input
            type="hidden"
            id="myradio_bonus_1"
            name="bonustype"
            value="1"
          />
          <div class="subtitle-spasibo">
            <span
              class="productive-heading-01 text-01"
              data-i18n="title.spasibo"
              >Бонусы Спасибо</span
            >
            <span class="pict-spasibo"></span>
          </div>
          <div class="operation">
            <div class="slider-left">-</div>
            <input
              id="OperationPoints"
              class="form-control slider-text-input code_02 text-01"
              type="text"
              name="bonusamount2"
              value="0"
            />
            <div class="slider-right disabled">+</div>
          </div>
          <div class="slider-conteiner" id="slider-conteiner">
            <div id="slider-range"></div>
          </div>
          <div class="slider-label">
            <div class="slider-renge-label-left code_02 text-05" id="minbonus">
              0
            </div>
            <div class="slider-renge-label-right code_02 text-05" id="bonus">
              NNN
            </div>
          </div>
        </div>
        <input
          type="hidden"
          id="Order_ID"
          value="125889579"
          data-tdata="[value]order.id"
        />
        <input
          type="hidden"
          id="MaxBonusamountCurrency"
          value="BYN"
          data-tdata="[value]operation.currencycode"
        />
      </div>
    </div>

    <div class="footer-right">
      <div class="legal-content-mobile">
        <div class="security-icon-gray"></div>
        <div class="disclaimer caption-01 text-02" data-i18n="sertinfo">
          Безопасность платежей подтверждена сертификатом PCI DSS. Все операции
          проводятся по требованиям Visa и&nbsp;Mastercard с использованием
          протокола 3‑D&nbsp;Secure. Assist не передает платежные данные
          сторонним лицам
        </div>
      </div>
      <button
        id="Buttons"
        class="button-primary-gray"
        type="Submit"
        name="Submit_Card_2"
      >
        <div class="button-text">
          <span id="buttonText" data-i18n="buttons.cardpay"
            >Укажите данные карты</span
          >
        </div>
        <div class="button-amount">
          <span id="buttonTextAmount" data-tdata="order.amountorg"> 92.75</span>
          <span id="buttonTextCurrency" data-tdata="order.currencyorg"
            >BYN</span
          >
        </div>
      </button>
    </div>
  </form>
  <form
    class="form-cancel-button"
    method="POST"
    data-tdata="[has]page.payerdenialbutton==1"
    style="display: none"
  >
    <input type="hidden" name="Submit_Card_4" value="1" />
    <button
      id="buttonCancelPay"
      class="button-cancel-pay"
      type="Submit"
      name="Submit_Card_4"
    >
      <span id="buttonText" data-i18n="buttons.payerdenial"
        >Отказ от платежа</span
      >
    </button>
  </form>
</div>

Edit djsmith85: Added the video to our internal ticket.

chenaski avatar Dec 20 '22 20:12 chenaski

@chenaski Just received approval from QA and this is ready to get merged. Thanks again for the work on this 👍

djsmith85 avatar Jan 18 '23 18:01 djsmith85

Thank you, I was glad to help 🙂

chenaski avatar Jan 21 '23 15:01 chenaski

Hello

I record my credit card in bitwarden, but when I use it, the expiration date is fill with the MM/YYYY format (exemple : 03/2025)

But the form need to be fill with the MM/YY (03/25) format.

How should I record my card to have the MM/YY format in the form?

i use : home server : 2023.9.1 firefox plugin : 2023.10.2 windows 10.

Lurikbolding avatar Dec 09 '23 23:12 Lurikbolding