const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const source = fs.readFileSync('background/phone-verification-flow.js', 'utf8'); const globalScope = {}; const api = new Function('self', `${source}; return self.MultiPageBackgroundPhoneVerification;`)(globalScope); test('phone verification helper requests HeroSMS numbers with fixed OpenAI and Thailand parameters', async () => { const requests = []; const helpers = api.createPhoneVerificationHelpers({ addLog: async () => {}, ensureStep8SignupPageReady: async () => {}, fetchImpl: async (url) => { requests.push(new URL(url)); return { ok: true, text: async () => 'ACCESS_NUMBER:123456:66959916439', }; }, getState: async () => ({ heroSmsApiKey: 'demo-key' }), sendToContentScriptResilient: async () => ({}), setState: async () => {}, sleepWithStop: async () => {}, throwIfStopped: () => {}, }); const activation = await helpers.requestPhoneActivation({ heroSmsApiKey: 'demo-key' }); assert.deepStrictEqual(activation, { activationId: '123456', phoneNumber: '66959916439', provider: 'hero-sms', serviceCode: 'dr', countryId: 52, successfulUses: 0, maxUses: 3, }); assert.equal(requests.length, 1); assert.equal(requests[0].searchParams.get('action'), 'getNumber'); assert.equal(requests[0].searchParams.get('service'), 'dr'); assert.equal(requests[0].searchParams.get('country'), '52'); assert.equal(requests[0].searchParams.get('api_key'), 'demo-key'); }); test('phone verification helper completes add-phone flow, clears current activation, and stores reusable number state', async () => { const requests = []; const stateUpdates = []; let currentState = { heroSmsApiKey: 'demo-key', verificationResendCount: 1, currentPhoneActivation: null, reusablePhoneActivation: null, }; const helpers = api.createPhoneVerificationHelpers({ addLog: async () => {}, ensureStep8SignupPageReady: async () => {}, fetchImpl: async (url) => { const parsedUrl = new URL(url); requests.push(parsedUrl); const action = parsedUrl.searchParams.get('action'); if (action === 'getNumber') { return { ok: true, text: async () => 'ACCESS_NUMBER:123456:66959916439', }; } if (action === 'getStatus') { return { ok: true, text: async () => 'STATUS_OK:654321', }; } if (action === 'setStatus') { return { ok: true, text: async () => 'ACCESS_ACTIVATION', }; } throw new Error(`Unexpected HeroSMS action: ${action}`); }, getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs, getState: async () => ({ ...currentState }), sendToContentScriptResilient: async (_source, message) => { if (message.type === 'SUBMIT_PHONE_NUMBER') { return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification', }; } if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') { return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }; } throw new Error(`Unexpected content-script message: ${message.type}`); }, setState: async (updates) => { stateUpdates.push(updates); currentState = { ...currentState, ...updates }; }, sleepWithStop: async () => {}, throwIfStopped: () => {}, }); const result = await helpers.completePhoneVerificationFlow(1, { addPhonePage: true, phoneVerificationPage: false, url: 'https://auth.openai.com/add-phone', }); assert.deepStrictEqual(result, { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }); assert.deepStrictEqual(stateUpdates, [ { currentPhoneActivation: { activationId: '123456', phoneNumber: '66959916439', provider: 'hero-sms', serviceCode: 'dr', countryId: 52, successfulUses: 0, maxUses: 3, }, }, { reusablePhoneActivation: { activationId: '123456', phoneNumber: '66959916439', provider: 'hero-sms', serviceCode: 'dr', countryId: 52, successfulUses: 1, maxUses: 3, }, }, { currentPhoneActivation: null, }, ]); const actions = requests.map((url) => url.searchParams.get('action')); assert.deepStrictEqual(actions, ['getNumber', 'getStatus', 'setStatus']); }); test('phone verification helper uses the configured HeroSMS country for both number acquisition and add-phone submission', async () => { const requests = []; const submittedPayloads = []; let currentState = { heroSmsApiKey: 'demo-key', heroSmsCountryId: 16, heroSmsCountryLabel: 'United Kingdom', verificationResendCount: 0, currentPhoneActivation: null, reusablePhoneActivation: null, }; const helpers = api.createPhoneVerificationHelpers({ addLog: async () => {}, ensureStep8SignupPageReady: async () => {}, fetchImpl: async (url) => { const parsedUrl = new URL(url); requests.push(parsedUrl); const action = parsedUrl.searchParams.get('action'); if (action === 'getNumber') { return { ok: true, text: async () => 'ACCESS_NUMBER:654321:447911123456', }; } if (action === 'getStatus') { return { ok: true, text: async () => 'STATUS_OK:112233', }; } if (action === 'setStatus') { return { ok: true, text: async () => 'ACCESS_ACTIVATION', }; } throw new Error(`Unexpected HeroSMS action: ${action}`); }, getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs, getState: async () => ({ ...currentState }), sendToContentScriptResilient: async (_source, message) => { if (message.type === 'SUBMIT_PHONE_NUMBER') { submittedPayloads.push(message.payload); return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification', }; } if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') { return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }; } throw new Error(`Unexpected content-script message: ${message.type}`); }, setState: async (updates) => { currentState = { ...currentState, ...updates }; }, sleepWithStop: async () => {}, throwIfStopped: () => {}, }); const result = await helpers.completePhoneVerificationFlow(1, { addPhonePage: true, phoneVerificationPage: false, url: 'https://auth.openai.com/add-phone', }); assert.deepStrictEqual(result, { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }); assert.equal(requests[0].searchParams.get('action'), 'getNumber'); assert.equal(requests[0].searchParams.get('country'), '16'); assert.deepStrictEqual(submittedPayloads, [{ phoneNumber: '447911123456', countryId: 16, countryLabel: 'United Kingdom', }]); }); test('phone verification helper throws a step-7 restart error after 60 seconds plus one resend window without SMS', async () => { const requests = []; const messages = []; let currentState = { heroSmsApiKey: 'demo-key', verificationResendCount: 0, currentPhoneActivation: null, reusablePhoneActivation: null, }; const statusCallsById = {}; const realDateNow = Date.now; let fakeNow = 0; Date.now = () => fakeNow; try { const helpers = api.createPhoneVerificationHelpers({ addLog: async () => {}, ensureStep8SignupPageReady: async () => {}, fetchImpl: async (url) => { const parsedUrl = new URL(url); requests.push(parsedUrl); const action = parsedUrl.searchParams.get('action'); const id = parsedUrl.searchParams.get('id'); if (action === 'getNumber') { return { ok: true, text: async () => 'ACCESS_NUMBER:123456:66959916439', }; } if (action === 'getStatus') { statusCallsById[id] = (statusCallsById[id] || 0) + 1; return { ok: true, text: async () => 'STATUS_WAIT_CODE', }; } if (action === 'setStatus') { return { ok: true, text: async () => 'ACCESS_ACTIVATION', }; } throw new Error(`Unexpected HeroSMS action: ${action}`); }, getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs, getState: async () => ({ ...currentState }), sendToContentScriptResilient: async (_source, message) => { messages.push(message.type); if (message.type === 'SUBMIT_PHONE_NUMBER') { return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification', }; } if (message.type === 'RESEND_PHONE_VERIFICATION_CODE') { return { resent: true, url: 'https://auth.openai.com/phone-verification', }; } throw new Error(`Unexpected content-script message: ${message.type}`); }, setState: async (updates) => { currentState = { ...currentState, ...updates }; }, sleepWithStop: async () => { fakeNow += 61000; }, throwIfStopped: () => {}, }); await assert.rejects( helpers.completePhoneVerificationFlow(1, { addPhonePage: true, phoneVerificationPage: false, url: 'https://auth.openai.com/add-phone', }), /Restart step 7 with a new number/i ); assert.ok(statusCallsById['123456'] >= 2, 'first number should be polled twice before being replaced'); assert.deepStrictEqual(messages, [ 'SUBMIT_PHONE_NUMBER', 'RESEND_PHONE_VERIFICATION_CODE', ]); const actions = requests.map((url) => `${url.searchParams.get('action')}:${url.searchParams.get('id') || ''}`); assert.deepStrictEqual(actions, [ 'getNumber:', 'getStatus:123456', 'setStatus:123456', 'getStatus:123456', 'setStatus:123456', ]); assert.equal(currentState.currentPhoneActivation, null); } finally { Date.now = realDateNow; } }); test('phone verification helper reuses the same number up to three successful registrations', async () => { const requests = []; let currentState = { heroSmsApiKey: 'demo-key', verificationResendCount: 0, currentPhoneActivation: null, reusablePhoneActivation: { activationId: '123456', phoneNumber: '66959916439', provider: 'hero-sms', serviceCode: 'dr', countryId: 52, successfulUses: 2, maxUses: 3, }, }; const helpers = api.createPhoneVerificationHelpers({ addLog: async () => {}, ensureStep8SignupPageReady: async () => {}, fetchImpl: async (url) => { const parsedUrl = new URL(url); requests.push(parsedUrl); const action = parsedUrl.searchParams.get('action'); if (action === 'reactivate') { return { ok: true, text: async () => JSON.stringify({ activationId: '222333', phoneNumber: '66959916439', }), }; } if (action === 'getStatus') { return { ok: true, text: async () => 'STATUS_OK:654321', }; } if (action === 'setStatus') { return { ok: true, text: async () => 'ACCESS_ACTIVATION', }; } throw new Error(`Unexpected HeroSMS action: ${action}`); }, getOAuthFlowStepTimeoutMs: async (defaultTimeoutMs) => defaultTimeoutMs, getState: async () => ({ ...currentState }), sendToContentScriptResilient: async (_source, message) => { if (message.type === 'SUBMIT_PHONE_NUMBER') { return { phoneVerificationPage: true, url: 'https://auth.openai.com/phone-verification', }; } if (message.type === 'SUBMIT_PHONE_VERIFICATION_CODE') { return { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }; } throw new Error(`Unexpected content-script message: ${message.type}`); }, setState: async (updates) => { currentState = { ...currentState, ...updates }; }, sleepWithStop: async () => {}, throwIfStopped: () => {}, }); const result = await helpers.completePhoneVerificationFlow(1, { addPhonePage: true, phoneVerificationPage: false, url: 'https://auth.openai.com/add-phone', }); assert.deepStrictEqual(result, { success: true, consentReady: true, url: 'https://auth.openai.com/authorize', }); assert.equal(requests[0].searchParams.get('action'), 'reactivate'); assert.equal(requests[0].searchParams.get('id'), '123456'); assert.deepStrictEqual(currentState.reusablePhoneActivation, null); });