Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24b074f436 | |||
| 181b48105e |
+14
-2
@@ -13,6 +13,7 @@ import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/uti
|
||||
import { buildRecordInputFromFilter } from '@/object-record/record-table/utils/buildRecordInputFromFilter';
|
||||
import { buildCompositeValueFromSubField } from '@/object-record/record-table/utils/buildValueFromFilter';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isUndefined } from '@sniptt/guards';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { isDefined, isPlainObject } from 'twenty-shared/utils';
|
||||
@@ -76,8 +77,19 @@ export const useBuildRecordInputFromRLSPredicates = ({
|
||||
);
|
||||
}
|
||||
|
||||
let workspaceMemberFieldValue =
|
||||
currentWorkspaceMemberRecord?.[workspaceMemberFieldMetadataItem.name];
|
||||
let workspaceMemberFieldValue: unknown;
|
||||
|
||||
if (workspaceMemberFieldMetadataItem.type === FieldMetadataType.RELATION) {
|
||||
const joinColumnName =
|
||||
workspaceMemberFieldMetadataItem.settings?.joinColumnName ??
|
||||
`${workspaceMemberFieldMetadataItem.name}Id`;
|
||||
|
||||
workspaceMemberFieldValue =
|
||||
currentWorkspaceMemberRecord?.[joinColumnName];
|
||||
} else {
|
||||
workspaceMemberFieldValue =
|
||||
currentWorkspaceMemberRecord?.[workspaceMemberFieldMetadataItem.name];
|
||||
}
|
||||
|
||||
if (isCompositeFieldType(workspaceMemberFieldMetadataItem.type)) {
|
||||
if (!workspaceMemberSubFieldName) {
|
||||
|
||||
+2
-6
@@ -3,7 +3,6 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { getFilterTypeFromFieldType } from 'twenty-shared/utils';
|
||||
|
||||
import { CoreObjectNameSingular, FieldMetadataType } from 'twenty-shared/types';
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { AdvancedFilterFieldSelectSearchInput } from '@/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput';
|
||||
import { useAdvancedFilterFieldSelectDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown';
|
||||
@@ -60,12 +59,9 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectF
|
||||
fieldMetadataItem.label
|
||||
.toLocaleLowerCase()
|
||||
.includes(objectFilterDropdownSearchInput.toLocaleLowerCase()) &&
|
||||
(RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
|
||||
RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
|
||||
fieldMetadataItem.type,
|
||||
) ||
|
||||
(fieldMetadataItem.type === FieldMetadataType.RELATION &&
|
||||
fieldMetadataItem.relation?.targetObjectMetadata.nameSingular ===
|
||||
CoreObjectNameSingular.WorkspaceMember)),
|
||||
),
|
||||
)
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
|
||||
|
||||
+11
@@ -137,6 +137,17 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionMeValueSelec
|
||||
}
|
||||
|
||||
if (field.type === targetFieldType) {
|
||||
if (
|
||||
targetFieldType === FieldMetadataType.RELATION &&
|
||||
isDefined(selectedFieldMetadataItem)
|
||||
) {
|
||||
return (
|
||||
field.relation?.targetObjectMetadata.nameSingular ===
|
||||
selectedFieldMetadataItem.relation?.targetObjectMetadata
|
||||
.nameSingular
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+53
@@ -20,6 +20,7 @@ import { getCompositeSubFieldType } from '@/object-record/object-filter-dropdown
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { FormFieldInput } from '@/object-record/record-field/ui/components/FormFieldInput';
|
||||
import { FormMultiSelectFieldInput } from '@/object-record/record-field/ui/form-types/components/FormMultiSelectFieldInput';
|
||||
import { FormRelationToOneFieldInput } from '@/object-record/record-field/ui/form-types/components/FormRelationToOneFieldInput';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
|
||||
import { createRecordLevelPermissionVariablePicker } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/components/SettingsRolePermissionsObjectLevelRecordLevelPermissionVariablePicker';
|
||||
@@ -318,6 +319,58 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionValueInput =
|
||||
);
|
||||
}
|
||||
|
||||
if (fieldMetadataItem.type === FieldMetadataType.RELATION) {
|
||||
const targetObjectNameSingular =
|
||||
fieldMetadataItem.relation?.targetObjectMetadata.nameSingular;
|
||||
|
||||
let defaultRecordId: string | undefined;
|
||||
|
||||
if (isDefined(recordFilter.value) && recordFilter.value !== '') {
|
||||
try {
|
||||
const parsed = JSON.parse(recordFilter.value);
|
||||
|
||||
if (
|
||||
isDefined(parsed) &&
|
||||
Array.isArray(parsed.selectedRecordIds) &&
|
||||
parsed.selectedRecordIds.length > 0
|
||||
) {
|
||||
defaultRecordId = parsed.selectedRecordIds[0];
|
||||
}
|
||||
} catch {
|
||||
// value may not be valid JSON yet
|
||||
}
|
||||
}
|
||||
|
||||
const handleRelationChange = (value: JsonValue) => {
|
||||
if (!isDefined(value) || value === '') {
|
||||
applyObjectFilterDropdownFilterValue('');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const filterValue = JSON.stringify({
|
||||
isCurrentWorkspaceMemberSelected: false,
|
||||
selectedRecordIds: [value],
|
||||
});
|
||||
|
||||
applyObjectFilterDropdownFilterValue(filterValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledFormFieldInputWrapper>
|
||||
<FormRelationToOneFieldInput
|
||||
label=""
|
||||
objectNameSingular={targetObjectNameSingular}
|
||||
defaultValue={defaultRecordId}
|
||||
onChange={handleRelationChange}
|
||||
VariablePicker={RecordLevelPermissionPicker}
|
||||
/>
|
||||
</StyledFormFieldInputWrapper>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledFormFieldInputWrapper>
|
||||
|
||||
+1
@@ -14,4 +14,5 @@ export const RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES = [
|
||||
FieldMetadataType.EMAILS,
|
||||
FieldMetadataType.FULL_NAME,
|
||||
FieldMetadataType.ADDRESS,
|
||||
FieldMetadataType.RELATION,
|
||||
];
|
||||
|
||||
+3
-12
@@ -1,10 +1,6 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import {
|
||||
FieldMetadataType,
|
||||
RecordFilterGroupLogicalOperator,
|
||||
CoreObjectNameSingular,
|
||||
} from 'twenty-shared/types';
|
||||
import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types';
|
||||
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -60,13 +56,8 @@ export const useRecordLevelPermissionFilterActions = ({
|
||||
const getDefaultFieldMetadataItemForRLS = () => {
|
||||
const availableFieldMetadataItemsForRls =
|
||||
availableFieldMetadataItemsForFilter.filter((fieldMetadataItem) => {
|
||||
return (
|
||||
RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
|
||||
fieldMetadataItem.type,
|
||||
) ||
|
||||
(fieldMetadataItem.type === FieldMetadataType.RELATION &&
|
||||
fieldMetadataItem.relation?.targetObjectMetadata.nameSingular ===
|
||||
CoreObjectNameSingular.WorkspaceMember)
|
||||
return RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
|
||||
fieldMetadataItem.type,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+19
-12
@@ -48,18 +48,25 @@ export const applyRowLevelPermissionPredicates = <T extends ObjectLiteral>({
|
||||
? internalContext.userWorkspaceRoleMap[userWorkspaceId]
|
||||
: undefined;
|
||||
|
||||
const recordFilter = buildRowLevelPermissionRecordFilter({
|
||||
flatRowLevelPermissionPredicateMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateGroupMaps,
|
||||
flatFieldMetadataMaps: internalContext.flatFieldMetadataMaps,
|
||||
objectMetadata,
|
||||
roleId,
|
||||
workspaceMember: isUserAuthContext(authContext)
|
||||
? authContext.workspaceMember
|
||||
: undefined,
|
||||
});
|
||||
const { filter: recordFilter, hasUnresolvablePredicate } =
|
||||
buildRowLevelPermissionRecordFilter({
|
||||
flatRowLevelPermissionPredicateMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateGroupMaps,
|
||||
flatFieldMetadataMaps: internalContext.flatFieldMetadataMaps,
|
||||
objectMetadata,
|
||||
roleId,
|
||||
workspaceMember: isUserAuthContext(authContext)
|
||||
? authContext.workspaceMember
|
||||
: undefined,
|
||||
});
|
||||
|
||||
if (hasUnresolvablePredicate) {
|
||||
queryBuilder.andWhere('1 = 0');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!recordFilter || Object.keys(recordFilter).length === 0) {
|
||||
return;
|
||||
|
||||
+91
-48
@@ -41,6 +41,11 @@ type BuildRowLevelPermissionRecordFilterArgs = {
|
||||
workspaceMember?: UserWorkspaceAuthContext['workspaceMember'];
|
||||
};
|
||||
|
||||
type BuildRowLevelPermissionRecordFilterResult = {
|
||||
filter: RecordGqlOperationFilter | null;
|
||||
hasUnresolvablePredicate: boolean;
|
||||
};
|
||||
|
||||
export const buildRowLevelPermissionRecordFilter = ({
|
||||
flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps,
|
||||
@@ -48,9 +53,9 @@ export const buildRowLevelPermissionRecordFilter = ({
|
||||
objectMetadata,
|
||||
roleId,
|
||||
workspaceMember,
|
||||
}: BuildRowLevelPermissionRecordFilterArgs): RecordGqlOperationFilter | null => {
|
||||
}: BuildRowLevelPermissionRecordFilterArgs): BuildRowLevelPermissionRecordFilterResult => {
|
||||
if (!isDefined(roleId)) {
|
||||
return null;
|
||||
return { filter: null, hasUnresolvablePredicate: false };
|
||||
}
|
||||
|
||||
const predicates = Object.values(
|
||||
@@ -65,9 +70,11 @@ export const buildRowLevelPermissionRecordFilter = ({
|
||||
);
|
||||
|
||||
if (predicates.length === 0) {
|
||||
return null;
|
||||
return { filter: null, hasUnresolvablePredicate: false };
|
||||
}
|
||||
|
||||
let hasUnresolvablePredicate = false;
|
||||
|
||||
const recordFilters = predicates
|
||||
.map((predicate) => {
|
||||
const fieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
@@ -105,51 +112,84 @@ export const buildRowLevelPermissionRecordFilter = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const rawWorkspaceMemberValue = Object.entries(workspaceMember).find(
|
||||
([key]) => key === workspaceMemberFieldMetadata.name,
|
||||
)?.[1];
|
||||
if (workspaceMemberFieldMetadata.type === FieldMetadataType.RELATION) {
|
||||
const joinColumnName = (
|
||||
workspaceMemberFieldMetadata.settings as {
|
||||
joinColumnName?: string;
|
||||
} | null
|
||||
)?.joinColumnName;
|
||||
|
||||
const workspaceMemberSubFieldName =
|
||||
predicate.workspaceMemberSubFieldName;
|
||||
if (!isDefined(joinColumnName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isDefined(rawWorkspaceMemberValue)) {
|
||||
return null;
|
||||
}
|
||||
const workspaceMemberJoinColumnValue = Object.entries(
|
||||
workspaceMember,
|
||||
).find(([key]) => key === joinColumnName)?.[1];
|
||||
|
||||
if (
|
||||
isDefined(workspaceMemberSubFieldName) &&
|
||||
isCompositeFieldMetadataType(workspaceMemberFieldMetadata.type) &&
|
||||
typeof rawWorkspaceMemberValue === 'object'
|
||||
) {
|
||||
predicateValue = rawWorkspaceMemberValue[workspaceMemberSubFieldName];
|
||||
if (
|
||||
!isDefined(workspaceMemberJoinColumnValue) ||
|
||||
typeof workspaceMemberJoinColumnValue !== 'string'
|
||||
) {
|
||||
hasUnresolvablePredicate = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
predicateValue = {
|
||||
selectedRecordIds: [workspaceMemberJoinColumnValue],
|
||||
};
|
||||
} else {
|
||||
predicateValue = rawWorkspaceMemberValue;
|
||||
}
|
||||
const rawWorkspaceMemberValue = Object.entries(workspaceMember).find(
|
||||
([key]) => key === workspaceMemberFieldMetadata.name,
|
||||
)?.[1];
|
||||
|
||||
if (!isDefined(predicateValue)) {
|
||||
return null;
|
||||
}
|
||||
const workspaceMemberSubFieldName =
|
||||
predicate.workspaceMemberSubFieldName;
|
||||
|
||||
// Validate that workspace member enum value is compatible with target field enum options
|
||||
const isEnumValueCompatible = validateEnumValueCompatibility({
|
||||
workspaceMemberFieldMetadata,
|
||||
targetFieldMetadata: fieldMetadata,
|
||||
predicateValue,
|
||||
});
|
||||
if (!isDefined(rawWorkspaceMemberValue)) {
|
||||
hasUnresolvablePredicate = true;
|
||||
|
||||
if (!isEnumValueCompatible) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// When workspace member field is SELECT or MULTI_SELECT and value is a string,
|
||||
// wrap it in an array to match the frontend format (which uses multi-select UI)
|
||||
if (
|
||||
(workspaceMemberFieldMetadata.type === FieldMetadataType.SELECT ||
|
||||
workspaceMemberFieldMetadata.type ===
|
||||
FieldMetadataType.MULTI_SELECT) &&
|
||||
typeof predicateValue === 'string'
|
||||
) {
|
||||
predicateValue = [predicateValue];
|
||||
if (
|
||||
isDefined(workspaceMemberSubFieldName) &&
|
||||
isCompositeFieldMetadataType(workspaceMemberFieldMetadata.type) &&
|
||||
typeof rawWorkspaceMemberValue === 'object'
|
||||
) {
|
||||
predicateValue =
|
||||
rawWorkspaceMemberValue[workspaceMemberSubFieldName];
|
||||
} else {
|
||||
predicateValue = rawWorkspaceMemberValue;
|
||||
}
|
||||
|
||||
if (!isDefined(predicateValue)) {
|
||||
hasUnresolvablePredicate = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const isEnumValueCompatible = validateEnumValueCompatibility({
|
||||
workspaceMemberFieldMetadata,
|
||||
targetFieldMetadata: fieldMetadata,
|
||||
predicateValue,
|
||||
});
|
||||
|
||||
if (!isEnumValueCompatible) {
|
||||
hasUnresolvablePredicate = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
(workspaceMemberFieldMetadata.type === FieldMetadataType.SELECT ||
|
||||
workspaceMemberFieldMetadata.type ===
|
||||
FieldMetadataType.MULTI_SELECT) &&
|
||||
typeof predicateValue === 'string'
|
||||
) {
|
||||
predicateValue = [predicateValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,12 +272,15 @@ export const buildRowLevelPermissionRecordFilter = ({
|
||||
options: field.options as PartialFieldMetadataItemOption[],
|
||||
}));
|
||||
|
||||
return computeRecordGqlOperationFilter({
|
||||
recordFilters,
|
||||
recordFilterGroups,
|
||||
fields: fieldMetadataItems,
|
||||
filterValueDependencies: {
|
||||
currentWorkspaceMemberId: workspaceMember?.id,
|
||||
},
|
||||
});
|
||||
return {
|
||||
filter: computeRecordGqlOperationFilter({
|
||||
recordFilters,
|
||||
recordFilterGroups,
|
||||
fields: fieldMetadataItems,
|
||||
filterValueDependencies: {
|
||||
currentWorkspaceMemberId: workspaceMember?.id,
|
||||
},
|
||||
}),
|
||||
hasUnresolvablePredicate,
|
||||
};
|
||||
};
|
||||
|
||||
+20
-12
@@ -47,18 +47,26 @@ export const validateRLSPredicatesForRecords = <T extends ObjectLiteral>({
|
||||
return;
|
||||
}
|
||||
|
||||
const recordFilter = buildRowLevelPermissionRecordFilter({
|
||||
flatRowLevelPermissionPredicateMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateGroupMaps,
|
||||
flatFieldMetadataMaps: internalContext.flatFieldMetadataMaps,
|
||||
objectMetadata,
|
||||
roleId,
|
||||
workspaceMember: isUserAuthContext(authContext)
|
||||
? authContext.workspaceMember
|
||||
: undefined,
|
||||
});
|
||||
const { filter: recordFilter, hasUnresolvablePredicate } =
|
||||
buildRowLevelPermissionRecordFilter({
|
||||
flatRowLevelPermissionPredicateMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateMaps,
|
||||
flatRowLevelPermissionPredicateGroupMaps:
|
||||
internalContext.flatRowLevelPermissionPredicateGroupMaps,
|
||||
flatFieldMetadataMaps: internalContext.flatFieldMetadataMaps,
|
||||
objectMetadata,
|
||||
roleId,
|
||||
workspaceMember: isUserAuthContext(authContext)
|
||||
? authContext.workspaceMember
|
||||
: undefined,
|
||||
});
|
||||
|
||||
if (hasUnresolvablePredicate) {
|
||||
throw new TwentyORMException(
|
||||
errorMessage,
|
||||
TwentyORMExceptionCode.RLS_VALIDATION_FAILED,
|
||||
);
|
||||
}
|
||||
|
||||
if (!recordFilter || Object.keys(recordFilter).length === 0) {
|
||||
return;
|
||||
|
||||
+20
-11
@@ -265,7 +265,10 @@ describe('WorkspaceEventEmitterService', () => {
|
||||
}),
|
||||
};
|
||||
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({});
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({
|
||||
filter: {},
|
||||
hasUnresolvablePredicate: false,
|
||||
});
|
||||
(
|
||||
isRecordMatchingRLSRowLevelPermissionPredicate as jest.Mock
|
||||
).mockReturnValue(true);
|
||||
@@ -752,9 +755,10 @@ describe('WorkspaceEventEmitterService', () => {
|
||||
it('should combine query filter with RLS filter', async () => {
|
||||
const rlsFilter: RecordGqlOperationFilter = { status: { eq: 'active' } };
|
||||
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue(
|
||||
rlsFilter,
|
||||
);
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({
|
||||
filter: rlsFilter,
|
||||
hasUnresolvablePredicate: false,
|
||||
});
|
||||
|
||||
const streamDataWithFilter: EventStreamData = {
|
||||
...mockStreamData,
|
||||
@@ -1020,9 +1024,10 @@ describe('WorkspaceEventEmitterService', () => {
|
||||
assigneeId: { eq: workspaceMemberId },
|
||||
};
|
||||
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue(
|
||||
rlsFilter,
|
||||
);
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({
|
||||
filter: rlsFilter,
|
||||
hasUnresolvablePredicate: false,
|
||||
});
|
||||
|
||||
const streamDataWithWorkspaceMember: EventStreamData = {
|
||||
authContext: {
|
||||
@@ -1104,9 +1109,10 @@ describe('WorkspaceEventEmitterService', () => {
|
||||
locale: { eq: 'en' },
|
||||
};
|
||||
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue(
|
||||
rlsFilter,
|
||||
);
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({
|
||||
filter: rlsFilter,
|
||||
hasUnresolvablePredicate: false,
|
||||
});
|
||||
|
||||
const streamDataWithWorkspaceMember: EventStreamData = {
|
||||
authContext: {
|
||||
@@ -1169,7 +1175,10 @@ describe('WorkspaceEventEmitterService', () => {
|
||||
idByUserId: {},
|
||||
};
|
||||
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({});
|
||||
(buildRowLevelPermissionRecordFilter as jest.Mock).mockReturnValue({
|
||||
filter: {},
|
||||
hasUnresolvablePredicate: false,
|
||||
});
|
||||
|
||||
const streamDataWithWorkspaceMember: EventStreamData = {
|
||||
authContext: {
|
||||
|
||||
+16
-8
@@ -307,13 +307,18 @@ export class WorkspaceEventEmitterService {
|
||||
|
||||
const objectNameSingular = workspaceEventBatch.objectMetadata.nameSingular;
|
||||
|
||||
const subscriberRLSFilter = this.buildSubscriberRLSFilter(
|
||||
streamData.authContext,
|
||||
roleId,
|
||||
workspaceEventBatch.objectMetadata,
|
||||
permissionsContext,
|
||||
flatWorkspaceMemberMaps,
|
||||
);
|
||||
const { filter: subscriberRLSFilter, hasUnresolvablePredicate } =
|
||||
this.buildSubscriberRLSFilter(
|
||||
streamData.authContext,
|
||||
roleId,
|
||||
workspaceEventBatch.objectMetadata,
|
||||
permissionsContext,
|
||||
flatWorkspaceMemberMaps,
|
||||
);
|
||||
|
||||
if (hasUnresolvablePredicate) {
|
||||
return;
|
||||
}
|
||||
|
||||
const restrictedFields = objectPermissions.restrictedFields;
|
||||
|
||||
@@ -486,7 +491,10 @@ export class WorkspaceEventEmitterService {
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
},
|
||||
flatWorkspaceMemberMaps: FlatWorkspaceMemberMaps,
|
||||
): RecordGqlOperationFilter | null {
|
||||
): {
|
||||
filter: RecordGqlOperationFilter | null;
|
||||
hasUnresolvablePredicate: boolean;
|
||||
} {
|
||||
const workspaceMember = isDefined(subscriberAuthContext.workspaceMemberId)
|
||||
? flatWorkspaceMemberMaps.byId[subscriberAuthContext.workspaceMemberId]
|
||||
: undefined;
|
||||
|
||||
Reference in New Issue
Block a user