import { validateSessionById, isAuthEnabled, SESSION_COOKIE } from './auth'; import { validateApiToken } from './api-tokens'; import { isEnterprise } from './license'; import { userHasAdminRole, userCanAccessEnvironment } from './db'; export interface WsUpgradeAuth { userId: number; username: string; isAdmin: boolean; authDisabled: boolean; } function parseCookieHeader(header: string | undefined): Record { if (!header) return {}; const out: Record = {}; for (const part of header.split(';')) { const eq = part.indexOf('='); if (eq < 0) continue; const k = part.slice(0, eq).trim(); let v = part.slice(eq + 1).trim(); if (v.startsWith('"') && v.endsWith('"')) v = v.slice(1, -1); if (k) out[k] = decodeURIComponent(v); } return out; } type LowercasedHeaders = Record; function pickHeader(headers: LowercasedHeaders, name: string): string | undefined { const v = headers[name]; if (Array.isArray(v)) return v[0]; return v; } export async function authenticateWsUpgrade( headers: LowercasedHeaders ): Promise { const authEnabled = await isAuthEnabled(); if (!authEnabled) { return { userId: -1, username: '__bootstrap__', isAdmin: true, authDisabled: true }; } const cookieHeader = pickHeader(headers, 'cookie'); const cookies = parseCookieHeader(cookieHeader); const sessionId = cookies[SESSION_COOKIE]; if (sessionId) { const user = await validateSessionById(sessionId); if (user) { const enterprise = await isEnterprise(); const isAdmin = enterprise ? await userHasAdminRole(user.id) : true; return { userId: user.id, username: user.username, isAdmin, authDisabled: false }; } } const authHeader = pickHeader(headers, 'authorization'); if (authHeader && authHeader.startsWith('Bearer ')) { const token = authHeader.slice(7).trim(); const user = await validateApiToken(token); if (user) { const enterprise = await isEnterprise(); const isAdmin = enterprise ? await userHasAdminRole(user.id) : true; return { userId: user.id, username: user.username, isAdmin, authDisabled: false }; } } return null; } export async function canAccessEnvForUser( auth: WsUpgradeAuth, environmentId: number | undefined | null ): Promise { if (auth.authDisabled) return true; if (auth.isAdmin) return true; const enterprise = await isEnterprise(); if (!enterprise) return true; if (environmentId == null) { return false; } return userCanAccessEnvironment(auth.userId, environmentId); } declare global { // eslint-disable-next-line no-var var __authenticateWsUpgrade: | ((headers: LowercasedHeaders) => Promise) | undefined; // eslint-disable-next-line no-var var __canAccessEnvForUser: | ((auth: WsUpgradeAuth, envId: number | undefined | null) => Promise) | undefined; } globalThis.__authenticateWsUpgrade = authenticateWsUpgrade; globalThis.__canAccessEnvForUser = canAccessEnvForUser;