T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/lavocat.ca/public_html/src/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/public_html/src/lib/permissions.ts
import { prisma } from './prisma';

export interface PermissionCheck {
  role: string;
  resource: string;
  action: string;
  conditions?: any;
  userId?: string;
  targetId?: string;
}

export interface User {
  id: string;
  role: string;
  email: string;
  name?: string;
}

// Role hierarchy for permission inheritance
const ROLE_HIERARCHY = {
  'SUPERADMIN': 999,
  'ADMIN': 100,
  'LAWYER': 90,
  'SECRETARY': 50,
  'CLERK': 40,
  'ASSISTANT': 30,
  'USER': 10
};

// Check if user has permission for a specific action
export async function hasPermission(
  user: User,
  resource: string,
  action: string,
  options?: {
    targetId?: string;
    conditions?: any;
  }
): Promise<boolean> {
  try {
    // SUPERADMIN has all permissions
    if (user.role === 'SUPERADMIN' || user.role === 'SUPERADMIN') {
      return true;
    }

    // Find specific permission
    const permission = await prisma.permission.findUnique({
      where: {
        role_resource_action: {
          role: user.role,
          resource,
          action
        }
      }
    });

    if (!permission) {
      return false;
    }

    // Check additional conditions if they exist
    if (permission.conditions) {
      const conditions = JSON.parse(permission.conditions);
      return checkConditions(user, conditions, options);
    }

    return true;

  } catch (error) {
    console.error('Error checking permission:', error);
    return false;
  }
}

// Check conditional permissions
function checkConditions(
  user: User,
  conditions: any,
  options?: { targetId?: string; conditions?: any }
): boolean {
  // Scope-based conditions
  if (conditions.scope) {
    switch (conditions.scope) {
      case 'own':
        return options?.targetId === user.id;
      case 'assigned':
        // TODO: Check if user is assigned to the case
        return true; // Placeholder - implement case assignment check
      case 'basic_info':
        return true; // Allow reading basic info
      default:
        return true;
    }
  }

  // Field-based restrictions
  if (conditions.fields) {
    return true; // Field-level permissions handled at application level
  }

  // Type-based restrictions
  if (conditions.types) {
    return true; // Type-level permissions handled at application level
  }

  return true;
}

// Check multiple permissions at once
export async function hasAnyPermission(
  user: User,
  checks: Array<{ resource: string; action: string; conditions?: any }>
): Promise<boolean> {
  for (const check of checks) {
    if (await hasPermission(user, check.resource, check.action, check.conditions)) {
      return true;
    }
  }
  return false;
}

// Check if user can access a specific case
export async function canAccessCase(
  user: User,
  caseId: string,
  action: 'read' | 'write' | 'delete' = 'read'
): Promise<boolean> {
  // SUPERADMIN and LAWYER roles can access all cases
  if (user.role === 'SUPERADMIN' || user.role === 'SUPERADMIN' || user.role === 'LAWYER' || user.role === 'ADMIN') {
    return hasPermission(user, 'cases', action);
  }

  // Check if user is assigned to the case
  const assignment = await prisma.caseAssignment.findFirst({
    where: {
      registrationId: caseId,
      userId: user.id,
      isActive: true
    }
  });

  if (assignment) {
    return hasPermission(user, 'cases', action, { targetId: caseId });
  }

  // Check if it's the user's own case (for clients)
  if (user.role === 'USER') {
    const registration = await prisma.registration.findFirst({
      where: {
        id: caseId,
        userId: user.id
      }
    });
    return !!registration;
  }

  return false;
}

// Check document access permissions
export async function canAccessDocument(
  user: User,
  documentId: string,
  action: 'read' | 'write' | 'download' | 'delete' = 'read'
): Promise<boolean> {
  // Get document details
  const document = await prisma.document.findUnique({
    where: { id: documentId },
    include: { registration: true }
  });

  if (!document) {
    return false;
  }

  // Check case access first
  const canAccessRelatedCase = await canAccessCase(user, document.registrationId, 'read');
  if (!canAccessRelatedCase) {
    return false;
  }

  // Check specific document permission
  return hasPermission(user, 'documents', action, { targetId: documentId });
}

// Get user's role level for comparisons
export function getRoleLevel(role: string): number {
  return ROLE_HIERARCHY[role as keyof typeof ROLE_HIERARCHY] || 0;
}

// Check if user can manage another user
export function canManageUser(managerRole: string, targetRole: string): boolean {
  return getRoleLevel(managerRole) > getRoleLevel(targetRole);
}

// Permission middleware for API routes
export function requirePermission(resource: string, action: string) {
  return async (user: User, options?: any) => {
    const allowed = await hasPermission(user, resource, action, options);
    if (!allowed) {
      throw new Error(`Insufficient permissions: ${resource}:${action}`);
    }
    return true;
  };
}

// Get all permissions for a role
export async function getRolePermissions(role: string) {
  return prisma.permission.findMany({
    where: { role },
    select: {
      resource: true,
      action: true,
      conditions: true
    }
  });
}

// Assign user to case
export async function assignUserToCase(
  caseId: string,
  userId: string,
  role: string,
  assignedBy: string
): Promise<boolean> {
  try {
    await prisma.caseAssignment.create({
      data: {
        registrationId: caseId,
        userId,
        role,
        assignedBy
      }
    });
    return true;
  } catch (error) {
    console.error('Error assigning user to case:', error);
    return false;
  }
}

// Remove user from case
export async function removeUserFromCase(
  caseId: string,
  userId: string
): Promise<boolean> {
  try {
    await prisma.caseAssignment.updateMany({
      where: {
        registrationId: caseId,
        userId
      },
      data: {
        isActive: false
      }
    });
    return true;
  } catch (error) {
    console.error('Error removing user from case:', error);
    return false;
  }
}

// Get users assigned to a case
export async function getCaseAssignments(caseId: string) {
  return prisma.caseAssignment.findMany({
    where: {
      registrationId: caseId,
      isActive: true
    },
    include: {
      user: {
        select: {
          id: true,
          name: true,
          email: true,
          role: true,
          title: true
        }
      }
    }
  });
} 

CasperSecurity Mini