diff --git a/.eslintignore b/.eslintignore
index 7f6c39a2c2fb..20ed14d2b0d4 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -19,7 +19,6 @@ sticker-creator/dist/**
# Third-party files
js/Mp3LameEncoder.min.js
js/WebAudioRecorderMp3.js
-js/libphonenumber-util.js
# TypeScript generated files
app/**/*.js
diff --git a/js/libphonenumber-util.js b/js/libphonenumber-util.js
deleted file mode 100644
index 57e4155ccd77..000000000000
--- a/js/libphonenumber-util.js
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2014-2020 Signal Messenger, LLC
-// SPDX-License-Identifier: AGPL-3.0-only
-
-(function () {
- 'use strict';
-
- /*
- * This file extends the libphonenumber object with a set of phonenumbery
- * utility functions. libphonenumber must be included before you call these
- * functions, but the order of the files/script-tags doesn't matter.
- */
-
- window.libphonenumber = window.libphonenumber || {};
- window.libphonenumber.util = {
- getRegionCodeForNumber: function (number) {
- try {
- var parsedNumber = libphonenumber.parse(number);
- return libphonenumber.getRegionCodeForNumber(parsedNumber);
- } catch (e) {
- return 'ZZ';
- }
- },
-
- splitCountryCode: function (number) {
- var parsedNumber = libphonenumber.parse(number);
- return {
- country_code: parsedNumber.values_[1],
- national_number: parsedNumber.values_[2],
- };
- },
-
- getCountryCode: function (regionCode) {
- var cc = libphonenumber.getCountryCodeForRegion(regionCode);
- return cc !== 0 ? cc : '';
- },
-
- parseNumber: function (number, defaultRegionCode) {
- try {
- var parsedNumber = libphonenumber.parse(number, defaultRegionCode);
-
- return {
- isValidNumber: libphonenumber.isValidNumber(parsedNumber),
- regionCode: libphonenumber.getRegionCodeForNumber(parsedNumber),
- countryCode: '' + parsedNumber.getCountryCode(),
- nationalNumber: '' + parsedNumber.getNationalNumber(),
- e164: libphonenumber.format(
- parsedNumber,
- libphonenumber.PhoneNumberFormat.E164
- ),
- };
- } catch (ex) {
- return { error: ex, isValidNumber: false };
- }
- },
-
- getAllRegionCodes: function () {
- return {
- AD: 'Andorra',
- AE: 'United Arab Emirates',
- AF: 'Afghanistan',
- AG: 'Antigua and Barbuda',
- AI: 'Anguilla',
- AL: 'Albania',
- AM: 'Armenia',
- AO: 'Angola',
- AR: 'Argentina',
- AS: 'AmericanSamoa',
- AT: 'Austria',
- AU: 'Australia',
- AW: 'Aruba',
- AX: 'Åland Islands',
- AZ: 'Azerbaijan',
- BA: 'Bosnia and Herzegovina',
- BB: 'Barbados',
- BD: 'Bangladesh',
- BE: 'Belgium',
- BF: 'Burkina Faso',
- BG: 'Bulgaria',
- BH: 'Bahrain',
- BI: 'Burundi',
- BJ: 'Benin',
- BL: 'Saint Barthélemy',
- BM: 'Bermuda',
- BN: 'Brunei Darussalam',
- BO: 'Bolivia, Plurinational State of',
- BR: 'Brazil',
- BS: 'Bahamas',
- BT: 'Bhutan',
- BW: 'Botswana',
- BY: 'Belarus',
- BZ: 'Belize',
- CA: 'Canada',
- CC: 'Cocos (Keeling) Islands',
- CD: 'Congo, The Democratic Republic of the',
- CF: 'Central African Republic',
- CG: 'Congo',
- CH: 'Switzerland',
- CI: "Cote d'Ivoire",
- CK: 'Cook Islands',
- CL: 'Chile',
- CM: 'Cameroon',
- CN: 'China',
- CO: 'Colombia',
- CR: 'Costa Rica',
- CU: 'Cuba',
- CV: 'Cape Verde',
- CX: 'Christmas Island',
- CY: 'Cyprus',
- CZ: 'Czech Republic',
- DE: 'Germany',
- DJ: 'Djibouti',
- DK: 'Denmark',
- DM: 'Dominica',
- DO: 'Dominican Republic',
- DZ: 'Algeria',
- EC: 'Ecuador',
- EE: 'Estonia',
- EG: 'Egypt',
- ER: 'Eritrea',
- ES: 'Spain',
- ET: 'Ethiopia',
- FI: 'Finland',
- FJ: 'Fiji',
- FK: 'Falkland Islands (Malvinas)',
- FM: 'Micronesia, Federated States of',
- FO: 'Faroe Islands',
- FR: 'France',
- GA: 'Gabon',
- GB: 'United Kingdom',
- GD: 'Grenada',
- GE: 'Georgia',
- GF: 'French Guiana',
- GG: 'Guernsey',
- GH: 'Ghana',
- GI: 'Gibraltar',
- GL: 'Greenland',
- GM: 'Gambia',
- GN: 'Guinea',
- GP: 'Guadeloupe',
- GQ: 'Equatorial Guinea',
- GR: 'Ελλάδα',
- GT: 'Guatemala',
- GU: 'Guam',
- GW: 'Guinea-Bissau',
- GY: 'Guyana',
- HK: 'Hong Kong',
- HN: 'Honduras',
- HR: 'Croatia',
- HT: 'Haiti',
- HU: 'Magyarország',
- ID: 'Indonesia',
- IE: 'Ireland',
- IL: 'Israel',
- IM: 'Isle of Man',
- IN: 'India',
- IO: 'British Indian Ocean Territory',
- IQ: 'Iraq',
- IR: 'Iran, Islamic Republic of',
- IS: 'Iceland',
- IT: 'Italy',
- JE: 'Jersey',
- JM: 'Jamaica',
- JO: 'Jordan',
- JP: 'Japan',
- KE: 'Kenya',
- KG: 'Kyrgyzstan',
- KH: 'Cambodia',
- KI: 'Kiribati',
- KM: 'Comoros',
- KN: 'Saint Kitts and Nevis',
- KP: "Korea, Democratic People's Republic of",
- KR: 'Korea, Republic of',
- KW: 'Kuwait',
- KY: 'Cayman Islands',
- KZ: 'Kazakhstan',
- LA: "Lao People's Democratic Republic",
- LB: 'Lebanon',
- LC: 'Saint Lucia',
- LI: 'Liechtenstein',
- LK: 'Sri Lanka',
- LR: 'Liberia',
- LS: 'Lesotho',
- LT: 'Lithuania',
- LU: 'Luxembourg',
- LV: 'Latvia',
- LY: 'Libyan Arab Jamahiriya',
- MA: 'Morocco',
- MC: 'Monaco',
- MD: 'Moldova, Republic of',
- ME: 'Црна Гора',
- MF: 'Saint Martin',
- MG: 'Madagascar',
- MH: 'Marshall Islands',
- MK: 'Macedonia, The Former Yugoslav Republic of',
- ML: 'Mali',
- MM: 'Myanmar',
- MN: 'Mongolia',
- MO: 'Macao',
- MP: 'Northern Mariana Islands',
- MQ: 'Martinique',
- MR: 'Mauritania',
- MS: 'Montserrat',
- MT: 'Malta',
- MU: 'Mauritius',
- MV: 'Maldives',
- MW: 'Malawi',
- MX: 'Mexico',
- MY: 'Malaysia',
- MZ: 'Mozambique',
- NA: 'Namibia',
- NC: 'New Caledonia',
- NE: 'Niger',
- NF: 'Norfolk Island',
- NG: 'Nigeria',
- NI: 'Nicaragua',
- NL: 'Netherlands',
- NO: 'Norway',
- NP: 'Nepal',
- NR: 'Nauru',
- NU: 'Niue',
- NZ: 'New Zealand',
- OM: 'Oman',
- PA: 'Panama',
- PE: 'Peru',
- PF: 'French Polynesia',
- PG: 'Papua New Guinea',
- PH: 'Philippines',
- PK: 'Pakistan',
- PL: 'Polska',
- PM: 'Saint Pierre and Miquelon',
- PR: 'Puerto Rico',
- PS: 'Palestinian Territory, Occupied',
- PT: 'Portugal',
- PW: 'Palau',
- PY: 'Paraguay',
- QA: 'Qatar',
- RE: 'Réunion',
- RO: 'Romania',
- RS: 'Србија',
- RU: 'Russia',
- RW: 'Rwanda',
- SA: 'Saudi Arabia',
- SB: 'Solomon Islands',
- SC: 'Seychelles',
- SD: 'Sudan',
- SE: 'Sweden',
- SG: 'Singapore',
- SH: 'Saint Helena, Ascension and Tristan Da Cunha',
- SI: 'Slovenia',
- SJ: 'Svalbard and Jan Mayen',
- SK: 'Slovakia',
- SL: 'Sierra Leone',
- SM: 'San Marino',
- SN: 'Senegal',
- SO: 'Somalia',
- SR: 'Suriname',
- ST: 'Sao Tome and Principe',
- SV: 'El Salvador',
- SY: 'Syrian Arab Republic',
- SZ: 'Swaziland',
- TC: 'Turks and Caicos Islands',
- TD: 'Chad',
- TG: 'Togo',
- TH: 'Thailand',
- TJ: 'Tajikistan',
- TK: 'Tokelau',
- TL: 'Timor-Leste',
- TM: 'Turkmenistan',
- TN: 'Tunisia',
- TO: 'Tonga',
- TR: 'Turkey',
- TT: 'Trinidad and Tobago',
- TV: 'Tuvalu',
- TW: 'Taiwan, Province of China',
- TZ: 'Tanzania, United Republic of',
- UA: 'Ukraine',
- UG: 'Uganda',
- US: 'United States',
- UY: 'Uruguay',
- UZ: 'Uzbekistan',
- VA: 'Holy See (Vatican City State)',
- VC: 'Saint Vincent and the Grenadines',
- VE: 'Venezuela',
- VG: 'Virgin Islands, British',
- VI: 'Virgin Islands, U.S.',
- VN: 'Viet Nam',
- VU: 'Vanuatu',
- WF: 'Wallis and Futuna',
- WS: 'Samoa',
- YE: 'Yemen',
- YT: 'Mayotte',
- ZA: 'South Africa',
- ZM: 'Zambia',
- ZW: 'Zimbabwe',
- };
- }, // getAllRegionCodes
- }; // libphonenumber.util
-})();
diff --git a/test/index.html b/test/index.html
index fd4cfec134db..2a7763c939a4 100644
--- a/test/index.html
+++ b/test/index.html
@@ -107,7 +107,6 @@
-
diff --git a/ts/components/StandaloneRegistration.tsx b/ts/components/StandaloneRegistration.tsx
index ce6cfd250d20..b8340c04aaa4 100644
--- a/ts/components/StandaloneRegistration.tsx
+++ b/ts/components/StandaloneRegistration.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 Signal Messenger, LLC
+// Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { ChangeEvent } from 'react';
@@ -7,6 +7,7 @@ import type { Plugin } from 'intl-tel-input';
import intlTelInput from 'intl-tel-input';
import { strictAssert } from '../util/assert';
+import { parseNumber } from '../util/libphonenumberUtil';
import { getChallengeURL } from '../challenge';
const PhoneInput = ({
@@ -42,10 +43,7 @@ const PhoneInput = ({
const regionCode = plugin.getSelectedCountryData().iso2;
- const parsedNumber = window.libphonenumber.util.parseNumber(
- number,
- regionCode
- );
+ const parsedNumber = parseNumber(number, regionCode);
setIsValid(parsedNumber.isValidNumber);
onValidation(parsedNumber.isValidNumber);
diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts
index 6fcfe0941b2c..f66a706d5ee8 100644
--- a/ts/models/conversations.ts
+++ b/ts/models/conversations.ts
@@ -19,6 +19,10 @@ import type {
} from '../model-types.d';
import { getInitials } from '../util/getInitials';
import { normalizeUuid } from '../util/normalizeUuid';
+import {
+ getRegionCodeForNumber,
+ parseNumber,
+} from '../util/libphonenumberUtil';
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import type { AttachmentType } from '../types/Attachment';
import { isGIF } from '../types/Attachment';
@@ -3406,7 +3410,7 @@ export class ConversationModel extends window.Backbone
if (!regionCode) {
throw new Error('No region code');
}
- const number = window.libphonenumber.util.parseNumber(
+ const number = parseNumber(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.get('e164')!,
regionCode
@@ -5017,8 +5021,7 @@ export class ConversationModel extends window.Backbone
const number = this.get('e164')!;
try {
const parsedNumber = window.libphonenumber.parse(number);
- const regionCode =
- window.libphonenumber.getRegionCodeForNumber(parsedNumber);
+ const regionCode = getRegionCodeForNumber(parsedNumber);
if (regionCode === window.storage.get('regionCode')) {
return window.libphonenumber.format(
parsedNumber,
diff --git a/test/libphonenumber_util_test.js b/ts/test-both/util/libphonenumberUtil_test.ts
similarity index 59%
rename from test/libphonenumber_util_test.js
rename to ts/test-both/util/libphonenumberUtil_test.ts
index 4c9effae24f1..85c53acd0491 100644
--- a/test/libphonenumber_util_test.js
+++ b/ts/test-both/util/libphonenumberUtil_test.ts
@@ -1,25 +1,26 @@
-// Copyright 2015-2020 Signal Messenger, LLC
+// Copyright 2015-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-/* global libphonenumber */
-
-'use strict';
+import { assert, AssertionError } from 'chai';
+import { parseNumber } from '../../util/libphonenumberUtil';
describe('libphonenumber util', () => {
describe('parseNumber', () => {
it('numbers with + are valid without providing regionCode', () => {
- const result = libphonenumber.util.parseNumber('+14155555555');
- assert.isTrue(result.isValidNumber);
- assert.strictEqual(result.nationalNumber, '4155555555');
+ const result = parseNumber('+14155555555');
+ if (!result.isValidNumber) {
+ throw new AssertionError('Phone number is not valid');
+ }
assert.strictEqual(result.e164, '+14155555555');
assert.strictEqual(result.regionCode, 'US');
assert.strictEqual(result.countryCode, '1');
});
it('variant numbers with the right regionCode are valid', () => {
['4155555555', '14155555555', '+14155555555'].forEach(number => {
- const result = libphonenumber.util.parseNumber(number, 'US');
- assert.isTrue(result.isValidNumber);
- assert.strictEqual(result.nationalNumber, '4155555555');
+ const result = parseNumber(number, 'US');
+ if (!result.isValidNumber) {
+ throw new AssertionError('Phone number is not valid');
+ }
assert.strictEqual(result.e164, '+14155555555');
assert.strictEqual(result.regionCode, 'US');
assert.strictEqual(result.countryCode, '1');
diff --git a/ts/textsecure/AccountManager.ts b/ts/textsecure/AccountManager.ts
index a0b0fd267085..7195985432b7 100644
--- a/ts/textsecure/AccountManager.ts
+++ b/ts/textsecure/AccountManager.ts
@@ -1,4 +1,4 @@
-// Copyright 2020-2021 Signal Messenger, LLC
+// Copyright 2020-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import PQueue from 'p-queue';
@@ -31,6 +31,7 @@ import { UUID, UUIDKind } from '../types/UUID';
import { isMoreRecentThan, isOlderThan } from '../util/timestamp';
import { ourProfileKeyService } from '../services/ourProfileKey';
import { assert, strictAssert } from '../util/assert';
+import { getRegionCodeForNumber } from '../util/libphonenumberUtil';
import { getProvisioningUrl } from '../util/getProvisioningUrl';
import { SignalService as Proto } from '../protobuf';
import * as log from '../logging/log';
@@ -689,8 +690,7 @@ export default class AccountManager extends EventTarget {
await storage.put('read-receipt-setting', Boolean(readReceipts));
- const regionCode =
- window.libphonenumber.util.getRegionCodeForNumber(number);
+ const regionCode = getRegionCodeForNumber(number);
await storage.put('regionCode', regionCode);
await storage.protocol.hydrateCaches();
}
diff --git a/ts/util/libphonenumberUtil.ts b/ts/util/libphonenumberUtil.ts
new file mode 100644
index 000000000000..c9fb9f69e272
--- /dev/null
+++ b/ts/util/libphonenumberUtil.ts
@@ -0,0 +1,51 @@
+// Copyright 2014-2022 Signal Messenger, LLC
+// SPDX-License-Identifier: AGPL-3.0-only
+
+import {
+ instance as libphonenumber,
+ PhoneNumberFormat,
+} from './libphonenumberInstance';
+
+const FALLBACK_REGION_CODE = 'ZZ';
+
+export function getRegionCodeForNumber(number: string): string {
+ try {
+ const parsedNumber = libphonenumber.parse(number);
+ return (
+ libphonenumber.getRegionCodeForNumber(parsedNumber) ||
+ FALLBACK_REGION_CODE
+ );
+ } catch (e) {
+ return FALLBACK_REGION_CODE;
+ }
+}
+
+export function parseNumber(
+ number: string,
+ defaultRegionCode?: string
+):
+ | { isValidNumber: false; error: unknown }
+ | {
+ isValidNumber: true;
+ regionCode: undefined | string;
+ countryCode: undefined | string;
+ e164: string;
+ } {
+ try {
+ const parsedNumber = libphonenumber.parse(number, defaultRegionCode);
+
+ const isValidNumber = libphonenumber.isValidNumber(parsedNumber);
+ if (!isValidNumber) {
+ return { error: new Error('Invalid phone number'), isValidNumber: false };
+ }
+
+ return {
+ isValidNumber: true,
+ regionCode: libphonenumber.getRegionCodeForNumber(parsedNumber),
+ countryCode: parsedNumber.getCountryCode()?.toString(),
+ e164: libphonenumber.format(parsedNumber, PhoneNumberFormat.E164),
+ };
+ } catch (error) {
+ return { error, isValidNumber: false };
+ }
+}
diff --git a/ts/util/scaleImageToLevel.ts b/ts/util/scaleImageToLevel.ts
index e125413d1428..a086893b6404 100644
--- a/ts/util/scaleImageToLevel.ts
+++ b/ts/util/scaleImageToLevel.ts
@@ -1,4 +1,4 @@
-// Copyright 2021 Signal Messenger, LLC
+// Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import loadImage from 'blueimp-load-image';
@@ -7,6 +7,7 @@ import type { MIMEType } from '../types/MIME';
import { IMAGE_JPEG } from '../types/MIME';
import { canvasToBlob } from './canvasToBlob';
import { getValue } from '../RemoteConfig';
+import { parseNumber } from './libphonenumberUtil';
enum MediaQualityLevels {
One = 1,
@@ -67,18 +68,22 @@ function getMediaQualityLevel(): MediaQualityLevels {
if (!values) {
return DEFAULT_LEVEL;
}
- const countryValues = parseCountryValues(values);
+
const e164 = window.textsecure.storage.user.getNumber();
if (!e164) {
return DEFAULT_LEVEL;
}
- const parsedPhoneNumber = window.libphonenumber.util.parseNumber(e164);
+ const parsedPhoneNumber = parseNumber(e164);
if (!parsedPhoneNumber.isValidNumber) {
return DEFAULT_LEVEL;
}
- const level = countryValues.get(parsedPhoneNumber.countryCode);
+ const countryValues = parseCountryValues(values);
+
+ const level = parsedPhoneNumber.countryCode
+ ? countryValues.get(parsedPhoneNumber.countryCode)
+ : undefined;
if (level) {
return level;
}
diff --git a/ts/window.d.ts b/ts/window.d.ts
index 373a3dfe7dfa..e913c8ee1d46 100644
--- a/ts/window.d.ts
+++ b/ts/window.d.ts
@@ -213,21 +213,6 @@ declare global {
isFullScreen: () => boolean;
initialTheme?: ThemeType;
libphonenumber: {
- util: {
- getRegionCodeForNumber: (number: string) => string;
- parseNumber: (
- e164: string,
- defaultRegionCode?: string
- ) =>
- | { isValidNumber: false; error: unknown }
- | {
- isValidNumber: true;
- regionCode: string | undefined;
- countryCode: string;
- nationalNumber: string;
- e164: string;
- };
- };
parse: (number: string) => string;
getRegionCodeForNumber: (number: string) => string;
format: (number: string, format: PhoneNumberFormat) => string;