fix: relationship field disabled from access control in related collections (#644)

* fix: disabled relationship field from access control in related collections

* fix: ids can be read from relationships regardless of access of related document
This commit is contained in:
Dan Ribbens
2022-07-03 07:01:45 -04:00
committed by GitHub
parent 601e69ab0d
commit 91e33d1c1c
10 changed files with 102 additions and 57 deletions

View File

@@ -1,4 +1,3 @@
import { Value } from '../../../elements/ReactSelect/types';
import { ValueWithRelation } from './types';
type RelationMap = {
@@ -17,11 +16,17 @@ export const createRelationMap: CreateRelationMap = ({
value,
}) => {
const hasMultipleRelations = Array.isArray(relationTo);
const relationMap: RelationMap = {};
let relationMap: RelationMap;
if (Array.isArray(relationTo)) {
relationMap = relationTo.reduce((map, current) => {
return { ...map, [current]: [] };
}, {});
} else {
relationMap = { [relationTo]: [] };
}
const add = (relation: string, id: unknown) => {
if (((typeof id === 'string' && id !== 'null') || typeof id === 'number') && typeof relation === 'string') {
if (typeof relationMap[relation] === 'undefined') relationMap[relation] = [];
if (((typeof id === 'string') || typeof id === 'number') && typeof relation === 'string') {
relationMap[relation].push(id);
}
};

View File

@@ -58,7 +58,7 @@ const Relationship: React.FC<Props> = (props) => {
} = useConfig();
const { id } = useDocumentInfo();
const { user } = useAuth();
const { user, permissions } = useAuth();
const { getData, getSiblingData } = useWatchForm();
const formProcessing = useFormProcessing();
const hasMultipleRelations = Array.isArray(relationTo);
@@ -93,6 +93,9 @@ const Relationship: React.FC<Props> = (props) => {
value: valueArg,
sort,
}) => {
if (!permissions) {
return;
}
let lastLoadedPageToUse = typeof lastLoadedPageArg !== 'undefined' ? lastLoadedPageArg : 1;
const lastFullyLoadedRelationToUse = typeof lastFullyLoadedRelationArg !== 'undefined' ? lastFullyLoadedRelationArg : -1;
@@ -160,13 +163,27 @@ const Relationship: React.FC<Props> = (props) => {
}
}
}
} else if (response.status === 403) {
setLastFullyLoadedRelation(relations.indexOf(relation));
lastLoadedPageToUse = 1;
dispatchOptions({ type: 'ADD', data: { docs: [] } as PaginatedDocs<unknown>, relation, hasMultipleRelations, collection, sort, ids: relationMap[relation] });
} else {
setErrorLoading('An error has occurred.');
}
}
}, Promise.resolve());
}
}, [relationTo, hasMany, errorLoading, collections, optionFilters, serverURL, api, hasMultipleRelations]);
}, [
permissions,
relationTo,
hasMany,
errorLoading,
collections,
optionFilters,
serverURL,
api,
hasMultipleRelations,
]);
const findOptionsByValue = useCallback((): Option | Option[] => {
if (value) {
@@ -264,12 +281,12 @@ const Relationship: React.FC<Props> = (props) => {
if (!errorLoading) {
const response = await fetch(`${serverURL}${api}/${relation}?${qs.stringify(query)}`);
const collection = collections.find((coll) => coll.slug === relation);
if (response.ok) {
const data = await response.json();
const collection = collections.find((coll) => coll.slug === relation);
dispatchOptions({ type: 'ADD', data, relation, hasMultipleRelations, collection, sort: true });
} else {
console.error(`There was a problem loading relationships to related collection ${relation}.`);
dispatchOptions({ type: 'ADD', data, relation, hasMultipleRelations, collection, sort: true, ids });
} else if (response.status === 403) {
dispatchOptions({ type: 'ADD', data: { docs: [] } as PaginatedDocs, relation, hasMultipleRelations, collection, sort: true, ids });
}
}
}

View File

@@ -29,7 +29,7 @@ const optionsReducer = (state: Option[], action: Action): Option[] => {
}
case 'ADD': {
const { hasMultipleRelations, collection, relation, data, sort } = action;
const { hasMultipleRelations, collection, relation, data, sort, ids = [] } = action;
const labelKey = collection.admin.useAsTitle || 'id';
@@ -50,7 +50,11 @@ const optionsReducer = (state: Option[], action: Action): Option[] => {
];
}
return docs;
}, []),
},
ids.map((id) => ({
label: labelKey === 'id' ? id : `Untitled - ID: ${id}`,
value: id,
}))),
];
return sort ? sortOptions(options) : options;
@@ -74,7 +78,14 @@ const optionsReducer = (state: Option[], action: Action): Option[] => {
}
return docs;
}, []);
},
[
...ids.map((id) => ({
label: labelKey === 'id' ? id : `Untitled - ID: ${id}`,
value: id,
relationTo: relation,
})),
]);
if (optionsToAddTo) {
const subOptions = [

View File

@@ -25,6 +25,7 @@ type ADD = {
hasMultipleRelations: boolean
collection: SanitizedCollectionConfig
sort?: boolean
ids?: unknown[]
}
export type Action = CLEAR | ADD

View File

@@ -20,8 +20,14 @@ const RelationshipCell = (props) => {
if (collection) {
const useAsTitle = collection.admin.useAsTitle ? collection.admin.useAsTitle : 'id';
let title: string;
if (typeof doc === 'string') {
title = doc;
} else {
title = doc?.[useAsTitle] ? doc[useAsTitle] : doc;
}
return newData ? `${newData}, ${doc?.[useAsTitle]}` : doc?.[useAsTitle];
return newData ? `${newData}, ${title}` : title;
}
return newData;
@@ -34,7 +40,7 @@ const RelationshipCell = (props) => {
if (collection && doc) {
const useAsTitle = collection.admin.useAsTitle ? collection.admin.useAsTitle : 'id';
setData(doc[useAsTitle]);
setData(doc[useAsTitle] ? doc[useAsTitle] : doc);
}
}
}