{"version":3,"file":"resource-permissions.mjs","sources":["../../../../src/lib/auth/rbac/resource-permissions.ts"],"sourcesContent":["/**\n * Resource Permissions\n *\n * Manages resource-level permissions and access control lists (ACLs).\n * Provides fine-grained access control at the individual resource level.\n *\n * @module auth/rbac/resource-permissions\n */\n\nimport type { ResourcePermission, ResourceACL, PermissionAction } from './types';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Permission levels from least to most permissive.\n */\nexport const PERMISSION_LEVELS = {\n  none: 0,\n  view: 1,\n  edit: 2,\n  manage: 3,\n  owner: 4,\n} as const;\n\n/**\n * Actions allowed at each permission level.\n */\nexport const LEVEL_ACTIONS: Record<keyof typeof PERMISSION_LEVELS, PermissionAction[]> = {\n  none: [],\n  view: ['read', 'list'],\n  edit: ['read', 'list', 'update'],\n  manage: ['read', 'list', 'update', 'delete', 'create'],\n  owner: ['read', 'list', 'update', 'delete', 'create', 'manage', '*'],\n};\n\n// =============================================================================\n// Resource Permission Manager\n// =============================================================================\n\n/**\n * Resource Permission Manager for managing resource-level access control.\n *\n * Provides functionality for managing individual resource permissions,\n * including ACL management, permission inheritance, and access checking.\n *\n * @example\n * ```typescript\n * const manager = new ResourcePermissionManager();\n *\n * // Create an ACL for a document\n * manager.createACL('documents', 'doc-123', 'user-456');\n *\n * // Grant permission to another user\n * manager.grantPermission('documents', 'doc-123', {\n *   granteeType: 'user',\n *   granteeId: 'user-789',\n *   permissionLevel: 'edit',\n * });\n *\n * // Check permission\n * manager.checkAccess('documents', 'doc-123', 'user-789', 'update'); // true\n * ```\n */\nexport class ResourcePermissionManager {\n  private acls: Map<string, ResourceACL>;\n  private permissionsByGrantee: Map<string, ResourcePermission[]>;\n\n  constructor() {\n    this.acls = new Map();\n    this.permissionsByGrantee = new Map();\n  }\n\n  // ===========================================================================\n  // ACL Management\n  // ===========================================================================\n\n  /**\n   * Create a new ACL for a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param owner - Owner user ID\n   * @param options - Additional options\n   * @returns Created ACL\n   */\n  createACL(\n    resourceType: string,\n    resourceId: string,\n    owner: string,\n    options?: {\n      inheritParent?: boolean;\n      parentResource?: { type: string; id: string };\n    }\n  ): ResourceACL {\n    const aclKey = this.getACLKey(resourceType, resourceId);\n\n    const acl: ResourceACL = {\n      resourceType,\n      resourceId,\n      owner,\n      entries: [\n        // Owner always has full access\n        {\n          resourceType,\n          resourceId,\n          granteeType: 'user',\n          granteeId: owner,\n          permissionLevel: 'owner',\n          grantedAt: new Date().toISOString(),\n          grantedBy: owner,\n        },\n      ],\n      inheritParent: options?.inheritParent ?? false,\n      parentResource: options?.parentResource,\n      version: 1,\n      updatedAt: new Date().toISOString(),\n    };\n\n    this.acls.set(aclKey, acl);\n    const [firstEntry] = acl.entries;\n    if (firstEntry != null) this.indexPermission(firstEntry);\n\n    return acl;\n  }\n\n  /**\n   * Get ACL for a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @returns ACL or undefined\n   */\n  getACL(resourceType: string, resourceId: string): ResourceACL | undefined {\n    return this.acls.get(this.getACLKey(resourceType, resourceId));\n  }\n\n  /**\n   * Delete ACL for a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   */\n  deleteACL(resourceType: string, resourceId: string): void {\n    const aclKey = this.getACLKey(resourceType, resourceId);\n    const acl = this.acls.get(aclKey);\n\n    if (acl) {\n      // Remove permission indexes\n      for (const entry of acl.entries) {\n        this.removePermissionIndex(entry);\n      }\n      this.acls.delete(aclKey);\n    }\n  }\n\n  /**\n   * Transfer ownership of a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param newOwner - New owner user ID\n   * @param grantor - User performing the transfer\n   */\n  transferOwnership(\n    resourceType: string,\n    resourceId: string,\n    newOwner: string,\n    grantor: string\n  ): void {\n    const acl = this.getACL(resourceType, resourceId);\n    if (!acl) {\n      throw new Error(`ACL not found for ${resourceType}/${resourceId}`);\n    }\n\n    // Update owner\n    const oldOwner = acl.owner;\n    acl.owner = newOwner;\n\n    // Update owner's permission entry\n    const ownerEntry = acl.entries.find(\n      (e) => e.granteeType === 'user' && e.granteeId === oldOwner && e.permissionLevel === 'owner'\n    );\n    if (ownerEntry) {\n      ownerEntry.granteeId = newOwner;\n      ownerEntry.grantedBy = grantor;\n      ownerEntry.grantedAt = new Date().toISOString();\n    }\n\n    // Demote old owner to manager\n    this.grantPermission(\n      resourceType,\n      resourceId,\n      {\n        granteeType: 'user',\n        granteeId: oldOwner,\n        permissionLevel: 'manage',\n      },\n      grantor\n    );\n\n    acl.version++;\n    acl.updatedAt = new Date().toISOString();\n  }\n\n  // ===========================================================================\n  // Permission Granting\n  // ===========================================================================\n\n  /**\n   * Grant permission on a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param grant - Permission grant details\n   * @param grantor - User granting the permission\n   */\n  grantPermission(\n    resourceType: string,\n    resourceId: string,\n    grant: {\n      granteeType: ResourcePermission['granteeType'];\n      granteeId?: string;\n      permissionLevel: ResourcePermission['permissionLevel'];\n      actions?: PermissionAction[];\n      expiresAt?: string;\n    },\n    grantor?: string\n  ): void {\n    const acl = this.getOrCreateACL(resourceType, resourceId, grantor);\n\n    // Remove existing permission for this grantee\n    this.revokePermission(resourceType, resourceId, grant.granteeType, grant.granteeId);\n\n    const permission: ResourcePermission = {\n      resourceType,\n      resourceId,\n      granteeType: grant.granteeType,\n      granteeId: grant.granteeId,\n      permissionLevel: grant.permissionLevel,\n      actions: grant.actions,\n      grantedAt: new Date().toISOString(),\n      grantedBy: grantor,\n      expiresAt: grant.expiresAt,\n    };\n\n    acl.entries.push(permission);\n    this.indexPermission(permission);\n\n    acl.version++;\n    acl.updatedAt = new Date().toISOString();\n  }\n\n  /**\n   * Revoke permission on a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param granteeType - Grantee type\n   * @param granteeId - Grantee ID (optional for 'everyone')\n   */\n  revokePermission(\n    resourceType: string,\n    resourceId: string,\n    granteeType: ResourcePermission['granteeType'],\n    granteeId?: string\n  ): void {\n    const acl = this.getACL(resourceType, resourceId);\n    if (!acl) return;\n\n    const index = acl.entries.findIndex(\n      (e) =>\n        e.granteeType === granteeType && (granteeType === 'everyone' || e.granteeId === granteeId)\n    );\n\n    if (index !== -1) {\n      const [removed] = acl.entries.splice(index, 1);\n      if (removed != null) this.removePermissionIndex(removed);\n      acl.version++;\n      acl.updatedAt = new Date().toISOString();\n    }\n  }\n\n  /**\n   * Grant permission to everyone.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param permissionLevel - Permission level\n   * @param grantor - User granting\n   */\n  grantPublicAccess(\n    resourceType: string,\n    resourceId: string,\n    permissionLevel: 'view' | 'edit' = 'view',\n    grantor?: string\n  ): void {\n    this.grantPermission(\n      resourceType,\n      resourceId,\n      {\n        granteeType: 'everyone',\n        permissionLevel,\n      },\n      grantor\n    );\n  }\n\n  /**\n   * Revoke public access.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   */\n  revokePublicAccess(resourceType: string, resourceId: string): void {\n    this.revokePermission(resourceType, resourceId, 'everyone');\n  }\n\n  // ===========================================================================\n  // Access Checking\n  // ===========================================================================\n\n  /**\n   * Check if a user has access to perform an action on a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param userId - User ID\n   * @param action - Action to check\n   * @param context - Additional context\n   * @returns Whether access is allowed\n   */\n  checkAccess(\n    resourceType: string,\n    resourceId: string,\n    userId: string,\n    action: PermissionAction,\n    context?: {\n      userRoles?: string[];\n      userGroups?: string[];\n    }\n  ): boolean {\n    const acl = this.getACL(resourceType, resourceId);\n    if (!acl) return false;\n\n    // Check user-specific permission\n    const userPermission = this.findPermission(acl, 'user', userId);\n    if (userPermission && this.actionAllowed(userPermission, action)) {\n      return true;\n    }\n\n    // Check role-based permissions\n    if (context?.userRoles) {\n      for (const role of context.userRoles) {\n        const rolePermission = this.findPermission(acl, 'role', role);\n        if (rolePermission && this.actionAllowed(rolePermission, action)) {\n          return true;\n        }\n      }\n    }\n\n    // Check group-based permissions\n    if (context?.userGroups) {\n      for (const group of context.userGroups) {\n        const groupPermission = this.findPermission(acl, 'group', group);\n        if (groupPermission && this.actionAllowed(groupPermission, action)) {\n          return true;\n        }\n      }\n    }\n\n    // Check 'everyone' permission\n    const everyonePermission = this.findPermission(acl, 'everyone');\n    if (everyonePermission && this.actionAllowed(everyonePermission, action)) {\n      return true;\n    }\n\n    // Check inherited permissions\n    if (acl.inheritParent === true && acl.parentResource != null) {\n      return this.checkAccess(\n        acl.parentResource.type,\n        acl.parentResource.id,\n        userId,\n        action,\n        context\n      );\n    }\n\n    return false;\n  }\n\n  /**\n   * Get the effective permission level for a user on a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @param userId - User ID\n   * @param context - Additional context\n   * @returns Effective permission level\n   */\n  getEffectivePermissionLevel(\n    resourceType: string,\n    resourceId: string,\n    userId: string,\n    context?: {\n      userRoles?: string[];\n      userGroups?: string[];\n    }\n  ): ResourcePermission['permissionLevel'] {\n    const acl = this.getACL(resourceType, resourceId);\n    if (!acl) return 'none';\n\n    let highestLevel: ResourcePermission['permissionLevel'] = 'none';\n\n    // Check user-specific permission\n    const userPermission = this.findPermission(acl, 'user', userId);\n    if (userPermission) {\n      highestLevel = this.getHigherLevel(highestLevel, userPermission.permissionLevel);\n    }\n\n    // Check role-based permissions\n    if (context?.userRoles) {\n      for (const role of context.userRoles) {\n        const rolePermission = this.findPermission(acl, 'role', role);\n        if (rolePermission) {\n          highestLevel = this.getHigherLevel(highestLevel, rolePermission.permissionLevel);\n        }\n      }\n    }\n\n    // Check group-based permissions\n    if (context?.userGroups) {\n      for (const group of context.userGroups) {\n        const groupPermission = this.findPermission(acl, 'group', group);\n        if (groupPermission) {\n          highestLevel = this.getHigherLevel(highestLevel, groupPermission.permissionLevel);\n        }\n      }\n    }\n\n    // Check 'everyone' permission\n    const everyonePermission = this.findPermission(acl, 'everyone');\n    if (everyonePermission) {\n      highestLevel = this.getHigherLevel(highestLevel, everyonePermission.permissionLevel);\n    }\n\n    return highestLevel;\n  }\n\n  /**\n   * Get all resources a user has access to.\n   *\n   * @param userId - User ID\n   * @param resourceType - Optional resource type filter\n   * @returns Array of accessible resource IDs\n   */\n  getAccessibleResources(userId: string, resourceType?: string): string[] {\n    const granteeKey = this.getGranteeKey('user', userId);\n    const permissions = this.permissionsByGrantee.get(granteeKey) ?? [];\n\n    return permissions\n      .filter((p) => resourceType == null || resourceType === '' || p.resourceType === resourceType)\n      .filter((p) => !this.isExpired(p))\n      .map((p) => p.resourceId ?? '')\n      .filter((id) => id !== '');\n  }\n\n  /**\n   * Get all users with access to a resource.\n   *\n   * @param resourceType - Resource type\n   * @param resourceId - Resource ID\n   * @returns Array of user permissions\n   */\n  getResourcePermissions(resourceType: string, resourceId: string): ResourcePermission[] {\n    const acl = this.getACL(resourceType, resourceId);\n    if (!acl) return [];\n\n    return acl.entries.filter((e) => !this.isExpired(e));\n  }\n\n  // ===========================================================================\n  // Private Methods\n  // ===========================================================================\n\n  /**\n   * Get ACL key from resource type and ID.\n   */\n  private getACLKey(resourceType: string, resourceId: string): string {\n    return `${resourceType}:${resourceId}`;\n  }\n\n  /**\n   * Get grantee key for indexing.\n   */\n  private getGranteeKey(\n    granteeType: ResourcePermission['granteeType'],\n    granteeId?: string\n  ): string {\n    return granteeType === 'everyone' ? 'everyone' : `${granteeType}:${granteeId}`;\n  }\n\n  /**\n   * Get or create ACL for a resource.\n   */\n  private getOrCreateACL(resourceType: string, resourceId: string, owner?: string): ResourceACL {\n    let acl = this.getACL(resourceType, resourceId);\n    acl ??= this.createACL(resourceType, resourceId, owner ?? 'system');\n    return acl;\n  }\n\n  /**\n   * Find permission in ACL entries.\n   */\n  private findPermission(\n    acl: ResourceACL,\n    granteeType: ResourcePermission['granteeType'],\n    granteeId?: string\n  ): ResourcePermission | undefined {\n    return acl.entries.find(\n      (e) =>\n        e.granteeType === granteeType &&\n        (granteeType === 'everyone' || e.granteeId === granteeId) &&\n        !this.isExpired(e)\n    );\n  }\n\n  /**\n   * Check if an action is allowed by a permission.\n   */\n  private actionAllowed(permission: ResourcePermission, action: PermissionAction): boolean {\n    // Check specific actions if defined\n    if ((permission.actions?.length ?? 0) > 0) {\n      return (\n        (permission.actions ?? []).includes(action) || (permission.actions ?? []).includes('*')\n      );\n    }\n\n    // Check against level-based actions\n    const levelActions = LEVEL_ACTIONS[permission.permissionLevel];\n    return levelActions.includes(action) || levelActions.includes('*');\n  }\n\n  /**\n   * Get the higher of two permission levels.\n   */\n  private getHigherLevel(\n    a: ResourcePermission['permissionLevel'],\n    b: ResourcePermission['permissionLevel']\n  ): ResourcePermission['permissionLevel'] {\n    return PERMISSION_LEVELS[a] >= PERMISSION_LEVELS[b] ? a : b;\n  }\n\n  /**\n   * Check if a permission has expired.\n   */\n  private isExpired(permission: ResourcePermission): boolean {\n    if (permission.expiresAt == null || permission.expiresAt === '') return false;\n    return new Date(permission.expiresAt) < new Date();\n  }\n\n  /**\n   * Index a permission for quick lookup by grantee.\n   */\n  private indexPermission(permission: ResourcePermission): void {\n    const granteeKey = this.getGranteeKey(permission.granteeType, permission.granteeId);\n\n    if (!this.permissionsByGrantee.has(granteeKey)) {\n      this.permissionsByGrantee.set(granteeKey, []);\n    }\n\n    const granteePermissions = this.permissionsByGrantee.get(granteeKey);\n    if (granteePermissions != null) {\n      granteePermissions.push(permission);\n    }\n  }\n\n  /**\n   * Remove a permission from the index.\n   */\n  private removePermissionIndex(permission: ResourcePermission): void {\n    const granteeKey = this.getGranteeKey(permission.granteeType, permission.granteeId);\n\n    const permissions = this.permissionsByGrantee.get(granteeKey);\n    if (permissions) {\n      const index = permissions.findIndex(\n        (p) => p.resourceType === permission.resourceType && p.resourceId === permission.resourceId\n      );\n      if (index !== -1) {\n        permissions.splice(index, 1);\n      }\n    }\n  }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new resource permission manager.\n *\n * @returns ResourcePermissionManager instance\n */\nexport function createResourcePermissionManager(): ResourcePermissionManager {\n  return new ResourcePermissionManager();\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Check if a permission level grants a specific action.\n *\n * @param level - Permission level\n * @param action - Action to check\n * @returns Whether action is granted\n */\nexport function levelGrantsAction(\n  level: keyof typeof PERMISSION_LEVELS,\n  action: PermissionAction\n): boolean {\n  const levelActions = LEVEL_ACTIONS[level];\n  return levelActions.includes(action) || levelActions.includes('*');\n}\n\n/**\n * Get the minimum permission level required for an action.\n *\n * @param action - Action to check\n * @returns Minimum required level\n */\nexport function getMinimumLevelForAction(action: PermissionAction): keyof typeof PERMISSION_LEVELS {\n  for (const [level, actions] of Object.entries(LEVEL_ACTIONS)) {\n    if (actions.includes(action) || actions.includes('*')) {\n      return level as keyof typeof PERMISSION_LEVELS;\n    }\n  }\n  return 'owner';\n}\n\n/**\n * Compare two permission levels.\n *\n * @param a - First level\n * @param b - Second level\n * @returns Positive if a > b, negative if a < b, 0 if equal\n */\nexport function comparePermissionLevels(\n  a: keyof typeof PERMISSION_LEVELS,\n  b: keyof typeof PERMISSION_LEVELS\n): number {\n  return PERMISSION_LEVELS[a] - PERMISSION_LEVELS[b];\n}\n"],"names":["PERMISSION_LEVELS","LEVEL_ACTIONS","ResourcePermissionManager","resourceType","resourceId","owner","options","aclKey","acl","firstEntry","entry","newOwner","grantor","oldOwner","ownerEntry","e","grant","permission","granteeType","granteeId","index","removed","permissionLevel","userId","action","context","userPermission","role","rolePermission","group","groupPermission","everyonePermission","highestLevel","granteeKey","p","id","levelActions","a","b","granteePermissions","permissions","createResourcePermissionManager","levelGrantsAction","level","getMinimumLevelForAction","actions","comparePermissionLevels"],"mappings":"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"}