Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If a number is in an unexpected format, fallback to a standard (sanitized) number #18

Merged
merged 1 commit into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/__tests__/base.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
);
});
});
26 changes: 12 additions & 14 deletions src/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]) {
Expand Down