Unifi-Voucher-Tool/m365_debug.php
Friederich Loheide 6da46f040a Alle Frontend-Assets lokal ausliefern statt über CDNs
Inter, Font Awesome, Chart.js, qrcodejs und TinyMCE liegen jetzt unter
assets/vendor/ und werden vom eigenen Server ausgeliefert.

Warum:
- Datenschutz: bisher ging bei jedem Seitenaufruf die IP der Nutzer an
  Google Fonts, cdnjs, jsDelivr und Tiny Cloud
- Funktion: UniFi-Installationen stehen oft in abgeschotteten Netzen –
  dort fehlten bisher Schrift, Icons, Diagramme und Editor

Neu: includes/Ui.php
- Ui::head()/Ui::script() binden die Assets ein und hängen einen
  Versionsstempel an (?v=filemtime), damit Browser nach einem Update
  nicht das alte CSS aus dem Cache nehmen
- Ui::themeScript() setzt das Theme aus der gespeicherten Auswahl oder
  – wenn keine vorliegt – aus prefers-color-scheme; global.js folgt
  Systemwechseln live, solange nichts manuell gewählt wurde
- <meta name="color-scheme"> ergänzt, damit Formularelemente passen

Der TinyMCE-API-Key entfällt: der Editor läuft immer lokal (GPL-Variante),
inklusive deutscher Oberfläche, wenn die App auf Deutsch steht.

Neu: tools/demo/build.py – baut aus dem Projekt eine Demo-Instanz ohne
Datenbank (Stubs für Database/Auth, feste Beispieldaten). Damit lassen
sich Screenshots reproduzierbar erzeugen und alle Seiten einmal rendern
(Smoke-Test), ohne eine MySQL-Instanz aufzusetzen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:23:44 +00:00

74 lines
No EOL
3.1 KiB
PHP

<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/includes/Database.php';
require_once __DIR__ . '/includes/Auth.php';
// Diagnose-Seite nur fuer angemeldete Admins (leakt sonst M365-Konfiguration)
$auth = new Auth();
$auth->requireAdmin();
$db = Database::getInstance();
// M365 Einstellungen abrufen
$clientId = $db->getSetting('m365_client_id', '');
$clientSecret = $db->getSetting('m365_client_secret', '');
$tenantId = $db->getSetting('m365_tenant_id', '');
// Dynamische URLs
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$scriptPath = dirname($_SERVER['SCRIPT_NAME']);
$scriptPath = $scriptPath === '/' ? '' : $scriptPath;
$redirectUri = $protocol . '://' . $host . $scriptPath . '/m365_callback.php';
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>M365 Debug</title>
<?php require_once __DIR__ . '/includes/Ui.php'; ?>
<?= Ui::head($db ?? null) ?>
<style>
body { padding: 32px 20px; }
.section { max-width: 820px; margin: 0 auto 18px; padding: 20px; background: var(--bg-card);
border: 1px solid var(--border-color); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.section h2 { font-size: 15px; margin-bottom: 12px; }
.ok { color: var(--success); font-weight: 600; }
.error { color: var(--danger); font-weight: 600; }
.info { color: var(--text-muted); }
.url { padding: 10px 12px; background: var(--bg-subtle); border: 1px solid var(--border-color);
border-radius: var(--r-sm); font-family: var(--font-mono); font-size: 12.5px; word-break: break-all; }
</style>
</head>
<body class="app-body">
<h1>🔍 Microsoft 365 OAuth Debug</h1>
<div class="section">
<h2>1. Konfiguration Status</h2>
<p>Client ID: <?= !empty($clientId) ? '<span class="ok">✓ Gesetzt</span>' : '<span class="error">✗ Fehlt</span>' ?></p>
<p>Client Secret: <?= !empty($clientSecret) ? '<span class="ok">✓ Gesetzt</span>' : '<span class="error">✗ Fehlt</span>' ?></p>
<p>Tenant ID: <?= !empty($tenantId) ? '<span class="ok">✓ Gesetzt</span>' : '<span class="error">✗ Fehlt</span>' ?></p>
</div>
<div class="section">
<h2>2. Redirect URI</h2>
<p>Diese URI muss exakt in der Azure-App-Registrierung hinterlegt sein:</p>
<div class="url"><?= htmlspecialchars($redirectUri) ?></div>
</div>
<div class="section">
<h2>3. Hinweise</h2>
<ul>
<li>Alle drei Werte (Client ID, Client Secret, Tenant ID) müssen gesetzt sein.</li>
<li>Die Redirect URI in Azure AD muss exakt mit der obigen übereinstimmen.</li>
<li>Benötigte API-Berechtigungen: <code>openid</code>, <code>profile</code>, <code>email</code>, <code>User.Read</code>.</li>
</ul>
</div>
</body>
</html>