import type { Permission, ServiceTokenEntry } from "@/lib/constants/auth"; import { forbidden, unauthorized } from "@/modules/auth/errors"; export type VerifiedServiceToken = { customerId: string; permissions: Permission[]; }; let cachedEnvTokenMap: Map | null = null; function loadEnvTokenMap(): Map { if (cachedEnvTokenMap) { return cachedEnvTokenMap; } const raw = process.env.HOST_SERVICE_TOKENS; if (!raw) { cachedEnvTokenMap = new Map(); return cachedEnvTokenMap; } let parsed: Record; try { parsed = JSON.parse(raw) as Record; } catch { throw new Error("HOST_SERVICE_TOKENS 配置无效"); } cachedEnvTokenMap = new Map(Object.entries(parsed)); return cachedEnvTokenMap; } /** 测试专用:重置 env 缓存 */ export function resetServiceTokenEnvCache(): void { cachedEnvTokenMap = null; } function verifyFromEnvMap( token: string, customerId?: string, ): VerifiedServiceToken | null { const entry = loadEnvTokenMap().get(token); if (!entry) { return null; } if (customerId && entry.customerId !== customerId) { throw forbidden("customer_id 与令牌租户不匹配"); } return { customerId: entry.customerId, permissions: entry.permissions ?? [], }; } /** env 命中则返回,未命中返回 null(不抛错) */ export function resolveEnvServiceToken( token: string, customerId?: string, ): VerifiedServiceToken | null { return verifyFromEnvMap(token, customerId); } /** env 中的客户 ID(同步) */ export function listEnvCustomerIds(): string[] { const ids = new Set(); for (const entry of loadEnvTokenMap().values()) { ids.add(entry.customerId); } const registry = process.env.CUSTOMER_REGISTRY; if (registry) { for (const part of registry.split(",")) { const id = part.trim(); if (id) { ids.add(id); } } } return [...ids].sort(); } /** 同步:仅 env + CUSTOMER_REGISTRY */ export function listRegisteredCustomerIds(): string[] { return listEnvCustomerIds(); } export function isKnownCustomer(customerId: string): boolean { return listEnvCustomerIds().includes(customerId); } /** 同步:仅校验 env 中配置的 Token(middleware 快路径) */ export function verifyServiceTokenFromEnv( token: string, customerId: string, ): VerifiedServiceToken { const verified = verifyFromEnvMap(token, customerId); if (!verified) { throw unauthorized("Service Token 无效"); } return verified; } /** 同步:env token 解析(无 customer_id 头时) */ export function parseServiceTokenFromEnv( token: string, ): VerifiedServiceToken | null { return verifyFromEnvMap(token); } /** @deprecated 使用 verifyServiceTokenFromEnv */ export function verifyServiceToken( token: string, customerId: string, ): VerifiedServiceToken { return verifyServiceTokenFromEnv(token, customerId); } /** @deprecated 使用 parseServiceTokenFromEnv */ export function parseServiceToken(token: string): VerifiedServiceToken | null { return parseServiceTokenFromEnv(token); }