|
|
@@ -13,12 +13,9 @@ const ADMIN_BASE = 'admin.booking.com';
|
|
|
const STRIP = new Set(['OptanonConsent', 'pcm_consent', 'uz']);
|
|
|
|
|
|
async function handleAuthAssurance(page: Page, masked: string): Promise<boolean> {
|
|
|
- console.error(`[booking-2fa] Challenge required (${masked || 'unknown number'}) — attempting SMS automation`);
|
|
|
-
|
|
|
// Verification options are <a> links, not buttons. Click the SMS link.
|
|
|
try {
|
|
|
await page.getByText(/via Text message \(SMS\)/i).click({ timeout: 10_000 });
|
|
|
- console.error('[booking-2fa] Clicked SMS option');
|
|
|
await page.waitForLoadState('domcontentloaded');
|
|
|
} catch {
|
|
|
// Already on PIN entry, or SMS nav already happened — continue.
|
|
|
@@ -27,7 +24,6 @@ async function handleAuthAssurance(page: Page, masked: string): Promise<boolean>
|
|
|
// Select-phone page: click "Send verification code" to trigger the SMS.
|
|
|
try {
|
|
|
await page.getByRole('button', { name: /send verification code/i }).click({ timeout: 10_000 });
|
|
|
- console.error('[booking-2fa] Clicked Send verification code');
|
|
|
} catch {
|
|
|
// Already past this step.
|
|
|
}
|
|
|
@@ -37,17 +33,15 @@ async function handleAuthAssurance(page: Page, masked: string): Promise<boolean>
|
|
|
try {
|
|
|
pinInput = await page.waitForSelector(PIN_SEL, { timeout: 30_000 });
|
|
|
} catch {
|
|
|
- console.error('[booking-2fa] No PIN input found — no active 2FA challenge, or challenge not visible');
|
|
|
- return false;
|
|
|
+ throw new Error(`[booking-2fa] PIN input not found — SMS may not have been sent to ${masked || 'unknown number'}`);
|
|
|
}
|
|
|
|
|
|
- console.error('[booking-2fa] Polling /sms/code for up to 2 minutes...');
|
|
|
+ console.error(`[booking-2fa] Sending SMS to ${masked || 'registered number'} — waiting for code...`);
|
|
|
const code = await fetchSmsCode(120);
|
|
|
if (!code) {
|
|
|
throw new Error('[booking-2fa] No SMS code received within timeout');
|
|
|
}
|
|
|
|
|
|
- console.error(`[booking-2fa] Filling code ${code}`);
|
|
|
await pinInput.fill(code);
|
|
|
await page.keyboard.press('Enter');
|
|
|
return true;
|
|
|
@@ -86,10 +80,8 @@ export async function triggerChatAuth(mode: string): Promise<CredentialsPayload>
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- console.error('[booking-2fa] Navigating to messaging inbox (headless)...');
|
|
|
await page.goto(messagingUrl);
|
|
|
await page.waitForLoadState('domcontentloaded');
|
|
|
- console.error(`[booking-2fa] Landed on: ${page.url()}`);
|
|
|
|
|
|
const landedUrl = page.url();
|
|
|
const onAuthAssurance = landedUrl.includes('auth-assurance');
|
|
|
@@ -106,10 +98,8 @@ export async function triggerChatAuth(mode: string): Promise<CredentialsPayload>
|
|
|
page.waitForURL('**auth-assurance**', { timeout: 10_000 }).catch(() => {}),
|
|
|
new Promise<void>(r => setTimeout(r, 10_000)),
|
|
|
]);
|
|
|
- console.error(`[booking-2fa] After wait — url: ${page.url()}, masked: ${smsMasked || '(none)'}`);
|
|
|
-
|
|
|
if (!page.url().includes('auth-assurance')) {
|
|
|
- console.error('[booking-2fa] No auth-assurance challenge — messaging already primed for this session.');
|
|
|
+ console.error('[booking-2fa] Messaging already authorized — no challenge needed.');
|
|
|
} else {
|
|
|
// Wait for the auth-assurance page to render — options are links, not buttons.
|
|
|
await page.waitForSelector('text=Text message', { timeout: 30_000 }).catch(() => {});
|
|
|
@@ -118,17 +108,11 @@ export async function triggerChatAuth(mode: string): Promise<CredentialsPayload>
|
|
|
if (page.url().includes('auth-assurance')) {
|
|
|
await page.waitForURL(`**${ADMIN_BASE}/**`, { timeout: 120_000 });
|
|
|
}
|
|
|
- console.error('[booking-2fa] Auth-assurance completed.');
|
|
|
+ console.error('[booking-2fa] 2FA complete.');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Diagnostic screenshot before closing
|
|
|
- const screenshotPath = path.join(DATA_HOME, 'booking-2fa-debug.png');
|
|
|
- await page.screenshot({ path: screenshotPath, fullPage: true }).catch(() => {});
|
|
|
- console.error(`[booking-2fa] Screenshot: ${screenshotPath}`);
|
|
|
-
|
|
|
if (!headless) {
|
|
|
- console.error('[booking-2fa] Headed mode — press Enter to close the browser...');
|
|
|
await new Promise<void>(resolve => process.stdin.once('data', () => resolve()));
|
|
|
}
|
|
|
|