From e1a1e0c825ba3fd7707c90644b7781ef6f62dadb Mon Sep 17 00:00:00 2001 From: shontzu-deriv Date: Fri, 13 Sep 2024 15:43:48 +0800 Subject: [PATCH] fix: validation to reject british pound as a special character --- .../reset-trading-password-modal.tsx | 6 ++---- packages/cfd/src/Containers/cfd-password-change.tsx | 8 +------- .../src/Containers/cfd-password-manager-modal.tsx | 6 ++++-- packages/cfd/src/Containers/cfd-password-modal.tsx | 8 +++----- .../cfd/src/Containers/cfd-reset-password-modal.tsx | 8 +++----- .../mt5-migration-back-side-content.tsx | 6 +++--- packages/cfd/src/Helpers/constants.ts | 9 ++++----- .../ResetPasswordModal/reset-password-modal.tsx | 12 +++++++++++- packages/core/src/Constants/form-error-messages.js | 2 ++ .../utils/validation/declarative-validation-rules.ts | 4 +++- .../utils/validation/form-error-messages-types.ts | 1 + 11 files changed, 37 insertions(+), 33 deletions(-) diff --git a/packages/account/src/Components/reset-trading-password-modal/reset-trading-password-modal.tsx b/packages/account/src/Components/reset-trading-password-modal/reset-trading-password-modal.tsx index 7d91931f0132..949437f899d0 100644 --- a/packages/account/src/Components/reset-trading-password-modal/reset-trading-password-modal.tsx +++ b/packages/account/src/Components/reset-trading-password-modal/reset-trading-password-modal.tsx @@ -64,12 +64,10 @@ const ResetTradingPassword = ({ min_number: 8, max_number: max_length, }); + } else if (platform === CFD_PLATFORMS.MT5 && !validMT5Password(values.password)) { + errors.password = getErrorMessages().special_characters(); } else if (!validPassword(values.password)) { errors.password = getErrorMessages().password(); - } else if (platform === CFD_PLATFORMS.MT5 && !validMT5Password(values.password)) { - errors.password = localize( - 'Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~' - ); } return errors; diff --git a/packages/cfd/src/Containers/cfd-password-change.tsx b/packages/cfd/src/Containers/cfd-password-change.tsx index 40121feeb571..8f4405671cab 100644 --- a/packages/cfd/src/Containers/cfd-password-change.tsx +++ b/packages/cfd/src/Containers/cfd-password-change.tsx @@ -94,13 +94,7 @@ const CFDPasswordChange = observer( if (response.error.code === 'PasswordError') actions.setFieldError('old_password', response.error.message); if (response.error.code === 'InputValidationFailed') - actions.setFieldError( - 'new_password', - // Localize is employed to convert the customized error message since the backend error lacks clarity. - localize( - 'Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~' - ) - ); + actions.setFieldError('new_password', getErrorMessages().special_characters()); } if (!response.error) { diff --git a/packages/cfd/src/Containers/cfd-password-manager-modal.tsx b/packages/cfd/src/Containers/cfd-password-manager-modal.tsx index 41276c3d41d4..009e58e2024f 100644 --- a/packages/cfd/src/Containers/cfd-password-manager-modal.tsx +++ b/packages/cfd/src/Containers/cfd-password-manager-modal.tsx @@ -13,7 +13,7 @@ import { } from '@deriv/components'; import { useDevice } from '@deriv-com/ui'; import { localize, Localize } from '@deriv/translations'; -import { getCFDPlatformLabel } from '@deriv/shared'; +import { getCFDPlatformLabel, getErrorMessages, validMT5Password } from '@deriv/shared'; import { FormikErrors } from 'formik'; import CFDStore from '../Stores/Modules/CFD/cfd-store'; import TradingPasswordManager from './trading-password-manager'; @@ -169,7 +169,9 @@ const CFDPasswordManagerTabContent = ({ errors.new_password = localize('This field is required'); } - if (validatePassword(values.new_password)) errors.new_password = validatePassword(values.new_password); + if (platform === CFD_PLATFORMS.MT5 && !validMT5Password(values.new_password)) { + errors.new_password = getErrorMessages().special_characters(); + } else if (validatePassword(values.new_password)) errors.new_password = validatePassword(values.new_password); return errors; }; diff --git a/packages/cfd/src/Containers/cfd-password-modal.tsx b/packages/cfd/src/Containers/cfd-password-modal.tsx index 6ee59387e14b..30262ef1b9ab 100644 --- a/packages/cfd/src/Containers/cfd-password-modal.tsx +++ b/packages/cfd/src/Containers/cfd-password-modal.tsx @@ -738,16 +738,14 @@ const CFDPasswordModal = observer(({ form_error, platform }: TCFDPasswordModalPr min_number: 8, max_number: max_length, }); - } else if (!validPassword(values.password)) { - errors.password = getErrorMessages().password(); } else if ( platform === CFD_PLATFORMS.MT5 && should_set_trading_password && !validMT5Password(values.password) ) { - errors.password = localize( - 'Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~' - ); + errors.password = getErrorMessages().special_characters(); + } else if (!validPassword(values.password)) { + getErrorMessages().password(); } if (values.password?.toLowerCase() === email.toLowerCase()) { errors.password = localize('Your password cannot be the same as your email address.'); diff --git a/packages/cfd/src/Containers/cfd-reset-password-modal.tsx b/packages/cfd/src/Containers/cfd-reset-password-modal.tsx index f468da5d96a1..31b153103eac 100644 --- a/packages/cfd/src/Containers/cfd-reset-password-modal.tsx +++ b/packages/cfd/src/Containers/cfd-reset-password-modal.tsx @@ -101,12 +101,10 @@ const CFDResetPasswordModal = observer(({ platform }: TCFDResetPasswordModal) => min_number: 8, max_number: max_length, }); - } else if (!validPassword(values.new_password)) { - errors.new_password = getErrorMessages().password(); } else if (platform !== CFD_PLATFORMS.DXTRADE && !validMT5Password(values.new_password)) { - errors.new_password = localize( - 'Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~' - ); + errors.new_password = getErrorMessages().special_characters(); + } else if (!validPassword(values.new_password)) { + errors.new_password = getErrorMessages().special_characters(); } if (values.new_password.toLowerCase() === email.toLowerCase()) { errors.new_password = localize('Your password cannot be the same as your email address.'); diff --git a/packages/cfd/src/Containers/mt5-migration-modal/mt5-migration-back-side-content.tsx b/packages/cfd/src/Containers/mt5-migration-modal/mt5-migration-back-side-content.tsx index 0cf68b938f9b..d78fe52c33ac 100644 --- a/packages/cfd/src/Containers/mt5-migration-modal/mt5-migration-back-side-content.tsx +++ b/packages/cfd/src/Containers/mt5-migration-modal/mt5-migration-back-side-content.tsx @@ -1,6 +1,6 @@ import { InlineMessage, Modal, Text, PasswordInput, FormSubmitButton } from '@deriv/components'; import { useMT5SVGEligibleToMigrate } from '@deriv/hooks'; -import { CFD_PLATFORMS, WS, validLength, validPassword, getErrorMessages } from '@deriv/shared'; +import { CFD_PLATFORMS, WS, validLength, validMT5Password, getErrorMessages } from '@deriv/shared'; import { observer, useStore } from '@deriv/stores'; import { Localize, localize } from '@deriv/translations'; import React from 'react'; @@ -58,8 +58,8 @@ const MT5MigrationBackSideContent = observer(() => { min_number: 8, max_number: 25, }); - } else if (!validPassword(values.password)) { - errors.password = getErrorMessages().password(); + } else if (!validMT5Password(values.password)) { + errors.password = getErrorMessages().special_characters(); } if (values.password?.toLowerCase() === email.toLowerCase()) { errors.password = localize('Your password cannot be the same as your email address.'); diff --git a/packages/cfd/src/Helpers/constants.ts b/packages/cfd/src/Helpers/constants.ts index 575e119d34f2..a8f542158583 100644 --- a/packages/cfd/src/Helpers/constants.ts +++ b/packages/cfd/src/Helpers/constants.ts @@ -6,6 +6,7 @@ import { validPassword, validMT5Password, mobileOSDetectAsync, + hasBritishPound, } from '@deriv/shared'; import { localize } from '@deriv/translations'; import { TCFDsPlatformType, TDetailsOfEachMT5Loginid, TMobilePlatforms } from 'Components/props.types'; @@ -139,12 +140,10 @@ const validatePassword = (password: string): string | undefined => { min_number: 8, max_number: 16, }); - } else if (!validPassword(password)) { - return getErrorMessages().password(); } else if (!validMT5Password(password)) { - return localize( - 'Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~' - ); + return getErrorMessages().special_characters(); + } else if (!validPassword(password)) { + return hasBritishPound(password) ? getErrorMessages().special_characters() : getErrorMessages().password(); } }; diff --git a/packages/core/src/App/Containers/ResetPasswordModal/reset-password-modal.tsx b/packages/core/src/App/Containers/ResetPasswordModal/reset-password-modal.tsx index 13d52bbfbe3f..63821223102a 100644 --- a/packages/core/src/App/Containers/ResetPasswordModal/reset-password-modal.tsx +++ b/packages/core/src/App/Containers/ResetPasswordModal/reset-password-modal.tsx @@ -2,7 +2,15 @@ import React from 'react'; import classNames from 'classnames'; import { Formik, Form, FormikHelpers, FormikErrors } from 'formik'; import { Button, Dialog, PasswordInput, PasswordMeter, Text } from '@deriv/components'; -import { redirectToLogin, validPassword, validLength, getErrorMessages, WS, removeActionParam } from '@deriv/shared'; +import { + redirectToLogin, + validPassword, + validLength, + getErrorMessages, + WS, + removeActionParam, + validMT5Password, +} from '@deriv/shared'; import { getLanguage, localize, Localize } from '@deriv/translations'; import { observer, useStore } from '@deriv/stores'; import { TSocketError, TSocketRequest, TSocketResponse } from '@deriv/api/types'; @@ -84,6 +92,8 @@ const ResetPasswordModal = observer(() => { min_number: 8, max_number: 25, }); + } else if (!validMT5Password(values.password)) { + errors.password = getErrorMessages().special_characters(); } else if (!validPassword(values.password)) { errors.password = getErrorMessages().password(); } diff --git a/packages/core/src/Constants/form-error-messages.js b/packages/core/src/Constants/form-error-messages.js index 491d4095bca5..c34269512ecd 100644 --- a/packages/core/src/Constants/form-error-messages.js +++ b/packages/core/src/Constants/form-error-messages.js @@ -16,6 +16,8 @@ export const FORM_ERROR_MESSAGES = { general: () => localize('Only letters, numbers, space, hyphen, period, and apostrophe are allowed.'), name: () => localize('Letters, spaces, periods, hyphens, apostrophes only.'), password: () => localize('Password should have lower and uppercase English letters with numbers.'), + special_characters: () => + localize('Password must have at least one of these special characters: !&‘’*-“%+.#&(),:;?=@<>\\[]^_{}|~'), po_box: () => localize('P.O. Box is not accepted in address'), phone: () => localize('Please enter a valid phone number (e.g. +15417541234).'), postcode: () => localize('Only letters, numbers, space and hyphen are allowed.'), diff --git a/packages/shared/src/utils/validation/declarative-validation-rules.ts b/packages/shared/src/utils/validation/declarative-validation-rules.ts index 0fc8148ea6d9..c1edda3387d1 100644 --- a/packages/shared/src/utils/validation/declarative-validation-rules.ts +++ b/packages/shared/src/utils/validation/declarative-validation-rules.ts @@ -62,6 +62,7 @@ export const validName = (value: string) => /^(?!.*\s{2,})(?!\s)[\p{L}\s'.-]{1,5 export const validLength = (value = '', options: TOptions) => (options.min ? value.length >= Number(options.min) : true) && (options.max ? value.length <= Number(options.max) : true); +export const hasBritishPound = (value: string) => /£/.test(value); export const validPassword = (value: string) => /^(?=.*[a-z])(?=.*\d)(?=.*[A-Z])[!-~]{8,25}$/.test(value); export const validEmail = (value: string) => /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/.test(value); const validBarrier = (value: string) => /^[+-]?\d+\.?\d*$/.test(value); @@ -74,7 +75,8 @@ export const hasInvalidCharacters = (target_string: string) => /[^\dX\s]/.test(t export const isFormattedCardNumber = (target_string: string) => /(^\d{4})\s(\d{2}X{2})\s(X{4})\s(\d{4}$)/.test(target_string); export const validFile = (file: File) => file?.type && /(image|application)\/(jpe?g|pdf|png)$/.test(file?.type); -export const validMT5Password = (value: string) => /^(?=.*[!@#$%^&*()+\-=[\]{};':"|,.<>/?_~])[ -~]{8,16}$/.test(value); +export const validMT5Password = (value: string) => + /^(?=.*[!@#$%^&*()+\-=[\]{};':"|,.<>/?_~])[ -~]{8,16}$/.test(value) && !hasBritishPound(value); let pre_build_dvrs: TInitPreBuildDVRs, form_error_messages: TFormErrorMessagesTypes; diff --git a/packages/shared/src/utils/validation/form-error-messages-types.ts b/packages/shared/src/utils/validation/form-error-messages-types.ts index b04937dbb60d..0dd38062eb67 100644 --- a/packages/shared/src/utils/validation/form-error-messages-types.ts +++ b/packages/shared/src/utils/validation/form-error-messages-types.ts @@ -9,6 +9,7 @@ export type TFormErrorMessagesTypes = Record< | 'general' | 'name' | 'password' + | 'special_characters' | 'po_box' | 'phone' | 'postcode'