cat monitor-whoami-prod.js const { chromium } = require('playwright'); const fs = require('fs'); const path = require('path'); const dotenv = require('dotenv'); const speakeasy = require('speakeasy');   // Lade .env-Variablen dotenv.config();   const {   USERNAME,   PASSWORD,   TOTP_SECRET,   LOGIN_URL = 'about:privatebrowsing',   LOGOUT_URL = 'about:privatebrowsing', } = process.env;   const nodemailer = require('nodemailer');   async function sendFailureMail(subject, text, attachments) {   const transporter = nodemailer.createTransport({     host: process.env.SMTP_HOST,     port: parseInt(process.env.SMTP_PORT, 10),     secure: false, // kein TLS     tls: {       rejectUnauthorized: false     }   });     await transporter.sendMail({     from: process.env.MAIL_FROM,     to: process.env.MAIL_TO,     subject,     text,     attachments   }); }   if (!USERNAME || !PASSWORD || !TOTP_SECRET) {   console.error('❌ Bitte .env mit USERNAME, PASSWORD und TOTP_SECRET konfigurieren');   process.exit(2); }   (async () => {   const resultDir = '/app/test-results';   const timestamp = new Date().toISOString().replace(/[:.]/g, '-');     const browser = await chromium.launch({ headless: true });   const context = await browser.newContext({   proxy: {     server: 'http://igw-axsg.abxsec.com:8080'   } });   const page = await context.newPage();   console.log('✅ Login aufrufen');     try {     await page.goto(LOGIN_URL);     await page.setViewportSize({ width: 1920, height: 937 });       await Promise.all([       page.click('#social-eIAM'),       page.waitForNavigation()     ]);       console.log('✅ Login eiam user eintragen');       await page.click('#isiwebuserid');     await page.fill('#isiwebuserid', USERNAME);       await page.screenshot({ path: '/app/test-results/userid.png', fullPage: true });       await Promise.all([ //      page.click('text=Continue'),       page.press('#isiwebuserid', 'Enter'),       page.waitForNavigation()     ]);       console.log('✅ Login eiam pw eintragen');       await page.click('#isiwebpasswd');     await page.fill('#isiwebpasswd', PASSWORD);       await page.screenshot({ path: '/app/test-results/pw.png', fullPage: true });       await Promise.all([ //      page.click('text=Login'),       page.press('#isiwebpasswd', 'Enter'),       page.waitForNavigation()     ]);       console.log('✅ Login eiam TOTP generieren');         const totp = speakeasy.totp({       secret: TOTP_SECRET,       encoding: 'base32'     });         console.log('✅ Login eiam TOTP ${totp}');       console.log('✅ Login eiam TOTP eintragen');         await page.fill('#code2FA', totp);       await page.screenshot({ path: '/app/test-results/totp.png', fullPage: true });       await Promise.all([ //      page.click('text=Continue'),       page.press('#code2FA', 'Enter'),       page.waitForNavigation()     ]);       console.log('✅ WhoAmI Webseite warten');       await page.waitForSelector(`text=${USERNAME}`, { timeout: 10000 });       await page.screenshot({ path: '/app/test-results/result.png', fullPage: true });       console.log(`🔎 Suche nach Benutzername: ${USERNAME}`);     const pageText = await page.textContent('body');       fs.writeFileSync(path.join(resultDir, `final-${timestamp}.html`), await page.content());     fs.writeFileSync(path.join(resultDir, `final-${timestamp}.txt`), pageText);       if (pageText.includes(USERNAME)) {       console.log('✅ Login erfolgreich – Benutzername sichtbar');     } else {       console.error('❌ Benutzername nicht gefunden – Login möglicherweise fehlerhaft');       await page.screenshot({ path: path.join(resultDir, `username-missing_${timestamp}.png`) });       fs.writeFileSync(path.join(resultDir, `page-username-missing_${timestamp}.html`), await page.content());       process.exit(1);     }       console.log('✅ Login erfolgreich - username sichtbar');       console.log('✅ Logout');       await page.goto(LOGOUT_URL);       await Promise.all([       page.click('#kc-logout'),       page.waitForNavigation()     ]);       console.log('✅ Logout erfolgreich');       await page.screenshot({ path: '/app/test-results/logout.png', fullPage: true });       await browser.close();         } catch (err) {     console.error('❌ Fehler beim Login:', err.message);       const screenshotPath = path.join(resultDir, `error_${timestamp}.png`);     const htmlPath = path.join(resultDir, `page_${timestamp}.html`);     const textPath = path.join(resultDir, `page-${timestamp}.txt`);       await page.screenshot({ path: screenshotPath });     const pageText = await page.textContent('body');     fs.writeFileSync(htmlPath, await page.content());     fs.writeFileSync(textPath, pageText);       const captchaDetected = await page.evaluate(() => {       return document.body.innerText.toLowerCase().includes('captcha') ||              document.querySelector('input[name="captcha"]') !== null ||              document.querySelector('.g-recaptcha') !== null;     });       await sendFailureMail(         '❌ OIDC Login Monitoring fehlgeschlagen',         `Fehler beim Login:\n\n${err.message}\n\nZeitpunkt: ${timestamp}`,         [           { filename: 'error.png', path: screenshotPath },           { filename: 'page.html', path: htmlPath },           { filename: 'page.txt', path: textPath }         ]       );       if (captchaDetected) {       console.error('🚫 Captcha erkannt – Test wird abgebrochen');         const captchaPath = path.join(resultDir, `captcha_${timestamp}.png`);       const htmlPath = path.join(resultDir, `captcha_${timestamp}.html`);       const textPath = path.join(resultDir, `captcha_${timestamp}.txt`);         await page.screenshot({ path: captchaPath });       fs.writeFileSync(htmlPath, await page.content());       fs.writeFileSync(textPath, await page.evaluate(() => document.body.innerText));         process.exit(3); // spezieller Exit-Code für Captcha     }         process.exit(1);   } finally {     await browser.close();   } })();