feat: Implement light/dark theme toggle and enhance UI components
- Added theme.js for managing light/dark mode with user preference persistence. - Updated lab.php to include theme toggle button and adjust styles for light mode. - Enhanced CSS styles in style.css for light theme support, including background and text colors. - Introduced DNS record lookup functionality in tools.php with user input for domain queries. - Improved UI for DNS lookup and outbound connectivity tests in tools.php. - Added historical benchmark trend chart in lab.php to visualize previous benchmark scores. - Refactored various UI elements for better spacing and alignment across components.
This commit is contained in:
@@ -1,14 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Web & PC Studio - Dev Tools & System Inspector
|
||||
* Technische inspectie en utilities voor serverbeheer en debugging.
|
||||
* Technische inspectie en utilities voor serverbeheer, DNS en debugging.
|
||||
*/
|
||||
|
||||
// PHP Backend AJAX handler
|
||||
if (isset($_GET['action'])) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// Outbound Connectiviteitstest
|
||||
// 1. DNS Record Lookup
|
||||
if ($_GET['action'] === 'dns_lookup') {
|
||||
$domain = trim($_GET['domain'] ?? 'webenpcstudio.nl');
|
||||
$domain = preg_replace('#^https?://#', '', $domain);
|
||||
$domain = rtrim(explode('/', $domain)[0], '.');
|
||||
|
||||
if (empty($domain)) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Geen geldig domein opgegeven.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$records = [];
|
||||
if (function_exists('dns_get_record')) {
|
||||
$raw = @dns_get_record($domain, DNS_A + DNS_AAAA + DNS_MX + DNS_NS + DNS_TXT);
|
||||
if ($raw) {
|
||||
foreach ($raw as $r) {
|
||||
$type = $r['type'] ?? 'UNKNOWN';
|
||||
$val = $r['ip'] ?? ($r['ipv6'] ?? ($r['target'] ?? ($r['txt'] ?? '')));
|
||||
$records[] = [
|
||||
'host' => $r['host'] ?? $domain,
|
||||
'type' => $type,
|
||||
'value' => $val,
|
||||
'ttl' => $r['ttl'] ?? 3600
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback als dns_get_record leeg is
|
||||
if (empty($records)) {
|
||||
$ip = @gethostbyname($domain);
|
||||
if ($ip && $ip !== $domain) {
|
||||
$records[] = ['host' => $domain, 'type' => 'A', 'value' => $ip, 'ttl' => 3600];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'domain' => $domain,
|
||||
'count' => count($records),
|
||||
'records' => $records
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. Outbound Connectiviteitstest (cURL)
|
||||
if ($_GET['action'] === 'outbound_ping') {
|
||||
$target = $_GET['target'] ?? 'https://git.webenpcstudio.nl';
|
||||
$allowed = ['https://git.webenpcstudio.nl', 'https://www.google.com', 'https://api.github.com'];
|
||||
@@ -43,7 +88,7 @@ if (isset($_GET['action'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Hash & Encoding API
|
||||
// 3. Hash & Encoding API
|
||||
if ($_GET['action'] === 'transform' && isset($_POST['input'])) {
|
||||
$text = (string)$_POST['input'];
|
||||
echo json_encode([
|
||||
@@ -69,7 +114,18 @@ $phpVersion = PHP_VERSION;
|
||||
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'Onbekend';
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Onbekend';
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS' : 'HTTP';
|
||||
$sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd');
|
||||
|
||||
// Extensies check
|
||||
$extensions = [
|
||||
'Database' => ['pdo', 'pdo_mysql', 'pdo_sqlite', 'mysqli'],
|
||||
'Beveiliging & Crypto' => ['openssl', 'sodium', 'hash'],
|
||||
'Netwerk & Web' => ['curl', 'sockets', 'fileinfo'],
|
||||
'Compressie & Media' => ['zip', 'zlib', 'gd', 'mbstring']
|
||||
];
|
||||
|
||||
// Server load
|
||||
$load = function_exists('sys_getloadavg') ? @sys_getloadavg() : false;
|
||||
$loadDisplay = $load ? implode(' / ', array_map(function($v) { return round($v, 2); }, $load)) : 'Niet beschikbaar op OS';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
@@ -78,6 +134,7 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Web & PC Studio - Dev Tools & Inspector</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="theme.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-wrapper">
|
||||
@@ -96,6 +153,7 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
<a href="tools.php" class="nav-item active">🛠️ Dev Tools</a>
|
||||
</div>
|
||||
<div class="nav-status">
|
||||
<button class="btn btn-secondary btn-sm theme-btn" onclick="toggleTheme()">🌙 Thema</button>
|
||||
<span class="nav-badge">
|
||||
<span class="pulse-dot"></span>
|
||||
Git Live
|
||||
@@ -107,79 +165,57 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
<header class="hero">
|
||||
<h1>Systeem & Developer Tools</h1>
|
||||
<p>
|
||||
Inspecteer binnenkomende HTTP headers, valideer server-connectiviteit en gebruik realtime cryptografische encoding tools.
|
||||
Realtime DNS lookup utility, HTTP header inspectie, PHP extensie matrix en outbound netwerk diagnostics.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- Grid: 2 Kolommen -->
|
||||
<div class="grid-2">
|
||||
<!-- Paneel 1: HTTP Headers & Client Inspectie -->
|
||||
<!-- Tool 1: DNS & Record Lookup -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🔍</span> HTTP Request Inspector
|
||||
<span>🔎</span> DNS & Domein Lookup
|
||||
</div>
|
||||
<span class="badge-pill"><?= htmlspecialchars($protocol); ?></span>
|
||||
<span class="badge-pill">Live DNS Query</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Reële headers zoals ontvangen door de Apache/Nginx webserver voor deze verbinding.
|
||||
Vraag rechtstreeks vanaf deze server de A, AAAA, MX, NS en TXT records op van een domein.
|
||||
</p>
|
||||
|
||||
<table class="data-table" style="margin-bottom: 16px;">
|
||||
<tr>
|
||||
<td class="label">Bezoekers IP:</td>
|
||||
<td class="val"><?= htmlspecialchars($clientIp); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Protocol / SSL:</td>
|
||||
<td class="val"><?= htmlspecialchars($protocol); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">User-Agent:</td>
|
||||
<td class="val" style="max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<?= htmlspecialchars($userAgent); ?>">
|
||||
<?= htmlspecialchars($userAgent); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="card-header" style="margin-bottom: 8px;">
|
||||
<span style="font-size: 0.8rem; color: var(--text-muted); font-weight: 600;">ALLE REQUEST HEADERS:</span>
|
||||
<button class="btn btn-secondary btn-sm" onclick="copyHeaders()">📋 Kopieer</button>
|
||||
<div style="display: flex; gap: 8px; margin-bottom: 14px;">
|
||||
<input type="text" id="dns-input" value="webenpcstudio.nl"
|
||||
style="flex: 1; background: rgba(0,0,0,0.3); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 8px 12px; color: var(--text-main); font-size: 0.88rem; outline: none;"
|
||||
placeholder="bijv. webenpcstudio.nl">
|
||||
<button class="btn btn-primary btn-sm" id="btn-dns" onclick="runDnsLookup()">
|
||||
Query DNS
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="dns-results" class="terminal-box" style="max-height: 200px; min-height: 80px;">
|
||||
Voer een domeinnaam in en klik op "Query DNS" om actieve records op te halen.
|
||||
</div>
|
||||
<div class="terminal-box" id="headers-box"><?php
|
||||
if (!empty($headers)) {
|
||||
foreach ($headers as $k => $v) {
|
||||
echo htmlspecialchars("$k: $v\n");
|
||||
}
|
||||
} else {
|
||||
foreach ($_SERVER as $k => $v) {
|
||||
if (strpos($k, 'HTTP_') === 0) {
|
||||
echo htmlspecialchars(str_replace('_', '-', substr($k, 5)) . ": $v\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
</div>
|
||||
|
||||
<!-- Paneel 2: Outbound Server Connectiviteit (cURL) -->
|
||||
<!-- Tool 2: Outbound Server Connectiviteit (cURL) -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🌐</span> Outbound Server Ping
|
||||
<span>🌐</span> Outbound Server Ping (cURL)
|
||||
</div>
|
||||
<span class="badge-pill">cURL Test</span>
|
||||
<span class="badge-pill">Verbindingstest</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Test of de webserver vanuit PHP naar buiten kan verbinden (bijv. voor Git webhooks of API syncs).
|
||||
Test of de webserver vanuit PHP naar buiten kan verbinden (bijv. voor Git webhooks of API communicatie).
|
||||
</p>
|
||||
|
||||
<div style="display: flex; gap: 8px; margin-bottom: 16px;">
|
||||
<select id="ping-target" class="btn btn-secondary" style="flex: 1; outline: none; background: #0b111e; color: #fff; cursor: pointer;">
|
||||
<div style="display: flex; gap: 8px; margin-bottom: 14px;">
|
||||
<select id="ping-target" class="btn btn-secondary" style="flex: 1; outline: none; background: #0b111e; color: var(--text-main); cursor: pointer; font-size: 0.84rem;">
|
||||
<option value="https://git.webenpcstudio.nl">git.webenpcstudio.nl (Git Server)</option>
|
||||
<option value="https://api.github.com">api.github.com (GitHub API)</option>
|
||||
<option value="https://www.google.com">google.com (Algemene DNS/Web)</option>
|
||||
<option value="https://www.google.com">google.com (Algemeen Web)</option>
|
||||
</select>
|
||||
<button class="btn btn-primary" id="btn-ping" onclick="runOutboundPing()">
|
||||
<button class="btn btn-primary btn-sm" id="btn-ping" onclick="runOutboundPing()">
|
||||
Ping
|
||||
</button>
|
||||
</div>
|
||||
@@ -203,29 +239,90 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ping-status-msg" style="font-size: 0.82rem; color: var(--text-muted); margin-top: 6px;">
|
||||
Selecteer een doellocatie en klik op Ping om de netwerk-latency te meten.
|
||||
<div id="ping-status-msg" style="font-size: 0.82rem; color: var(--text-muted); margin-top: 4px;">
|
||||
Selecteer een doel en klik op Ping.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rij 2: Live String, Hash & Epoch Transformer -->
|
||||
<!-- Tool 3: PHP Extensies & Server Capabilities Matrix -->
|
||||
<div class="card" style="margin-bottom: 24px;">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🧩</span> PHP Extensies & Server Matrix
|
||||
</div>
|
||||
<span class="badge-pill success">PHP v<?= htmlspecialchars($phpVersion); ?></span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Overzicht van geladen modules die cruciaal zijn voor databases, encryptie, netwerkcommunicatie en bestandsverwerking.
|
||||
</p>
|
||||
|
||||
<div class="grid-2" style="margin-bottom: 0;">
|
||||
<?php foreach ($extensions as $cat => $extList): ?>
|
||||
<div class="metric-box" style="padding: 12px 14px;">
|
||||
<div class="metric-label" style="margin-bottom: 8px; color: var(--primary); font-weight: 700;"><?= $cat; ?></div>
|
||||
<div style="display: flex; gap: 6px; flex-wrap: wrap;">
|
||||
<?php foreach ($extList as $ext):
|
||||
$isLoaded = extension_loaded($ext);
|
||||
?>
|
||||
<span class="badge-pill <?= $isLoaded ? 'success' : 'warning'; ?>" style="font-size: 0.76rem;">
|
||||
<?= $isLoaded ? '✓' : '✗'; ?> <?= $ext; ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border-subtle); display: flex; justify-content: space-between; font-size: 0.82rem; color: var(--text-muted);">
|
||||
<span>Server Load Average (1 / 5 / 15 min): <strong><?= htmlspecialchars($loadDisplay); ?></strong></span>
|
||||
<span>Actief Werkgeheugen: <strong><?= round(memory_get_usage() / 1024 / 1024, 1); ?> MB</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tool 4: HTTP Headers Inspector -->
|
||||
<div class="card" style="margin-bottom: 24px;">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🔍</span> Inkomende HTTP Request Headers
|
||||
</div>
|
||||
<button class="btn btn-secondary btn-sm" onclick="copyHeaders()">📋 Kopieer Headers</button>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Headers zoals ontvangen door de webserver voor de huidige verbinding van client <?= htmlspecialchars($clientIp); ?>.
|
||||
</p>
|
||||
<div class="terminal-box" id="headers-box"><?php
|
||||
if (!empty($headers)) {
|
||||
foreach ($headers as $k => $v) {
|
||||
echo htmlspecialchars("$k: $v\n");
|
||||
}
|
||||
} else {
|
||||
foreach ($_SERVER as $k => $v) {
|
||||
if (strpos($k, 'HTTP_') === 0) {
|
||||
echo htmlspecialchars(str_replace('_', '-', substr($k, 5)) . ": $v\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
</div>
|
||||
|
||||
<!-- Tool 5: Realtime Crypto & String Transformer -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🔐</span> Realtime Crypto & String Transformer
|
||||
</div>
|
||||
<span class="badge-pill">PHP & JS Dual Engine</span>
|
||||
<span class="badge-pill">Dual Engine</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Converteer strings direct naar verschillende hashing formaten, base64 encoding en timestamp berekeningen.
|
||||
Converteer strings direct naar MD5, SHA-256 en Base64 formaten.
|
||||
</p>
|
||||
|
||||
<div style="display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap;">
|
||||
<div style="display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap;">
|
||||
<input type="text" id="trans-input" value="WebenPCStudio 2026 Git Testdrive"
|
||||
style="flex: 1; min-width: 260px; background: rgba(0,0,0,0.4); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 10px 14px; color: #fff; font-size: 0.9rem; outline: none;"
|
||||
style="flex: 1; min-width: 260px; background: rgba(0,0,0,0.3); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 10px 14px; color: var(--text-main); font-size: 0.9rem; outline: none;"
|
||||
placeholder="Typ invoertekst..." oninput="updateTransforms()">
|
||||
<button class="btn btn-secondary" onclick="insertCurrentEpoch()">⏱️ Epoch Nu</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="insertCurrentEpoch()">⏱️ Epoch Nu</button>
|
||||
</div>
|
||||
|
||||
<div class="grid-3" style="margin-bottom: 0;">
|
||||
@@ -252,7 +349,40 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
|
||||
<!-- Script Logic -->
|
||||
<script>
|
||||
// 1. Outbound Ping via PHP cURL
|
||||
// 1. DNS Record Lookup
|
||||
async function runDnsLookup() {
|
||||
const btn = document.getElementById('btn-dns');
|
||||
const domain = document.getElementById('dns-input').value.trim();
|
||||
const resBox = document.getElementById('dns-results');
|
||||
|
||||
if (!domain) return;
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Querying...';
|
||||
resBox.textContent = `DNS records opzoeken voor ${domain}...`;
|
||||
|
||||
try {
|
||||
const res = await fetch(`tools.php?action=dns_lookup&domain=${encodeURIComponent(domain)}&t=${Date.now()}`);
|
||||
const data = await res.json();
|
||||
|
||||
if (data.status === 'success' && data.records.length > 0) {
|
||||
let out = `[DNS RECORDS VOOR: ${data.domain}]\n`;
|
||||
out += `Totaal gevonden: ${data.count} records\n\n`;
|
||||
data.records.forEach(r => {
|
||||
out += `${r.type.padEnd(8)} ${r.value.padEnd(36)} (TTL: ${r.ttl}s)\n`;
|
||||
});
|
||||
resBox.textContent = out;
|
||||
} else {
|
||||
resBox.textContent = `Geen DNS records gevonden voor ${domain}.`;
|
||||
}
|
||||
} catch (err) {
|
||||
resBox.textContent = 'DNS Lookup fout: ' + err.message;
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Query DNS';
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Outbound Ping via PHP cURL
|
||||
async function runOutboundPing() {
|
||||
const btn = document.getElementById('btn-ping');
|
||||
const target = document.getElementById('ping-target').value;
|
||||
@@ -286,7 +416,7 @@ $sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd'
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Realtime Hashing & Transforms
|
||||
// 3. Realtime Hashing & Transforms
|
||||
async function sha256(msg) {
|
||||
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(msg));
|
||||
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
|
||||
Reference in New Issue
Block a user