1/*! 2 * Authyo - Phone Validation Module (libphonenumber wrapper) 3 * Only loaded when "Advanced Phone Validation" setting is enabled. 4 */ 5(function () { 6 'use strict'; 7 8 if (typeof libphonenumber === 'undefined' || !libphonenumber.PhoneNumberUtil) { 9 console.warn('Authyo: libphonenumber not loaded. Advanced phone validation disabled.'); 10 return; 11 } 12 13 var phoneUtil = libphonenumber.PhoneNumberUtil.getInstance(); 14 var PhoneNumberType = libphonenumber.PhoneNumberType; 15 var PhoneNumberFormat = libphonenumber.PhoneNumberFormat; 16 17 window.AuthyoPhoneValidation = { 18 19 /** 20 * Validate a phone number for a given country. 21 * 22 * @param {string} number - The phone number input (local or international) 23 * @param {string} countryISO - The 2-letter ISO country code (e.g., "IN", "US") 24 * @returns {object} { valid, type, warning, error, e164 } 25 */ 26 validate: function (number, countryISO) { 27 var result = { 28 valid: false, 29 type: null, 30 warning: null, 31 error: null, 32 e164: null 33 }; 34 35 if (!number || !number.trim()) { 36 return result; 37 } 38 39 var cleaned = number.trim(); 40 var parsed; 41 42 // Step 1: Parse 43 try { 44 parsed = phoneUtil.parseAndKeepRawInput(cleaned, countryISO || ''); 45 } catch (e) { 46 result.error = 'Invalid phone number format.'; 47 return result; 48 } 49 50 // Step 2: Validate for region 51 if (countryISO) { 52 var validForRegion = phoneUtil.isValidNumberForRegion(parsed, countryISO); 53 if (!validForRegion) { 54 var validGeneral = phoneUtil.isValidNumber(parsed); 55 if (validGeneral) { 56 result.error = 'This number does not match the selected country.'; 57 } else { 58 result.error = 'Invalid number for the selected country.'; 59 } 60 return result; 61 } 62 } else { 63 if (!phoneUtil.isValidNumber(parsed)) { 64 result.error = 'Invalid phone number.'; 65 return result; 66 } 67 } 68 69 // Step 3: Check number type 70 var numType = phoneUtil.getNumberType(parsed); 71 var typeNames = {}; 72 typeNames[PhoneNumberType.FIXED_LINE] = 'fixed_line'; 73 typeNames[PhoneNumberType.MOBILE] = 'mobile'; 74 typeNames[PhoneNumberType.FIXED_LINE_OR_MOBILE] = 'fixed_line_or_mobile'; 75 typeNames[PhoneNumberType.TOLL_FREE] = 'toll_free'; 76 typeNames[PhoneNumberType.PREMIUM_RATE] = 'premium_rate'; 77 typeNames[PhoneNumberType.SHARED_COST] = 'shared_cost'; 78 typeNames[PhoneNumberType.VOIP] = 'voip'; 79 typeNames[PhoneNumberType.PERSONAL_NUMBER] = 'personal'; 80 typeNames[PhoneNumberType.PAGER] = 'pager'; 81 typeNames[PhoneNumberType.UAN] = 'uan'; 82 typeNames[PhoneNumberType.UNKNOWN] = 'unknown'; 83 84 result.type = typeNames[numType] || 'unknown'; 85 86 // Warn for landlines (don't block) 87 if (numType === PhoneNumberType.FIXED_LINE) { 88 result.warning = 'This appears to be a landline number. OTP delivery may not work.'; 89 } else if (numType === PhoneNumberType.PAGER) { 90 result.warning = 'This appears to be a pager number. OTP delivery may not work.'; 91 } else if (numType === PhoneNumberType.PREMIUM_RATE) { 92 result.warning = 'This appears to be a premium rate number.'; 93 } 94 95 // Step 4: Format to E.164 96 result.e164 = phoneUtil.format(parsed, PhoneNumberFormat.E164); 97 result.valid = true; 98 99 return result; 100 }, 101 102 /** 103 * Get expected mobile number length for a given dial code. 104 * 105 * @param {string} countryCode - Dial code e.g., "+91" or "91" 106 * @returns {number} Expected digit count, or 0 if unknown 107 */ 108 getMobileNumberLength: function (countryCode) { 109 try { 110 var parsedCode = String(countryCode).replace('+', ''); 111 var regionCode = phoneUtil.getRegionCodeForCountryCode(parseInt(parsedCode, 10)); 112 if (!regionCode) return 0; 113 var exampleNumber = phoneUtil.getExampleNumberForType(regionCode, PhoneNumberType.MOBILE); 114 if (!exampleNumber) return 0; 115 return exampleNumber.getNationalNumber().toString().length; 116 } catch (e) { 117 return 0; 118 } 119 }, 120 121 /** 122 * Get expected mobile number length using ISO country code. 123 * 124 * @param {string} countryISO - 2-letter ISO code (e.g., "IN", "US") 125 * @returns {number} Expected digit count, or 0 if unknown 126 */ 127 getMobileNumberLengthByISO: function (countryISO) { 128 try { 129 if (!countryISO) return 0; 130 var exampleNumber = phoneUtil.getExampleNumberForType( 131 countryISO.toUpperCase(), PhoneNumberType.MOBILE 132 ); 133 if (!exampleNumber) return 0; 134 return exampleNumber.getNationalNumber().toString().length; 135 } catch (e) { 136 return 0; 137 } 138 }, 139 140 /** 141 * Quick check if libphonenumber is available 142 */ 143 isAvailable: function () { 144 return true; 145 } 146 }; 147})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.