Skip to content

Commit 573a480

Browse files
authored
Make authorizer work for nested relations (#355)
Currently authorizer works more-or-less only one level down. For example, if you have following entities: - TaskDTO - .subTasks (SubTaskDTO) - .subSubTasks (SubSubTaskDTO) Then if you try to fetch tasks along with their sub-tasks and sub-sub-tasks; the authorizer of `SubSubTaskDTO` isn't used, nor is the `relation.auth` used which can be defined at `SubTaskDTO` level for the `subSubTasks` relation. This PR fixes it - so that authorizers defined in nested DTOs are also called, if they exist. P.S. **For now this PR makes the fix only for read relations**, but I can easily do it for update/remove relations resolvers too. @TriPSs just let me know if you're okay with the fix and be willing to merge this - then I'll finish the PR so it works for the other resolvers as well.
2 parents 1d57489 + 39c1122 commit 573a480

File tree

13 files changed

+431
-63
lines changed

13 files changed

+431
-63
lines changed

examples/auth/e2e/fixtures.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DataSource } from 'typeorm'
22

33
import { executeTruncate } from '../../helpers'
4+
import { SubSubTaskEntity } from '../src/sub-sub-task/sub-sub-task.entity'
45
import { SubTaskEntity } from '../src/sub-task/sub-task.entity'
56
import { TagEntity } from '../src/tag/tag.entity'
67
import { TodoItemEntity } from '../src/todo-item/todo-item.entity'
@@ -15,6 +16,7 @@ export const refresh = async (dataSource: DataSource): Promise<void> => {
1516
const userRepo = dataSource.getRepository(UserEntity)
1617
const todoRepo = dataSource.getRepository(TodoItemEntity)
1718
const subTaskRepo = dataSource.getRepository(SubTaskEntity)
19+
const subSubTaskRepo = dataSource.getRepository(SubSubTaskEntity)
1820
const tagsRepo = dataSource.getRepository(TagEntity)
1921

2022
const users = await userRepo.save([
@@ -50,15 +52,24 @@ export const refresh = async (dataSource: DataSource): Promise<void> => {
5052
Promise.resolve([] as TodoItemEntity[])
5153
)
5254

53-
await subTaskRepo.save(
54-
todoItems.reduce(
55-
(subTasks, todo) => [
56-
...subTasks,
55+
const subTasks: SubTaskEntity[] = await subTaskRepo.save(
56+
todoItems.flatMap(
57+
(todo) => [
5758
{ completed: true, title: `${todo.title} - Sub Task 1`, todoItem: todo, ownerId: todo.ownerId },
5859
{ completed: false, title: `${todo.title} - Sub Task 2`, todoItem: todo, ownerId: todo.ownerId },
5960
{ completed: false, title: `${todo.title} - Sub Task 3`, todoItem: todo, ownerId: todo.ownerId }
6061
],
61-
[] as Partial<SubTaskEntity>[]
62+
[]
63+
)
64+
)
65+
66+
await subSubTaskRepo.save(
67+
subTasks.flatMap(
68+
(parent) => [
69+
{ subTask: parent, title: `${parent.title} - Sub Sub Task Public`, public: true },
70+
{ subTask: parent, title: `${parent.title} - Sub Sub Task Private`, public: false }
71+
],
72+
[]
6273
)
6374
)
6475
}

examples/auth/e2e/todo-item.resolver.spec.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,61 @@ describe('TodoItemResolver (auth - e2e)', () => {
426426
])
427427
}))
428428

429+
it(`should allow fetching subSubTasks, but only the ones that are allowed by the nested authorizers`, () =>
430+
request(app.getHttpServer())
431+
.post('/graphql')
432+
.auth(jwtToken, { type: 'bearer' })
433+
.send({
434+
operationName: null,
435+
variables: {},
436+
query: `{
437+
todoItems {
438+
edges {
439+
node {
440+
subTasks {
441+
edges {
442+
node {
443+
subSubTasks {
444+
title
445+
}
446+
}
447+
}
448+
}
449+
}
450+
}
451+
}
452+
}`
453+
})
454+
.expect(200)
455+
.then(({ body }) => {
456+
const {
457+
edges: [{ node: task }]
458+
}: {
459+
edges: Array<{
460+
node: {
461+
subTasks: {
462+
edges: Array<{
463+
node: {
464+
subSubTasks: Array<{
465+
title: string
466+
}>
467+
}
468+
}>
469+
}
470+
}
471+
}>
472+
} = body.data.todoItems
473+
const [subTask] = task.subTasks.edges.map((e) => e.node)
474+
475+
expect(subTask).toEqual({
476+
subSubTasks: [
477+
{
478+
title: 'Create Nest App - Sub Task 1 - Sub Sub Task Public'
479+
}
480+
]
481+
})
482+
}))
483+
429484
it(`should allow querying on tags`, () =>
430485
request(app.getHttpServer())
431486
.post('/graphql')
@@ -620,7 +675,7 @@ describe('TodoItemResolver (auth - e2e)', () => {
620675
.send({
621676
operationName: null,
622677
variables: {},
623-
query: `{
678+
query: `{
624679
todoItemAggregate {
625680
${todoItemAggregateFields}
626681
}
@@ -647,7 +702,7 @@ describe('TodoItemResolver (auth - e2e)', () => {
647702
.send({
648703
operationName: null,
649704
variables: {},
650-
query: `{
705+
query: `{
651706
todoItemAggregate {
652707
${todoItemAggregateFields}
653708
}
@@ -674,7 +729,7 @@ describe('TodoItemResolver (auth - e2e)', () => {
674729
.send({
675730
operationName: null,
676731
variables: {},
677-
query: `{
732+
query: `{
678733
todoItemAggregate(filter: { completed: { is: false } }) {
679734
${todoItemAggregateFields}
680735
}

0 commit comments

Comments
 (0)