{"version":3,"file":"user.mjs","names":["RoleIdEnums","UserCanMap","Record","UserRole","roleId","tenantId","productId","name","description","productVersionId","isProductRole","isSystemWide","UserApiResponse","firstName","familyName","jobTitle","email","mobile","phone","location","userId","externalUUID","isUnitySystemAdmin","roles","permissions","can","defaultTenantId","currentTenantId","statusCode","assertNonEmptyString","value","fieldName","trim","length","Error","getHttpStatusCodeFromError","isApiResponse","v","Partial","Array","isArray","User","accessToken","products","tenantIds","additionalProperties","constructor","api","currentTenantIdParam","userLike","arg","Boolean","undefined","u","hasRole","Unity_System_Administrator","id","unityId","aadId","roleIds","map","r","roleNames","includes","toJSON","createUser","userInfo","createUserFromUserObject","userObject"],"sources":["../../../src/utilities/auth/user.ts"],"sourcesContent":["import { RoleIdEnums } from '../../enums/unitySystemEnums';\n\nexport type UserCanMap = Record<string, boolean | string | number | null | undefined>;\n\nexport interface UserRole {\n  roleId: string;\n  tenantId: string | null;\n  productId: number | null;\n  name: string;\n  description?: string | null;\n  productVersionId?: string | null;\n  isProductRole?: boolean;\n  isSystemWide?: boolean;\n}\n\nexport interface UserApiResponse {\n  name: string;\n  firstName: string;\n  familyName: string;\n  jobTitle: string | null;\n  email: string;\n  mobile: string | null;\n  phone: string | null;\n  location: string | null;\n  userId: string;\n  externalUUID: string;\n  isUnitySystemAdmin: boolean;\n  roles: UserRole[];\n  permissions: unknown[];\n  can: UserCanMap;\n  defaultTenantId: string;\n  currentTenantId: string;\n  statusCode?: number;\n}\n\nfunction assertNonEmptyString(value: unknown, fieldName: string): asserts value is string {\n  if (typeof value !== 'string' || value.trim().length === 0) {\n    throw new Error(`User is missing required field: ${fieldName}`);\n  }\n}\n\nfunction getHttpStatusCodeFromError(): number {\n  return 401;\n}\n\nfunction isApiResponse(value: unknown): value is UserApiResponse {\n  if (!value || typeof value !== 'object') return false;\n  const v = value as Partial<UserApiResponse>;\n  return (\n    typeof v.userId === 'string' &&\n    typeof v.externalUUID === 'string' &&\n    typeof v.name === 'string' &&\n    Array.isArray(v.roles)\n  );\n}\n\n/**\n * Canonical User model.\n *\n * - Construct from the new API response (preferred)\n * - Or rehydrate from a previously-serialized User instance\n *\n * NOTE: This model intentionally does NOT read from storage or config.\n */\nexport class User {\n  // --- Canonical fields (new API) ---\n  public readonly userId: string;\n  public readonly externalUUID: string;\n  public readonly name: string;\n  public readonly firstName: string;\n  public readonly familyName: string;\n  public readonly jobTitle: string | null;\n  public readonly email: string;\n  public readonly mobile: string | null;\n  public readonly phone: string | null;\n  public readonly location: string | null;\n  public readonly isUnitySystemAdmin: boolean;\n  public readonly roles: UserRole[];\n  public readonly permissions: unknown[];\n  public readonly can: UserCanMap;\n  public readonly defaultTenantId: string;\n  public readonly currentTenantId: string;\n\n  /**\n   * @deprecated Do not use `user.accessToken`.\n   * This value is not reliably refreshed/updated when the session is refreshed.\n   * Use token acquisition helpers instead.\n   */\n  public readonly accessToken?: string;\n\n  /** @deprecated Legacy/unused. use the TenantProvider i.e.\n   * `const tenant = useTenant()` to get TenantContext\n   * `tenant.activeTenant` to get the current tenant, and\n   * `tenant.activeTenant.products` for the product list.\n   */\n  public readonly products?: object[];\n  /** @deprecated Legacy/unused. Prefer TenantProvider i.e.\n   *  `const tenant = useTenant()` to get TenantContext\n   * `tenant.tenantsList` for the full list of tenants available to the user.\n   */\n  public readonly tenantIds?: string[];\n  /** @deprecated Legacy/unused. Do not use User model to store arbitrary data */\n  public readonly additionalProperties?: unknown;\n  /** @deprecated Legacy/unused. Prefer HTTP status handling outside the model */\n  public readonly statusCode?: number;\n\n  // Overloads (\"two constructors\")\n  public constructor(api: UserApiResponse, currentTenantIdParam?: string);\n  public constructor(userLike: Partial<User>);\n  public constructor(arg: UserApiResponse | Partial<User>, currentTenantIdParam?: string) {\n    // Deliberately ignored when the API response includes `currentTenantId` (response wins).\n    void currentTenantIdParam;\n    if (isApiResponse(arg)) {\n      assertNonEmptyString(arg.defaultTenantId, 'defaultTenantId');\n      assertNonEmptyString(arg.currentTenantId, 'currentTenantId');\n      assertNonEmptyString(arg.userId, 'userId');\n      assertNonEmptyString(arg.externalUUID, 'externalUUID');\n\n      this.userId = arg.userId;\n      this.externalUUID = arg.externalUUID;\n      this.name = arg.name ?? '';\n      this.firstName = arg.firstName ?? '';\n      this.familyName = arg.familyName ?? '';\n      this.jobTitle = arg.jobTitle ?? null;\n      this.email = arg.email ?? '';\n      this.mobile = arg.mobile ?? null;\n      this.phone = arg.phone ?? null;\n      this.location = arg.location ?? null;\n      this.isUnitySystemAdmin = Boolean(arg.isUnitySystemAdmin);\n      this.roles = Array.isArray(arg.roles) ? arg.roles : [];\n      this.permissions = Array.isArray(arg.permissions) ? arg.permissions : [];\n      this.can = arg.can ?? {};\n      this.defaultTenantId = arg.defaultTenantId;\n      this.currentTenantId = arg.currentTenantId;\n\n      // Legacy fields - intentionally minimized\n      this.accessToken = undefined;\n      this.products = undefined;\n      this.tenantIds = undefined;\n      this.additionalProperties = undefined;\n      // Deprecated: populate for legacy flows. Treat missing/invalid API response fields as unauthorized.\n      // If required fields are present, consider it a successful fetch.\n      this.statusCode = typeof arg.statusCode === 'number' ? arg.statusCode : 200;\n      return;\n    }\n\n    // Rehydrate path\n    const u = arg;\n    assertNonEmptyString(u.defaultTenantId, 'defaultTenantId');\n    assertNonEmptyString(u.currentTenantId, 'currentTenantId');\n    assertNonEmptyString(u.userId, 'userId');\n    assertNonEmptyString(u.externalUUID, 'externalUUID');\n\n    this.userId = u.userId;\n    this.externalUUID = u.externalUUID;\n    this.name = u.name ?? '';\n    this.firstName = u.firstName ?? '';\n    this.familyName = u.familyName ?? '';\n    this.jobTitle = u.jobTitle ?? null;\n    this.email = u.email ?? '';\n    this.mobile = u.mobile ?? null;\n    this.phone = u.phone ?? null;\n    this.location = u.location ?? null;\n    this.isUnitySystemAdmin = Boolean(u.isUnitySystemAdmin ?? this.hasRole(RoleIdEnums.Unity_System_Administrator));\n    this.roles = u.roles ?? [];\n    this.permissions = u.permissions ?? [];\n    this.can = u.can ?? {};\n    this.defaultTenantId = u.defaultTenantId;\n    this.currentTenantId = u.currentTenantId;\n\n    // Legacy pass-through (still deprecated)\n    this.accessToken = u.accessToken;\n    this.products = u.products;\n    this.tenantIds = u.tenantIds;\n    this.additionalProperties = u.additionalProperties;\n    this.statusCode = typeof u.statusCode === 'number' ? u.statusCode : 200;\n  }\n\n  // --- Deprecated legacy accessors (derived) ---\n  /** @deprecated Prefer `userId` */\n  public get id(): string {\n    return this.userId;\n  }\n\n  /** @deprecated Prefer `userId` */\n  public get unityId(): string {\n    return this.userId;\n  }\n\n  /** @deprecated Prefer `externalUUID` */\n  public get aadId(): string {\n    return this.externalUUID;\n  }\n\n  /** @deprecated Prefer `roles` */\n  public get roleIds(): string[] {\n    return (this.roles ?? []).map((r) => r.roleId);\n  }\n\n  /** @deprecated Prefer `roles` */\n  public get roleNames(): string[] {\n    return (this.roles ?? []).map((r) => r.name);\n  }\n\n  public hasRole(roleId: string): boolean {\n    return this.roleIds.includes(roleId);\n  }\n\n  public toJSON(): Record<string, unknown> {\n    // Ensure JSON.stringify(new User(...)) produces a plain object with stable keys.\n    return {\n      userId: this.userId,\n      externalUUID: this.externalUUID,\n      name: this.name,\n      firstName: this.firstName,\n      familyName: this.familyName,\n      jobTitle: this.jobTitle,\n      email: this.email,\n      mobile: this.mobile,\n      phone: this.phone,\n      location: this.location,\n      isUnitySystemAdmin: this.isUnitySystemAdmin,\n      roles: this.roles,\n      permissions: this.permissions,\n      can: this.can,\n      defaultTenantId: this.defaultTenantId,\n      currentTenantId: this.currentTenantId,\n\n      // Deprecated legacy\n      accessToken: this.accessToken,\n      products: this.products,\n      tenantIds: this.tenantIds,\n      additionalProperties: this.additionalProperties,\n      statusCode: this.statusCode\n    };\n  }\n}\n\n/**\n * @deprecated Prefer `new User(apiResponse)`.\n * This wrapper exists to reduce migration churn.\n */\nexport function createUser(userInfo: UserApiResponse): User {\n  try {\n    return new User(userInfo);\n  } catch {\n    // Legacy wrapper: surface a best-effort User instance with statusCode=401.\n    // Callers should migrate to handling HTTP errors outside the model.\n    return new User({\n      userId: 'unknown',\n      externalUUID: 'unknown',\n      name: '',\n      firstName: '',\n      familyName: '',\n      jobTitle: null,\n      email: '',\n      mobile: null,\n      phone: null,\n      location: null,\n      isUnitySystemAdmin: false,\n      roles: [],\n      permissions: [],\n      can: {},\n      defaultTenantId: 'unknown',\n      currentTenantId: 'unknown',\n      statusCode: getHttpStatusCodeFromError()\n    } as Partial<User>);\n  }\n}\n\n/**\n * @deprecated Prefer `new User(userLike)`.\n * This wrapper exists to reduce migration churn.\n */\nexport function createUserFromUserObject(userObject: Partial<User>): User {\n  return new User(userObject);\n}\n"],"mappings":"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"}