Skip to content

Commit

Permalink
Chore/reorganisation secured fields directory (#1457)
Browse files Browse the repository at this point in the history
* Receiving and storing panLength prop

* Created SFP directory

* Created CSF directory

* Created CSF/extensions and lib/securedField directories

* Moving files into CSF/extensions

* More files moved

* Moving utils

* Removing panLength related vars - they belong in another PR

* First batch of partials

* Adding 3 more partials

* Removing files replaced by partials

* Removing private function getIframeContentWindow form CSF (replace by util)

* fix unit tests

* Fixed linting error
  • Loading branch information
sponglord authored Jan 21, 2022
1 parent 913881b commit 23ac528
Show file tree
Hide file tree
Showing 75 changed files with 668 additions and 574 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { h } from 'preact';
import { useState, useEffect, useRef } from 'preact/hooks';
import classNames from 'classnames';
import AchSecuredFields from './components/AchSecuredFields';
import SecuredFieldsProvider from '../../../../components/internal/SecuredFields/SecuredFieldsProvider';
import SecuredFieldsProvider from '../../../internal/SecuredFields/SFP/SecuredFieldsProvider';
import Address from '../../../internal/Address';
import { renderFormField } from '../../../internal/FormFields';
import Field from '../../../internal/FormFields/Field';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Language from '../../../../language/Language';
import { CardInputDataState, CardInputValidState } from './types';
import { render, screen, fireEvent } from '@testing-library/preact';

jest.mock('../../../internal/SecuredFields/lib');
jest.mock('../../../internal/SecuredFields/lib/CSF');

let valid = {} as CardInputValidState;
let data = {} as CardInputDataState;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { h } from 'preact';
import { useState, useEffect, useRef, useMemo } from 'preact/hooks';
import SecuredFieldsProvider, { SFPState } from '../../../internal/SecuredFields/SecuredFieldsProvider';
import SecuredFieldsProvider, { SFPState } from '../../../internal/SecuredFields/SFP/SecuredFieldsProvider';
import defaultProps from './defaultProps';
import defaultStyles from './defaultStyles';
import styles from './CardInput.module.scss';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PaymentAmount } from '../../../../../types';
import { CardBrandsConfiguration } from '../../../types';
import { ComponentChildren } from 'preact';
import { CVCPolicyType, DatePolicyType } from '../../../../internal/SecuredFields/lib/core/AbstractSecuredField';
import { CVCPolicyType, DatePolicyType } from '../../../../internal/SecuredFields/lib/types';

export interface BrandIconProps {
brand: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CardBrandsConfiguration, CardConfiguration, DualBrandSelectElement, Soc
import { PaymentAmount } from '../../../../types';
import { InstallmentOptions } from './components/types';
import { ValidationResult } from '../../../internal/PersonalDetails/types';
import { CVCPolicyType, DatePolicyType } from '../../../internal/SecuredFields/lib/core/AbstractSecuredField';
import { CVCPolicyType, DatePolicyType } from '../../../internal/SecuredFields/lib/types';
import { ValidationRuleResult } from '../../../../utils/Validator/Validator';
import Specifications from '../../../internal/Address/Specifications';
import { AddressSchema, StringObject } from '../../../internal/Address/types';
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/components/Card/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
CbObjOnLoad,
CbObjOnBinLookup
} from '../internal/SecuredFields/lib/types';
import { CVCPolicyType, DatePolicyType } from '../internal/SecuredFields/lib/core/AbstractSecuredField';
import { CVCPolicyType, DatePolicyType } from '../internal/SecuredFields/lib/types';

export interface CardElementProps extends UIElementProps {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, h } from 'preact';
import classNames from 'classnames';
import SecuredFieldsProvider from '../../../components/internal/SecuredFields/SecuredFieldsProvider';
import SecuredFieldsProvider from '../../internal/SecuredFields/SFP/SecuredFieldsProvider';
import Field from '../../internal/FormFields/Field';
import Alert from '../../internal/Alert';
import GiftcardResult from './GiftcardResult';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { h } from 'preact';
import { useState, useEffect, useRef, useMemo } from 'preact/hooks';
import Language from '../../../language/Language';
import SecuredFieldsProvider, { SFPState } from '../../internal/SecuredFields/SecuredFieldsProvider';
import SecuredFieldsProvider, { SFPState } from '../../internal/SecuredFields/SFP/SecuredFieldsProvider';
import { BinLookupResponse } from '../../Card/types';
import SFExtensions from '../../internal/SecuredFields/binLookup/extensions';

Expand Down
108 changes: 108 additions & 0 deletions packages/lib/src/components/internal/SecuredFields/SFP/SFPUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// ROUTINES USED IN SecuredFieldsProvider.componentDidMount TO DETECT & MAP FIELD NAMES ///////////
import {
CVC_POLICY_HIDDEN,
CVC_POLICY_OPTIONAL,
DATE_POLICY_HIDDEN,
DATE_POLICY_OPTIONAL,
ENCRYPTED_EXPIRY_DATE,
ENCRYPTED_EXPIRY_MONTH,
ENCRYPTED_EXPIRY_YEAR,
ENCRYPTED_SECURITY_CODE
} from '../lib/configuration/constants';
import getProp from '../../../../utils/getProp';
import { DEFAULT_ERROR } from '../../../../core/Errors/constants';

