Skip to content

Commit

Permalink
Revert "[PhoneNumber Verification] Display only valid numbers in user…
Browse files Browse the repository at this point in the history
… search."
  • Loading branch information
puneetlath authored Apr 27, 2023
1 parent 1bc672f commit fcf63a9
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 38 deletions.
6 changes: 6 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -963,10 +963,15 @@ const CONST = {
},
REGEX: {
SPECIAL_CHARS_WITHOUT_NEWLINE: /((?!\n)[()-\s\t])/g,
US_PHONE: /^\+1\d{10}$/,
US_PHONE_WITH_OPTIONAL_COUNTRY_CODE: /^(\+1)?\d{10}$/,
DIGITS_AND_PLUS: /^\+?[0-9]*$/,
PHONE_E164_PLUS: /^\+?[1-9]\d{1,14}$/,
PHONE_WITH_SPECIAL_CHARS: /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/,
ALPHABETIC_CHARS: /[a-zA-Z]+/,
ALPHABETIC_CHARS_WITH_NUMBER: /^[a-zA-Z0-9 ]*$/,
POSITIVE_INTEGER: /^\d+$/,
NON_ALPHA_NUMERIC: /[^A-Za-z0-9+]/g,
PO_BOX: /\b[P|p]?(OST|ost)?\.?\s*[O|o|0]?(ffice|FFICE)?\.?\s*[B|b][O|o|0]?[X|x]?\.?\s+[#]?(\d+)\b/,
ANY_VALUE: /^.+$/,
ZIP_CODE: /[0-9]{5}(?:[- ][0-9]{4})?/,
Expand All @@ -988,6 +993,7 @@ const CONST = {
// Extract attachment's source from the data's html string
ATTACHMENT_DATA: /(data-expensify-source|data-name)="([^"]+)"/g,

NON_NUMERIC_WITH_PLUS: /[^0-9+]/g,
EMOJI_NAME: /:[\w+-]+:/g,
EMOJI_SUGGESTIONS: /:[a-zA-Z0-9_+-]{1,40}$/,
AFTER_FIRST_LINE_BREAK: /\n.*/g,
Expand Down
16 changes: 15 additions & 1 deletion src/libs/LoginUtils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Str from 'expensify-common/lib/str';
import Onyx from 'react-native-onyx';
import CONST from '../CONST';
import ONYXKEYS from '../ONYXKEYS';
Expand All @@ -18,17 +19,30 @@ function getPhoneNumberWithoutSpecialChars(phone) {
return phone.replace(CONST.REGEX.SPECIAL_CHARS_WITHOUT_NEWLINE, '');
}

/**
* Remove +1 and special chars from the phone number
*
* @param {String} phone
* @return {String}
*/
function getPhoneNumberWithoutUSCountryCodeAndSpecialChars(phone) {
return getPhoneNumberWithoutSpecialChars(phone.replace(/^\+1/, ''));
}

/**
* Append user country code to the phone number
*
* @param {String} phone
* @return {String}
*/
function appendCountryCode(phone) {
return phone.startsWith('+') ? phone : `+${countryCodeByIP}${phone}`;
return (Str.isValidPhone(phone) && !phone.includes('+'))
? `+${countryCodeByIP}${phone}`
: phone;
}

export {
getPhoneNumberWithoutSpecialChars,
getPhoneNumberWithoutUSCountryCodeAndSpecialChars,
appendCountryCode,
};
41 changes: 25 additions & 16 deletions src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Onyx from 'react-native-onyx';
import lodashOrderBy from 'lodash/orderBy';
import lodashGet from 'lodash/get';
import Str from 'expensify-common/lib/str';
import {parsePhoneNumber} from 'awesome-phonenumber';
import ONYXKEYS from '../ONYXKEYS';
import CONST from '../CONST';
import * as ReportUtils from './ReportUtils';
Expand Down Expand Up @@ -33,6 +32,12 @@ Onyx.connect({
callback: val => loginList = _.isEmpty(val) ? {} : val,
});

let countryCodeByIP;
Onyx.connect({
key: ONYXKEYS.COUNTRY_CODE,
callback: val => countryCodeByIP = val || 1,
});

let preferredLocale;
Onyx.connect({
key: ONYXKEYS.NVP_PREFERRED_LOCALE,
Expand Down Expand Up @@ -129,9 +134,9 @@ function getPolicyExpenseReportOptions(report) {
* @return {String}
*/
function addSMSDomainIfPhoneNumber(login) {
const parsedPhoneNumber = parsePhoneNumber(login);
if (parsedPhoneNumber.possible && !Str.isValidEmail(login)) {
return parsedPhoneNumber.number.e164 + CONST.SMS.DOMAIN;
if (Str.isValidPhone(login) && !Str.isValidEmail(login)) {
const smsLogin = login + CONST.SMS.DOMAIN;
return smsLogin.includes('+') ? smsLogin : `+${countryCodeByIP}${smsLogin}`;
}
return login;
}
Expand Down Expand Up @@ -527,8 +532,8 @@ function getOptions(reports, personalDetails, {
let recentReportOptions = [];
let personalDetailsOptions = [];
const reportMapForLogins = {};
const parsedPhoneNumber = parsePhoneNumber(LoginUtils.appendCountryCode(searchInputValue));
const searchValue = parsedPhoneNumber.possible ? parsedPhoneNumber.number.e164 : searchInputValue;
const isPhoneNumber = CONST.REGEX.PHONE_WITH_SPECIAL_CHARS.test(searchInputValue);
const searchValue = isPhoneNumber ? searchInputValue.replace(CONST.REGEX.NON_NUMERIC_WITH_PLUS, '') : searchInputValue;

// Filter out all the reports that shouldn't be displayed
const filteredReports = _.filter(reports, report => ReportUtils.shouldReportBeInOptionList(
Expand Down Expand Up @@ -671,21 +676,25 @@ function getOptions(reports, personalDetails, {
const noOptions = (recentReportOptions.length + personalDetailsOptions.length) === 0;
const noOptionsMatchExactly = !_.find(personalDetailsOptions.concat(recentReportOptions), option => option.login === searchValue.toLowerCase());

if (searchValue && (noOptions || noOptionsMatchExactly)
&& !isCurrentUser({login: searchValue})
&& _.every(selectedOptions, option => option.login !== searchValue)
&& ((Str.isValidEmail(searchValue) && !Str.isDomainEmail(searchValue)) || parsedPhoneNumber.possible)
&& (!_.find(loginOptionsToExclude, loginOptionToExclude => loginOptionToExclude.login === addSMSDomainIfPhoneNumber(searchValue).toLowerCase()))
&& (searchValue !== CONST.EMAIL.CHRONOS || Permissions.canUseChronos(betas))
// If the phone number doesn't have an international code then let's prefix it with the
// current user's international code based on their IP address.
const login = LoginUtils.appendCountryCode(searchValue);

if (login && (noOptions || noOptionsMatchExactly)
&& !isCurrentUser({login})
&& _.every(selectedOptions, option => option.login !== login)
&& ((Str.isValidEmail(login) && !Str.isDomainEmail(login)) || Str.isValidPhone(login))
&& (!_.find(loginOptionsToExclude, loginOptionToExclude => loginOptionToExclude.login === addSMSDomainIfPhoneNumber(login).toLowerCase()))
&& (login !== CONST.EMAIL.CHRONOS || Permissions.canUseChronos(betas))
) {
userToInvite = createOption([searchValue], personalDetails, null, reportActions, {
userToInvite = createOption([login], personalDetails, null, reportActions, {
showChatPreviewLine,
});

// If user doesn't exist, use a default avatar
userToInvite.icons = [{
source: ReportUtils.getAvatar('', searchValue),
name: searchValue,
source: ReportUtils.getAvatar('', login),
name: login,
type: CONST.ICON_TYPE_AVATAR,
}];
}
Expand Down Expand Up @@ -855,7 +864,7 @@ function getHeaderMessage(hasSelectableOptions, hasUserToInvite, searchValue, ma
return Localize.translate(preferredLocale, 'common.maxParticipantsReached', {count: CONST.REPORT.MAXIMUM_PARTICIPANTS});
}

const isValidPhone = parsePhoneNumber(LoginUtils.appendCountryCode(searchValue)).possible;
const isValidPhone = Str.isValidPhone(LoginUtils.appendCountryCode(searchValue));

const isValidEmail = Str.isValidEmail(searchValue);

Expand Down
10 changes: 5 additions & 5 deletions src/libs/ValidationUtils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import moment from 'moment';
import _ from 'underscore';
import {URL_REGEX_WITH_REQUIRED_PROTOCOL} from 'expensify-common/lib/Url';
import {parsePhoneNumber} from 'awesome-phonenumber';
import CONST from '../CONST';
import * as CardUtils from './CardUtils';
import * as LoginUtils from './LoginUtils';
Expand Down Expand Up @@ -298,11 +297,12 @@ function validateIdentity(identity) {
* @returns {Boolean}
*/
function isValidUSPhone(phoneNumber = '', isCountryCodeOptional) {
const phone = phoneNumber || '';
const regionCode = isCountryCodeOptional ? CONST.COUNTRY.US : null;
// Remove non alphanumeric characters from the phone number
const sanitizedPhone = (phoneNumber || '').replace(CONST.REGEX.NON_ALPHA_NUMERIC, '');
const isUsPhone = isCountryCodeOptional
? CONST.REGEX.US_PHONE_WITH_OPTIONAL_COUNTRY_CODE.test(sanitizedPhone) : CONST.REGEX.US_PHONE.test(sanitizedPhone);

const parsedPhoneNumber = parsePhoneNumber(phone, {regionCode});
return parsedPhoneNumber.possible && parsedPhoneNumber.regionCode === CONST.COUNTRY.US;
return CONST.REGEX.PHONE_E164_PLUS.test(sanitizedPhone) && isUsPhone;
}

/**
Expand Down
6 changes: 2 additions & 4 deletions src/pages/DetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import _ from 'underscore';
import {withOnyx} from 'react-native-onyx';
import Str from 'expensify-common/lib/str';
import lodashGet from 'lodash/get';
import {parsePhoneNumber} from 'awesome-phonenumber';
import styles from '../styles/styles';
import Text from '../components/Text';
import ONYXKEYS from '../ONYXKEYS';
Expand Down Expand Up @@ -74,9 +73,8 @@ const defaultProps = {
*/
const getPhoneNumber = (details) => {
// If the user hasn't set a displayName, it is set to their phone number, so use that
const parsedPhoneNumber = parsePhoneNumber(details.displayName);
if (parsedPhoneNumber.possible) {
return parsedPhoneNumber.number.e164;
if (Str.isValidPhone(details.displayName)) {
return details.displayName;
}

// If the user has set a displayName, get the phone number from the SMS login
Expand Down
4 changes: 2 additions & 2 deletions src/pages/EnablePayments/AdditionalDetailsStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import {View} from 'react-native';
import moment from 'moment/moment';
import {parsePhoneNumber} from 'awesome-phonenumber';
import IdologyQuestions from './IdologyQuestions';
import ScreenWrapper from '../../components/ScreenWrapper';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
Expand All @@ -19,6 +18,7 @@ import TextLink from '../../components/TextLink';
import TextInput from '../../components/TextInput';
import * as Wallet from '../../libs/actions/Wallet';
import * as ValidationUtils from '../../libs/ValidationUtils';
import * as LoginUtils from '../../libs/LoginUtils';
import * as ErrorUtils from '../../libs/ErrorUtils';
import AddressForm from '../ReimbursementAccount/AddressForm';
import DatePicker from '../../components/DatePicker';
Expand Down Expand Up @@ -173,7 +173,7 @@ class AdditionalDetailsStep extends React.Component {
*/
activateWallet(values) {
const personalDetails = {
phoneNumber: parsePhoneNumber(values[INPUT_IDS.PHONE_NUMBER], {regionCode: CONST.COUNTRY.US}).number.significant,
phoneNumber: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(values[INPUT_IDS.PHONE_NUMBER]),
legalFirstName: values[INPUT_IDS.LEGAL_FIRST_NAME],
legalLastName: values[INPUT_IDS.LEGAL_LAST_NAME],
addressStreet: values[INPUT_IDS.ADDRESS.street],
Expand Down
4 changes: 2 additions & 2 deletions src/pages/ReimbursementAccount/CompanyStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {View} from 'react-native';
import Str from 'expensify-common/lib/str';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import {parsePhoneNumber} from 'awesome-phonenumber';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
import CONST from '../../CONST';
import * as BankAccounts from '../../libs/actions/BankAccounts';
Expand All @@ -19,6 +18,7 @@ import TextLink from '../../components/TextLink';
import StatePicker from '../../components/StatePicker';
import withLocalize from '../../components/withLocalize';
import * as ValidationUtils from '../../libs/ValidationUtils';
import * as LoginUtils from '../../libs/LoginUtils';
import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import Picker from '../../components/Picker';
Expand Down Expand Up @@ -148,7 +148,7 @@ class CompanyStep extends React.Component {
// Fields from Company step
...values,
companyTaxID: values.companyTaxID.replace(CONST.REGEX.NON_NUMERIC, ''),
companyPhone: parsePhoneNumber(values.companyPhone, {regionCode: CONST.COUNTRY.US}).number.significant,
companyPhone: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(values.companyPhone),
};

BankAccounts.updateCompanyInformationForBankAccount(bankAccount);
Expand Down
5 changes: 2 additions & 3 deletions src/pages/settings/Profile/Contacts/NewContactMethodPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {withOnyx} from 'react-native-onyx';
import {compose} from 'underscore';
import lodashGet from 'lodash/get';
import Str from 'expensify-common/lib/str';
import {parsePhoneNumber} from 'awesome-phonenumber';
import Button from '../../../../components/Button';
import FixedFooter from '../../../../components/FixedFooter';
import HeaderWithCloseButton from '../../../../components/HeaderWithCloseButton';
Expand Down Expand Up @@ -69,10 +68,10 @@ function NewContactMethodPage(props) {
}, []);

const isFormValid = useMemo(() => {
const phoneLogin = LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(login));
const phoneLogin = LoginUtils.getPhoneNumberWithoutSpecialChars(login);

return (Permissions.canUsePasswordlessLogins(props.betas) || password)
&& (Str.isValidEmail(login) || parsePhoneNumber(phoneLogin).possible);
&& (Str.isValidEmail(login) || Str.isValidPhone(phoneLogin));
}, [login, password, props.betas]);

const submitForm = useCallback(() => {
Expand Down
9 changes: 4 additions & 5 deletions src/pages/signin/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import _ from 'underscore';
import Str from 'expensify-common/lib/str';
import {parsePhoneNumber} from 'awesome-phonenumber';
import styles from '../../styles/styles';
import Text from '../../components/Text';
import * as Session from '../../libs/actions/Session';
Expand Down Expand Up @@ -144,10 +143,10 @@ class LoginForm extends React.Component {
return;
}

const phoneLogin = LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(login));
const parsedPhoneNumber = parsePhoneNumber(phoneLogin);
const phoneLogin = LoginUtils.getPhoneNumberWithoutSpecialChars(login);
const isValidPhoneLogin = Str.isValidPhone(phoneLogin);

if (!Str.isValidEmail(login) && !parsedPhoneNumber.possible) {
if (!Str.isValidEmail(login) && !isValidPhoneLogin) {
if (ValidationUtils.isNumericWithSpecialChars(login)) {
this.setState({formError: 'common.error.phoneNumber'});
} else {
Expand All @@ -161,7 +160,7 @@ class LoginForm extends React.Component {
});

// Check if this login has an account associated with it or not
Session.beginSignIn(parsedPhoneNumber.possible ? parsedPhoneNumber.number.e164 : login);
Session.beginSignIn(isValidPhoneLogin ? phoneLogin : login);
}

render() {
Expand Down

0 comments on commit fcf63a9

Please sign in to comment.