aegida-console / lib / auth / types.ts
types.ts
Raw
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<AuthIdentity, "id" | "email"> & {
  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<string, unknown> {
  return typeof value === "object" && value !== null;
}

function isString(value: unknown): value is string {
  return typeof value === "string";
}