From 8284fb028c9c6c67dec600e433f672d2aee26cb9 Mon Sep 17 00:00:00 2001 From: Brian J Date: Thu, 31 Oct 2024 16:13:19 -0700 Subject: [PATCH] If a number is in an unexpected format, fallback to a standard (sanitized) number --- src/__tests__/base.test.js | 13 +++++++++++-- src/base.js | 26 ++++++++++++-------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/__tests__/base.test.js b/src/__tests__/base.test.js index fdcecf1..8dac37d 100644 --- a/src/__tests__/base.test.js +++ b/src/__tests__/base.test.js @@ -220,20 +220,29 @@ describe('Phone number pretty formatting', () => { format: findPhoneFormat({ regionCode: '57', e164: '+573211234567' }), }, germany: { - e164: '+49 170 87654321', + e164: '+4917087654321', regionCode: '49', format: findPhoneFormat({ regionCode: '49', e164: '+4917087654321' }), }, germanyAlt: { - e164: '+49 170 8765432', + e164: '+491708765432', regionCode: '49', format: findPhoneFormat({ regionCode: '49', e164: '+491708765432' }), }, + norwayUnexpected: { + e164: '+47174087654', + regionCode: '47', + format: findPhoneFormat({ regionCode: '47', e164: '+471740876543' }), + }, }; expect(formatPhoneNumber(testNumbers.nullCase)).toBe(null); expect(formatPhoneNumber(testNumbers.us)).toBe('(310) 349-6200'); expect(formatPhoneNumber(testNumbers.colombia)).toBe('+57 321 123 4567'); expect(formatPhoneNumber(testNumbers.germanyAlt)).toBe('+49 17 08765432'); + // This looks like a Norwegian number, but doesn't match a known format. In this case, we'll return a sanitized generic format. + expect(formatPhoneNumber(testNumbers.norwayUnexpected)).toBe( + '+47174087654', + ); }); }); diff --git a/src/base.js b/src/base.js index 3fdf9aa..a5ee738 100644 --- a/src/base.js +++ b/src/base.js @@ -234,18 +234,6 @@ export const getPhoneParts = (phoneNumber) => { phoneParts.e164 = formatPhoneNumberForE164(phoneParts); phoneParts.format = findPhoneFormat(phoneParts); phoneParts.formattedNumber = formatPhoneNumber(phoneParts); - - // If there are left over x's, the formatting ran into something unexpected. - // This may be ok depending on the region and their phone number formats. - // But it does mean we don't want to display this number. - if ( - phoneParts.formattedNumber && - phoneParts.formattedNumber.indexOf('x') !== -1 - ) { - // Since `rawNumber` isn't sanitized, we'll use a simple format that we - // are assured to be safe. - phoneParts.formattedNumber = strippedPhoneNumber; - } } return phoneParts; @@ -353,16 +341,26 @@ export const findPhoneFormat = ({ regionCode, e164 }) => { * @param {Object} params - The parameters for formatting the phone number. * @param {string} params.format - The desired format for the phone number. Example: `(xxx) xxx-xxxx`. * @param {string} params.e164 - The E.164 formatted phone number to format. Example: `+12065551234`. + * @param {string} params.regionCode - The region code of the phone number. Example, the US would be "1". * @returns {string|null} The formatted phone number, or null if the E.164 number or format is not provided. */ -export const formatPhoneNumber = ({ format, e164 }) => { +export const formatPhoneNumber = ({ format, e164, regionCode }) => { let formattedNumber = ''; if (e164 && format) { // Remove the leading '+' and let the format handle it. - const strippedPhone = e164.replace(/\D/g, ''); + const strippedPhone = e164.replace(/\+/g, ''); let phoneIndex = strippedPhone.length - 1; + // The US / NANP rarely includes region code prefix when sharing numbers. Other regions often do, so we'll have a special condition to allow ignoring of the region code for region 1. + // For other regions, we'll return the stripped number to safely display the presumed good number that may be in a safe but not-ideal format. + if ( + regionCode !== '1' && + strippedPhone.length !== format.split('x').length - 1 + ) { + return e164; + } + // Traverse backward so we can omit country code in some formats (like US). for (let i = format.length; i >= 0; i--) { if (format[i]) {