From dce8e8cccd7904cc0bd17e6f455dbcd850ddc178 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Tue, 26 Mar 2024 17:59:23 +0700 Subject: [PATCH 1/9] Rename isValidPhone to isValidE164Phone --- lib/str.d.ts | 6 +++--- lib/str.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/str.d.ts b/lib/str.d.ts index fa9a1d0d..5ab0aad9 100644 --- a/lib/str.d.ts +++ b/lib/str.d.ts @@ -476,10 +476,10 @@ declare const Str: { */ boldify(text: string, regexp: RegExp): string; /** - * Check for whether a phone number is valid. + * Check for whether a phone number is valid according to E.164 standard. * @param phone */ - isValidPhone(phone: string): boolean; + isValidE164Phone(phone: string): boolean; /** * We validate mentions by checking if it's first character is an allowed character. * @@ -493,7 +493,7 @@ declare const Str: { */ removeSMSDomain(text: string): string; /** - * Returns true if the text is a valid phone number with our SMS domain removed + * Returns true if the text is a valid E.164 phone number with our SMS domain removed * * @param text */ diff --git a/lib/str.js b/lib/str.js index 813e51eb..b09ef482 100644 --- a/lib/str.js +++ b/lib/str.js @@ -926,12 +926,12 @@ const Str = { }, /** - * Check for whether a phone number is valid. + * Check for whether a phone number is valid according to E.164 standard. * @param {String} phone * * @return {bool} */ - isValidPhone(phone) { + isValidE164Phone(phone) { return CONST.SMS.E164_REGEX.test(phone); }, @@ -965,13 +965,13 @@ const Str = { }, /** - * Returns true if the text is a valid phone number with our SMS domain removed + * Returns true if the text is a valid E.164 phone number with our SMS domain removed * * @param {String} text * @return {String} */ isSMSLogin(text) { - return this.isValidPhone(this.removeSMSDomain(text)); + return this.isValidE164Phone(this.removeSMSDomain(text)); }, /** From d04c9f9688ceb8074a649fb9728ac9fd297b20c4 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Wed, 27 Mar 2024 18:06:34 +0700 Subject: [PATCH 2/9] add isValidPhone function to check phone numbers in general --- lib/CONST.d.ts | 6 +++++- lib/CONST.jsx | 9 ++++++++- lib/ExpensiMark.js | 4 ++-- lib/str.js | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/CONST.d.ts b/lib/CONST.d.ts index 02eb3fe2..ae06fde7 100644 --- a/lib/CONST.d.ts +++ b/lib/CONST.d.ts @@ -251,10 +251,14 @@ export declare const CONST: { * Regex matching an text containing an email */ readonly EMAIL_PART: "([\\w\\-\\+\\'#]+(?:\\.[\\w\\-\\'\\+]+)*@(?:[\\w\\-]+\\.)+[a-z]{2,})"; + /** + * Regex matching a text containing general phone number + */ + readonly GENERAL_PHONE_PART: RegExp, /** * Regex matching a text containing an E.164 format phone number */ - readonly PHONE_PART: "\\+[1-9]\\d{1,14}"; + readonly E164_PHONE_PART: "\\+[1-9]\\d{1,14}"; /** * Regular expression to check that a basic name is valid */ diff --git a/lib/CONST.jsx b/lib/CONST.jsx index abdc31b3..97531154 100644 --- a/lib/CONST.jsx +++ b/lib/CONST.jsx @@ -295,10 +295,17 @@ export const CONST = { */ EMAIL_PART: EMAIL_BASE_REGEX, + /** + * Regex matching a text containing general phone number + * + * @type RegExp + */ + GENERAL_PHONE_PART: /(\+\d{1,2}\s?)?(\(\d{3}\)|\d{3})[\s.-]?\d{3}[\s.-]?\d{4}/, + /** * Regex matching a text containing an E.164 format phone number */ - PHONE_PART: '\\+[1-9]\\d{1,14}', + E164_PHONE_PART: '\\+[1-9]\\d{1,14}', /** * Regular expression to check that a basic name is valid diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index e3822d20..c8b8b982 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -180,12 +180,12 @@ export default class ExpensiMark { */ { name: 'userMentions', - regex: new RegExp(`(@here|[a-zA-Z0-9.!$%&+=?^\`{|}-]?)(@${CONST.REG_EXP.EMAIL_PART}|@${CONST.REG_EXP.PHONE_PART})(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gim'), + regex: new RegExp(`(@here|[a-zA-Z0-9.!$%&+=?^\`{|}-]?)(@${CONST.REG_EXP.EMAIL_PART}|@${CONST.REG_EXP.E164_PHONE_PART})(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gim'), replacement: (match, g1, g2) => { if (!Str.isValidMention(match)) { return match; } - const phoneRegex = new RegExp(`^@${CONST.REG_EXP.PHONE_PART}$`); + const phoneRegex = new RegExp(`^@${CONST.REG_EXP.E164_PHONE_PART}$`); return `${g1}${g2}${phoneRegex.test(g2) ? `@${CONST.SMS.DOMAIN}` : ''}`; }, }, diff --git a/lib/str.js b/lib/str.js index b09ef482..6478e35e 100644 --- a/lib/str.js +++ b/lib/str.js @@ -935,6 +935,21 @@ const Str = { return CONST.SMS.E164_REGEX.test(phone); }, + /** + * Check for whether a phone number is valid in different formats/standards. For example: + * significant: 4404589784 + * international: +1 440-458-9784 + * e164: +14404589784 + * national: (440) 458-978 + * 123.456.7890 + * @param {String} phone + * + * @return {bool} + */ + isValidPhone(phone) { + return CONST.REG_EXP.GENERAL_PHONE_PART.test(phone); + }, + /** * We validate mentions by checking if it's first character is an allowed character. * From aa2c6d204228870feb6e9b402030e3e97ece3714 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Wed, 27 Mar 2024 18:12:24 +0700 Subject: [PATCH 3/9] add type def --- lib/str.d.ts | 9 +++++++++ lib/str.js | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/str.d.ts b/lib/str.d.ts index 5ab0aad9..54eb0e32 100644 --- a/lib/str.d.ts +++ b/lib/str.d.ts @@ -475,6 +475,15 @@ declare const Str: { * @param regexp */ boldify(text: string, regexp: RegExp): string; + /** + * Check for whether a phone number is valid in different formats/standards. For example: + * significant: 4404589784 + * international: +1 440-458-9784 + * e164: +14404589784 + * national: (440) 458-978 + * 123.456.7890 + */ + isValidPhone(phone: string): boolean; /** * Check for whether a phone number is valid according to E.164 standard. * @param phone diff --git a/lib/str.js b/lib/str.js index 6478e35e..c295e04c 100644 --- a/lib/str.js +++ b/lib/str.js @@ -925,16 +925,6 @@ const Str = { return text.replace(regexp, '$1'); }, - /** - * Check for whether a phone number is valid according to E.164 standard. - * @param {String} phone - * - * @return {bool} - */ - isValidE164Phone(phone) { - return CONST.SMS.E164_REGEX.test(phone); - }, - /** * Check for whether a phone number is valid in different formats/standards. For example: * significant: 4404589784 @@ -950,6 +940,16 @@ const Str = { return CONST.REG_EXP.GENERAL_PHONE_PART.test(phone); }, + /** + * Check for whether a phone number is valid according to E.164 standard. + * @param {String} phone + * + * @return {bool} + */ + isValidE164Phone(phone) { + return CONST.SMS.E164_REGEX.test(phone); + }, + /** * We validate mentions by checking if it's first character is an allowed character. * From df180d062d23f2dc6563bbea5b72271befe89c30 Mon Sep 17 00:00:00 2001 From: Tienifr <113963320+tienifr@users.noreply.github.com> Date: Fri, 29 Mar 2024 02:20:38 +0700 Subject: [PATCH 4/9] Fix typo Co-authored-by: Pujan Shah --- lib/str.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/str.d.ts b/lib/str.d.ts index 54eb0e32..9879bf6d 100644 --- a/lib/str.d.ts +++ b/lib/str.d.ts @@ -480,7 +480,7 @@ declare const Str: { * significant: 4404589784 * international: +1 440-458-9784 * e164: +14404589784 - * national: (440) 458-978 + * national: (440) 458-9784 * 123.456.7890 */ isValidPhone(phone: string): boolean; From dca25d75f269861209a10ed03fbabfcd8b6bea1b Mon Sep 17 00:00:00 2001 From: Tienifr Date: Fri, 29 Mar 2024 02:25:43 +0700 Subject: [PATCH 5/9] fix lint --- lib/CONST.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/CONST.jsx b/lib/CONST.jsx index 97531154..8c1fe042 100644 --- a/lib/CONST.jsx +++ b/lib/CONST.jsx @@ -40,11 +40,11 @@ export const CONST = { /** * Display this amount to users to encourage them to book a call - * + * * @type Number */ MAX_TRIAL_BONUS_DAYS: 42, - + COUNTRY: { US: 'US', AU: 'AU', @@ -297,7 +297,7 @@ export const CONST = { /** * Regex matching a text containing general phone number - * + * * @type RegExp */ GENERAL_PHONE_PART: /(\+\d{1,2}\s?)?(\(\d{3}\)|\d{3})[\s.-]?\d{3}[\s.-]?\d{4}/, @@ -364,6 +364,7 @@ export const CONST = { * @type RegExp */ EMOJIS: /[\p{Extended_Pictographic}\u200d\u{1f1e6}-\u{1f1ff}\u{1f3fb}-\u{1f3ff}\u{e0020}-\u{e007f}\u20E3\uFE0F]|[#*0-9]\uFE0F?\u20E3/gu, + /** * Regex matching an text containing an Emoji that can be a single emoji or made up by some different emojis * @@ -544,7 +545,7 @@ export const CONST = { 'notifications@expensify.com', ], - /** + /** * Emails that the user shouldn't submit reports to nor share reports with * Any changes here should be reflected in the PHP constant, * which is located in _constant.php and also named INVALID_APPROVER_AND_SHAREE_EMAILS From 9481629e03eea4f1abac1717c3d275f251011019 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Fri, 29 Mar 2024 17:17:30 +0700 Subject: [PATCH 6/9] add unit test --- __tests__/Str-test.js | 21 +++++++++++++++++++++ lib/str.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/__tests__/Str-test.js b/__tests__/Str-test.js index 23d9eec0..f9ac9661 100644 --- a/__tests__/Str-test.js +++ b/__tests__/Str-test.js @@ -189,3 +189,24 @@ describe('Str.isValidEmail', () => { expect(Str.isValidEmail('a@a.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl')).toBeFalsy(); }); }); + + +describe('Str.isValidPhone', () => { + it('Correctly identifies valid phone numbers', () => { + // Significant part of phone + expect(Str.isValidPhone('4404589784')).toBeTruthy(); + // International standard + expect(Str.isValidPhone('+1 440-458-9784')).toBeTruthy(); + // E.164 standard + expect(Str.isValidPhone('+14404589784')).toBeTruthy(); + // US national standard + expect(Str.isValidPhone('(440) 458-9784')).toBeTruthy(); + expect(Str.isValidPhone('123.456.7890')).toBeTruthy(); + }); +}); + +describe('Str.isValidE164Phone', () => { + it('Correctly identifies valid E.164 phone numbers', () => { + expect(Str.isValidE164Phone('+14404589784')).toBeTruthy(); + }); +}); \ No newline at end of file diff --git a/lib/str.js b/lib/str.js index c295e04c..94363382 100644 --- a/lib/str.js +++ b/lib/str.js @@ -930,7 +930,7 @@ const Str = { * significant: 4404589784 * international: +1 440-458-9784 * e164: +14404589784 - * national: (440) 458-978 + * national: (440) 458-9784 * 123.456.7890 * @param {String} phone * From 5cab0086af275715fe359a69b2a0d0ff37de25db Mon Sep 17 00:00:00 2001 From: Tienifr Date: Fri, 29 Mar 2024 17:17:47 +0700 Subject: [PATCH 7/9] remove redudant changes --- __tests__/Str-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/__tests__/Str-test.js b/__tests__/Str-test.js index f9ac9661..7457c17e 100644 --- a/__tests__/Str-test.js +++ b/__tests__/Str-test.js @@ -190,7 +190,6 @@ describe('Str.isValidEmail', () => { }); }); - describe('Str.isValidPhone', () => { it('Correctly identifies valid phone numbers', () => { // Significant part of phone From bf623a3edf28fbb788c7dcc61a1bebb046012678 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Mon, 1 Apr 2024 16:39:02 +0700 Subject: [PATCH 8/9] Deprecate isValidPhone function --- __tests__/Str-test.js | 21 ++++++++++++--------- lib/CONST.d.ts | 2 +- lib/CONST.jsx | 2 +- lib/ExpensiMark.js | 4 ++-- lib/str.d.ts | 17 ++++++++++++----- lib/str.js | 25 ++++++++++++++++++------- 6 files changed, 46 insertions(+), 25 deletions(-) diff --git a/__tests__/Str-test.js b/__tests__/Str-test.js index 7457c17e..6ccd9944 100644 --- a/__tests__/Str-test.js +++ b/__tests__/Str-test.js @@ -1,6 +1,6 @@ import Str from '../lib/str'; -const buildTestURLForType = (type) => `https://chat.expensify.com/chat-attachments/5/w_eadf5d35cfce6a98e2dd3607cf8463b1e46219e4.${type}?authToken=12345`; +const buildTestURLForType = type => `https://chat.expensify.com/chat-attachments/5/w_eadf5d35cfce6a98e2dd3607cf8463b1e46219e4.${type}?authToken=12345`; describe('Str.isImage', () => { it('Correctly identifies all valid image types', () => { @@ -114,7 +114,7 @@ describe('Str.isValidEmail', () => { expect(Str.isValidEmail('test@gmail')).toBeFalsy(); expect(Str.isValidEmail('@gmail.com')).toBeFalsy(); expect(Str.isValidEmail('usernamelongerthan64charactersshouldnotworkaccordingtorfc822whichisusedbyphp@gmail.com')).toBeFalsy(); - + // Domain length (63 chars in each label) expect(Str.isValidEmail('test@asjjssjdjdjdjdjdjjeiwiwiwowkdjdjdieikdjfidekjcjdkekejdcjdkeekcj.com')).toBeTruthy(); expect(Str.isValidEmail('abc@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.km')).toBeTruthy(); @@ -190,17 +190,20 @@ describe('Str.isValidEmail', () => { }); }); -describe('Str.isValidPhone', () => { +describe('Str.isValidPhoneFormat', () => { it('Correctly identifies valid phone numbers', () => { // Significant part of phone - expect(Str.isValidPhone('4404589784')).toBeTruthy(); + expect(Str.isValidPhoneFormat('4404589784')).toBeTruthy(); + // International standard - expect(Str.isValidPhone('+1 440-458-9784')).toBeTruthy(); + expect(Str.isValidPhoneFormat('+1 440-458-9784')).toBeTruthy(); + // E.164 standard - expect(Str.isValidPhone('+14404589784')).toBeTruthy(); + expect(Str.isValidPhoneFormat('+14404589784')).toBeTruthy(); + // US national standard - expect(Str.isValidPhone('(440) 458-9784')).toBeTruthy(); - expect(Str.isValidPhone('123.456.7890')).toBeTruthy(); + expect(Str.isValidPhoneFormat('(440) 458-9784')).toBeTruthy(); + expect(Str.isValidPhoneFormat('123.456.7890')).toBeTruthy(); }); }); @@ -208,4 +211,4 @@ describe('Str.isValidE164Phone', () => { it('Correctly identifies valid E.164 phone numbers', () => { expect(Str.isValidE164Phone('+14404589784')).toBeTruthy(); }); -}); \ No newline at end of file +}); diff --git a/lib/CONST.d.ts b/lib/CONST.d.ts index ae06fde7..6ca55dae 100644 --- a/lib/CONST.d.ts +++ b/lib/CONST.d.ts @@ -258,7 +258,7 @@ export declare const CONST: { /** * Regex matching a text containing an E.164 format phone number */ - readonly E164_PHONE_PART: "\\+[1-9]\\d{1,14}"; + readonly PHONE_PART: "\\+[1-9]\\d{1,14}"; /** * Regular expression to check that a basic name is valid */ diff --git a/lib/CONST.jsx b/lib/CONST.jsx index 8c1fe042..9897f271 100644 --- a/lib/CONST.jsx +++ b/lib/CONST.jsx @@ -305,7 +305,7 @@ export const CONST = { /** * Regex matching a text containing an E.164 format phone number */ - E164_PHONE_PART: '\\+[1-9]\\d{1,14}', + PHONE_PART: '\\+[1-9]\\d{1,14}', /** * Regular expression to check that a basic name is valid diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 04bb722a..03324013 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -180,12 +180,12 @@ export default class ExpensiMark { */ { name: 'userMentions', - regex: new RegExp(`(@here|[a-zA-Z0-9.!$%&+=?^\`{|}-]?)(@${CONST.REG_EXP.EMAIL_PART}|@${CONST.REG_EXP.E164_PHONE_PART})(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gim'), + regex: new RegExp(`(@here|[a-zA-Z0-9.!$%&+=?^\`{|}-]?)(@${CONST.REG_EXP.EMAIL_PART}|@${CONST.REG_EXP.PHONE_PART})(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gim'), replacement: (match, g1, g2) => { if (!Str.isValidMention(match)) { return match; } - const phoneRegex = new RegExp(`^@${CONST.REG_EXP.E164_PHONE_PART}$`); + const phoneRegex = new RegExp(`^@${CONST.REG_EXP.PHONE_PART}$`); return `${g1}${g2}${phoneRegex.test(g2) ? `@${CONST.SMS.DOMAIN}` : ''}`; }, }, diff --git a/lib/str.d.ts b/lib/str.d.ts index 9879bf6d..43fc2e68 100644 --- a/lib/str.d.ts +++ b/lib/str.d.ts @@ -475,6 +475,17 @@ declare const Str: { * @param regexp */ boldify(text: string, regexp: RegExp): string; + /** + * Check for whether a phone number is valid. + * @param phone + * @deprecated use isValidE164Phone instead + */ + isValidPhone(phone: string): boolean; + /** + * Check for whether a phone number is valid according to E.164 standard. + * @param phone + */ + isValidE164Phone(phone: string): boolean; /** * Check for whether a phone number is valid in different formats/standards. For example: * significant: 4404589784 @@ -482,13 +493,9 @@ declare const Str: { * e164: +14404589784 * national: (440) 458-9784 * 123.456.7890 - */ - isValidPhone(phone: string): boolean; - /** - * Check for whether a phone number is valid according to E.164 standard. * @param phone */ - isValidE164Phone(phone: string): boolean; + isValidPhoneFormat(phone: string): boolean; /** * We validate mentions by checking if it's first character is an allowed character. * diff --git a/lib/str.js b/lib/str.js index 94363382..c6be2717 100644 --- a/lib/str.js +++ b/lib/str.js @@ -926,18 +926,14 @@ const Str = { }, /** - * Check for whether a phone number is valid in different formats/standards. For example: - * significant: 4404589784 - * international: +1 440-458-9784 - * e164: +14404589784 - * national: (440) 458-9784 - * 123.456.7890 + * Check for whether a phone number is valid. * @param {String} phone * * @return {bool} + * @deprecated use isValidE164Phone instead */ isValidPhone(phone) { - return CONST.REG_EXP.GENERAL_PHONE_PART.test(phone); + return CONST.SMS.E164_REGEX.test(phone); }, /** @@ -950,6 +946,21 @@ const Str = { return CONST.SMS.E164_REGEX.test(phone); }, + /** + * Check for whether a phone number is valid in different formats/standards. For example: + * significant: 4404589784 + * international: +1 440-458-9784 + * e164: +14404589784 + * national: (440) 458-9784 + * 123.456.7890 + * @param {String} phone + * + * @return {bool} + */ + isValidPhoneFormat(phone) { + return CONST.REG_EXP.GENERAL_PHONE_PART.test(phone); + }, + /** * We validate mentions by checking if it's first character is an allowed character. * From 2c2d3afae1465eca4642d5134be7a3ec29b67532 Mon Sep 17 00:00:00 2001 From: Tienifr Date: Mon, 1 Apr 2024 16:43:08 +0700 Subject: [PATCH 9/9] Update deprecated doc --- lib/str.d.ts | 2 +- lib/str.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/str.d.ts b/lib/str.d.ts index 43fc2e68..cf03dc66 100644 --- a/lib/str.d.ts +++ b/lib/str.d.ts @@ -478,7 +478,7 @@ declare const Str: { /** * Check for whether a phone number is valid. * @param phone - * @deprecated use isValidE164Phone instead + * @deprecated use isValidE164Phone to validate E.164 phone numbers or isValidPhoneFormat to validate phone numbers in general */ isValidPhone(phone: string): boolean; /** diff --git a/lib/str.js b/lib/str.js index c6be2717..73f11b0a 100644 --- a/lib/str.js +++ b/lib/str.js @@ -930,7 +930,7 @@ const Str = { * @param {String} phone * * @return {bool} - * @deprecated use isValidE164Phone instead + * @deprecated use isValidE164Phone to validate E.164 phone numbers or isValidPhoneFormat to validate phone numbers in general */ isValidPhone(phone) { return CONST.SMS.E164_REGEX.test(phone);