diff --git a/src/app/api/auth/session/route.ts b/src/app/api/auth/session/route.ts index 4fbebac..b46a3a3 100644 --- a/src/app/api/auth/session/route.ts +++ b/src/app/api/auth/session/route.ts @@ -2,17 +2,9 @@ import { cookies } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; import { SESSION_COOKIE_NAME, clearSessionCookie } from "@lib/authGateway"; -import { - getAccountServiceApiBaseUrl, - getAccountServiceBaseUrl, -} from "@server/serviceConfig"; -import { - buildInternalServiceHeaders, - isServiceTokenConfigured, -} from "@server/internalServiceAuth"; +import { getAccountServiceApiBaseUrl } from "@server/serviceConfig"; const ACCOUNT_API_BASE = getAccountServiceApiBaseUrl(); -const ACCOUNT_BASE = getAccountServiceBaseUrl(); type AccountUser = { id?: string; @@ -48,13 +40,6 @@ type SessionResponse = { error?: string; }; -type SandboxGuestResponse = { - email?: string; - proxyUuid?: string; - proxyUuidExpiresAt?: string; - error?: string; -}; - function normalizeRole(role: unknown): string { if (typeof role !== "string") { return "user"; @@ -94,69 +79,10 @@ async function fetchSession(token: string, requestHost?: string | null) { } } -async function fetchSandboxGuest(): Promise { - if (!isServiceTokenConfigured()) { - return null; - } - - try { - const response = await fetch(`${ACCOUNT_BASE}/api/internal/sandbox/guest`, { - method: "GET", - headers: buildInternalServiceHeaders({ - Accept: "application/json", - }), - cache: "no-store", - }); - - if (!response.ok) { - return null; - } - - const payload = (await response - .json() - .catch(() => null)) as SandboxGuestResponse | null; - const proxyUuid = - typeof payload?.proxyUuid === "string" ? payload.proxyUuid.trim() : ""; - if (!proxyUuid) { - return null; - } - - const proxyUuidExpiresAt = - typeof payload?.proxyUuidExpiresAt === "string" && - payload.proxyUuidExpiresAt.trim().length > 0 - ? payload.proxyUuidExpiresAt.trim() - : undefined; - - // Shape this as a pseudo-session user for the Guest/Demo experience. - return { - id: proxyUuid, - uuid: proxyUuid, - proxyUuid, - proxyUuidExpiresAt, - name: "Guest user", - username: "guest", - email: "sandbox@svc.plus", - role: "guest", - groups: ["guest", "sandbox"], - permissions: ["read"], - readOnly: true, - tenantId: "guest-sandbox", - tenants: [{ id: "guest-sandbox", name: "Guest Sandbox", role: "guest" }], - mfaEnabled: false, - mfaPending: false, - }; - } catch (error) { - console.error("Sandbox guest session proxy failed", error); - return null; - } -} - export async function GET(request: NextRequest) { - void request; const token = (await cookies()).get(SESSION_COOKIE_NAME)?.value; if (!token) { - const sandboxGuest = await fetchSandboxGuest(); - return NextResponse.json({ user: sandboxGuest }); + return NextResponse.json({ user: null }); } const requestHost = request.headers.get("host"); diff --git a/src/lib/userStore.ts b/src/lib/userStore.ts index 0012d66..962737b 100644 --- a/src/lib/userStore.ts +++ b/src/lib/userStore.ts @@ -65,16 +65,6 @@ const KNOWN_ROLE_MAP: Record = { member: 'user', } -const GUEST_SESSION_STORAGE_KEY = 'xcontrol.guest.session' -const GUEST_SESSION_TTL_MS = 60 * 60 * 1000 -const GUEST_SANDBOX_TENANT_ID = 'guest-sandbox' -const GUEST_SANDBOX_TENANT_NAME = 'Guest Sandbox' - -type GuestSession = { - uuid: string - issuedAt: number -} - function normalizeRole(input?: string | null): UserRole { if (!input || typeof input !== 'string') { return 'guest' @@ -88,92 +78,6 @@ function normalizeRole(input?: string | null): UserRole { return KNOWN_ROLE_MAP[normalized] ?? 'guest' } -function createUUID(): string { - if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { - return crypto.randomUUID() - } - return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}` -} - -function readGuestSession(): GuestSession | null { - if (typeof window === 'undefined') { - return null - } - const raw = window.sessionStorage.getItem(GUEST_SESSION_STORAGE_KEY) - if (!raw) { - return null - } - - try { - const parsed = JSON.parse(raw) as GuestSession - if ( - typeof parsed?.uuid === 'string' && - parsed.uuid.trim().length > 0 && - typeof parsed?.issuedAt === 'number' && - Number.isFinite(parsed.issuedAt) - ) { - return { - uuid: parsed.uuid.trim(), - issuedAt: parsed.issuedAt, - } - } - } catch (error) { - console.warn('Failed to parse guest session payload', error) - } - - return null -} - -function writeGuestSession(session: GuestSession) { - if (typeof window === 'undefined') { - return - } - window.sessionStorage.setItem(GUEST_SESSION_STORAGE_KEY, JSON.stringify(session)) -} - -function resolveGuestUUID(now = Date.now()): string { - const existing = readGuestSession() - if (!existing || now - existing.issuedAt >= GUEST_SESSION_TTL_MS) { - const next: GuestSession = { uuid: createUUID(), issuedAt: now } - writeGuestSession(next) - return next.uuid - } - return existing.uuid -} - -function buildGuestUser(): User { - const identifier = resolveGuestUUID() - return { - id: identifier, - uuid: identifier, - email: 'sandbox@svc.plus', - name: 'Guest user', - username: 'guest', - mfaEnabled: false, - mfaPending: false, - mfa: { - totpEnabled: false, - totpPending: false, - }, - role: 'guest', - groups: ['guest', 'sandbox'], - permissions: ['read'], - isGuest: true, - isUser: false, - isOperator: false, - isAdmin: false, - isReadOnly: true, - tenantId: GUEST_SANDBOX_TENANT_ID, - tenants: [ - { - id: GUEST_SANDBOX_TENANT_ID, - name: GUEST_SANDBOX_TENANT_NAME, - role: 'guest', - }, - ], - } -} - async function fetchSessionUser(): Promise { try { const response = await fetch('/api/auth/session', { @@ -185,7 +89,7 @@ async function fetchSessionUser(): Promise { }) if (!response.ok) { - return buildGuestUser() + return null } const payload = (await response.json()) as { @@ -217,7 +121,7 @@ async function fetchSessionUser(): Promise { const sessionUser = payload?.user if (!sessionUser) { - return buildGuestUser() + return null } const { id, uuid, email, name, username, mfaEnabled, mfa, mfaPending, role, groups, permissions } = sessionUser @@ -229,7 +133,7 @@ async function fetchSessionUser(): Promise { : '' if (!identifier) { - return buildGuestUser() + return null } const normalizedName = typeof name === 'string' && name.trim().length > 0 ? name.trim() : undefined const normalizedUsername = @@ -309,18 +213,6 @@ async function fetchSessionUser(): Promise { .filter((tenant): tenant is TenantMembership => Boolean(tenant)) : undefined - const effectiveTenantId = normalizedRole === 'guest' ? GUEST_SANDBOX_TENANT_ID : normalizedTenantId - const effectiveTenants = - normalizedRole === 'guest' - ? [ - { - id: GUEST_SANDBOX_TENANT_ID, - name: GUEST_SANDBOX_TENANT_NAME, - role: 'guest' as UserRole, - }, - ] - : normalizedTenants - return { id: identifier, uuid: identifier, @@ -339,13 +231,13 @@ async function fetchSessionUser(): Promise { isUser: normalizedRole === 'user', isOperator: normalizedRole === 'operator', isAdmin: normalizedRole === 'admin', - isReadOnly: normalizedRole === 'guest' ? true : normalizedReadOnly, - tenantId: effectiveTenantId, - tenants: effectiveTenants, + isReadOnly: normalizedReadOnly, + tenantId: normalizedTenantId, + tenants: normalizedTenants, } } catch (error) { console.warn('Failed to resolve user session', error) - return buildGuestUser() + return null } } diff --git a/src/modules/extensions/builtin/user-center/lib/fetchAgentNodes.ts b/src/modules/extensions/builtin/user-center/lib/fetchAgentNodes.ts index e1463e6..ea53927 100644 --- a/src/modules/extensions/builtin/user-center/lib/fetchAgentNodes.ts +++ b/src/modules/extensions/builtin/user-center/lib/fetchAgentNodes.ts @@ -2,14 +2,17 @@ import type { VlessNode } from './vless' -const PRIMARY_ENDPOINT = '/api/agent-server/v1/nodes' +const PRIMARY_ENDPOINT = '/api/auth/sync/config?since_version=0' const FALLBACK_ENDPOINT = '/api/agent/nodes' -type AgentNodePayload = { - nodes?: unknown - message?: unknown - error?: unknown -} +type AgentNodePayload = + | { + nodes?: unknown + profiles?: unknown + message?: unknown + error?: unknown + } + | VlessNode[] type AgentNodesError = Error & { status?: number @@ -34,7 +37,7 @@ async function requestAgentNodes(url: string): Promise { }, }) - const payload = (await response.json().catch(() => null)) as AgentNodePayload | VlessNode[] | null + const payload = (await response.json().catch(() => null)) as AgentNodePayload | null if (!response.ok) { const error = new Error(extractMessage(Array.isArray(payload) ? null : payload, response.status)) as AgentNodesError @@ -45,10 +48,15 @@ async function requestAgentNodes(url: string): Promise { if (Array.isArray(payload)) { return payload as VlessNode[] } - if (payload && Array.isArray((payload as AgentNodePayload).nodes)) { + + if (payload && Array.isArray((payload as { nodes?: unknown }).nodes)) { return (payload as { nodes: VlessNode[] }).nodes } + if (payload && Array.isArray((payload as { profiles?: unknown }).profiles)) { + return (payload as { profiles: VlessNode[] }).profiles + } + throw new Error('unexpected_agent_nodes_payload') }