fix(qr): Use raw URI for X-Ray QR codes to ensure compatibility
This commit is contained in:
+16
-29
@@ -264,7 +264,8 @@ 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'] ?? [];
|
||||||
@@ -388,7 +389,10 @@ class VpnClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure client_id (UUID) for X-Ray
|
// Ensure client_id (UUID) for X-Ray
|
||||||
if (empty($vars['client_id']) && (stripos($slug, 'xray') !== false || stripos($slug, 'vless') !== false)) {
|
if (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);
|
||||||
@@ -400,12 +404,16 @@ 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("Failed to add client to server: " . $e->getMessage());
|
error_log("DEBUG: 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) : '';
|
||||||
@@ -959,32 +967,11 @@ class VpnClient
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Check for X-Ray VLESS
|
// Check for X-Ray VLESS
|
||||||
if (strpos($config, 'vless://') === 0) {
|
// Check for X-Ray VLESS, VMess, Shadowsocks (Standard URI schemes)
|
||||||
// Parse VLESS URI
|
if (strpos($config, 'vless://') === 0 || strpos($config, 'vmess://') === 0 || strpos($config, 'ss://') === 0) {
|
||||||
$parsed = parse_url($config);
|
// Generate a standard QR code containing just the URI string.
|
||||||
// Allow missing user (UUID) and port for partial configs
|
// This is compatible with Amnezia VPB, v2rayNG, and other standard clients.
|
||||||
if ($parsed && isset($parsed['host'])) {
|
return QrUtil::pngBase64($config);
|
||||||
$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
|
||||||
|
|||||||
Reference in New Issue
Block a user