diff --git a/src/browser/Browser.ts b/src/browser/Browser.ts index fb82afe..57f4b3f 100644 --- a/src/browser/Browser.ts +++ b/src/browser/Browser.ts @@ -182,36 +182,12 @@ class Browser { try { context.on('page', async (page) => { try { - // CRITICAL: Install dialog handlers FIRST to prevent Bluetooth/Passkey native popups - page.removeAllListeners('dialog') - page.on('dialog', async (dialog) => { - const message = dialog.message() - const type = dialog.type() - - this.bot.log( - this.bot.isMobile, - 'BROWSER-DIALOG', - `Native dialog: [${type}] "${message.substring(0, 50)}"`, - 'warn' - ) - - try { - if (type === 'beforeunload') { - await dialog.accept() - } else { - // Dismiss all other dialogs (Bluetooth, Passkey, Windows Hello) - await dialog.dismiss() - this.bot.log(this.bot.isMobile, 'BROWSER-DIALOG', `Dismissed ${type} dialog`, 'log', 'green') - } - } catch (e) { - this.bot.log(this.bot.isMobile, 'BROWSER-DIALOG', `Dialog error: ${e instanceof Error ? e.message : String(e)}`, 'error') - } - }) - // CRITICAL: Inject anti-detection scripts BEFORE any page load await page.addInitScript(antiDetectScript) await page.addInitScript(timezoneScript) + // Virtual Authenticator support removed — no CDP WebAuthn setup performed here + // IMPROVED: Use crypto-secure random for viewport sizes const { secureRandomInt } = await import('../util/security/SecureRandom') diff --git a/src/functions/Login.ts b/src/functions/Login.ts index 9f59453..d39be61 100644 --- a/src/functions/Login.ts +++ b/src/functions/Login.ts @@ -228,9 +228,6 @@ export class Login { await this.disableFido(page) - // CRITICAL: Start automatic Escape sender to dismiss native OS dialogs - this.passkeyHandler.startEscapeWatcher(page) - const [reloadResult, totpResult, portalCheck] = await Promise.allSettled([ this.bot.browser.utils.reloadBadPage(page), this.totpHandler.tryAutoTotp(page, 'initial landing'), @@ -262,12 +259,8 @@ export class Login { this.bot.log(this.bot.isMobile, 'LOGIN', 'Login complete') this.totpHandler.setTotpSecret(undefined) - // CRITICAL: Keep Escape watcher running for 10 more seconds - // Bluetooth/Windows Hello dialogs appear AFTER login completion - this.bot.log(this.bot.isMobile, 'LOGIN-ESCAPE', 'Keeping Escape watcher active for 10s (dialogs may appear after login)', 'log', 'cyan') - setTimeout(() => { - this.passkeyHandler.stopEscapeWatcher() - }, 10000) + this.bot.log(this.bot.isMobile, 'LOGIN', 'Login complete') + this.totpHandler.setTotpSecret(undefined) } catch (e) { const errorMessage = e instanceof Error ? e.message : String(e) const stackTrace = e instanceof Error ? e.stack : undefined diff --git a/src/functions/login/PasskeyHandler.ts b/src/functions/login/PasskeyHandler.ts index 8848b93..e079919 100644 --- a/src/functions/login/PasskeyHandler.ts +++ b/src/functions/login/PasskeyHandler.ts @@ -31,55 +31,12 @@ export class PasskeyHandler { }).catch(logError('LOGIN-FIDO', 'Route interception setup failed', this.bot.isMobile)) } - private escapeWatcherInterval: NodeJS.Timeout | null = null - - /** - * Start automatic Escape key sender to dismiss native OS dialogs (Bluetooth, Windows Hello) - * CRITICAL: Native system dialogs cannot be dismissed via Playwright dialog handlers - * They can only be closed with Escape key (as user discovered) - */ - public startEscapeWatcher(page: Page) { - // Stop any existing watcher - this.stopEscapeWatcher() - - this.bot.log(this.bot.isMobile, 'LOGIN-ESCAPE', 'Starting automatic Escape sender (500ms interval)', 'log', 'cyan') - - this.escapeWatcherInterval = setInterval(async () => { - try { - // Send Escape key to dismiss any native dialogs - await page.keyboard.press('Escape').catch(() => { - // Silent failure - page might be closed - }) - } catch { - // Silent failure - interval will be cleared when stopEscapeWatcher is called - } - }, 500) - } - - /** - * Stop the automatic Escape key sender - */ - public stopEscapeWatcher() { - if (this.escapeWatcherInterval) { - clearInterval(this.escapeWatcherInterval) - this.escapeWatcherInterval = null - this.bot.log(this.bot.isMobile, 'LOGIN-ESCAPE', 'Stopped automatic Escape sender', 'log', 'cyan') - } - } + // NOTE: Automatic Escape sender removed - native OS dialogs should be handled + // via safer server-side/workflow changes or Playwright Virtual Authenticator. public async handlePasskeyPrompts(page: Page, context: 'main' | 'oauth') { let did = false - // CRITICAL: Send Escape key FIRST to dismiss any native OS dialogs (Bluetooth, Windows Hello) - // These dialogs appear AFTER password/TOTP and cannot be dismissed via DOM clicks - try { - await page.keyboard.press('Escape') - await page.waitForTimeout(100) // Brief wait for dialog to close - this.bot.log(this.bot.isMobile, 'PASSKEY-ESCAPE', 'Sent Escape key to dismiss native dialogs', 'log', 'green') - } catch { - // Silent failure - page might not be ready - } - // Early exit for passkey creation flows (common on mobile): hit cancel/skip if present const currentUrl = page.url() if (/fido\/create|passkey/i.test(currentUrl)) {