fix(qr): Pass raw VLESS URI in last_config without JSON wrapper

This commit is contained in:
infosave2007
2026-01-24 14:50:55 +03:00
parent 4554a77033
commit 1018f96fc4
2 changed files with 31 additions and 18 deletions
+2 -2
View File
@@ -439,8 +439,8 @@ class QrUtil
[ [
'xray' => [ 'xray' => [
'isThirdPartyConfig' => true, 'isThirdPartyConfig' => true,
// Wrap the raw VLESS URI in a "config" field inside last_config // Pass raw VLESS URI directly, without JSON wrapper
'last_config' => json_encode(['config' => $rawConfig], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'last_config' => $rawConfig,
'port' => (string) $port, 'port' => (string) $port,
'transport_proto' => 'tcp' 'transport_proto' => 'tcp'
], ],
+29 -16
View File
@@ -264,8 +264,7 @@ class VpnClient
if (is_array($clients) && !empty($clients)) { if (is_array($clients) && !empty($clients)) {
$cid = $clients[0]['id'] ?? null; $cid = $clients[0]['id'] ?? null;
if (is_string($cid) && $cid !== '' && empty($vars['client_id'])) { if (is_string($cid) && $cid !== '' && empty($vars['client_id'])) {
// $vars['client_id'] = $cid; $vars['client_id'] = $cid;
// DO NOT reuse existing ID. We want to create a NEW client.
} }
} }
$stream = $inbounds[0]['streamSettings'] ?? []; $stream = $inbounds[0]['streamSettings'] ?? [];
@@ -389,10 +388,7 @@ class VpnClient
} }
// Ensure client_id (UUID) for X-Ray // Ensure client_id (UUID) for X-Ray
if (stripos($slug, 'xray') !== false || stripos($slug, 'vless') !== false) { if (empty($vars['client_id']) && (stripos($slug, 'xray') !== false || stripos($slug, 'vless') !== false)) {
// Force clear any pre-existing ID from extras
unset($vars['client_id']);
$data = random_bytes(16); $data = random_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
@@ -404,16 +400,12 @@ class VpnClient
// We pass generic options. InstallProtocolManager will handle specific logic for 'add_client' phase. // We pass generic options. InstallProtocolManager will handle specific logic for 'add_client' phase.
// For xray-vless it uses builtin fallback in runScript. // For xray-vless it uses builtin fallback in runScript.
try { try {
error_log("DEBUG: Attempting to add client via IPM. Slug: " . ($protoRow['slug'] ?? 'N/A') . ", ClientUUID: " . ($vars['client_id'] ?? 'N/A'));
require_once __DIR__ . '/InstallProtocolManager.php'; require_once __DIR__ . '/InstallProtocolManager.php';
InstallProtocolManager::addClient($server, $protoRow, $vars); InstallProtocolManager::addClient($server, $protoRow, $vars);
error_log("DEBUG: IPM::addClient returned successfully");
} catch (Exception $e) { } catch (Exception $e) {
error_log("DEBUG: Failed to add client to server: " . $e->getMessage()); error_log("Failed to add client to server: " . $e->getMessage());
throw $e; throw $e;
} }
} else {
error_log("DEBUG: protoRow is empty, cannot call IPM::addClient");
} }
$config = $protoRow ? ProtocolService::generateProtocolOutput($protoRow, $vars) : ''; $config = $protoRow ? ProtocolService::generateProtocolOutput($protoRow, $vars) : '';
@@ -967,11 +959,32 @@ class VpnClient
try { try {
// Check for X-Ray VLESS // Check for X-Ray VLESS
// Check for X-Ray VLESS, VMess, Shadowsocks (Standard URI schemes) if (strpos($config, 'vless://') === 0) {
if (strpos($config, 'vless://') === 0 || strpos($config, 'vmess://') === 0 || strpos($config, 'ss://') === 0) { // Parse VLESS URI
// Generate a standard QR code containing just the URI string. $parsed = parse_url($config);
// This is compatible with Amnezia VPB, v2rayNG, and other standard clients. // Allow missing user (UUID) and port for partial configs
return QrUtil::pngBase64($config); if ($parsed && isset($parsed['host'])) {
$host = $parsed['host'];
$port = isset($parsed['port']) ? (int) $parsed['port'] : 443;
$clientId = $parsed['user'] ?? '';
$fragment = $parsed['fragment'] ?? '';
parse_str($parsed['query'] ?? '', $query);
$reality = null;
if (($query['security'] ?? '') === 'reality') {
$reality = [
'publicKey' => $query['pbk'] ?? '',
'serverName' => $query['sni'] ?? '',
'shortId' => $query['sid'] ?? '',
'fingerprint' => $query['fp'] ?? 'chrome'
];
}
// Use QrUtil to encode correct X-Ray payload
$payloadXray = QrUtil::encodeXrayPayload($host, $port, $clientId, $fragment, $reality, $config);
return QrUtil::pngBase64($payloadXray);
}
} }
// Fallback for WireGuard / default // Fallback for WireGuard / default