/** * SEO Handler for V-Card * Proxies social media crawlers to the backend sharer while maintaining the frontend domain. */ // Final Security Headers header("X-Frame-Options: SAMEORIGIN"); header("X-Content-Type-Options: nosniff"); header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload"); header("Referrer-Policy: strict-origin-when-cross-origin"); header("Permissions-Policy: geolocation=(), microphone=(), camera=(self)"); header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://be.vcardi.net https://www.gstatic.com https://www.google.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://be.vcardi.net https://www.gstatic.com https://www.google.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://be.vcardi.net https://v-card.nacerdev.com https://www.googleapis.com https://identitytoolkit.googleapis.com; frame-src 'self' https://www.google.com; frame-ancestors 'none'; form-action 'self'; object-src 'none'; base-uri 'self'; upgrade-insecure-requests;"); $qrCode = $_GET['qr_code'] ?? ''; if (empty($qrCode)) { // If no QR code, just serve the main app include 'index.html'; exit; } // Build the backend sharer URL // Note: Hardcoded to be.vcardi.net as per user's specific backend $backendUrl = "https://be.vcardi.net/share/" . $qrCode; // Fetch the HTML from the backend sharer $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $backendUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] . " (Proxy via c.vcardi.net)"); curl_setopt($ch, CURLOPT_TIMEOUT, 5); // Don't hang the request $html = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200 && !empty($html)) { // Return the relayed HTML which contains OpenGraph meta tags echo $html; } else { // Fallback to static index.html if backend is unreachable or returns error include 'index.html'; }