From c6cd323bde67a6e36df01f69e225064c7633316e Mon Sep 17 00:00:00 2001 From: Christopher Shea Date: Fri, 14 Feb 2025 13:17:57 +0100 Subject: [PATCH 1/3] feat: add type, first 6, last 4 fields to the wallet cc form --- Controller/Cards/Save.php | 6 +++++- Gateway/Request/WalletPaymentBuilder.php | 3 +++ view/frontend/web/js/view/vault/card.js | 19 ++++++++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Controller/Cards/Save.php b/Controller/Cards/Save.php index 29700415..61482374 100644 --- a/Controller/Cards/Save.php +++ b/Controller/Cards/Save.php @@ -90,7 +90,8 @@ public function execute() /** @var \Magento\Framework\Controller\Result\Json $resultJson */ $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); - if (!$this->formKeyValidator->validate($this->getRequest()) + if ( + !$this->formKeyValidator->validate($this->getRequest()) || !$this->getRequest()->isPost() || !$this->platformVaultConfig->isActive() ) { @@ -147,6 +148,9 @@ private function prepareVerifyCommandSubject(array $profileData, DataObject $tra 'customer_id' => $this->customerSession->getCustomerId(), 'creditcard_month' => $profileData[PaymentProfileInterface::CREDITCARD_MONTH], 'creditcard_year' => $profileData[PaymentProfileInterface::CREDITCARD_YEAR], + 'creditcard_type' => $profileData[PaymentProfileInterface::CREDITCARD_TYPE], + 'creditcard_first_digits' => $profileData[PaymentProfileInterface::CREDITCARD_FIRST_DIGITS], + 'creditcard_last_digits' => $profileData[PaymentProfileInterface::CREDITCARD_LAST_DIGITS], 'billing_address' => $profileData[PaymentProfileInterface::BILLING_ADDRESS], 'customer_email' => $this->customerSession->getCustomer()->getEmail(), 'browser_info' => ($profileData['browser_info'] ?? ''), diff --git a/Gateway/Request/WalletPaymentBuilder.php b/Gateway/Request/WalletPaymentBuilder.php index fddede2e..00d0546c 100644 --- a/Gateway/Request/WalletPaymentBuilder.php +++ b/Gateway/Request/WalletPaymentBuilder.php @@ -18,6 +18,9 @@ public function build(array $buildSubject) return [ PaymentProfileInterface::CREDITCARD_MONTH => $this->getCreditCardMonth($buildSubject), PaymentProfileInterface::CREDITCARD_YEAR => $this->getCreditCardYear($buildSubject), + PaymentProfileInterface::CREDITCARD_TYPE => $buildSubject['creditcard_type'] ?? null, + PaymentProfileInterface::CREDITCARD_LAST_DIGITS => $buildSubject['creditcard_last_digits'] ?? null, + PaymentProfileInterface::CREDITCARD_FIRST_DIGITS => $buildSubject['creditcard_first_digits'] ?? null, PaymentProfileInterface::BILLING_ADDRESS => $this->getBillingAddress($buildSubject), PaymentDataBuilder::PAYMENT_METHOD_TOKEN => $this->getPaymentToken($buildSubject), diff --git a/view/frontend/web/js/view/vault/card.js b/view/frontend/web/js/view/vault/card.js index 6d606804..078e4fe2 100644 --- a/view/frontend/web/js/view/vault/card.js +++ b/view/frontend/web/js/view/vault/card.js @@ -19,13 +19,21 @@ define( defaults: { formSelector: "#vault-edit", formSubmitSelector: "#vault-edit .save", - isLoading: false + isLoading: false, + creditCardLastDigits: null, + creditCardFirstDigits: null, + paymentMethodToken: null, + selectedCardType: null, }, initObservable: function () { this._super() .observe([ - 'isLoading' + 'isLoading', + 'creditCardLastDigits', + 'creditCardFirstDigits', + 'paymentMethodToken', + 'selectedCardType', ]); var self = this; @@ -56,12 +64,17 @@ define( 'zip': $("#postcode").val(), 'country': $("#country").val(), 'year': this.creditCardExpYear(), - 'month': this.creditCardExpMonth() + 'month': this.creditCardExpMonth(), + 'creditcard_first_digits': this.creditCardFirstDigits(), + 'creditcard_last_digits': this.creditCardLastDigits(), + 'creditcard_type': this.selectedCardType(), }; }, submitPayment: function () { var cartData = $(this.formSelector).serializeJSON(); + cartData.creditcard_last_digits = this.creditCardLastDigits(); + cartData.creditcard_first_digits = this.creditCardFirstDigits(); if (config.isThreeDSActive()) { cartData.browser_info = this.getThreeDSBrowserInfo(); From 0dee6faf3fb1b254502b2e4804b2113b6e207188 Mon Sep 17 00:00:00 2001 From: Christopher Shea Date: Fri, 14 Feb 2025 14:00:30 +0100 Subject: [PATCH 2/3] Add coderabbit config --- .coderabbit.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .coderabbit.yaml diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 00000000..e69de29b From a68b5029aacc676b27a366862444621740baf21f Mon Sep 17 00:00:00 2001 From: Christopher Shea Date: Fri, 14 Feb 2025 14:01:17 +0100 Subject: [PATCH 3/3] Add validation for sensitive credit card fields --- Gateway/Request/WalletPaymentBuilder.php | 43 +++++++++++++++++++++--- view/frontend/web/js/view/vault/card.js | 6 ++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Gateway/Request/WalletPaymentBuilder.php b/Gateway/Request/WalletPaymentBuilder.php index 00d0546c..597d9614 100644 --- a/Gateway/Request/WalletPaymentBuilder.php +++ b/Gateway/Request/WalletPaymentBuilder.php @@ -18,11 +18,10 @@ public function build(array $buildSubject) return [ PaymentProfileInterface::CREDITCARD_MONTH => $this->getCreditCardMonth($buildSubject), PaymentProfileInterface::CREDITCARD_YEAR => $this->getCreditCardYear($buildSubject), - PaymentProfileInterface::CREDITCARD_TYPE => $buildSubject['creditcard_type'] ?? null, - PaymentProfileInterface::CREDITCARD_LAST_DIGITS => $buildSubject['creditcard_last_digits'] ?? null, - PaymentProfileInterface::CREDITCARD_FIRST_DIGITS => $buildSubject['creditcard_first_digits'] ?? null, + PaymentProfileInterface::CREDITCARD_TYPE => $this->getCreditCardType($buildSubject), + PaymentProfileInterface::CREDITCARD_LAST_DIGITS => $this->getCreditCardLastDigits($buildSubject), + PaymentProfileInterface::CREDITCARD_FIRST_DIGITS => $this->getCreditCardFirstDigits($buildSubject), PaymentProfileInterface::BILLING_ADDRESS => $this->getBillingAddress($buildSubject), - PaymentDataBuilder::PAYMENT_METHOD_TOKEN => $this->getPaymentToken($buildSubject), VaultConfigProvider::IS_ACTIVE_CODE => 1, ]; @@ -75,4 +74,40 @@ private function getPaymentToken(array $buildSubject) } return $buildSubject['token']; } + + /** + * @param array $buildSubject + * @return array + */ + private function getCreditCardType(array $buildSubject) + { + if (empty($buildSubject['creditcard_type'])) { + throw new \InvalidArgumentException('Credit card type is not passed.'); + } + return $buildSubject['creditcard_type']; + } + + /** + * @param array $buildSubject + * @return array + */ + private function getCreditCardLastDigits(array $buildSubject) + { + if (empty($buildSubject['creditcard_last_digits'])) { + throw new \InvalidArgumentException('Credit card last digits are not passed.'); + } + return $buildSubject['creditcard_last_digits']; + } + + /** + * @param array $buildSubject + * @return array + */ + private function getCreditCardFirstDigits(array $buildSubject) + { + if (empty($buildSubject['creditcard_first_digits'])) { + throw new \InvalidArgumentException('Credit card first digits are not passed.'); + } + return $buildSubject['creditcard_first_digits']; + } } diff --git a/view/frontend/web/js/view/vault/card.js b/view/frontend/web/js/view/vault/card.js index 078e4fe2..202afaa1 100644 --- a/view/frontend/web/js/view/vault/card.js +++ b/view/frontend/web/js/view/vault/card.js @@ -51,6 +51,12 @@ define( }, getPaymentData: function () { + if (this.creditCardFirstDigits() && !/^\d{6}$/.test(this.creditCardFirstDigits())) { + throw new Error('Invalid credit card first digits'); + } + if (this.creditCardLastDigits() && !/^\d{4}$/.test(this.creditCardLastDigits())) { + throw new Error('Invalid credit card last digits'); + } return { 'first_name': $("#first_name").val(), 'last_name': $("#last_name").val(),