import crypto from "node:crypto"; import http from "node:http"; const DEFAULT_PORT = 18473; const MOCK_JWT = "e2e-mock-jwt-token"; const MAX_PORT_RETRY_ATTEMPTS = 10; let requestLog = []; let mockBehavior = {}; let server = null; const openSockets = new Set(); let mockTunnels = []; const CORS_HEADERS = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization, x-device-fingerprint, x-tauri-version, x-core-version, x-ios-version, x-android-version, x-web-version", "Access-Control-Max-Age": "86400", }; function setCors(res) { for (const [key, value] of Object.entries(CORS_HEADERS)) { res.setHeader(key, value); } } function json(res, status, body) { setCors(res); res.writeHead(status, { "Content-Type": "application/json" }); res.end(JSON.stringify(body)); } function html(res, status, body) { setCors(res); res.writeHead(status, { "Content-Type": "text/html; charset=utf-8" }); res.end(body); } function requestOrigin(req) { const host = req.headers.host || "127.0.0.1:18473"; return `http://${host}`; } function getMockUser() { return { _id: "user-123", telegramId: 12345678, hasAccess: true, magicWord: "alpha", firstName: "Test", lastName: "User", username: "testuser", role: "user", activeTeamId: "team-1", referral: {}, subscription: { hasActiveSubscription: false, plan: "FREE" }, settings: { dailySummariesEnabled: false, dailySummaryChatIds: [], autoCompleteEnabled: false, autoCompleteVisibility: "always", autoCompleteWhitelistChatIds: [], autoCompleteBlacklistChatIds: [], }, usage: { cycleBudgetUsd: 10, remainingUsd: 10, spentThisCycleUsd: 0, spentTodayUsd: 0, cycleStartDate: new Date().toISOString(), }, autoDeleteTelegramMessagesAfterDays: 30, autoDeleteThreadsAfterDays: 30, }; } function getMockTeam() { const plan = mockBehavior.plan || "FREE"; const isActive = mockBehavior.planActive === "true"; const expiry = mockBehavior.planExpiry || null; return { team: { _id: "team-1", name: "Personal", slug: "personal", createdBy: "test-user-123", isPersonal: true, maxMembers: 1, subscription: { plan, hasActiveSubscription: isActive, planExpiry: expiry, }, usage: { dailyTokenLimit: 1000, remainingTokens: 1000, activeSessionCount: 0, }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, role: "ADMIN", }; } function getRequestLog() { return [...requestLog]; } function clearRequestLog() { requestLog = []; } function resetMockTunnels() { mockTunnels = []; } function setMockBehavior(key, value) { mockBehavior[key] = String(value); } function setMockBehaviors(behavior, mode = "merge") { if (mode === "replace") { mockBehavior = {}; } for (const [key, value] of Object.entries(behavior || {})) { mockBehavior[key] = String(value); } } function resetMockBehavior() { mockBehavior = {}; } function getMockBehavior() { return { ...mockBehavior }; } function readBody(req) { return new Promise((resolve) => { const chunks = []; req.on("data", (c) => chunks.push(c)); req.on("end", () => resolve(Buffer.concat(chunks).toString())); }); } function tryParseJson(raw) { if (!raw) return null; try { return JSON.parse(raw); } catch { return null; } } const REDACTED_HEADER_VALUE = "[REDACTED]"; const SENSITIVE_HEADER_NAMES = new Set([ "authorization", "cookie", "set-cookie", "proxy-authorization", ]); function normalizeHeaders(headers) { const entries = Object.entries(headers || {}); return Object.fromEntries( entries.map(([key, value]) => { if (SENSITIVE_HEADER_NAMES.has(String(key).toLowerCase())) { return [key, REDACTED_HEADER_VALUE]; } return [ key, Array.isArray(value) ? value.join(", ") : String(value ?? ""), ]; }), ); } function getDelayMs(key) { const value = Number(mockBehavior[key] || 0); return Number.isFinite(value) && value > 0 ? value : 0; } function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function createMockTunnel(payload = {}) { const now = new Date().toISOString(); return { id: crypto.randomUUID(), uuid: crypto.randomUUID(), name: String(payload.name || "Mock Tunnel").trim(), description: String(payload.description || "").trim(), isActive: payload.isActive ?? true, createdAt: now, updatedAt: now, }; } async function handleRequest(req, res) { const method = req.method ?? "GET"; const url = req.url ?? "/"; const body = await readBody(req); const parsedBody = tryParseJson(body); const origin = requestOrigin(req); requestLog.push({ method, url, body, headers: normalizeHeaders(req.headers), timestamp: Date.now(), }); if (method === "OPTIONS") { setCors(res); res.writeHead(204); res.end(); return; } if (method === "GET" && /^\/__admin\/health\/?$/.test(url)) { json(res, 200, { ok: true, port: server?.address()?.port ?? null }); return; } if (method === "GET" && /^\/__admin\/requests\/?$/.test(url)) { json(res, 200, { success: true, data: getRequestLog() }); return; } if (method === "GET" && /^\/__admin\/behavior\/?$/.test(url)) { json(res, 200, { success: true, data: getMockBehavior() }); return; } if (method === "POST" && /^\/__admin\/reset\/?$/.test(url)) { const keepBehavior = parsedBody?.keepBehavior === true; const keepRequests = parsedBody?.keepRequests === true; if (!keepBehavior) resetMockBehavior(); if (!keepRequests) clearRequestLog(); resetMockTunnels(); json(res, 200, { success: true, data: { behavior: getMockBehavior(), requestCount: getRequestLog().length, }, }); return; } if (method === "POST" && /^\/__admin\/behavior\/?$/.test(url)) { if (parsedBody?.behavior && typeof parsedBody.behavior === "object") { setMockBehaviors(parsedBody.behavior, parsedBody.mode); } else if (parsedBody?.key) { setMockBehavior(parsedBody.key, parsedBody.value ?? ""); } json(res, 200, { success: true, data: getMockBehavior() }); return; } if (url.startsWith("/socket.io/")) { const eioOpen = JSON.stringify({ sid: "mock-sid-" + Date.now(), upgrades: ["websocket"], pingInterval: 25000, pingTimeout: 20000, }); const packet = `${eioOpen.length + 1}:0${eioOpen}`; setCors(res); res.writeHead(200, { "Content-Type": "text/plain" }); res.end(packet); return; } if ( method === "POST" && /^\/telegram\/login-tokens\/[^/]+\/consume\/?$/.test(url) ) { if (mockBehavior.token === "expired") { json(res, 401, { success: false, error: "Token expired or invalid" }); return; } if (mockBehavior.token === "invalid") { json(res, 401, { success: false, error: "Invalid token" }); return; } const jwt = mockBehavior.jwt ? `${MOCK_JWT}-${mockBehavior.jwt}` : MOCK_JWT; json(res, 200, { success: true, data: { jwtToken: jwt } }); return; } if (method === "POST" && /^\/auth\/desktop-exchange\/?$/.test(url)) { json(res, 200, { sessionToken: "mock-session-token", user: { id: "user-123", firstName: "Test", username: "testuser" }, }); return; } if ( method === "GET" && (/^\/telegram\/me\/?(\?.*)?$/.test(url) || /^\/auth\/me\/?(\?.*)?$/.test(url)) ) { const delayMs = getDelayMs("telegramMeDelayMs"); if (delayMs > 0) { await sleep(delayMs); } if (mockBehavior.telegramMeStatus) { const status = Number(mockBehavior.telegramMeStatus) || 500; json(res, status, { success: false, error: mockBehavior.telegramMeError || "Mock telegram/me failure", }); return; } if (mockBehavior.session === "revoked") { json(res, 401, { success: false, error: "Unauthorized" }); return; } json(res, 200, { success: true, data: getMockUser() }); return; } if (method === "GET" && /^\/settings\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: { _id: "e2e-user-1", username: "e2e" }, }); return; } if (method === "GET" && /^\/teams\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: [getMockTeam()] }); return; } if (method === "GET" && /^\/teams\/me\/usage\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: { cycleBudgetUsd: 10, remainingUsd: 10, cycleLimit5hr: 0, cycleLimit7day: 0, fiveHourCapUsd: 5, fiveHourResetsAt: null, cycleStartDate: new Date().toISOString(), cycleEndsAt: new Date( Date.now() + 7 * 24 * 60 * 60 * 1000, ).toISOString(), bypassCycleLimit: false, }, }); return; } if (method === "GET" && /^\/auth\/integrations\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: [] }); return; } if (method === "POST" && /^\/webhooks\/core\/?$/.test(url)) { const tunnel = createMockTunnel(parsedBody || {}); mockTunnels.unshift(tunnel); json(res, 200, { success: true, data: tunnel }); return; } if (method === "GET" && /^\/webhooks\/core\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: mockTunnels }); return; } if (method === "GET" && /^\/webhooks\/core\/bandwidth\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: { remainingBudgetUsd: 10 } }); return; } const webhookCoreMatch = url.match(/^\/webhooks\/core\/([^/?]+)\/?(\?.*)?$/); if (webhookCoreMatch) { const [, tunnelId] = webhookCoreMatch; const tunnelIndex = mockTunnels.findIndex((entry) => entry.id === tunnelId); const tunnel = tunnelIndex >= 0 ? mockTunnels[tunnelIndex] : null; if (!tunnel) { json(res, 404, { success: false, error: "Tunnel not found" }); return; } if (method === "GET") { json(res, 200, { success: true, data: tunnel }); return; } if (method === "PATCH") { const updated = { ...tunnel, ...(parsedBody || {}), updatedAt: new Date().toISOString(), }; mockTunnels[tunnelIndex] = updated; json(res, 200, { success: true, data: updated }); return; } if (method === "DELETE") { mockTunnels.splice(tunnelIndex, 1); json(res, 200, { success: true, data: tunnel }); return; } } // --- Payments / Credits / Billing --- if ( method === "GET" && /^\/payments\/credits\/balance\/?(\?.*)?$/.test(url) ) { json(res, 200, { success: true, data: { balanceUsd: 10, topUpBalanceUsd: 0, topUpBaselineUsd: 0 }, }); return; } if ( method === "GET" && (/^\/payments\/plan\/?(\?.*)?$/.test(url) || /^\/payments\/stripe\/currentPlan\/?(\?.*)?$/.test(url)) ) { const plan = mockBehavior.plan || "FREE"; const isActive = mockBehavior.planActive === "true"; const periodEnd = new Date(Date.now() + 30 * 86400000).toISOString(); json(res, 200, { success: true, data: { plan, hasActiveSubscription: isActive, planExpiry: isActive ? periodEnd : null, subscription: isActive ? { id: "sub_mock_1", status: "active", currentPeriodEnd: periodEnd } : null, }, }); return; } if ( method === "POST" && (/^\/payments\/stripe\/checkout\/?$/.test(url) || /^\/payments\/stripe\/purchasePlan\/?$/.test(url)) ) { if (mockBehavior.purchaseError === "true") { json(res, 500, { success: false, error: "Payment service unavailable" }); return; } json(res, 200, { success: true, data: { sessionId: "cs_mock_" + Date.now(), // Return null checkoutUrl so the app doesn't navigate the WebView away. // The test verifies the API call was made, not the redirect. checkoutUrl: null, }, }); return; } if (method === "POST" && /^\/payments\/stripe\/portal\/?$/.test(url)) { json(res, 200, { success: true, data: { portalUrl: "https://billing.stripe.com/mock-portal" }, }); return; } if (method === "POST" && /^\/payments\/coinbase\/charge\/?$/.test(url)) { if (mockBehavior.coinbaseError === "true") { json(res, 500, { success: false, error: "Coinbase service unavailable" }); return; } json(res, 200, { success: true, data: { gatewayTransactionId: "charge_mock_" + Date.now(), hostedUrl: "https://commerce.coinbase.com/mock-charge", status: "NEW", expiresAt: new Date(Date.now() + 3600000).toISOString(), }, }); return; } if (method === "POST" && /^\/payments\/purchase\/?$/.test(url)) { const plan = parsedBody?.plan || mockBehavior.plan || "BASIC"; json(res, 200, { success: true, data: { sessionId: "cs_mock_" + Date.now(), url: "https://checkout.stripe.com/mock-purchase", plan, }, }); return; } if ( method === "GET" && /^\/payments\/credits\/auto-recharge\/?(\?.*)?$/.test(url) ) { json(res, 200, { success: true, data: { enabled: false, thresholdUsd: 5, rechargeAmountUsd: 10, weeklyLimitUsd: 50, spentThisWeekUsd: 0, weekStartDate: new Date().toISOString(), inFlight: false, hasSavedPaymentMethod: false, lastTriggeredAt: null, lastRechargeAt: null, }, }); return; } if (method === "GET" && /^\/payments\/cards\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: { cards: [], defaultCardId: null } }); return; } if ( method === "GET" && /^\/payments\/credits\/auto-recharge\/cards\/?(\?.*)?$/.test(url) ) { json(res, 200, { success: true, data: { cards: [], defaultCardId: null } }); return; } if (method === "GET" && /^\/openai\/v1\/models\/?(\?.*)?$/.test(url)) { json(res, 200, { data: [{ id: "e2e-mock-model", object: "model" }] }); return; } if (method === "POST" && /^\/openai\/v1\/chat\/completions\/?$/.test(url)) { json(res, 200, { choices: [ { message: { role: "assistant", content: "Hello from e2e mock agent" }, }, ], }); return; } if (method === "GET" && /^\/auth\/[^/]+\/login\/?(\?.*)?$/.test(url)) { const redirectUrl = `${origin}/mock-oauth`; if (url.includes("responseType=json")) { json(res, 200, { success: true, data: { oauthUrl: redirectUrl } }); return; } setCors(res); res.writeHead(302, { Location: redirectUrl }); res.end(); return; } if (method === "GET" && /^\/auth\/telegram\/connect\/?(\?.*)?$/.test(url)) { if (mockBehavior.telegramDuplicate === "true") { json(res, 409, { success: false, error: "Telegram account already linked to another user", }); return; } json(res, 200, { success: true, data: { oauthUrl: `${origin}/mock-telegram-oauth` }, }); return; } if (method === "GET" && /^\/auth\/notion\/connect\/?(\?.*)?$/.test(url)) { if (mockBehavior.notionTokenRevoked === "true") { json(res, 401, { success: false, error: "OAuth token has been revoked" }); return; } const workspace = mockBehavior.notionWorkspace || "Test User's Workspace"; json(res, 200, { success: true, data: { oauthUrl: `${origin}/mock-notion-oauth`, workspace }, }); return; } if (method === "GET" && /^\/auth\/google\/connect\/?(\?.*)?$/.test(url)) { if (mockBehavior.gmailTokenRevoked === "true") { json(res, 401, { success: false, error: "OAuth token has been revoked" }); return; } if (mockBehavior.gmailTokenExpired === "true") { json(res, 401, { success: false, error: "OAuth token has expired" }); return; } json(res, 200, { success: true, data: { oauthUrl: `${origin}/mock-google-oauth` }, }); return; } if (method === "POST" && /^\/telegram\/command\/?$/.test(url)) { if (mockBehavior.telegramUnauthorized === "true") { json(res, 403, { success: false, error: "Unauthorized: insufficient permissions", }); return; } if (mockBehavior.telegramCommandError === "true") { json(res, 400, { success: false, error: "Invalid command format" }); return; } json(res, 200, { success: true, data: { result: "Command executed successfully" }, }); return; } if (method === "GET" && /^\/telegram\/permissions\/?(\?.*)?$/.test(url)) { const level = mockBehavior.telegramPermission || "read"; json(res, 200, { success: true, data: { level, canRead: true, canWrite: level !== "read", canInitiate: level === "admin", }, }); return; } if (method === "POST" && /^\/telegram\/webhook\/configure\/?$/.test(url)) { json(res, 200, { success: true, data: { webhookUrl: "https://api.example.com/webhook/telegram", active: true, }, }); return; } if (method === "POST" && /^\/telegram\/disconnect\/?$/.test(url)) { json(res, 200, { success: true, data: { disconnected: true } }); return; } if (method === "GET" && /^\/notion\/permissions\/?(\?.*)?$/.test(url)) { const level = mockBehavior.notionPermission || "read"; json(res, 200, { success: true, data: { level, canRead: true, canWrite: level !== "read", canCreate: level !== "read", }, }); return; } if (method === "GET" && /^\/gmail\/permissions\/?(\?.*)?$/.test(url)) { const level = mockBehavior.gmailPermission || "read"; json(res, 200, { success: true, data: { level, canRead: true, canWrite: level !== "read", canInitiate: level === "admin", }, }); return; } if (method === "POST" && /^\/gmail\/disconnect\/?$/.test(url)) { json(res, 200, { success: true, data: { disconnected: true } }); return; } if (method === "GET" && /^\/gmail\/emails\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: [ { id: "msg-1", subject: "Welcome to OpenHuman", from: "team@openhuman.com", date: new Date().toISOString(), snippet: "Welcome to the platform!", hasAttachments: false, }, ], }); return; } if (method === "GET" && /^\/skills\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: [ { id: "telegram", name: "Telegram", status: mockBehavior.telegramSkillStatus || "installed", setupComplete: mockBehavior.telegramSetupComplete === "true", }, { id: "notion", name: "Notion", status: mockBehavior.notionSkillStatus || "installed", setupComplete: mockBehavior.notionSetupComplete === "true", }, { id: "email", name: "Email", status: mockBehavior.gmailSkillStatus || "installed", setupComplete: mockBehavior.gmailSetupComplete === "true", }, ], }); return; } if (method === "POST" && /^\/invite\/redeem\/?$/.test(url)) { json(res, 200, { success: true, data: { message: "Invite code redeemed successfully" }, }); return; } if (method === "GET" && /^\/invite\/my-codes\/?(\?.*)?$/.test(url)) { json(res, 200, { success: true, data: [] }); return; } if (method === "GET" && /^\/invite\/status/.test(url)) { json(res, 200, { success: true, data: { valid: true } }); return; } if (method === "GET" && /^\/referral\/stats\/?(\?.*)?$/.test(url)) { const origin = requestOrigin(req); json(res, 200, { success: true, data: { referralCode: "MOCKREF1", referralLink: `${origin}/#/rewards?ref=MOCKREF1`, totals: { totalRewardUsd: 10, pendingCount: 1, convertedCount: 2, }, referrals: [ { id: "ref-row-1", referredUserId: "user-456", status: "pending", createdAt: new Date(Date.now() - 86400000).toISOString(), }, { id: "ref-row-2", referredUserId: "user-789", status: "converted", createdAt: new Date(Date.now() - 172800000).toISOString(), convertedAt: new Date().toISOString(), rewardUsd: 5, }, ], appliedReferralCode: null, canApplyReferral: true, }, }); return; } if (method === "POST" && /^\/referral\/claim\/?$/.test(url)) { json(res, 200, { success: true, data: { ok: true, message: "Referral claimed" }, }); return; } // Rewards & Progression snapshot — feature 12.x. // // Honours mockBehavior knobs so individual e2e cases can flip unlock state // without rewriting fixtures: // // rewardsScenario — preset bundle: // "default" (FREE plan, no streak, no Discord) // "activity_unlocked" (12.1.1 — streak/feature counts trigger achievement) // "integration_unlocked" (12.1.2 — Discord member assigns role) // "plan_unlocked" (12.1.3 — PRO plan unlocks tier achievement) // "high_usage" (12.2.1/12.2.2 — message + token + streak metrics) // "post_restart" (12.2.3 — same metrics persist after the second fetch) // rewardsServiceError — when "true", returns 503 to exercise the failure path. // rewardsLastSyncedAt — overrides the metrics.lastSyncedAt timestamp (useful for restart drift assertions). if (method === "GET" && /^\/rewards\/me\/?(\?.*)?$/.test(url)) { if (mockBehavior.rewardsServiceError === "true") { json(res, 503, { success: false, error: "Rewards service unavailable", }); return; } const scenario = mockBehavior.rewardsScenario || "default"; const lastSyncedAt = mockBehavior.rewardsLastSyncedAt || new Date().toISOString(); const baseAchievements = [ { id: "STREAK_7", title: "7-Day Streak", description: "Use OpenHuman on seven consecutive active days.", actionLabel: "Keep your streak alive for 7 days", unlocked: false, progressLabel: "0 / 7 days", roleId: "role-streak-7", discordRoleStatus: "not_linked", creditAmountUsd: null, }, { id: "DISCORD_MEMBER", title: "Discord Member", description: "Join the OpenHuman Discord server.", actionLabel: "Connect Discord and join the server", unlocked: false, progressLabel: "Not joined", roleId: "role-discord-member", discordRoleStatus: "not_linked", creditAmountUsd: null, }, { id: "PLAN_PRO", title: "Pro Supporter", description: "Upgrade to the Pro plan.", actionLabel: "Upgrade to Pro", unlocked: false, progressLabel: "Locked", roleId: "role-plan-pro", discordRoleStatus: "not_assigned", creditAmountUsd: 5, }, ]; let snapshot; switch (scenario) { case "activity_unlocked": snapshot = { discord: { linked: false, discordId: null, inviteUrl: "https://discord.gg/openhuman", membershipStatus: "not_linked", }, summary: { unlockedCount: 1, totalCount: 3, assignedDiscordRoleCount: 0, plan: "FREE", hasActiveSubscription: false, }, metrics: { currentStreakDays: 7, longestStreakDays: 7, cumulativeTokens: 250000, featuresUsedCount: 4, trackedFeaturesCount: 6, lastEvaluatedAt: lastSyncedAt, lastSyncedAt, }, achievements: [ { ...baseAchievements[0], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "not_linked", }, baseAchievements[1], baseAchievements[2], ], }; break; case "integration_unlocked": snapshot = { discord: { linked: true, discordId: "discord-mock-123", inviteUrl: "https://discord.gg/openhuman", membershipStatus: "member", }, summary: { unlockedCount: 1, totalCount: 3, assignedDiscordRoleCount: 1, plan: "FREE", hasActiveSubscription: false, }, metrics: { currentStreakDays: 0, longestStreakDays: 0, cumulativeTokens: 0, featuresUsedCount: 0, trackedFeaturesCount: 6, lastEvaluatedAt: lastSyncedAt, lastSyncedAt, }, achievements: [ baseAchievements[0], { ...baseAchievements[1], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "assigned", }, baseAchievements[2], ], }; break; case "plan_unlocked": snapshot = { discord: { linked: false, discordId: null, inviteUrl: "https://discord.gg/openhuman", membershipStatus: "not_linked", }, summary: { unlockedCount: 1, totalCount: 3, assignedDiscordRoleCount: 0, plan: "PRO", hasActiveSubscription: true, }, metrics: { currentStreakDays: 0, longestStreakDays: 0, cumulativeTokens: 0, featuresUsedCount: 0, trackedFeaturesCount: 6, lastEvaluatedAt: lastSyncedAt, lastSyncedAt, }, achievements: [ baseAchievements[0], baseAchievements[1], { ...baseAchievements[2], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "not_linked", }, ], }; break; case "high_usage": case "post_restart": snapshot = { discord: { linked: true, discordId: "discord-mock-123", inviteUrl: "https://discord.gg/openhuman", membershipStatus: "member", }, summary: { unlockedCount: 3, totalCount: 3, assignedDiscordRoleCount: 1, plan: "PRO", hasActiveSubscription: true, }, metrics: { currentStreakDays: 14, longestStreakDays: 21, cumulativeTokens: 12500000, featuresUsedCount: 6, trackedFeaturesCount: 6, lastEvaluatedAt: lastSyncedAt, lastSyncedAt, }, achievements: [ { ...baseAchievements[0], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "assigned", }, { ...baseAchievements[1], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "assigned", }, { ...baseAchievements[2], unlocked: true, progressLabel: "Unlocked", discordRoleStatus: "assigned", }, ], }; break; case "default": default: snapshot = { discord: { linked: false, discordId: null, inviteUrl: "https://discord.gg/openhuman", membershipStatus: "not_linked", }, summary: { unlockedCount: 0, totalCount: 3, assignedDiscordRoleCount: 0, plan: "FREE", hasActiveSubscription: false, }, metrics: { currentStreakDays: 0, longestStreakDays: 0, cumulativeTokens: 0, featuresUsedCount: 0, trackedFeaturesCount: 6, lastEvaluatedAt: lastSyncedAt, lastSyncedAt, }, achievements: baseAchievements, }; break; } json(res, 200, { success: true, data: snapshot }); return; } if ( method === "POST" && /^\/telegram\/settings\/onboarding-complete\/?$/.test(url) ) { json(res, 200, { success: true, data: {} }); return; } if (method === "POST" && /^\/settings\/onboarding-complete\/?$/.test(url)) { json(res, 200, { success: true, data: {} }); return; } // currentPlan is handled by the earlier consolidated handler. if (method === "GET" && /^\/billing\/current-plan\/?(\?.*)?$/.test(url)) { const plan = mockBehavior.plan || "FREE"; const isActive = mockBehavior.planActive === "true"; const expiry = mockBehavior.planExpiry || null; json(res, 200, { success: true, data: { plan, hasActiveSubscription: isActive, planExpiry: expiry, subscription: isActive ? { id: "sub_mock_123", status: "active", currentPeriodEnd: expiry || new Date(Date.now() + 30 * 86400000).toISOString(), } : null, }, }); return; } // purchasePlan, portal, and coinbase/charge are handled by the earlier // consolidated handlers (with mockBehavior checks). Only the coinbase // charge-status polling endpoint remains here. if ( method === "GET" && /^\/payments\/coinbase\/charge\/[^/]+\/?(\?.*)?$/.test(url) ) { const status = mockBehavior.cryptoStatus || "NEW"; json(res, 200, { success: true, data: { status, payment: { status, amountPaid: status === "UNDERPAID" ? "150.00" : status === "OVERPAID" ? "350.00" : "250.00", amountExpected: "250.00", currency: "USDC", underpaidAmount: mockBehavior.cryptoUnderpaidAmount || "0", overpaidAmount: mockBehavior.cryptoOverpaidAmount || "0", }, expiresAt: new Date(Date.now() + 3600000).toISOString(), }, }); return; } if ( method === "GET" && /^\/mock-(telegram|notion|google)-oauth\/?(\?.*)?$/.test(url) ) { html(res, 200, "

