102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
/**
|
|
* User Context Module
|
|
* Manages the active user context for per-user config isolation
|
|
*/
|
|
|
|
import path from "path"
|
|
import os from "os"
|
|
import { existsSync, mkdirSync } from "fs"
|
|
|
|
const CONFIG_ROOT = path.join(os.homedir(), ".config", "codenomad")
|
|
const USERS_ROOT = path.join(CONFIG_ROOT, "users")
|
|
|
|
// Active user ID (set by the main process or HTTP header)
|
|
let activeUserId: string | null = null
|
|
|
|
/**
|
|
* Set the active user ID
|
|
*/
|
|
export function setActiveUserId(userId: string | null): void {
|
|
activeUserId = userId
|
|
console.log(`[UserContext] Active user set to: ${userId || "(none)"}`)
|
|
}
|
|
|
|
/**
|
|
* Get the active user ID
|
|
*/
|
|
export function getActiveUserId(): string | null {
|
|
return activeUserId
|
|
}
|
|
|
|
/**
|
|
* Get the data root for a specific user
|
|
* Falls back to global config if no user is set
|
|
*/
|
|
export function getUserDataRoot(userId?: string): string {
|
|
const effectiveUserId = userId || activeUserId
|
|
|
|
if (effectiveUserId) {
|
|
const userDir = path.join(USERS_ROOT, effectiveUserId)
|
|
return userDir
|
|
}
|
|
|
|
// Prioritize environment variable if set (from Electron)
|
|
const override = process.env.CODENOMAD_USER_DIR
|
|
if (override && override.trim().length > 0) {
|
|
return path.resolve(override)
|
|
}
|
|
|
|
// Fallback to global config root
|
|
return CONFIG_ROOT
|
|
}
|
|
|
|
/**
|
|
* Get the integrations directory for the current or specified user
|
|
*/
|
|
export function getUserIntegrationsDir(userId?: string): string {
|
|
const userRoot = getUserDataRoot(userId)
|
|
const integrationsDir = path.join(userRoot, "integrations")
|
|
|
|
// Ensure directory exists
|
|
if (!existsSync(integrationsDir)) {
|
|
try {
|
|
mkdirSync(integrationsDir, { recursive: true })
|
|
console.log(`[UserContext] Created integrations dir: ${integrationsDir}`)
|
|
} catch (e) {
|
|
console.error(`[UserContext] Failed to create integrations dir:`, e)
|
|
}
|
|
}
|
|
|
|
return integrationsDir
|
|
}
|
|
|
|
/**
|
|
* Get the instances directory for the current or specified user
|
|
*/
|
|
export function getUserInstancesDir(userId?: string): string {
|
|
const userRoot = getUserDataRoot(userId)
|
|
return path.join(userRoot, "instances")
|
|
}
|
|
|
|
/**
|
|
* Get the config file path for a specific integration
|
|
*/
|
|
export function getIntegrationConfigPath(integrationId: string, userId?: string): string {
|
|
const integrationsDir = getUserIntegrationsDir(userId)
|
|
return path.join(integrationsDir, `${integrationId}-config.json`)
|
|
}
|
|
|
|
/**
|
|
* Extract user ID from request headers
|
|
*/
|
|
export function getUserIdFromRequest(request: { headers?: Record<string, string | string[] | undefined> }): string | null {
|
|
const header = request.headers?.["x-user-id"]
|
|
if (typeof header === "string" && header.length > 0) {
|
|
return header
|
|
}
|
|
if (Array.isArray(header) && header.length > 0) {
|
|
return header[0]
|
|
}
|
|
return activeUserId
|
|
}
|