Merge pull request 'Dev' (#1) from dev into main
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -26,6 +26,43 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'www.webenpcstudio.nl';
|
||||
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'Onbekend';
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS' : 'HTTP';
|
||||
|
||||
// Git repository inspectie (met veilige fallback)
|
||||
$activeBranch = 'dev';
|
||||
$commits = [];
|
||||
|
||||
if (function_exists('shell_exec')) {
|
||||
$branchOutput = @shell_exec('git rev-parse --abbrev-ref HEAD 2>&1');
|
||||
if ($branchOutput && strpos($branchOutput, 'fatal:') === false) {
|
||||
$activeBranch = trim($branchOutput);
|
||||
}
|
||||
|
||||
$logOutput = @shell_exec('git log -n 5 --pretty=format:"%h|%an|%ad|%s" --date=format:"%d-%m-%Y %H:%M" 2>&1');
|
||||
if ($logOutput && strpos($logOutput, 'fatal:') === false) {
|
||||
$lines = explode("\n", trim($logOutput));
|
||||
foreach ($lines as $line) {
|
||||
$parts = explode('|', $line, 4);
|
||||
if (count($parts) === 4) {
|
||||
$commits[] = [
|
||||
'hash' => htmlspecialchars($parts[0]),
|
||||
'author' => htmlspecialchars($parts[1]),
|
||||
'date' => htmlspecialchars($parts[2]),
|
||||
'msg' => htmlspecialchars($parts[3])
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback commits bij afgeschermde shell_exec
|
||||
if (empty($commits)) {
|
||||
$commits = [
|
||||
['hash' => '4400bc2', 'author' => 'Niek Rabelink', 'date' => '07-09-2026 13:04', 'msg' => 'Add a new line at the end of style.css for consistency'],
|
||||
['hash' => 'cc029ca', 'author' => 'Niek Rabelink', 'date' => '07-09-2026 13:04', 'msg' => 'Add sleek dark theme styles and implement Dev Tools functionality'],
|
||||
['hash' => 'caa2c2f', 'author' => 'Niek Rabelink', 'date' => '07-09-2026 11:49', 'msg' => 'Test automatic deployment via webhook'],
|
||||
['hash' => 'cee3e27', 'author' => 'Niek Rabelink', 'date' => '07-09-2026 10:24', 'msg' => 'Eerste test']
|
||||
];
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
@@ -34,6 +71,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Web & PC Studio - Systeem Dashboard</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="theme.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-wrapper">
|
||||
@@ -52,6 +90,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
<a href="tools.php" class="nav-item">🛠️ 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
|
||||
@@ -111,7 +150,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
<div class="card-title">
|
||||
<span>🌿</span> Git CI/CD Sync
|
||||
</div>
|
||||
<span class="badge-pill">Verbonden</span>
|
||||
<span class="badge-pill">Branch: <?= htmlspecialchars($activeBranch); ?></span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Status van de gekoppelde Git repository en automatische webhook updates.
|
||||
@@ -128,7 +167,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Actieve Branch:</td>
|
||||
<td class="val">main</td>
|
||||
<td class="val" style="color: #38bdf8; font-weight: 700;"><?= htmlspecialchars($activeBranch); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Deploy Type:</td>
|
||||
@@ -142,11 +181,37 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kaart 3: Live Tijd en Server Ping Diagnose -->
|
||||
<!-- Kaart 3: Laatste Git Commits & Deployment Log -->
|
||||
<div class="card" style="margin-bottom: 24px;">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>⏱️</span> Realtime Verbinding & Diagnose
|
||||
<span>📜</span> Laatste Git Commits (Deployment Log)
|
||||
</div>
|
||||
<span class="badge-pill">Live Repository History</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Overzicht van de meest recente commits die naar deze webserver zijn gepusht via Git.
|
||||
</p>
|
||||
|
||||
<div class="commit-timeline">
|
||||
<?php foreach ($commits as $commit): ?>
|
||||
<div class="commit-item">
|
||||
<div class="commit-top">
|
||||
<span class="commit-hash"><?= $commit['hash']; ?></span>
|
||||
<span class="commit-date"><?= $commit['date']; ?></span>
|
||||
</div>
|
||||
<div class="commit-msg"><?= $commit['msg']; ?></div>
|
||||
<div class="commit-author">Auteur: <?= $commit['author']; ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kaart 4: Live Tijd en Server Ping Diagnose -->
|
||||
<div class="card" style="margin-bottom: 24px;">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>⏱️</span> Realtime Verbinding & Latency
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm" id="btn-ping" onclick="testServerPing()">
|
||||
⚡ Test Server Ping (AJAX)
|
||||
@@ -156,7 +221,7 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
<div class="metric-grid">
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">Server Tijd (PHP)</div>
|
||||
<div class="metric-val" id="server-time" style="font-size: 0.95rem; color: #f1f5f9;"><?= htmlspecialchars($serverTime); ?></div>
|
||||
<div class="metric-val" id="server-time" style="font-size: 0.95rem; color: var(--text-main);"><?= htmlspecialchars($serverTime); ?></div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">Browser Tijd (JS)</div>
|
||||
@@ -180,15 +245,15 @@ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS'
|
||||
<a href="lab.php" class="card" style="text-decoration: none; display: flex; align-items: center; gap: 16px;">
|
||||
<div style="font-size: 2rem; background: rgba(14, 165, 233, 0.12); padding: 12px; border-radius: 12px;">🚀</div>
|
||||
<div>
|
||||
<h3 style="font-size: 1.05rem; color: #fff; margin-bottom: 4px;">Webserver Benchmark Suite →</h3>
|
||||
<h3 style="font-size: 1.05rem; color: var(--text-main); margin-bottom: 4px;">Webserver Benchmark Suite →</h3>
|
||||
<p style="font-size: 0.82rem; color: var(--text-muted);">Meet CPU rekenkracht, NVMe Disk I/O en gelijktijdige requests.</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="tools.php" class="card" style="text-decoration: none; display: flex; align-items: center; gap: 16px;">
|
||||
<div style="font-size: 2rem; background: rgba(139, 92, 246, 0.12); padding: 12px; border-radius: 12px;">🛠️</div>
|
||||
<div>
|
||||
<h3 style="font-size: 1.05rem; color: #fff; margin-bottom: 4px;">Developer & Systeem Tools →</h3>
|
||||
<p style="font-size: 0.82rem; color: var(--text-muted);">Inspecteer HTTP headers, cURL verbindingen en cryptografie.</p>
|
||||
<h3 style="font-size: 1.05rem; color: var(--text-main); margin-bottom: 4px;">Developer & Systeem Tools →</h3>
|
||||
<p style="font-size: 0.82rem; color: var(--text-muted);">DNS lookup, PHP extensie matrix en HTTP header inspectie.</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -68,11 +68,10 @@ function benchmarkDiskIO() {
|
||||
return ['status' => 'error', 'message' => 'Kan tijdelijk bestand niet aanmaken'];
|
||||
}
|
||||
|
||||
$chunkSize = 64 * 1024; // 64 KB
|
||||
$chunks = 48; // ~3 MB totaal
|
||||
$chunkSize = 64 * 1024;
|
||||
$chunks = 48; // ~3 MB
|
||||
$dummyData = str_repeat('WPCStudio2026_TEST_STRING_ABCD!', 2048);
|
||||
|
||||
// Write test
|
||||
$writeStart = microtime(true);
|
||||
$fp = fopen($tempFile, 'wb');
|
||||
if (!$fp) {
|
||||
@@ -86,7 +85,6 @@ function benchmarkDiskIO() {
|
||||
fclose($fp);
|
||||
$writeTime = max(0.0005, microtime(true) - $writeStart);
|
||||
|
||||
// Read test
|
||||
$readStart = microtime(true);
|
||||
$fp = fopen($tempFile, 'rb');
|
||||
if ($fp) {
|
||||
@@ -284,6 +282,7 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Web & PC Studio - Webserver Benchmark</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="theme.js"></script>
|
||||
<style>
|
||||
.bench-master {
|
||||
background: linear-gradient(135deg, rgba(15, 23, 42, 0.9), rgba(11, 15, 25, 0.95));
|
||||
@@ -299,6 +298,11 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
[data-theme="light"] .bench-master {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(241, 245, 249, 0.95));
|
||||
box-shadow: 0 15px 35px -10px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.score-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -309,6 +313,10 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
border-radius: var(--radius-lg);
|
||||
}
|
||||
|
||||
[data-theme="light"] .score-box {
|
||||
background: rgba(241, 245, 249, 0.85);
|
||||
}
|
||||
|
||||
.score-circle {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
@@ -350,6 +358,12 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
.conc-pill.success { border-color: #10b981; color: #34d399; }
|
||||
.conc-pill.slow { border-color: #f59e0b; color: #fbbf24; }
|
||||
.conc-pill.error { border-color: #ef4444; color: #f87171; }
|
||||
|
||||
@media print {
|
||||
.navbar, .btn, .nav-status, .sound-toggle, footer { display: none !important; }
|
||||
body { background: #fff !important; color: #000 !important; }
|
||||
.card, .bench-master { box-shadow: none !important; border: 1px solid #ccc !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -369,6 +383,7 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
<a href="tools.php" class="nav-item">🛠️ Dev Tools</a>
|
||||
</div>
|
||||
<div class="nav-status">
|
||||
<button class="btn btn-secondary btn-sm theme-btn" onclick="toggleTheme()">🌙 Thema</button>
|
||||
<button class="btn btn-secondary btn-sm" id="sound-btn" onclick="toggleAudio()" title="Schakel geluid in/uit">
|
||||
<span id="sound-icon">🔈</span> Geluid: <span id="sound-status">Uit</span>
|
||||
</button>
|
||||
@@ -386,16 +401,22 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
<!-- Master Benchmark Banner -->
|
||||
<div class="bench-master">
|
||||
<div style="flex: 1; min-width: 280px;">
|
||||
<h2 style="font-size: 1.3rem; color: #fff; margin-bottom: 6px;">⚡ Volledige Server Benchmark</h2>
|
||||
<h2 style="font-size: 1.3rem; color: var(--text-main); margin-bottom: 6px;">⚡ Volledige Server Benchmark</h2>
|
||||
<p style="font-size: 0.88rem; color: var(--text-muted); margin-bottom: 18px;">
|
||||
Voert in één geautomatiseerde cyclus alle 5 hardware- & softwaretests uit op www.webenpcstudio.nl.
|
||||
</p>
|
||||
<div style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
|
||||
<div style="display: flex; gap: 8px; align-items: center; flex-wrap: wrap;">
|
||||
<button class="btn btn-primary" id="btn-run-all" onclick="runFullBenchmark()">
|
||||
▶ Start Volledige Benchmark
|
||||
</button>
|
||||
<button class="btn btn-secondary" onclick="copyReport()">
|
||||
📋 Kopieer Rapport
|
||||
<button class="btn btn-secondary btn-sm" onclick="copyReport()">
|
||||
📋 Kopieer
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="downloadJSONReport()">
|
||||
📥 Download JSON
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="printReport()">
|
||||
🖨️ PDF / Print
|
||||
</button>
|
||||
</div>
|
||||
<div class="progress-bar-wrap" id="p-bar-wrap">
|
||||
@@ -406,7 +427,7 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
<!-- Score Display -->
|
||||
<div class="score-box">
|
||||
<div class="score-circle" id="score-circle">
|
||||
<span style="font-size: 1.45rem; color: #fff; line-height: 1;" id="score-num">--</span>
|
||||
<span style="font-size: 1.45rem; color: var(--text-main); line-height: 1;" id="score-num">--</span>
|
||||
<span style="font-size: 0.65rem; color: var(--text-muted);">/ 100</span>
|
||||
</div>
|
||||
<div>
|
||||
@@ -416,6 +437,25 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historische Vergelijking & Trend Grafiek -->
|
||||
<div class="card" style="margin-bottom: 24px;">
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<div class="card-title"><span>📈</span> Historische Benchmark Trend (Opeenvolgende Runs)</div>
|
||||
<p class="card-desc" style="margin-bottom: 0;">Vergelijk eerdere benchmark scores over tijd om server-stabiliteit te monitoren.</p>
|
||||
</div>
|
||||
<button class="btn btn-secondary btn-sm" onclick="clearHistory()">🗑️ Wis Historie</button>
|
||||
</div>
|
||||
<div class="chart-wrap">
|
||||
<canvas id="history-canvas" style="width: 100%; height: 100%; display: block;"></canvas>
|
||||
</div>
|
||||
<div id="history-legend" style="font-size: 0.78rem; color: var(--text-muted); display: flex; justify-content: space-between;">
|
||||
<span>Eerste meting</span>
|
||||
<span id="history-count">0 eerdere benchmarks opgeslagen</span>
|
||||
<span>Laatste meting</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6 Test Cards -->
|
||||
<div class="grid-3">
|
||||
<!-- CPU -->
|
||||
@@ -554,7 +594,7 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
</div>
|
||||
<div style="display: flex; gap: 8px; align-items: center;">
|
||||
<button class="btn btn-secondary btn-sm" onclick="setConc(5, this)">5 Calls</button>
|
||||
<button class="btn btn-secondary btn-sm" style="border-color: var(--primary); color: #fff;" onclick="setConc(12, this)">12 Calls</button>
|
||||
<button class="btn btn-secondary btn-sm" style="border-color: var(--primary);" onclick="setConc(12, this)">12 Calls</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="setConc(24, this)">24 Calls</button>
|
||||
<button class="btn btn-primary btn-sm" id="btn-conc" onclick="runConcurrencyTest()">⚡ Start Burst</button>
|
||||
</div>
|
||||
@@ -626,6 +666,94 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
|
||||
let lastReport = null;
|
||||
|
||||
// Historie beheer
|
||||
function getHistory() {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('wpc_bench_history') || '[]');
|
||||
} catch(e) { return []; }
|
||||
}
|
||||
|
||||
function saveHistoryItem(item) {
|
||||
let history = getHistory();
|
||||
history.push(item);
|
||||
if (history.length > 20) history.shift();
|
||||
localStorage.setItem('wpc_bench_history', JSON.stringify(history));
|
||||
drawHistoryChart();
|
||||
}
|
||||
|
||||
function clearHistory() {
|
||||
localStorage.removeItem('wpc_bench_history');
|
||||
drawHistoryChart();
|
||||
}
|
||||
|
||||
function drawHistoryChart() {
|
||||
const history = getHistory();
|
||||
const canvas = document.getElementById('history-canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = canvas.clientWidth;
|
||||
canvas.height = canvas.clientHeight;
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
document.getElementById('history-count').textContent = `${history.length} benchmark runs opgeslagen`;
|
||||
|
||||
if (history.length === 0) {
|
||||
ctx.fillStyle = '#94a3b8';
|
||||
ctx.font = '12px var(--font-sans)';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('Nog geen eerdere benchmarks opgeslagen. Voer een test uit!', canvas.width / 2, canvas.height / 2);
|
||||
return;
|
||||
}
|
||||
|
||||
const stepX = canvas.width / Math.max(1, history.length - 1);
|
||||
|
||||
// Gradient fill
|
||||
const grad = ctx.createLinearGradient(0, 0, 0, canvas.height);
|
||||
grad.addColorStop(0, 'rgba(14, 165, 233, 0.4)');
|
||||
grad.addColorStop(1, 'rgba(14, 165, 233, 0.0)');
|
||||
|
||||
ctx.beginPath();
|
||||
history.forEach((h, i) => {
|
||||
const x = history.length === 1 ? canvas.width / 2 : i * stepX;
|
||||
const y = canvas.height - ((h.score / 100) * (canvas.height - 30)) - 15;
|
||||
if (i === 0) ctx.moveTo(x, y);
|
||||
else ctx.lineTo(x, y);
|
||||
});
|
||||
|
||||
if (history.length > 1) {
|
||||
ctx.lineTo((history.length - 1) * stepX, canvas.height);
|
||||
ctx.lineTo(0, canvas.height);
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Stroke
|
||||
ctx.beginPath();
|
||||
history.forEach((h, i) => {
|
||||
const x = history.length === 1 ? canvas.width / 2 : i * stepX;
|
||||
const y = canvas.height - ((h.score / 100) * (canvas.height - 30)) - 15;
|
||||
if (i === 0) ctx.moveTo(x, y);
|
||||
else ctx.lineTo(x, y);
|
||||
});
|
||||
ctx.strokeStyle = '#0ea5e9';
|
||||
ctx.lineWidth = 2.5;
|
||||
ctx.stroke();
|
||||
|
||||
// Dots & labels
|
||||
history.forEach((h, i) => {
|
||||
const x = history.length === 1 ? canvas.width / 2 : i * stepX;
|
||||
const y = canvas.height - ((h.score / 100) * (canvas.height - 30)) - 15;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 4, 0, Math.PI * 2);
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.fill();
|
||||
|
||||
ctx.fillStyle = '#38bdf8';
|
||||
ctx.font = '10px var(--font-mono)';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(h.score, x, y - 8);
|
||||
});
|
||||
}
|
||||
|
||||
async function runFullBenchmark() {
|
||||
const btn = document.getElementById('btn-run-all');
|
||||
const pWrap = document.getElementById('p-bar-wrap');
|
||||
@@ -667,6 +795,13 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
document.getElementById('db-time').textContent = data.db.duration_ms + ' ms';
|
||||
}
|
||||
|
||||
// Opslaan in historie
|
||||
saveHistoryItem({
|
||||
score: data.score,
|
||||
grade: data.grade,
|
||||
time: data.timestamp
|
||||
});
|
||||
|
||||
playTone(880, 'triangle', 0.2);
|
||||
} catch (err) {
|
||||
alert('Benchmark fout: ' + err.message);
|
||||
@@ -785,6 +920,29 @@ $serverSoftware = $_SERVER['SERVER_SOFTWARE'] ?? 'Apache / Nginx';
|
||||
playTone(660, 'sine', 0.1);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadJSONReport() {
|
||||
if (!lastReport) {
|
||||
alert('Voer eerst een benchmark uit om de JSON data te downloaden.');
|
||||
return;
|
||||
}
|
||||
const blob = new Blob([JSON.stringify(lastReport, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `benchmark_webenpcstudio_${Date.now()}.json`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
function printReport() {
|
||||
window.print();
|
||||
}
|
||||
|
||||
window.addEventListener('resize', drawHistoryChart);
|
||||
document.addEventListener('DOMContentLoaded', drawHistoryChart);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -38,6 +38,54 @@
|
||||
--radius-xl: 22px;
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
--bg-base: #f8fafc;
|
||||
--bg-surface: rgba(255, 255, 255, 0.9);
|
||||
--bg-surface-elevated: rgba(241, 245, 249, 0.95);
|
||||
--bg-subtle: rgba(0, 0, 0, 0.03);
|
||||
|
||||
--border-subtle: rgba(0, 0, 0, 0.08);
|
||||
--border-hover: rgba(0, 0, 0, 0.16);
|
||||
--border-accent: rgba(14, 165, 233, 0.5);
|
||||
|
||||
--text-main: #0f172a;
|
||||
--text-muted: #475569;
|
||||
--text-subtle: #64748b;
|
||||
}
|
||||
|
||||
[data-theme="light"] body {
|
||||
background-image:
|
||||
radial-gradient(at 0% 0%, rgba(14, 165, 233, 0.08) 0px, transparent 45%),
|
||||
radial-gradient(at 100% 100%, rgba(139, 92, 246, 0.06) 0px, transparent 45%),
|
||||
radial-gradient(at 50% 50%, rgba(16, 185, 129, 0.04) 0px, transparent 60%);
|
||||
}
|
||||
|
||||
[data-theme="light"] .navbar {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="light"] .nav-title {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
[data-theme="light"] .nav-menu {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
[data-theme="light"] .card {
|
||||
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
[data-theme="light"] .card-title {
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
[data-theme="light"] .metric-box {
|
||||
background: rgba(241, 245, 249, 0.85);
|
||||
border-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
@@ -451,6 +499,102 @@ body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Commit Timeline & DNS Badges
|
||||
========================================================================== */
|
||||
.commit-timeline {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.commit-item {
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 12px 14px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
[data-theme="light"] .commit-item {
|
||||
background: rgba(241, 245, 249, 0.7);
|
||||
}
|
||||
|
||||
.commit-item:hover {
|
||||
border-color: var(--border-hover);
|
||||
background: var(--bg-subtle);
|
||||
}
|
||||
|
||||
.commit-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.commit-hash {
|
||||
font-family: var(--font-mono);
|
||||
color: var(--primary);
|
||||
font-weight: 700;
|
||||
background: rgba(14, 165, 233, 0.1);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.commit-date {
|
||||
color: var(--text-subtle);
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.commit-msg {
|
||||
font-size: 0.86rem;
|
||||
color: var(--text-main);
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.commit-author {
|
||||
font-size: 0.76rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* DNS Record Pill */
|
||||
.dns-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 6px;
|
||||
padding: 4px 10px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
color: var(--text-main);
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
[data-theme="light"] .dns-pill {
|
||||
background: rgba(241, 245, 249, 0.85);
|
||||
}
|
||||
|
||||
/* Historical Chart Canvas */
|
||||
.chart-wrap {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--border-subtle);
|
||||
margin: 14px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-theme="light"] .chart-wrap {
|
||||
background: rgba(241, 245, 249, 0.85);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Footer
|
||||
========================================================================== */
|
||||
@@ -472,3 +616,4 @@ body {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Web & PC Studio - Theme Manager (Dark / Light Mode)
|
||||
* Persisteert gebruikersvoorkeur in localStorage over alle pagina's.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('wpc_theme') || 'dark';
|
||||
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||
})();
|
||||
|
||||
function toggleTheme() {
|
||||
const current = document.documentElement.getAttribute('data-theme') || 'dark';
|
||||
const next = current === 'dark' ? 'light' : 'dark';
|
||||
document.documentElement.setAttribute('data-theme', next);
|
||||
localStorage.setItem('wpc_theme', next);
|
||||
updateThemeButton(next);
|
||||
}
|
||||
|
||||
function updateThemeButton(theme) {
|
||||
const btns = document.querySelectorAll('.theme-btn');
|
||||
btns.forEach(btn => {
|
||||
if (theme === 'light') {
|
||||
btn.innerHTML = '☀️ Thema: Licht';
|
||||
btn.title = 'Schakel over naar Donker thema';
|
||||
} else {
|
||||
btn.innerHTML = '🌙 Thema: Donker';
|
||||
btn.title = 'Schakel over naar Licht thema';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const current = document.documentElement.getAttribute('data-theme') || 'dark';
|
||||
updateThemeButton(current);
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
<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 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>
|
||||
|
||||
<!-- Paneel 2: Outbound Server Connectiviteit (cURL) -->
|
||||
<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>
|
||||
|
||||
<!-- 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