feat(acl): deep data access by section for roles and users
Role default + user override with OR rules; covers customers, leads, sales, activities, notes, routines, projects, and tickets.
This commit is contained in:
@@ -24,6 +24,7 @@ import { PrismaService } from '../prisma/prisma.service';
|
||||
import { SmsGatewayService } from '../sms-billing/sms-gateway.service';
|
||||
import { renderSmsText } from '../common/sms-text';
|
||||
import { OutboundSmsLogService } from '../outbound-sms/outbound-sms-log.service';
|
||||
import { leadsDeepWhere } from '../common/data-access';
|
||||
import {
|
||||
type Actor,
|
||||
elevated,
|
||||
@@ -59,18 +60,21 @@ function mobileKey(raw: string | null | undefined): string | null {
|
||||
return d.startsWith('0') ? d : d;
|
||||
}
|
||||
|
||||
function leadAccessWhere(baseActor: Actor): Prisma.LeadWhereInput {
|
||||
const actor = forScope(baseActor, 'leads');
|
||||
if (elevated(actor.role)) return {};
|
||||
if (actor.dataVisibility === 'org') return {};
|
||||
if (
|
||||
actor.dataVisibility === 'team' &&
|
||||
actor.visibleUserIds &&
|
||||
actor.visibleUserIds.length
|
||||
) {
|
||||
return { assigneeId: { in: actor.visibleUserIds } };
|
||||
function leadAccessWhere(actor: Actor): Prisma.LeadWhereInput {
|
||||
if (actor.leadsAccess !== undefined) {
|
||||
return leadsDeepWhere(actor);
|
||||
}
|
||||
return { assigneeId: actor.userId };
|
||||
const scoped = forScope(actor, 'leads');
|
||||
if (elevated(scoped.role)) return {};
|
||||
if (scoped.dataVisibility === 'org') return {};
|
||||
if (
|
||||
scoped.dataVisibility === 'team' &&
|
||||
scoped.visibleUserIds &&
|
||||
scoped.visibleUserIds.length
|
||||
) {
|
||||
return { assigneeId: { in: scoped.visibleUserIds } };
|
||||
}
|
||||
return { assigneeId: scoped.userId };
|
||||
}
|
||||
|
||||
const leadInclude = {
|
||||
|
||||
Reference in New Issue
Block a user