/**
* Make an array of encrypted field names based on the value of the 'data-cse' attribute of elements in the rootNode
*/
export const getFields = rootNode => {
if (rootNode) {
return Array.prototype.slice.call(rootNode.querySelectorAll('[data-cse*="encrypted"]')).map(f => f.getAttribute('data-cse'));
}
return [];
};

/**
* If, visually, we're dealing with a single date field (expiryDate) we still need separate entries
* for expiryMonth & expiryYear - since that is how the values will be delivered from securedFields
*/
export const validFieldsReducer = (acc, cur) => {
if (cur === ENCRYPTED_EXPIRY_DATE) {
acc[ENCRYPTED_EXPIRY_MONTH] = false;
acc[ENCRYPTED_EXPIRY_YEAR] = false;
} else {
acc[cur] = false;
}

return acc;
};
// -- end ROUTINES USED IN SecuredFieldsProvider.componentDidMount --------------------------------

// ROUTINES USED IN SecuredFieldsProvider.showValidation TO GENERATE ERRORS ///////////
/**
* If, visually, we're dealing with a single date field (expiryDate) remap the separate entries we have
* for the valid states of expiryMonth & expiryYear back to the single key we use to an store an error
* i.e `"encryptedExpiryMonth" & "encryptedExpiryYear" => "encryptedExpiryDate"`
*/
const mapDateFields = (field, numDateFields) => {
const isDateField = field === ENCRYPTED_EXPIRY_MONTH || field === ENCRYPTED_EXPIRY_YEAR;
return numDateFields === 1 && isDateField ? ENCRYPTED_EXPIRY_DATE : field;
};

/**
* Skip generating an error for an optional field, unless it is already in error
*/
const skipOptionalFields = (field, state, fieldNames) => {
// console.log('\n### utils::skipOptionalField3:: examining field=', field);
const { isFieldOfType, fieldIsValid } = fieldNames.reduce(
(acc, fieldName) => {
if (!acc.isFieldOfType) {
// console.log('### utils:: fieldName:: ', fieldName, 'match=', field === fieldName);
acc.isFieldOfType = field === fieldName;
acc.fieldIsValid = !state.errors[fieldName];
}
return acc;
},
{ isFieldOfType: false, fieldIsValid: false }
);

const policyType = field === ENCRYPTED_SECURITY_CODE ? 'cvcPolicy' : 'expiryDatePolicy';

const policyOptional = policyType === 'cvcPolicy' ? CVC_POLICY_OPTIONAL : DATE_POLICY_OPTIONAL;
const policyHidden = policyType === 'cvcPolicy' ? CVC_POLICY_HIDDEN : DATE_POLICY_HIDDEN;

// if policy != required
return (state[policyType] === policyOptional || state[policyType] === policyHidden) && fieldIsValid && isFieldOfType ? null : field;
};

export const getErrorReducer = (numDateFields, state) => (acc, field) => {
// We're only interested in the non-valid fields from the state.valid object...
let val =
state.valid[field] !== true
? mapDateFields(field, numDateFields) // Map the keys we use for the valid state to the key(s) we use for the error state
: null;

// Skip error generation for optional/hidden CVC & Date unless the fields are already in error
val = skipOptionalFields(val, state, [ENCRYPTED_SECURITY_CODE, ENCRYPTED_EXPIRY_DATE, ENCRYPTED_EXPIRY_MONTH, ENCRYPTED_EXPIRY_YEAR]);

// console.log('### utils:::: ############# val=', val);

if (val && !acc.includes(val)) acc.push(val);

return acc;
};

/**
* Create an object suitable for sending to our handleOnError function
*/
export const getErrorObject = (fieldType, rootNode, state) => {
const error = getProp(state, `errors.${fieldType}`) || DEFAULT_ERROR;

return {
rootNode,
fieldType,
error,
type: 'card'
};
};
// -- end ROUTINES USED IN SecuredFieldsProvider.showValidation -----------------------
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { shallow } from 'enzyme';
import { h } from 'preact';
import SecuredFieldsProvider from './SecuredFieldsProvider';
import Language from '../../../language/Language';
import { ERROR_CODES, ERROR_MSG_INCOMPLETE_FIELD, ERROR_MSG_UNSUPPORTED_CARD_ENTERED, ERROR_MSG_CLEARED } from '../../../core/Errors/constants';
import { getError } from '../../../core/Errors/utils';
import Language from '../../../../language/Language';
import { ERROR_CODES, ERROR_MSG_INCOMPLETE_FIELD, ERROR_MSG_UNSUPPORTED_CARD_ENTERED, ERROR_MSG_CLEARED } from '../../../../core/Errors/constants';
import { getError } from '../../../../core/Errors/utils';

