Skip to content

Commit

Permalink
Cosmetic core changes before error handling (#6104)
Browse files Browse the repository at this point in the history
  • Loading branch information
timleslie authored Jul 15, 2021
1 parent 8990007 commit 3f03b8c
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 355 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-turkeys-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-next/keystone': patch
---

Cosmetic changes to the core code in preparation for improvements to the error handling logic.
3 changes: 1 addition & 2 deletions examples/custom-field/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# @keystone-next/example-custom-field

## 0.0.1
### Patch Changes


### Patch Changes

- [#6087](https://github.com/keystonejs/keystone/pull/6087) [`139d7a8de`](https://github.com/keystonejs/keystone/commit/139d7a8def263d40c0d1d5353d2744842d9a0951) Thanks [@JedWatson](https://github.com/JedWatson)! - Move source code from the `packages-next` to the `packages` directory.

Expand Down
116 changes: 48 additions & 68 deletions packages/keystone/src/lib/core/mutations/access-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ export async function getAccessControlledItemForDelete(
inputFilter: UniqueInputFilter
): Promise<ItemRootValue> {
const itemId = await getStringifiedItemIdFromUniqueWhereInput(filter, list.listKey, context);

// List access: pass 1
const access = await validateNonCreateListAccessControl({
access: list.access.delete,
args: { context, listKey: list.listKey, operation: 'delete', session: context.session, itemId },
});
if (access === false) {
throw accessDeniedError('mutation');
}

// List access: pass 2
const prismaModel = getPrismaModelForList(context.prisma, list.listKey);
let where: PrismaFilter = mapUniqueWhereToWhere(
list,
Expand All @@ -41,37 +45,8 @@ export async function getAccessControlledItemForDelete(
if (item === null) {
throw accessDeniedError('mutation');
}
return item;
}

export async function checkFieldAccessControlForUpdate(
list: InitialisedList,
context: KeystoneContext,
originalInput: Record<string, any>,
item: Record<string, any>
) {
const results = await Promise.all(
Object.keys(originalInput).map(fieldKey => {
const field = list.fields[fieldKey];
return validateFieldAccessControl({
access: field.access.update,
args: {
context,
fieldKey,
listKey: list.listKey,
operation: 'update',
originalInput,
session: context.session,
item,
itemId: item.id.toString(),
},
});
})
);

if (results.some(canAccess => !canAccess)) {
throw accessDeniedError('mutation');
}
return item;
}

export async function getAccessControlledItemForUpdate(
Expand All @@ -83,33 +58,51 @@ export async function getAccessControlledItemForUpdate(
const prismaModel = getPrismaModelForList(context.prisma, list.listKey);
const resolvedUniqueWhere = await resolveUniqueWhereInput(uniqueWhere, list.fields, context);
const itemId = await getStringifiedItemIdFromUniqueWhereInput(uniqueWhere, list.listKey, context);
const args = {
context,
itemId,
listKey: list.listKey,
operation: 'update' as const,
originalInput: update,
session: context.session,
};

// List access: pass 1
const accessControl = await validateNonCreateListAccessControl({
access: list.access.update,
args: {
context,
itemId,
listKey: list.listKey,
operation: 'update',
originalInput: update,
session: context.session,
},
args,
});
if (accessControl === false) {
throw accessDeniedError('mutation');
}

// List access: pass 2
const uniqueWhereInWhereForm = mapUniqueWhereToWhere(list, resolvedUniqueWhere);
const item = await prismaModel.findFirst({
where:
accessControl === true
? uniqueWhereInWhereForm
: {
AND: [uniqueWhereInWhereForm, await resolveWhereInput(accessControl, list)],
},
: { AND: [uniqueWhereInWhereForm, await resolveWhereInput(accessControl, list)] },
});
if (!item) {
throw accessDeniedError('mutation');
}
await checkFieldAccessControlForUpdate(list, context, update, item);

// Field access
const results = await Promise.all(
Object.keys(update).map(fieldKey => {
const field = list.fields[fieldKey];
return validateFieldAccessControl({
access: field.access.update,
args: { ...args, fieldKey, item },
});
})
);

if (results.some(canAccess => !canAccess)) {
throw accessDeniedError('mutation');
}

return item;
}

Expand All @@ -118,40 +111,27 @@ export async function applyAccessControlForCreate(
context: KeystoneContext,
originalInput: Record<string, unknown>
) {
const result = await validateCreateListAccessControl({
access: list.access.create,
args: {
context,
listKey: list.listKey,
operation: 'create',
originalInput,
session: context.session,
},
});
const args = {
context,
listKey: list.listKey,
operation: 'create' as const,
originalInput,
session: context.session,
};

// List access
const result = await validateCreateListAccessControl({ access: list.access.create, args });
if (!result) {
throw accessDeniedError('mutation');
}
await checkFieldAccessControlForCreate(list, context, originalInput);
}

async function checkFieldAccessControlForCreate(
list: InitialisedList,
context: KeystoneContext,
originalInput: Record<string, any>
) {
// Field access
const results = await Promise.all(
Object.keys(originalInput).map(fieldKey => {
const field = list.fields[fieldKey];
return validateFieldAccessControl({
access: field.access.create,
args: {
context,
fieldKey,
listKey: list.listKey,
operation: 'create',
originalInput,
session: context.session,
},
args: { fieldKey, ...args },
});
})
);
Expand All @@ -170,7 +150,7 @@ async function getStringifiedItemIdFromUniqueWhereInput(
return uniqueWhere.id;
}
try {
const item = await context.sudo().lists[listKey].findOne({ where: uniqueWhere as any });
const item = await context.sudo().lists[listKey].findOne({ where: uniqueWhere });
return item.id;
} catch (err) {
throw accessDeniedError('mutation');
Expand Down
Loading

1 comment on commit 3f03b8c

@vercel
Copy link

@vercel vercel bot commented on 3f03b8c Jul 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.