From 618f2005864122752af6521a6dec25dd03d1af8d Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sun, 14 Nov 2021 17:27:11 +0530 Subject: [PATCH 1/5] Allow spaces and special chars in phone number username Sanitize the phone input before sending to backend. --- src/libs/ValidationUtils.js | 2 +- src/pages/signin/LoginForm.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index 13d1c2501321..3f3aa6a75855 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -236,7 +236,7 @@ function isValidUSPhone(phoneNumber) { * @returns {Boolean} */ function isNumericWithSpecialChars(input) { - return /^\+?\d*$/.test(input.replace(/[()-]/g, '')); + return /^\+?\d*$/.test(input.replace(/((?!\n)[()-\s\t])/g, '')); } /** diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 6da966cf1770..e0c1252a95e4 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -79,7 +79,10 @@ class LoginForm extends React.Component { return; } - if (!Str.isValidEmail(this.state.login) && !Str.isValidPhone(this.state.login)) { + const phoneLogin = this.state.login.replace(/((?!\n)[()-\s\t])/g, ''); + const isValidPhoneLogin = Str.isValidPhone(phoneLogin); + + if (!Str.isValidEmail(this.state.login) && !isValidPhoneLogin) { if (isNumericWithSpecialChars(this.state.login)) { this.setState({formError: 'messages.errorMessageInvalidPhone'}); } else { @@ -93,7 +96,7 @@ class LoginForm extends React.Component { }); // Check if this login has an account associated with it or not - fetchAccountDetails(this.state.login); + fetchAccountDetails(isValidPhoneLogin ? phoneLogin : this.state.login); } render() { From 3d68071d7cd8a5390c5ffd5770a67a706b840f98 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sun, 14 Nov 2021 17:33:54 +0530 Subject: [PATCH 2/5] allow comma --- src/libs/ValidationUtils.js | 2 +- src/pages/signin/LoginForm.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index 3f3aa6a75855..8286774a5cb5 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -236,7 +236,7 @@ function isValidUSPhone(phoneNumber) { * @returns {Boolean} */ function isNumericWithSpecialChars(input) { - return /^\+?\d*$/.test(input.replace(/((?!\n)[()-\s\t])/g, '')); + return /^\+?\d*$/.test(input.replace(/((?!\n)[,()-\s\t])/g, '')); } /** diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index e0c1252a95e4..2492a80a6688 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -79,7 +79,7 @@ class LoginForm extends React.Component { return; } - const phoneLogin = this.state.login.replace(/((?!\n)[()-\s\t])/g, ''); + const phoneLogin = this.state.login.replace(/((?!\n)[,()-\s\t])/g, ''); const isValidPhoneLogin = Str.isValidPhone(phoneLogin); if (!Str.isValidEmail(this.state.login) && !isValidPhoneLogin) { From 4d44bdfaf020f74ceb5ca58e116d778d3e00fec6 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Sun, 14 Nov 2021 17:48:08 +0530 Subject: [PATCH 3/5] No comma needed --- src/libs/ValidationUtils.js | 2 +- src/pages/signin/LoginForm.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index 8286774a5cb5..3f3aa6a75855 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -236,7 +236,7 @@ function isValidUSPhone(phoneNumber) { * @returns {Boolean} */ function isNumericWithSpecialChars(input) { - return /^\+?\d*$/.test(input.replace(/((?!\n)[,()-\s\t])/g, '')); + return /^\+?\d*$/.test(input.replace(/((?!\n)[()-\s\t])/g, '')); } /** diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 2492a80a6688..e0c1252a95e4 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -79,7 +79,7 @@ class LoginForm extends React.Component { return; } - const phoneLogin = this.state.login.replace(/((?!\n)[,()-\s\t])/g, ''); + const phoneLogin = this.state.login.replace(/((?!\n)[()-\s\t])/g, ''); const isValidPhoneLogin = Str.isValidPhone(phoneLogin); if (!Str.isValidEmail(this.state.login) && !isValidPhoneLogin) { From e93acde491fe2cc64a1de9d3cdc150e084d693ab Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Wed, 17 Nov 2021 22:40:35 +0530 Subject: [PATCH 4/5] Allow special chars in the RequestCallpage --- src/pages/RequestCallPage.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/RequestCallPage.js b/src/pages/RequestCallPage.js index de3f9243828c..2ea2e83dda55 100644 --- a/src/pages/RequestCallPage.js +++ b/src/pages/RequestCallPage.js @@ -106,13 +106,13 @@ class RequestCallPage extends Component { Growl.error(this.props.translate('requestCallPage.growlMessageNoPersonalPolicy'), 3000); return; } - + const phoneNumber = this.state.phoneNumber.replace(/((?!\n)[()-\s\t])/g, ''); requestInboxCall({ + phoneNumber, taskID: this.props.route.params.taskID, policyID: personalPolicy.id, firstName: this.state.firstName, lastName: this.state.lastName, - phoneNumber: this.state.phoneNumber, email: this.props.session.email, }); } @@ -137,7 +137,8 @@ class RequestCallPage extends Component { if (_.isEmpty(this.state.phoneNumber.trim())) { return this.props.translate('messages.noPhoneNumber'); } - if (!Str.isValidPhone(this.state.phoneNumber)) { + const phoneNumber = this.state.phoneNumber.replace(/((?!\n)[()-\s\t])/g, ''); + if (!Str.isValidPhone(phoneNumber)) { return this.props.translate('messages.errorMessageInvalidPhone'); } return ''; From ac23e2e9fc7a35f48739c989857cfe46f4514626 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 18 Nov 2021 11:09:06 +0530 Subject: [PATCH 5/5] Dried up code --- src/CONST.js | 1 + src/libs/LoginUtil.js | 14 ++++++++++++++ src/libs/ValidationUtils.js | 3 ++- src/pages/RequestCallPage.js | 7 ++++--- src/pages/signin/LoginForm.js | 3 ++- 5 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 src/libs/LoginUtil.js diff --git a/src/CONST.js b/src/CONST.js index 9a0fe6e80263..e7ba8ef4cd40 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -431,6 +431,7 @@ const CONST = { PHONE_MAX_LENGTH: 15, PHONE_MIN_LENGTH: 5, REGEX: { + SPECIAL_CHARS_WITHOUT_NEWLINE: /((?!\n)[()-\s\t])/g, US_PHONE: /^\+1\d{10}$/, DIGITS_AND_PLUS: /^\+?[0-9]*$/, PHONE_E164_PLUS: /^\+?[1-9]\d{1,14}$/, diff --git a/src/libs/LoginUtil.js b/src/libs/LoginUtil.js new file mode 100644 index 000000000000..e8346b2bfc54 --- /dev/null +++ b/src/libs/LoginUtil.js @@ -0,0 +1,14 @@ +import CONST from '../CONST'; + +/** + * Remove the special chars from the phone number + * @param {String} phone + * @return {String} + */ +function getPhoneNumberWithoutSpecialChars(phone) { + return phone.replace(CONST.REGEX.SPECIAL_CHARS_WITHOUT_NEWLINE, ''); +} + +export default { + getPhoneNumberWithoutSpecialChars, +}; diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index d6e2a08b3cac..e90d7b2658d6 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -2,6 +2,7 @@ import moment from 'moment'; import _ from 'underscore'; import CONST from '../CONST'; import {getMonthFromExpirationDateString, getYearFromExpirationDateString} from './CardUtils'; +import LoginUtil from './LoginUtil'; /** * Implements the Luhn Algorithm, a checksum formula used to validate credit card @@ -253,7 +254,7 @@ function isValidUSPhone(phoneNumber) { * @returns {Boolean} */ function isNumericWithSpecialChars(input) { - return /^\+?\d*$/.test(input.replace(/((?!\n)[()-\s\t])/g, '')); + return /^\+?\d*$/.test(LoginUtil.getPhoneNumberWithoutSpecialChars(input)); } /** diff --git a/src/pages/RequestCallPage.js b/src/pages/RequestCallPage.js index e43b0da3134b..922d9b30ced7 100644 --- a/src/pages/RequestCallPage.js +++ b/src/pages/RequestCallPage.js @@ -24,6 +24,7 @@ import Text from '../components/Text'; import KeyboardAvoidingView from '../components/KeyboardAvoidingView'; import RequestCallIcon from '../../assets/images/request-call.svg'; import {getFirstAndLastNameErrors} from '../libs/actions/PersonalDetails'; +import LoginUtil from '../libs/LoginUtil'; const propTypes = { ...withLocalizePropTypes, @@ -106,13 +107,13 @@ class RequestCallPage extends Component { Growl.error(this.props.translate('requestCallPage.growlMessageNoPersonalPolicy'), 3000); return; } - const phoneNumber = this.state.phoneNumber.replace(/((?!\n)[()-\s\t])/g, ''); + requestInboxCall({ - phoneNumber, taskID: this.props.route.params.taskID, policyID: personalPolicy.id, firstName: this.state.firstName, lastName: this.state.lastName, + phoneNumber: LoginUtil.getPhoneNumberWithoutSpecialChars(this.state.phoneNumber), email: this.props.session.email, }); } @@ -134,7 +135,7 @@ class RequestCallPage extends Component { * @returns {String} */ getPhoneNumberError() { - const phoneNumber = this.state.phoneNumber.replace(/((?!\n)[()-\s\t])/g, ''); + const phoneNumber = LoginUtil.getPhoneNumberWithoutSpecialChars(this.state.phoneNumber); if (_.isEmpty(this.state.phoneNumber.trim()) || !Str.isValidPhone(phoneNumber)) { return this.props.translate('messages.errorMessageInvalidPhone'); } diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index e0c1252a95e4..602be57d2a64 100755 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -16,6 +16,7 @@ import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize import getEmailKeyboardType from '../../libs/getEmailKeyboardType'; import ExpensiTextInput from '../../components/ExpensiTextInput'; import {isNumericWithSpecialChars} from '../../libs/ValidationUtils'; +import LoginUtil from '../../libs/LoginUtil'; const propTypes = { /* Onyx Props */ @@ -79,7 +80,7 @@ class LoginForm extends React.Component { return; } - const phoneLogin = this.state.login.replace(/((?!\n)[()-\s\t])/g, ''); + const phoneLogin = LoginUtil.getPhoneNumberWithoutSpecialChars(this.state.login); const isValidPhoneLogin = Str.isValidPhone(phoneLogin); if (!Str.isValidEmail(this.state.login) && !isValidPhoneLogin) {