jest.mock('./lib', () => {
jest.mock('../lib/CSF', () => {
return () => true;
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { Component } from 'preact';
import { getErrorObject, getFields, getErrorReducer, validFieldsReducer } from './utils';
import initCSF from './lib';
import { getErrorObject, getFields, getErrorReducer, validFieldsReducer } from './SFPUtils';
import initCSF from '../lib/CSF';
import handlers from './SecuredFieldsProviderHandlers';
import defaultProps, { SFPProps } from './defaultProps';
import {
CSFReturnObject,
CSFSetupObject,
StylesObject,
CbObjOnError,
CbObjOnFocus,
Expand All @@ -15,12 +13,13 @@ import {
CbObjOnAutoComplete,
CbObjOnConfigSuccess,
CbObjOnLoad
} from './lib/types';
import { AddressData } from '../../../types';
import { CVC_POLICY_REQUIRED, DATE_POLICY_REQUIRED, ENCRYPTED_CARD_NUMBER, ENCRYPTED_PWD_FIELD } from './lib/configuration/constants';
import { BinLookupResponse } from '../../Card/types';
import { CVCPolicyType, DatePolicyType } from './lib/core/AbstractSecuredField';
import { getError } from '../../../core/Errors/utils';
} from '../lib/types';
import { CSFReturnObject, CSFSetupObject } from '../lib/CSF/types';
import { AddressData } from '../../../../types';
import { CVC_POLICY_REQUIRED, DATE_POLICY_REQUIRED, ENCRYPTED_CARD_NUMBER, ENCRYPTED_PWD_FIELD } from '../lib/configuration/constants';
import { BinLookupResponse } from '../../../Card/types';
import { CVCPolicyType, DatePolicyType } from '../lib/types';
import { getError } from '../../../../core/Errors/utils';

export interface SFPState {
status?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCardImageUrl } from './utils';
import { getCardImageUrl } from '../utils';
import {
ENCRYPTED_SECURITY_CODE,
ENCRYPTED_CARD_NUMBER,
Expand All @@ -9,7 +9,7 @@ import {
HIDDEN,
ENCRYPTED_EXPIRY_MONTH,
ENCRYPTED_EXPIRY_YEAR
} from './lib/configuration/constants';
} from '../lib/configuration/constants';
import {
CbObjOnError,
CbObjOnFocus,
Expand All @@ -19,8 +19,8 @@ import {
CbObjOnAutoComplete,
CbObjOnConfigSuccess,
CbObjOnLoad
} from './lib/types';
import { existy } from './lib/utilities/commonUtils';
} from '../lib/types';
import { existy } from '../lib/utilities/commonUtils';

/**
* Emits the onConfigSuccess (ready) event
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Language } from '../../../language/Language';
import { CVCPolicyType } from './lib/core/AbstractSecuredField';
import { Language } from '../../../../language/Language';
import { CVCPolicyType } from '../lib/types';

export interface SFPProps {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SingleBrandResetObject } from '../SecuredFieldsProvider';
import { SingleBrandResetObject } from '../SFP/SecuredFieldsProvider';
import { BrandObject } from '../../../Card/types';
import createCardVariantSwitcher from './createCardVariantSwitcher';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { CSFSetupObject, CSFConfigObject, CSFCallbacksConfig, CSFStateObject, SFFeedbackObj, SendBrandObject, SendExpiryDateObject } from '../types';
import { createSecuredFields } from './createSecuredFields';
import { handleProcessBrand } from './utils/processBrand';
import { handleBrandFromBinLookup } from './utils/handleBrandFromBinLookup';
import { CSFSetupObject, CSFConfigObject, CSFCallbacksConfig, CSFStateObject } from './types';
import { SFFeedbackObj, SendBrandObject, SendExpiryDateObject } from '../types';
import { createSecuredFields } from './extensions/createSecuredFields';
import processBrand from './partials/processBrand';
import handleBrandFromBinLookup from './extensions/handleBrandFromBinLookup';

abstract class AbstractCSF {
// Set in CSF
protected callbacks: CSFCallbacksConfig;
protected config: CSFConfigObject;
protected props: CSFSetupObject;
protected state: CSFStateObject;
protected assessFormValidity: () => void;
protected brandsFromBinLookup: typeof handleBrandFromBinLookup;
protected validateForm: () => void;
protected handleBrandFromBinLookup: typeof handleBrandFromBinLookup;
protected callbacksHandler: (callbacksObj: object) => void;
protected configHandler: () => void;
protected createCardSecuredFields: (securedFields: HTMLElement[]) => number;
Expand All @@ -29,7 +30,7 @@ abstract class AbstractCSF {
protected isConfigured: () => void;
protected postMessageToAllIframes: (pDataObj: object) => void;
protected processAutoComplete: (pFeedbackObj: SFFeedbackObj) => void;
protected processBrand: typeof handleProcessBrand;
protected processBrand: typeof processBrand;
protected sendBrandToCardSF: (brandObj: SendBrandObject) => void;
protected sendExpiryDatePolicyToSF: (dateObj: SendExpiryDateObject) => void;
protected setFocusOnFrame: (pFieldType: string, doLog?: boolean) => void;
Expand Down
Loading

0 comments on commit 23ac528

Please sign in to comment.