mirror of
https://github.com/jlengrand/adyen-web.git
synced 2026-03-10 08:01:22 +00:00
Feature/detect unsupported sf fields (#2495)
* detect unrecognised data-cse attributes and don't create a SF for them * Added unit test for new functionality * added changeset
This commit is contained in:
5
.changeset/mighty-ladybugs-worry.md
Normal file
5
.changeset/mighty-ladybugs-worry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@adyen/adyen-web': patch
|
||||
---
|
||||
|
||||
Detect when the value of a data-cse attribute is not supported, and don't create a SF for it
|
||||
@@ -47,7 +47,7 @@ describe("Testing setupSecuredField's createCardSecuredFields functionality", ()
|
||||
SecuredFieldMock.mockClear();
|
||||
});
|
||||
|
||||
test("setupSecuredField's createCardSecuredFields function should call the onBrand callback", async () => {
|
||||
test("setupSecuredField's createCardSecuredFields function, as a single-branded card, should call the onBrand callback", async () => {
|
||||
myCSF.state.type = 'mc';
|
||||
myCSF.isSingleBrandedCard = true;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { setupSecuredField } from './createSecuredFields';
|
||||
import { createSecuredFields, setupSecuredField } from './createSecuredFields';
|
||||
import { DATA_ENCRYPTED_FIELD_ATTR, ENCRYPTED_CARD_NUMBER, ENCRYPTED_EXPIRY_DATE, SF_CONFIG_TIMEOUT } from '../../configuration/constants';
|
||||
import { SecuredFields } from '../../types';
|
||||
import Language from '../../../../../../language';
|
||||
@@ -18,12 +18,14 @@ let MySecuredField;
|
||||
const myCSF = {
|
||||
state: { type: 'card', hasSeparateDateFields: null, securedFields: {} as SecuredFields, iframeCount: 0, originalNumIframes: 2, numIframes: 2 },
|
||||
config: { shouldDisableIOSArrowKeys: null },
|
||||
props: { i18n: new Language('en-US', {}) },
|
||||
props: { rootNode: null, i18n: new Language('en-US', {}) },
|
||||
callbacks: {
|
||||
onLoad: jest.fn(() => {}),
|
||||
onTouchstartIOS: jest.fn(() => {})
|
||||
},
|
||||
createSecuredFields,
|
||||
setupSecuredField,
|
||||
createNonCardSecuredFields: jest.fn(() => {}),
|
||||
encryptedAttrName: DATA_ENCRYPTED_FIELD_ATTR,
|
||||
destroySecuredFields: jest.fn(() => {
|
||||
console.log('### createSecuredFields.test::calling destroySecuredFields:: ');
|
||||
@@ -52,6 +54,7 @@ const dummyObj = { foo: 'bar' };
|
||||
describe('Testing CSFs setupSecuredField functionality', () => {
|
||||
beforeEach(() => {
|
||||
console.log = jest.fn(() => {});
|
||||
console.warn = jest.fn(() => {});
|
||||
|
||||
MySecuredField = {
|
||||
fieldType: ENCRYPTED_CARD_NUMBER,
|
||||
@@ -108,6 +111,23 @@ describe('Testing CSFs setupSecuredField functionality', () => {
|
||||
SecuredFieldMock.mockClear();
|
||||
});
|
||||
|
||||
test('Calling setupSecuredField with an unsupported value for the data-cse attribute should see that a SF is not created and that a warning is given', () => {
|
||||
const rootNode = document.createElement('div');
|
||||
const unsupportedEl = makeDiv('encryptedCustomField');
|
||||
rootNode.appendChild(unsupportedEl);
|
||||
myCSF.props.rootNode = rootNode;
|
||||
|
||||
const numIframes: number = myCSF.createSecuredFields();
|
||||
|
||||
expect(numIframes).toEqual(0);
|
||||
|
||||
expect(console.warn).toBeCalledWith(
|
||||
`WARNING: 'encryptedCustomField' is not a valid type for the '${DATA_ENCRYPTED_FIELD_ATTR}' attribute. A SecuredField will not be created for this element.`
|
||||
);
|
||||
|
||||
expect(myCSF.createNonCardSecuredFields).toBeCalledWith([]);
|
||||
});
|
||||
|
||||
test('Calling setupSecuredField to see that an "encryptedCardNumber" SF is created and stored in state', () => {
|
||||
myCSF.setupSecuredField(makeDiv(ENCRYPTED_CARD_NUMBER));
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ import {
|
||||
DATA_ENCRYPTED_FIELD_ATTR,
|
||||
DATA_INFO,
|
||||
DATA_UID,
|
||||
SF_CONFIG_TIMEOUT
|
||||
SF_CONFIG_TIMEOUT,
|
||||
ALL_SECURED_FIELDS
|
||||
} from '../../configuration/constants';
|
||||
import { existy } from '../../utilities/commonUtils';
|
||||
import cardType from '../utils/cardType';
|
||||
@@ -22,8 +23,17 @@ import AdyenCheckoutError from '../../../../../../core/Errors/AdyenCheckoutError
|
||||
export function createSecuredFields(): number {
|
||||
this.encryptedAttrName = DATA_ENCRYPTED_FIELD_ATTR;
|
||||
|
||||
// Detect DOM elements that qualify as securedField holders
|
||||
const securedFields: HTMLElement[] = select(this.props.rootNode, `[${this.encryptedAttrName}]`);
|
||||
// Detect DOM elements that qualify as securedField holders & filter them for valid types
|
||||
const securedFields: HTMLElement[] = select(this.props.rootNode, `[${this.encryptedAttrName}]`).filter(field => {
|
||||
const fieldType: string = getAttribute(field, this.encryptedAttrName);
|
||||
const isValidType = ALL_SECURED_FIELDS.includes(fieldType);
|
||||
if (!isValidType) {
|
||||
console.warn(
|
||||
`WARNING: '${fieldType}' is not a valid type for the '${this.encryptedAttrName}' attribute. A SecuredField will not be created for this element.`
|
||||
);
|
||||
}
|
||||
return isValidType;
|
||||
});
|
||||
|
||||
/**
|
||||
* cvcPolicy - 'required' | 'optional' | 'hidden'
|
||||
|
||||
@@ -8,7 +8,7 @@ import '../../style.scss';
|
||||
import { MockReactApp } from './MockReactApp';
|
||||
import { searchFunctionExample } from '../../utils';
|
||||
|
||||
const onlyShowCard = true;
|
||||
const onlyShowCard = false;
|
||||
|
||||
const showComps = {
|
||||
clickToPay: true,
|
||||
@@ -53,7 +53,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse =
|
||||
// Stored Card
|
||||
if (!onlyShowCard && showComps.storedCard) {
|
||||
if (checkout.paymentMethodsResponse.storedPaymentMethods && checkout.paymentMethodsResponse.storedPaymentMethods.length > 0) {
|
||||
const storedCardData = checkout.paymentMethodsResponse.storedPaymentMethods[2];
|
||||
const storedCardData = checkout.paymentMethodsResponse.storedPaymentMethods[0];
|
||||
window.storedCard = checkout
|
||||
.create('card', {
|
||||
...storedCardData,
|
||||
|
||||
@@ -227,7 +227,7 @@ function handlePaymentResult(result, component) {
|
||||
function startPayment(component) {
|
||||
if (!component.isValid) return component.showValidation();
|
||||
|
||||
const allow3DS2 = paymentsConfig.additionalData.allow3DS2 || false;
|
||||
const allow3DS2 = paymentsConfig.additionalData?.allow3DS2 || false;
|
||||
|
||||
const riskdata = checkout.modules.risk.data;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user