Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
165 lines
5.3 KiB
PHP
165 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\QrCode\QrCodeGenerator;
|
|
use App\Framework\QrCode\QrCodeRenderer;
|
|
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
|
|
use App\Framework\QrCode\ValueObjects\EncodingMode;
|
|
|
|
echo "=== Analyzing Problematic QR Code ===\n\n";
|
|
|
|
// Parse the SVG to understand what data it contains
|
|
// The SVG shows a 580x580 canvas with 20x20 modules
|
|
// Quiet zone: 80px = 4 modules
|
|
// Actual matrix: 29x29 modules? No, that doesn't match
|
|
// Let's calculate: 580 - 2*80 = 420, so 420/20 = 21 modules
|
|
// So it's Version 1 (21x21 modules)
|
|
|
|
echo "SVG Analysis:\n";
|
|
echo " Canvas size: 580x580\n";
|
|
echo " Module size: 20x20\n";
|
|
echo " Quiet zone: 80px (4 modules)\n";
|
|
echo " Matrix size: (580-160)/20 = 21x21 (Version 1)\n\n";
|
|
|
|
// Generate a QR code with same parameters
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber(1),
|
|
errorCorrectionLevel: ErrorCorrectionLevel::M,
|
|
encodingMode: EncodingMode::BYTE
|
|
);
|
|
|
|
// Try to decode what data might be in the problematic QR code
|
|
// We'll generate our own and compare
|
|
$testData = 'HELLO WORLD'; // Standard test
|
|
$matrix = QrCodeGenerator::generate($testData, $config);
|
|
|
|
echo "Generated QR Code:\n";
|
|
echo " Data: '{$testData}'\n";
|
|
echo " Version: 1\n";
|
|
echo " Error Correction: M\n";
|
|
echo " Matrix size: {$matrix->getSize()}x{$matrix->getSize()}\n\n";
|
|
|
|
// Check critical areas
|
|
echo "=== Critical Area Checks ===\n\n";
|
|
|
|
// 1. Format Information (horizontal)
|
|
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
|
|
$formatH = '';
|
|
foreach ($formatCols as $col) {
|
|
$formatH .= $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0';
|
|
}
|
|
echo "Format Info (Horizontal): {$formatH}\n";
|
|
|
|
// 2. Format Information (vertical)
|
|
$formatRows = [20, 19, 18, 17, 16, 15, 14, 8, 7, 5, 4, 3, 2, 1, 0];
|
|
$formatV = '';
|
|
foreach ($formatRows as $row) {
|
|
$formatV .= $matrix->getModuleAt($row, 8)->isDark() ? '1' : '0';
|
|
}
|
|
echo "Format Info (Vertical): {$formatV}\n";
|
|
|
|
if ($formatH === $formatV) {
|
|
echo "✅ Format info matches\n\n";
|
|
} else {
|
|
echo "❌ Format info doesn't match!\n";
|
|
echo "This is a CRITICAL error - QR code won't scan!\n\n";
|
|
}
|
|
|
|
// 3. Check finder patterns
|
|
echo "=== Finder Pattern Check ===\n";
|
|
$finderPositions = [
|
|
['name' => 'Top-Left', 'row' => 0, 'col' => 0],
|
|
['name' => 'Top-Right', 'row' => 0, 'col' => 14],
|
|
['name' => 'Bottom-Left', 'row' => 14, 'col' => 0],
|
|
];
|
|
|
|
foreach ($finderPositions as $finder) {
|
|
$pattern = '';
|
|
for ($r = 0; $r < 7; $r++) {
|
|
for ($c = 0; $c < 7; $c++) {
|
|
$pattern .= $matrix->getModuleAt($finder['row'] + $r, $finder['col'] + $c)->isDark() ? '1' : '0';
|
|
}
|
|
}
|
|
$expected = '1111111100000110111110110111110110111110110000011111111';
|
|
|
|
if ($pattern === $expected) {
|
|
echo "✅ {$finder['name']} finder pattern correct\n";
|
|
} else {
|
|
echo "❌ {$finder['name']} finder pattern incorrect\n";
|
|
echo " Got: {$pattern}\n";
|
|
echo " Expected: {$expected}\n";
|
|
}
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
// 4. Generate SVG with same parameters
|
|
$renderer = new QrCodeRenderer();
|
|
$svg = $renderer->renderSvg($matrix);
|
|
|
|
// Check module size and quiet zone in generated SVG
|
|
if (preg_match('/<rect x="(\d+\.?\d*)" y="(\d+\.?\d*)" width="(\d+\.?\d*)" height="(\d+\.?\d*)" fill="white"/', $svg, $matches)) {
|
|
$quietZone = (float)$matches[1];
|
|
$moduleSize = (float)$matches[3];
|
|
echo "Generated SVG:\n";
|
|
echo " Quiet zone: {$quietZone}px\n";
|
|
echo " Module size: {$moduleSize}px\n";
|
|
echo " Total size: " . ($matrix->getSize() * $moduleSize + 2 * $quietZone) . "px\n\n";
|
|
}
|
|
|
|
// 5. Check if there's a dark module (Version 1 requirement)
|
|
$darkModuleRow = 4 * 1 + 9; // 13 for version 1
|
|
$darkModuleCol = 8;
|
|
$hasDarkModule = $matrix->getModuleAt($darkModuleRow, $darkModuleCol)->isDark();
|
|
echo "Dark module (row {$darkModuleRow}, col {$darkModuleCol}): " . ($hasDarkModule ? "✅ Present" : "❌ Missing") . "\n\n";
|
|
|
|
// 6. Output comparison SVG
|
|
$outputDir = __DIR__ . '/test-qrcodes';
|
|
$comparisonFile = $outputDir . '/comparison-correct.svg';
|
|
file_put_contents($comparisonFile, $svg);
|
|
echo "✅ Saved comparison QR code: {$comparisonFile}\n";
|
|
echo " Compare this with the problematic QR code to find differences.\n\n";
|
|
|
|
// 7. Check data placement
|
|
echo "=== Data Placement Check ===\n";
|
|
echo "Checking if data bits are placed correctly...\n";
|
|
|
|
// Count dark modules in data area
|
|
$dataAreaDark = 0;
|
|
$dataAreaTotal = 0;
|
|
for ($row = 0; $row < $matrix->getSize(); $row++) {
|
|
for ($col = 0; $col < $matrix->getSize(); $col++) {
|
|
// Skip function patterns
|
|
if (
|
|
($row <= 8 && $col <= 8) ||
|
|
($row <= 7 && $col >= 13) ||
|
|
($row >= 13 && $col <= 7) ||
|
|
$row === 6 || $col === 6
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
$dataAreaTotal++;
|
|
if ($matrix->getModuleAt($row, $col)->isDark()) {
|
|
$dataAreaDark++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "Data area: {$dataAreaDark} dark / {$dataAreaTotal} total modules\n";
|
|
$darkRatio = $dataAreaDark / $dataAreaTotal;
|
|
echo "Dark ratio: " . number_format($darkRatio * 100, 2) . "%\n";
|
|
|
|
if ($darkRatio > 0.3 && $darkRatio < 0.7) {
|
|
echo "✅ Dark ratio is reasonable (should be ~40-60%)\n";
|
|
} else {
|
|
echo "⚠️ Dark ratio seems unusual\n";
|
|
}
|
|
|
|
|