'error', 'message' => 'Method not allowed']); exit; } $ENCRYPTION_KEY = 'FiberID_DoorAccess_SecretKey_2026!'; $TOKEN_LIFETIME = 30; // seconds $MANIFEST_PATH = __DIR__ . '/custom_code_tokens.json'; // --- Clean expired tokens --- $tokens = []; if (file_exists($MANIFEST_PATH)) { $tokens = json_decode(file_get_contents($MANIFEST_PATH), true) ?: []; } $now = time(); foreach ($tokens as $k => $v) { if ($now > $v['expires_at']) { unset($tokens[$k]); } } // --- Rate limiting: max 1 token per 10 seconds per IP --- $clientIP = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; foreach ($tokens as $k => $v) { if (isset($v['ip']) && $v['ip'] === $clientIP && ($now - $v['created_at']) < 10) { echo json_encode(['status' => 'error', 'message' => 'Please wait before scanning again']); exit; } } // --- Generate new token --- $randomBytes = bin2hex(random_bytes(16)); $payload = json_encode([ 'ts' => $now, 'rand' => $randomBytes, 'src' => 'door_access' ]); $iv = random_bytes(16); $cipher = openssl_encrypt($payload, 'AES-256-CBC', $ENCRYPTION_KEY, 0, $iv); $token = rtrim(strtr(base64_encode($iv . '::' . $cipher), '+/', '-_'), '='); // Store token $tokens[$token] = [ 'created_at' => $now, 'expires_at' => $now + $TOKEN_LIFETIME, 'ip' => $clientIP ]; file_put_contents($MANIFEST_PATH, json_encode($tokens, JSON_PRETTY_PRINT)); echo json_encode([ 'status' => 'success', 'token' => $token ]);