diff --git a/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx b/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx index f13287e..8af80ca 100644 --- a/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx +++ b/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx @@ -96,11 +96,26 @@ export default function VlessQrCard({ if (selectedNode) return selectedNode // 1. Try to use the node bound by root management (search in all nodes, including filtered ones) - if (boundNodeAddress && allNodes?.length) { - const matched = allNodes.find((node) => node.address === boundNodeAddress) + if (boundNodeAddress) { + const matched = (allNodes ?? []).find((node) => node.address === boundNodeAddress) if (matched) { return matched } + + // If we are in sandbox mode and API failed or node not found in list, create a synthetic fallback + if (allowSandboxFallbackNode) { + return { + name: 'Sandbox Node', + address: boundNodeAddress, + port: 443, + transport: 'tcp', + security: 'tls', + flow: 'xtls-rprx-vision', + // These templates are needed for URI generation if the API missed them + uri_scheme_tcp: 'vless://${UUID}@${DOMAIN}:${PORT}?encryption=none&flow=${FLOW}&security=tls&sni=${SNI}&fp=${FP}&type=tcp#${TAG}', + uri_scheme_xhttp: 'vless://${UUID}@${DOMAIN}:${PORT}?encryption=none&security=tls&sni=${SNI}&fp=${FP}&type=xhttp&mode=${MODE}&path=${PATH}#${TAG}', + } as VlessNode + } } // 2. Default to the first visible (non-filtered) node diff --git a/src/modules/extensions/builtin/user-center/routes/agent.tsx b/src/modules/extensions/builtin/user-center/routes/agent.tsx index 684f006..0fd16dd 100644 --- a/src/modules/extensions/builtin/user-center/routes/agent.tsx +++ b/src/modules/extensions/builtin/user-center/routes/agent.tsx @@ -125,6 +125,11 @@ export default function UserCenterAgentRoute() { } } + // Fallback if no nodes were returned by the API but we are in sandbox mode + if (isGuestSandboxReadOnly && boundNode && base.length === 0) { + return [boundNode] + } + return base }, [isGuestSandboxReadOnly, nodes, visibleNodes, normalizedEmail, boundAddress, boundNode])