Mock OAuth

"); return; } if (method === "GET" && /^\/mock-oauth\/?(\?.*)?$/.test(url)) { html(res, 200, "

Mock OAuth Redirect

"); return; } // ── Composio routes (used by trigger-toggles E2E spec) ──────────── // // Behavior knobs (set via /__admin/behavior): // composioConnections — JSON array, default `[{id:'c1',toolkit:'gmail',status:'ACTIVE'}]` // composioAvailableTriggers — JSON array, default one Gmail trigger // composioActiveTriggers — JSON array, default empty // composioEnableFails — '1' to make POST /triggers return 500 // // Enable/disable requests mutate `composioActiveTriggers` in place so the // UI can poll subsequent reads and observe the change. if ( method === "GET" && /^\/agent-integrations\/composio\/connections\/?(\?.*)?$/.test(url) ) { const connections = parseBehaviorJson("composioConnections", [ { id: "c1", toolkit: "gmail", status: "ACTIVE" }, ]); json(res, 200, { success: true, data: { connections } }); return; } if ( method === "GET" && /^\/agent-integrations\/composio\/triggers\/available(\?.*)?$/.test(url) ) { const triggers = parseBehaviorJson("composioAvailableTriggers", [ { slug: "GMAIL_NEW_GMAIL_MESSAGE", scope: "static" }, ]); json(res, 200, { success: true, data: { triggers } }); return; } if ( method === "GET" && /^\/agent-integrations\/composio\/triggers(\?.*)?$/.test(url) ) { const triggers = parseBehaviorJson("composioActiveTriggers", []); json(res, 200, { success: true, data: { triggers } }); return; } if ( method === "POST" && /^\/agent-integrations\/composio\/triggers\/?$/.test(url) ) { if (mockBehavior.composioEnableFails === "1") { json(res, 500, { success: false, error: "Mock enable trigger failure" }); return; } const slug = typeof parsedBody?.slug === "string" ? parsedBody.slug.trim() : ""; const connectionId = typeof parsedBody?.connectionId === "string" ? parsedBody.connectionId.trim() : ""; if (!slug) { json(res, 400, { success: false, error: "Missing required field: slug" }); return; } if (!connectionId) { json(res, 400, { success: false, error: "Missing required field: connectionId", }); return; } const triggerId = `ti-${Date.now()}`; const active = parseBehaviorJson("composioActiveTriggers", []); active.push({ id: triggerId, slug, toolkit: slug.split("_")[0]?.toLowerCase() ?? "", connectionId, ...(parsedBody?.triggerConfig ? { triggerConfig: parsedBody.triggerConfig } : {}), }); setMockBehavior("composioActiveTriggers", JSON.stringify(active)); json(res, 200, { success: true, data: { triggerId, slug, connectionId }, }); return; } if ( method === "DELETE" && /^\/agent-integrations\/composio\/triggers\/[^/]+\/?$/.test(url) ) { let id = url.split("/").filter(Boolean).pop() ?? ""; id = id.split("?")[0]; if (!id) { json(res, 400, { success: false, error: "Missing trigger id" }); return; } try { id = decodeURIComponent(id); } catch { json(res, 400, { success: false, error: "Invalid trigger id encoding" }); return; } const active = parseBehaviorJson("composioActiveTriggers", []); const next = active.filter((t) => t.id !== id); const deleted = next.length !== active.length; if (deleted) { setMockBehavior("composioActiveTriggers", JSON.stringify(next)); } json(res, 200, { success: true, data: { deleted } }); return; } // Catch-all: fail fast so tests notice missing mock endpoints. console.log(`[MockServer] UNHANDLED ${method} ${url}`); json(res, 404, { success: false, error: `Mock server: no handler for ${method} ${url}`, }); } function parseBehaviorJson(key, fallback) { const raw = mockBehavior[key]; if (!raw) return JSON.parse(JSON.stringify(fallback)); try { return JSON.parse(raw); } catch { return JSON.parse(JSON.stringify(fallback)); } } function handleSocketIOMessage(socket, text, sid) { if (text === "2") { sendWsText(socket, "3"); return; } if (text.startsWith("40")) { sendWsText(socket, `40{"sid":"${sid}"}`); } } function sendWsText(socket, text) { sendWsFrame(socket, 0x01, Buffer.from(text, "utf-8")); } function sendWsFrame(socket, opcode, payload) { if (socket.destroyed) return; const len = payload.length; let header; if (len < 126) { header = Buffer.alloc(2); header[0] = 0x80 | opcode; header[1] = len; } else if (len < 65536) { header = Buffer.alloc(4); header[0] = 0x80 | opcode; header[1] = 126; header.writeUInt16BE(len, 2); } else { header = Buffer.alloc(10); header[0] = 0x80 | opcode; header[1] = 127; header.writeBigUInt64BE(BigInt(len), 2); } try { socket.write(header); socket.write(payload); } catch { // noop } } function handleWebSocketUpgrade(req, socket) { if (!req.url?.startsWith("/socket.io/")) { socket.destroy(); return; } const key = req.headers["sec-websocket-key"]; if (!key) { socket.destroy(); return; } const acceptKey = crypto .createHash("sha1") .update(key + "258EAFA5-E914-47DA-95CA-5AB5DC085B11") .digest("base64"); socket.write( "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + `Sec-WebSocket-Accept: ${acceptKey}\r\n` + "\r\n", ); const mockSid = "mock-ws-" + Date.now(); const eioOpen = JSON.stringify({ sid: mockSid, upgrades: [], pingInterval: 25000, pingTimeout: 60000, maxPayload: 1000000, }); sendWsText(socket, `0${eioOpen}`); let buffer = Buffer.alloc(0); socket.on("data", (chunk) => { buffer = Buffer.concat([buffer, chunk]); while (buffer.length >= 2) { const firstByte = buffer[0]; const opcode = firstByte & 0x0f; const secondByte = buffer[1]; const masked = (secondByte & 0x80) !== 0; let payloadLen = secondByte & 0x7f; let offset = 2; if (payloadLen === 126) { if (buffer.length < 4) return; payloadLen = buffer.readUInt16BE(2); offset = 4; } else if (payloadLen === 127) { if (buffer.length < 10) return; payloadLen = Number(buffer.readBigUInt64BE(2)); offset = 10; } const maskSize = masked ? 4 : 0; const totalLen = offset + maskSize + payloadLen; if (buffer.length < totalLen) return; let payload = buffer.subarray(offset + maskSize, totalLen); if (masked) { const mask = buffer.subarray(offset, offset + 4); payload = Buffer.from(payload); for (let i = 0; i < payload.length; i += 1) { payload[i] ^= mask[i % 4]; } } buffer = buffer.subarray(totalLen); if (opcode === 0x08) { socket.end(); return; } if (opcode === 0x09) { sendWsFrame(socket, 0x0a, payload); continue; } if (opcode === 0x01) { handleSocketIOMessage(socket, payload.toString("utf-8"), mockSid); } } }); socket.on("error", () => {}); socket.on("close", () => {}); } function getMockServerPort() { const address = server?.address(); return typeof address === "object" && address ? address.port : null; } function createServerInstance() { const nextServer = http.createServer((req, res) => { handleRequest(req, res).catch((err) => { console.error("[MockServer] Unhandled error:", err); json(res, 500, { success: false, error: "Internal mock error" }); }); }); nextServer.on("connection", (socket) => { openSockets.add(socket); socket.on("close", () => openSockets.delete(socket)); }); nextServer.on("upgrade", (req, socket) => handleWebSocketUpgrade(req, socket), ); return nextServer; } function listen(serverInstance, port) { return new Promise((resolve, reject) => { const onError = (err) => { serverInstance.off("listening", onListening); reject(err); }; const onListening = () => { serverInstance.off("error", onError); const address = serverInstance.address(); const resolvedPort = typeof address === "object" && address ? address.port : port; resolve(resolvedPort); }; serverInstance.once("error", onError); serverInstance.once("listening", onListening); serverInstance.listen(port, "127.0.0.1"); }); } async function startMockServer(port = DEFAULT_PORT, options = {}) { if (server) { return { port: getMockServerPort() ?? port, alreadyRunning: true }; } const preferredPort = Number.isInteger(port) && port > 0 ? port : DEFAULT_PORT; const retryIfInUse = options.retryIfInUse === true; const candidatePorts = retryIfInUse ? [ preferredPort, ...Array.from( { length: MAX_PORT_RETRY_ATTEMPTS }, (_, i) => preferredPort + i + 1, ), 0, ] : [preferredPort]; let lastError = null; for (const candidatePort of candidatePorts) { const nextServer = createServerInstance(); try { const resolvedPort = await listen(nextServer, candidatePort); server = nextServer; const retryNote = resolvedPort === preferredPort ? "" : ` (preferred ${preferredPort} unavailable)`; console.log( `[MockServer] Listening on http://127.0.0.1:${resolvedPort}${retryNote}`, ); return { port: resolvedPort, alreadyRunning: false, requestedPort: preferredPort, retried: resolvedPort !== preferredPort, }; } catch (err) { try { nextServer.close(); } catch { // The failed candidate may never have reached the listening state. } lastError = err; if (!retryIfInUse || err?.code !== "EADDRINUSE") { throw err; } console.warn( `[MockServer] Port ${candidatePort} unavailable; trying another local port`, ); } } throw lastError ?? new Error("Mock server failed to start"); } function stopMockServer() { return new Promise((resolve) => { if (!server) { resolve(); return; } for (const socket of openSockets) { socket.destroy(); } openSockets.clear(); server.close(() => { console.log("[MockServer] Stopped"); server = null; resolve(); }); }); } export { DEFAULT_PORT, clearRequestLog, getMockServerPort, getMockBehavior, getRequestLog, resetMockBehavior, setMockBehavior, setMockBehaviors, startMockServer, stopMockServer, };