Verbessere CAPTCHA-Handling im Login-Prozess: Implementiere automatische Token-Generierung und verbessere Fehlerbehandlung.
All checks were successful
Code Analysis and Production Deploy / analyze (push) Successful in 4m55s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Successful in 2m45s

This commit is contained in:
Torsten Schulz (local)
2026-09-04 15:11:15 +02:00
parent d31026a606
commit ee93e15af8

View File

@@ -37,17 +37,44 @@ async function loginWithBrowser(email, password) {
const browser = await chromium.launch({ headless: true })
try {
const page = await browser.newPage()
await page.goto(`${BASE_URL}/login?next=%2F`, { waitUntil: 'networkidle' })
// Das myTT-CAPTCHA wird erst nach dem Laden der Seite erzeugt. Der Ablauf
// entspricht der erprobten Integration im Trainingstagebuch.
await page.goto(BASE_URL, { waitUntil: 'domcontentloaded', timeout: 30_000 }).catch(() => {})
await page.goto(`${BASE_URL}/login?next=%2F`, { waitUntil: 'domcontentloaded', timeout: 45_000 })
await page.locator('input[name="email"]').fill(email)
await page.locator('input[name="password"]').fill(password)
// Das CAPTCHA wird vom Anbieter im Browser erzeugt. Ohne erfolgreiches Token wird nicht abgesendet.
await page.waitForFunction(() => {
const input = document.querySelector('input[name="captcha"]')
return Boolean(input?.value)
}, { timeout: 25_000 })
await page.locator('form').evaluate(form => form.requestSubmit())
await page.waitForTimeout(1_500)
const cookie = (await page.context().cookies(BASE_URL)).find(item => item.name === 'sb-10-auth-token')
const captchaHost = page.locator('private-captcha').first()
const hasCaptcha = await captchaHost.count() > 0
if (hasCaptcha) {
await page.waitForTimeout(1_200)
await page.evaluate(() => {
const host = document.querySelector('private-captcha')
const checkbox = host?.shadowRoot?.querySelector('#pc-checkbox')
if (!checkbox) return
checkbox.click()
checkbox.dispatchEvent(new Event('input', { bubbles: true }))
checkbox.dispatchEvent(new Event('change', { bubbles: true }))
})
await page.waitForFunction(() => {
const token = document.querySelector('input[name="captcha"]')?.value?.trim() || ''
const clicked = document.querySelector('input[name="captcha_clicked"]')?.value?.toLowerCase() || ''
return token.length > 80 && (clicked === 'true' || clicked === '1')
}, { timeout: 32_000 }).catch(() => {})
const captchaReady = await page.evaluate(() => (document.querySelector('input[name="captcha"]')?.value?.trim().length || 0) > 80)
if (!captchaReady) throw new Error('CAPTCHA konnte nicht automatisch gelöst werden.')
await page.waitForTimeout(2_500)
}
const submit = page.locator('button[type="submit"][name="intent"][value="login"], button[type="submit"], input[type="submit"]').first()
if (await submit.count()) await submit.click({ noWaitAfter: true })
else await page.locator('form').evaluate(form => form.requestSubmit())
let cookie = null
for (let attempt = 0; attempt < 40; attempt += 1) {
cookie = (await page.context().cookies(BASE_URL)).find(item => /^sb-\d+-auth-token$/.test(item.name))
if (cookie) break
await page.waitForTimeout(500)
}
if (!cookie) throw new Error('CAPTCHA konnte nicht automatisch gelöst werden.')
return `${cookie.name}=${cookie.value}`
} finally { await browser.close() }