diff --git a/background.js b/background.js index e4d51e5..9a307ae 100644 --- a/background.js +++ b/background.js @@ -993,7 +993,7 @@ function normalizeHeroSmsCountryFallback(value = []) { } } - if (!Number.isFinite(countryId) || countryId <= 0 || !HERO_SMS_SUPPORTED_COUNTRY_ID_SET.has(String(countryId)) || seenIds.has(countryId)) { + if (!Number.isFinite(countryId) || countryId <= 0 || seenIds.has(countryId)) { continue; } seenIds.add(countryId); @@ -1128,7 +1128,7 @@ function normalizeFiveSimCountryId(value, fallback = FIVE_SIM_COUNTRY_ID) { ? rootScope.PhoneSmsFiveSimProvider.normalizeFiveSimCountryId(value, '') : String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); const normalized = String(rawNormalized || '').trim().toLowerCase(); - if (FIVE_SIM_SUPPORTED_COUNTRY_ID_SET.has(normalized)) { + if (normalized) { return normalized; } const fallbackSource = fallback === undefined || fallback === null ? FIVE_SIM_COUNTRY_ID : fallback; @@ -1136,7 +1136,7 @@ function normalizeFiveSimCountryId(value, fallback = FIVE_SIM_COUNTRY_ID) { if (!normalizedFallback) { return ''; } - return FIVE_SIM_SUPPORTED_COUNTRY_ID_SET.has(normalizedFallback) ? normalizedFallback : FIVE_SIM_COUNTRY_ID; + return normalizedFallback || FIVE_SIM_COUNTRY_ID; } function normalizeFiveSimCountryCode(value = '', fallback = 'thailand') { @@ -2225,7 +2225,7 @@ function normalizePersistentSettingValue(key, value) { return normalizeHeroSmsMaxPrice(value); case 'heroSmsCountryId': { const parsed = Math.floor(Number(value)); - if (Number.isFinite(parsed) && HERO_SMS_SUPPORTED_COUNTRY_ID_SET.has(String(parsed))) { + if (Number.isFinite(parsed) && parsed > 0) { return parsed; } return HERO_SMS_COUNTRY_ID; diff --git a/phone-sms/providers/five-sim.js b/phone-sms/providers/five-sim.js index 77a57c6..b034e3f 100644 --- a/phone-sms/providers/five-sim.js +++ b/phone-sms/providers/five-sim.js @@ -15,6 +15,10 @@ const SUPPORTED_COUNTRY_ITEMS = Object.freeze([ { id: 'indonesia', label: '印度尼西亚 (Indonesia)' }, { id: 'thailand', label: '泰国 (Thailand)' }, + { id: 'england', label: '英国 (England)' }, + { id: 'usa', label: '美国 (United States)' }, + { id: 'japan', label: '日本 (Japan)' }, + { id: 'germany', label: '德国 (Germany)' }, { id: 'vietnam', label: '越南 (Vietnam)' }, ]); const SUPPORTED_COUNTRY_ID_SET = new Set(SUPPORTED_COUNTRY_ITEMS.map((item) => item.id)); @@ -115,7 +119,7 @@ function normalizeFiveSimCountryId(value, fallback = DEFAULT_COUNTRY_ID) { const normalized = String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); - if (SUPPORTED_COUNTRY_ID_SET.has(normalized)) { + if (normalized) { return normalized; } const fallbackSource = fallback === undefined || fallback === null ? DEFAULT_COUNTRY_ID : fallback; @@ -123,7 +127,7 @@ if (!normalizedFallback) { return ''; } - return SUPPORTED_COUNTRY_ID_SET.has(normalizedFallback) ? normalizedFallback : DEFAULT_COUNTRY_ID; + return normalizedFallback || DEFAULT_COUNTRY_ID; } function getCountryIdFromPayload(record = {}, fallback = DEFAULT_COUNTRY_ID) { @@ -414,12 +418,8 @@ ].filter(Boolean).join(' '), }; }) - .filter((entry) => entry && SUPPORTED_COUNTRY_ID_SET.has(String(entry.id))) - .sort((left, right) => { - const leftIndex = SUPPORTED_COUNTRY_ITEMS.findIndex((item) => item.id === String(left.id)); - const rightIndex = SUPPORTED_COUNTRY_ITEMS.findIndex((item) => item.id === String(right.id)); - return leftIndex - rightIndex; - }); + .filter(Boolean) + .sort((left, right) => String(left.label || '').localeCompare(String(right.label || ''))); } function collectPriceEntries(payload, entries = []) { diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 1426bbe..7f8235a 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -516,6 +516,11 @@ const DEFAULT_HERO_SMS_ACQUIRE_PRIORITY = HERO_SMS_ACQUIRE_PRIORITY_COUNTRY; const HERO_SMS_SUPPORTED_COUNTRY_ITEMS = Object.freeze([ { id: 6, chn: '印度尼西亚', eng: 'Indonesia' }, { id: 52, chn: '泰国', eng: 'Thailand' }, + { id: 187, chn: '美国(物理)', eng: 'USA' }, + { id: 16, chn: '英国', eng: 'United Kingdom' }, + { id: 151, chn: '日本', eng: 'Japan' }, + { id: 43, chn: '德国', eng: 'Germany' }, + { id: 73, chn: '法国', eng: 'France' }, { id: 10, chn: '越南', eng: 'Vietnam' }, ]); const HERO_SMS_SUPPORTED_COUNTRY_ID_SET = new Set(HERO_SMS_SUPPORTED_COUNTRY_ITEMS.map((item) => String(item.id))); @@ -759,11 +764,17 @@ const DEFAULT_FIVE_SIM_COUNTRY_LABEL = '越南 (Vietnam)'; const FIVE_SIM_SUPPORTED_COUNTRY_ITEMS = Object.freeze([ { id: 'indonesia', chn: '印度尼西亚', eng: 'Indonesia', searchText: 'indonesia 印度尼西亚 印尼 Indonesia ID +62' }, { id: 'thailand', chn: '泰国', eng: 'Thailand', searchText: 'thailand 泰国 Thailand TH +66' }, + { id: 'england', chn: '英国', eng: 'England', searchText: 'england 英国 England UK GB United Kingdom +44' }, + { id: 'usa', chn: '美国', eng: 'United States', searchText: 'usa 美国 United States US +1' }, + { id: 'japan', chn: '日本', eng: 'Japan', searchText: 'japan 日本 Japan JP +81' }, + { id: 'germany', chn: '德国', eng: 'Germany', searchText: 'germany 德国 Germany DE +49' }, { id: 'vietnam', chn: '越南', eng: 'Vietnam', searchText: 'vietnam 越南 Vietnam VN +84' }, ]); const FIVE_SIM_SUPPORTED_COUNTRY_ID_SET = new Set(FIVE_SIM_SUPPORTED_COUNTRY_ITEMS.map((item) => item.id)); const NEX_SMS_FALLBACK_COUNTRY_ITEMS = Object.freeze([ - { id: 1, label: 'Country #1', searchText: 'Country #1 1' }, + { id: 1, label: 'Ukraine (#1)', searchText: 'Ukraine 1 UA' }, + { id: 6, label: 'Indonesia (#6)', searchText: 'Indonesia 6 ID' }, + { id: 7, label: 'Malaysia (#7)', searchText: 'Malaysia 7 MY' }, ]); const DEFAULT_IP_PROXY_SERVICE = '711proxy'; const SUPPORTED_IP_PROXY_SERVICES = ['711proxy', 'lumiproxy', 'iproyal', 'omegaproxy']; @@ -3280,22 +3291,19 @@ function normalizePhoneSmsMaxPriceValue(value = '', provider = getSelectedPhoneS } function normalizeFiveSimCountryId(value, fallback = DEFAULT_FIVE_SIM_COUNTRY_ID) { - const supportedCountryIds = typeof FIVE_SIM_SUPPORTED_COUNTRY_ID_SET !== 'undefined' - ? FIVE_SIM_SUPPORTED_COUNTRY_ID_SET - : new Set(['indonesia', 'thailand', 'vietnam']); const fallbackSource = fallback === undefined || fallback === null ? DEFAULT_FIVE_SIM_COUNTRY_ID : fallback; const normalizedFallback = String(fallbackSource).trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); const rawNormalized = typeof window !== 'undefined' && window.PhoneSmsFiveSimProvider?.normalizeFiveSimCountryId ? window.PhoneSmsFiveSimProvider.normalizeFiveSimCountryId(value, '') : String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); const normalized = String(rawNormalized || '').trim().toLowerCase(); - if (supportedCountryIds.has(normalized)) { + if (normalized) { return normalized; } if (!normalizedFallback) { return ''; } - return supportedCountryIds.has(normalizedFallback) ? normalizedFallback : DEFAULT_FIVE_SIM_COUNTRY_ID; + return normalizedFallback || DEFAULT_FIVE_SIM_COUNTRY_ID; } function normalizeFiveSimCountryLabel(value = '', fallback = DEFAULT_FIVE_SIM_COUNTRY_LABEL) { @@ -3384,15 +3392,12 @@ function normalizeFiveSimCountryFallbackList(value = []) { } function normalizeHeroSmsCountryId(value, fallback = DEFAULT_HERO_SMS_COUNTRY_ID) { - const supportedCountryIds = typeof HERO_SMS_SUPPORTED_COUNTRY_ID_SET !== 'undefined' - ? HERO_SMS_SUPPORTED_COUNTRY_ID_SET - : new Set(['6', '52', '10']); const parsed = Math.floor(Number(value)); - if (Number.isFinite(parsed) && supportedCountryIds.has(String(parsed))) { + if (Number.isFinite(parsed) && parsed > 0) { return parsed; } const fallbackParsed = Math.floor(Number(fallback)); - return supportedCountryIds.has(String(fallbackParsed)) ? fallbackParsed : DEFAULT_HERO_SMS_COUNTRY_ID; + return Number.isFinite(fallbackParsed) && fallbackParsed > 0 ? fallbackParsed : DEFAULT_HERO_SMS_COUNTRY_ID; } function normalizeHeroSmsCountryLabel(value = '') { @@ -4011,10 +4016,7 @@ function normalizeHeroSmsCountryFallbackList(value = []) { } } - const supportedCountryIds = typeof HERO_SMS_SUPPORTED_COUNTRY_ID_SET !== 'undefined' - ? HERO_SMS_SUPPORTED_COUNTRY_ID_SET - : new Set(['6', '52', '10']); - if (!id || !supportedCountryIds.has(String(id)) || seen.has(id)) { + if (!id || seen.has(id)) { return; } seen.add(id); @@ -5221,12 +5223,8 @@ async function loadHeroSmsCountries() { ].filter(Boolean).join(' '), }; }) - .filter((entry) => entry.id && FIVE_SIM_SUPPORTED_COUNTRY_ID_SET.has(String(entry.id))) - .sort((left, right) => { - const leftIndex = FIVE_SIM_SUPPORTED_COUNTRY_ITEMS.findIndex((item) => item.id === String(left.id)); - const rightIndex = FIVE_SIM_SUPPORTED_COUNTRY_ITEMS.findIndex((item) => item.id === String(right.id)); - return leftIndex - rightIndex; - }); + .filter((entry) => entry.id) + .sort((left, right) => String(left.label || '').localeCompare(String(right.label || ''))); if (!optionItems.length) { throw new Error('empty country list'); } @@ -5263,12 +5261,8 @@ async function loadHeroSmsCountries() { throw new Error('empty country list'); } const optionItems = countries - .filter((item) => HERO_SMS_SUPPORTED_COUNTRY_ID_SET.has(String(Math.floor(Number(item?.id)))) && (String(item?.eng || '').trim() || String(item?.chn || '').trim())) - .sort((left, right) => { - const leftIndex = HERO_SMS_SUPPORTED_COUNTRY_ITEMS.findIndex((item) => String(item.id) === String(Math.floor(Number(left?.id)))); - const rightIndex = HERO_SMS_SUPPORTED_COUNTRY_ITEMS.findIndex((item) => String(item.id) === String(Math.floor(Number(right?.id)))); - return leftIndex - rightIndex; - }) + .filter((item) => Number(item?.id) > 0 && (String(item?.eng || '').trim() || String(item?.chn || '').trim())) + .sort((left, right) => String(left.eng || '').localeCompare(String(right.eng || ''))) .map((item) => { const id = normalizeHeroSmsCountryId(item.id); const label = buildHeroSmsCountryDisplayLabel(item); @@ -5657,8 +5651,7 @@ async function loadFiveSimCountries() { throw new Error(`HTTP ${response.status}`); } const payload = await response.json(); - const items = parseFiveSimCountriesPayload(payload) - .filter((entry) => FIVE_SIM_SUPPORTED_COUNTRY_ID_SET.has(entry.code || entry.id)); + const items = parseFiveSimCountriesPayload(payload); applyOptions(items.length ? items : fallbackItems); } catch (error) { console.warn('Failed to load 5sim countries:', error); diff --git a/tests/background-account-history-settings.test.js b/tests/background-account-history-settings.test.js index 841571a..ec11026 100644 --- a/tests/background-account-history-settings.test.js +++ b/tests/background-account-history-settings.test.js @@ -176,7 +176,7 @@ return { assert.deepStrictEqual(api.normalizePersistentSettingValue('phoneSmsProviderOrder', ['nexsms', '5sim', 'nexsms']), ['nexsms', '5sim']); assert.equal(api.normalizePersistentSettingValue('fiveSimApiKey', ' demo-five '), ' demo-five '); assert.equal(api.normalizePersistentSettingValue('fiveSimProduct', ' OpenAI! '), 'openai'); - assert.equal(api.normalizePersistentSettingValue('fiveSimCountryId', ' England! '), 'vietnam'); + assert.equal(api.normalizePersistentSettingValue('fiveSimCountryId', ' England! '), 'england'); assert.equal(api.normalizePersistentSettingValue('fiveSimCountryId', ''), 'vietnam'); assert.equal(api.normalizePersistentSettingValue('fiveSimCountryLabel', ''), '越南 (Vietnam)'); assert.equal(api.normalizePersistentSettingValue('fiveSimMaxPrice', '9.87654'), '9.8765'); @@ -184,11 +184,11 @@ return { assert.equal(api.normalizePersistentSettingValue('fiveSimOperator', ''), 'any'); assert.deepStrictEqual( api.normalizePersistentSettingValue('fiveSimCountryFallback', [{ id: 'usa', label: 'USA' }, 'thailand:Thailand']), - [{ id: 'thailand', label: 'Thailand' }] + [{ id: 'usa', label: 'USA' }, { id: 'thailand', label: 'Thailand' }] ); assert.deepStrictEqual( api.normalizePersistentSettingValue('heroSmsCountryFallback', [{ id: 16, label: 'United Kingdom' }, { id: 52 }]), - [{ id: 52, label: 'Country #52' }] + [{ id: 16, label: 'United Kingdom' }, { id: 52, label: 'Country #52' }] ); assert.equal( api.normalizePersistentSettingValue('accountRunHistoryHelperBaseUrl', 'http://127.0.0.1:17373/append-account-log'), diff --git a/tests/five-sim-provider.test.js b/tests/five-sim-provider.test.js index 9f8118c..4ee374f 100644 --- a/tests/five-sim-provider.test.js +++ b/tests/five-sim-provider.test.js @@ -55,12 +55,17 @@ test('5sim provider maps countries and prices', async () => { const prices = await provider.fetchPrices({}, { id: 'vietnam', label: 'Vietnam' }); const entries = provider.collectPriceEntries(prices, []); - assert.deepStrictEqual(countries.map((country) => country.id), ['indonesia', 'thailand', 'vietnam']); - assert.deepStrictEqual(countries[2], { - id: 'vietnam', - label: '越南 (Vietnam)', - searchText: 'vietnam 越南 (Vietnam) Vietnam VN +84', - }); + assert.equal(countries.length, 4); + assert.equal(countries.some((country) => country.id === 'england'), true); + assert.equal(countries.some((country) => country.id === 'indonesia'), true); + assert.deepStrictEqual( + countries.find((country) => country.id === 'vietnam'), + { + id: 'vietnam', + label: '越南 (Vietnam)', + searchText: 'vietnam 越南 (Vietnam) Vietnam VN +84', + } + ); assert.equal(requests[1].url.searchParams.get('country'), 'vietnam'); assert.equal(requests[1].url.searchParams.get('product'), 'openai'); assert.deepStrictEqual(entries, [{ cost: 10, count: 2, inStock: true }]); @@ -283,4 +288,3 @@ test('5sim provider reports purchase rate limit separately from no-number countr ] ); }); - diff --git a/tests/sidepanel-phone-verification-settings.test.js b/tests/sidepanel-phone-verification-settings.test.js index c24f1e3..1528cb4 100644 --- a/tests/sidepanel-phone-verification-settings.test.js +++ b/tests/sidepanel-phone-verification-settings.test.js @@ -144,6 +144,21 @@ return { btnHeroSmsCountryMenu, updateHeroSmsCountryMenuSummary }; assert.equal(api.btnHeroSmsCountryMenu.textContent, '\u672a\u9009\u62e9 (0/3)'); }); +test('live phone country sources are not hard-filtered down to the reduced country whitelist', () => { + assert.doesNotMatch( + sidepanelSource, + /\.filter\(\(entry\) => entry\.id && FIVE_SIM_SUPPORTED_COUNTRY_ID_SET\.has\(String\(entry\.id\)\)\)/ + ); + assert.doesNotMatch( + sidepanelSource, + /\.filter\(\(item\) => HERO_SMS_SUPPORTED_COUNTRY_ID_SET\.has\(String\(Math\.floor\(Number\(item\?\.id\)\)\)\)/ + ); + assert.doesNotMatch( + sidepanelSource, + /\.filter\(\(entry\) => FIVE_SIM_SUPPORTED_COUNTRY_ID_SET\.has\(entry\.code \|\| entry\.id\)\)/ + ); +}); + test('removeHeroSmsCountryFromOrder clears the selected country and triggers a silent save', async () => { const api = new Function(` let heroSmsCountrySelectionOrder = [52, 6];