prepare("SELECT * FROM system_license WHERE status = 'active' LIMIT 1"); $stmt->execute(); $license = $stmt->fetch(); if (!$license) return false; // 1. Verify fingerprint matches (Physical Protection) if ($license['fingerprint'] !== self::getFingerprint()) { return false; } // 2. Periodic Remote Validation (e.g., every 7 days) // This ensures if you disable a key on your server, the client will stop working. $last_check = strtotime($license['activated_at']); // In real use, store 'last_verified_at' if (time() - $last_check > (7 * 24 * 60 * 60)) { // It's been more than 7 days, let's re-verify $res = self::callRemoteApi('/verify', [ 'license_key' => $license['license_key'], 'fingerprint' => $license['fingerprint'], 'token' => $license['activation_token'] ]); if (!$res['success']) { db()->exec("UPDATE system_license SET status = 'suspended'"); return false; } // Update last verified timestamp db()->exec("UPDATE system_license SET activated_at = NOW()"); } return true; } /** * Attempts to activate the product online. */ public static function activate($license_key) { $license_key = trim($license_key); $fingerprint = self::getFingerprint(); // Call remote API for real validation $response = self::callRemoteApi('/activate', [ 'license_key' => $license_key, 'fingerprint' => $fingerprint, 'domain' => $_SERVER['HTTP_HOST'] ?? 'unknown', 'product' => 'Flatlogic Admin Panel' ]); if (!$response['success']) { return ['success' => false, 'error' => $response['error'] ?? 'Remote activation failed.']; } require_once __DIR__ . '/../db/config.php'; // Clear previous pending/failed attempts db()->exec("DELETE FROM system_license"); $stmt = db()->prepare("INSERT INTO system_license (license_key, fingerprint, status, activated_at, activation_token) VALUES (?, ?, 'active', NOW(), ?)"); $token = $response['activation_token'] ?? bin2hex(random_bytes(32)); $stmt->execute([$license_key, $fingerprint, $token]); return ['success' => true]; } /** * Remote API Caller */ private static function callRemoteApi($endpoint, $params) { // In a real production environment, this would hit your licensing server. // For this demonstration, we simulate the request logic. $url = self::$remote_api_url . $endpoint; /* // Real implementation would look like this: $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); $resp = curl_exec($ch); curl_close($ch); $data = json_decode($resp, true); return $data; */ // SIMULATION: If the key starts with 'FLAT-' (case-insensitive), we treat it as valid. $clean_key = strtoupper(trim($params['license_key'] ?? '')); if (strpos($clean_key, 'FLAT-') === 0) { // Check if it's a verification request if ($endpoint === '/verify') { return ['success' => true]; } return [ 'success' => true, 'activation_token' => hash('sha256', $params['license_key'] . $params['fingerprint'] . 'SECRET_SALT') ]; } return [ 'success' => false, 'error' => 'License key invalid or expired. Please contact support.' ]; } }