const LOGIN_URL_PATTERN = /https?:\/\/[^\s]+\/login\?[^\s]+/g; const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]); export function parseMulticaLoginOutput(output) { const matches = String(output || "").match(LOGIN_URL_PATTERN) || []; const loginUrl = new URL(matches.at(-1) || ""); const callbackUrl = new URL(loginUrl.searchParams.get("cli_callback") || ""); const state = loginUrl.searchParams.get("cli_state") || ""; const port = Number(callbackUrl.port); if (callbackUrl.protocol !== "http:" || !LOOPBACK_HOSTS.has(callbackUrl.hostname) || callbackUrl.pathname !== "/callback") { throw new Error("Multica 尚未生成有效的本机回调地址"); } if (!Number.isInteger(port) || port < 1024 || port > 65535 || !state) { throw new Error("Multica 登录链接缺少端口或 state"); } return { loginUrl, callbackUrl, state }; } export function buildManagedMulticaLoginUrl(output, publicOrigin, sessionId) { const { loginUrl } = parseMulticaLoginOutput(output); const managedCallback = new URL(`/api/integrations/multica/oauth/callback/${encodeURIComponent(sessionId)}`, publicOrigin); loginUrl.searchParams.set("cli_callback", managedCallback.toString()); return loginUrl.toString(); } export function buildLocalMulticaCallbackUrl(output, query) { const { callbackUrl, state } = parseMulticaLoginOutput(output); const returnedState = typeof query?.state === "string" ? query.state : ""; const token = typeof query?.token === "string" ? query.token : ""; if (!token || !returnedState || returnedState !== state) throw new Error("Multica 回调校验失败,请重新发起验证"); callbackUrl.search = ""; callbackUrl.searchParams.set("token", token); callbackUrl.searchParams.set("state", returnedState); return callbackUrl.toString(); }