require('dotenv').config(); const express = require('express'); const { exec } = require('child_process'); const axios = require('axios'); const nodemailer = require('nodemailer'); const INTERVAL_MINUTES = 30; const MAX_RETRIES = 3; const PORT = process.env.PORT || 3000; const app = express(); let lastStatus = { success: null, message: null, timestamp: null, duration: null }; function runCheck(attempt = 1) { const startTs = Date.now(); console.log(`[{new Date().toISOString()}] ▶️ Starting OIDC check (try {attempt}/{MAX_RETRIES})...`); const child = exec('node /app/test/monitor.js', (error, stdout, stderr) => { lastStatus.timestamp = new Date().toISOString(); lastStatus.duration = Date.now() - startTs; if (stdout) console.log(stdout); if (stderr) console.error(stderr); lastStatus.success = !error; lastStatus.message = error ? `Fehlgeschlagen: ${error.message}` : 'Login erfolgreich'; if (error) { notifySlack(`Fehler beim Login:\n${lastStatus.message}`); sendEmail('❌ OIDC Monitoring Fehler', `Zeit: ${lastStatus.timestamp}\n${lastStatus.message}`); } pushToPrometheus(!error, lastStatus.duration); }); } function pushToPrometheus(success, duration) { const labels = `{job="oidc-monitor",instance="${process.env.PROMETHEUS_INSTANCE_ID}"}`; const metrics = ` oidc_login_success${labels} ${success ? 1 : 0} oidc_login_duration_seconds${labels} ${(duration / 1000).toFixed(2)} `; axios.post(`${process.env.PUSHGATEWAY_URL}/metrics/job/oidc-monitor`, metrics, { headers: { 'Content-Type': 'text/plain' } }).then(() => console.log('📡 Prometheus Push erfolgreich')) .catch(err => console.error('❌ Prometheus Push fehlgeschlagen:', err.message)); } function notifySlack(message) { if (!process.env.SLACK_WEBHOOK_URL) return; axios.post(process.env.SLACK_WEBHOOK_URL, { text: `❗️OIDC Monitoring Alert:\n${message}` }) .then(() => console.log('📣 Slack-Nachricht gesendet')) .catch(err => console.error('❌ Slack fehlgeschlagen:', err.message)); } function sendEmail(subject, text) { const transporter = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT || '25', 10), secure: false }); transporter.sendMail({ from: process.env.MAIL_FROM, to: process.env.MAIL_TO, subject, text }).then(() => console.log('✉️ E-Mail gesendet')) .catch(err => console.error('❌ Mail fehlgeschlagen:', err.message)); } app.get('/run-now', (req, res) => { runCheck(); res.send('▶️ Check gestartet'); }); app.get('/healthz', (req, res) => { if (lastStatus.success === false) return res.status(500).send('Letzter Check fehlgeschlagen'); res.send('OK'); }); app.get('/status', (req, res) => res.json(lastStatus)); app.listen(PORT, () => { console.log(`🌐 Web API läuft auf Port ${PORT}`); }); runCheck(); setInterval(runCheck, INTERVAL_MINUTES * 60 * 1000);