import { isModelId, type ModelId } from "@/lib/chat/types"; export type ExternalUserId = string; export type AuthIdentity = { id: string; externalUserId: ExternalUserId; login: string; fullName: string; position: string; email: string; firstName: string; lastName: string; middleName: string; roles: string[]; lastModelId: ModelId; }; export type AuthTokenIdentity = Pick< AuthIdentity, "id" | "email" | "externalUserId" > & { tenantId: string; }; export type LegacyAuthIdentity = Pick & { lastModelId?: ModelId; }; const maximumExternalUserId = "9223372036854775807"; const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; export function parseAuthIdentity(value: unknown): AuthIdentity | null { if (!isRecord(value)) return null; if ( !isUuid(value.id) || !isExternalUserId(value.externalUserId) || !isString(value.login) || !isString(value.fullName) || !isString(value.position) || !isString(value.email) || !isString(value.firstName) || !isString(value.lastName) || !isString(value.middleName) || !Array.isArray(value.roles) || !value.roles.every(isString) || !isModelId(value.lastModelId) ) { return null; } return { id: value.id, externalUserId: value.externalUserId, login: value.login, fullName: value.fullName, position: value.position, email: value.email, firstName: value.firstName, lastName: value.lastName, middleName: value.middleName, roles: value.roles, lastModelId: value.lastModelId, }; } export function isUuid(value: unknown): value is string { return typeof value === "string" && uuidPattern.test(value); } export function isExternalUserId(value: unknown): value is ExternalUserId { return ( typeof value === "string" && /^[1-9]\d*$/.test(value) && (value.length < maximumExternalUserId.length || (value.length === maximumExternalUserId.length && value <= maximumExternalUserId)) ); } function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null; } function isString(value: unknown): value is string { return typeof value === "string"; }