debug(auth): log session cookie source
All checks were successful
ci/woodpecker/push/infra Pipeline was successful
ci/woodpecker/push/orchestrator Pipeline was successful
ci/woodpecker/push/api Pipeline was successful
ci/woodpecker/push/web Pipeline was successful

This commit is contained in:
2026-02-18 21:30:00 -06:00
parent fa9f173f8e
commit af299abdaf
21 changed files with 1502 additions and 78 deletions

View File

@@ -5,7 +5,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { API_BASE_URL } from "../config";
import { API_BASE_URL, IS_MOCK_AUTH_MODE } from "../config";
/**
* In-memory CSRF token storage
@@ -41,6 +41,74 @@ export interface ApiRequestOptions extends RequestInit {
_isRetry?: boolean; // Internal flag to prevent infinite retry loops
}
const MOCK_ACTIVE_PROJECTS_RESPONSE = [
{
id: "project-dev-1",
name: "Mosaic Stack FE Go-Live",
status: "active",
lastActivity: new Date().toISOString(),
taskCount: 7,
eventCount: 2,
color: "#3B82F6",
},
{
id: "project-dev-2",
name: "Auth Flow Remediation",
status: "in-progress",
lastActivity: new Date(Date.now() - 12 * 60_000).toISOString(),
taskCount: 4,
eventCount: 0,
color: "#F59E0B",
},
] as const;
const MOCK_AGENT_CHAINS_RESPONSE = [
{
id: "agent-session-dev-1",
sessionKey: "dev-session-1",
label: "UI Validator Agent",
channel: "codex",
agentName: "jarvis-agent",
agentStatus: "WORKING",
status: "active",
startedAt: new Date(Date.now() - 42 * 60_000).toISOString(),
lastMessageAt: new Date(Date.now() - 20_000).toISOString(),
runtimeMs: 42 * 60_000,
messageCount: 27,
contextSummary: "Validating dashboard, tasks, and auth-bypass UX for local development flow.",
},
{
id: "agent-session-dev-2",
sessionKey: "dev-session-2",
label: "Telemetry Stub Agent",
channel: "codex",
agentName: "jarvis-agent",
agentStatus: "TERMINATED",
status: "ended",
startedAt: new Date(Date.now() - 3 * 60 * 60_000).toISOString(),
lastMessageAt: new Date(Date.now() - 2 * 60 * 60_000).toISOString(),
runtimeMs: 63 * 60_000,
messageCount: 41,
contextSummary: "Generated telemetry mock payloads for usage and widget rendering.",
},
] as const;
function getMockApiResponse(endpoint: string, method: string): unknown {
if (!IS_MOCK_AUTH_MODE || process.env.NODE_ENV !== "development") {
return undefined;
}
if (method === "POST" && endpoint === "/api/widgets/data/active-projects") {
return [...MOCK_ACTIVE_PROJECTS_RESPONSE];
}
if (method === "POST" && endpoint === "/api/widgets/data/agent-chains") {
return [...MOCK_AGENT_CHAINS_RESPONSE];
}
return undefined;
}
/**
* Fetch CSRF token from the API
* Token is stored in an httpOnly cookie and returned in response body
@@ -100,6 +168,12 @@ async function ensureCsrfToken(): Promise<string> {
export async function apiRequest<T>(endpoint: string, options: ApiRequestOptions = {}): Promise<T> {
const url = `${API_BASE_URL}${endpoint}`;
const { workspaceId, timeoutMs, _isRetry, ...fetchOptions } = options;
const method = (fetchOptions.method ?? "GET").toUpperCase();
const mockResponse = getMockApiResponse(endpoint, method);
if (mockResponse !== undefined) {
return mockResponse as T;
}
// Set up abort controller for timeout
const timeout = timeoutMs ?? DEFAULT_API_TIMEOUT_MS;
@@ -134,7 +208,6 @@ export async function apiRequest<T>(endpoint: string, options: ApiRequestOptions
}
// Add CSRF token for state-changing requests (POST, PUT, PATCH, DELETE)
const method = (fetchOptions.method ?? "GET").toUpperCase();
const isStateChanging = ["POST", "PUT", "PATCH", "DELETE"].includes(method);
if (isStateChanging) {