Skip to content

Commit 91bedcd

Browse files
committed
fix(auth): refix issue #1997
fixes #2019
1 parent e0d25d4 commit 91bedcd

File tree

3 files changed

+97
-18
lines changed

3 files changed

+97
-18
lines changed

packages/runtime/src/cross/model-meta.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ export type FieldInfo = {
8686
relationField?: string;
8787

8888
/**
89-
* Mapping from foreign key field names to relation field names.
90-
* Only available on relation fields.
89+
* Mapping from relation's pk to fk. Only available on relation fields.
9190
*/
9291
foreignKeyMapping?: Record<string, string>;
9392

packages/runtime/src/enhancements/node/default-auth.ts

+9-16
Original file line numberDiff line numberDiff line change
@@ -126,31 +126,24 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
126126
return;
127127
}
128128

129-
if (context.field?.backLink && context.nestingPath.length > 1) {
129+
if (context.field?.backLink) {
130130
// if the fk field is in a creation context where its implied by the parent,
131131
// we should not set the default value, e.g.:
132132
//
133133
// ```
134134
// parent.create({ data: { child: { create: {} } } })
135135
// ```
136136
//
137-
// event if child's fk to parent has a default value, we should not set default
137+
// even if child's fk to parent has a default value, we should not set default
138138
// value here
139139

140-
// fetch parent model from the parent context
141-
const parentModel = getModelInfo(
142-
this.options.modelMeta,
143-
context.nestingPath[context.nestingPath.length - 2].model
144-
);
145-
146-
if (parentModel) {
147-
// get the opposite side of the relation for the current create context
148-
const oppositeRelationField = requireField(this.options.modelMeta, model, context.field.backLink);
149-
if (parentModel.name === oppositeRelationField.type) {
150-
// if the opposite side matches the parent model, it means we currently in a creation context
151-
// that implicitly sets this fk field
152-
return;
153-
}
140+
// get the opposite side of the relation for the current create context
141+
const oppositeRelationField = requireField(this.options.modelMeta, model, context.field.backLink);
142+
if (
143+
oppositeRelationField.foreignKeyMapping &&
144+
Object.values(oppositeRelationField.foreignKeyMapping).includes(fieldInfo.name)
145+
) {
146+
return;
154147
}
155148
}
156149

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2019', () => {
4+
it('regression', async () => {
5+
const { prisma, enhance } = await loadSchema(
6+
`
7+
model Tenant {
8+
id String @id @default(uuid())
9+
10+
users User[]
11+
content Content[]
12+
}
13+
14+
model User {
15+
id String @id @default(uuid())
16+
tenantId String @default(auth().tenantId)
17+
tenant Tenant @relation(fields: [tenantId], references: [id])
18+
posts Post[]
19+
likes PostUserLikes[]
20+
21+
@@allow('all', true)
22+
}
23+
24+
model Content {
25+
tenantId String @default(auth().tenantId)
26+
tenant Tenant @relation(fields: [tenantId], references: [id])
27+
id String @id @default(uuid())
28+
contentType String
29+
30+
@@delegate(contentType)
31+
@@allow('all', true)
32+
}
33+
34+
model Post extends Content {
35+
author User @relation(fields: [authorId], references: [id])
36+
authorId String @default(auth().id)
37+
38+
comments Comment[]
39+
likes PostUserLikes[]
40+
41+
@@allow('all', true)
42+
}
43+
44+
model PostUserLikes extends Content {
45+
userId String
46+
user User @relation(fields: [userId], references: [id])
47+
48+
postId String
49+
post Post @relation(fields: [postId], references: [id])
50+
51+
@@unique([userId, postId])
52+
53+
@@allow('all', true)
54+
}
55+
56+
model Comment extends Content {
57+
postId String
58+
post Post @relation(fields: [postId], references: [id])
59+
60+
@@allow('all', true)
61+
}
62+
`,
63+
{ logPrismaQuery: true }
64+
);
65+
66+
const tenant = await prisma.tenant.create({ data: {} });
67+
const user = await prisma.user.create({ data: { tenantId: tenant.id } });
68+
const db = enhance({ id: user.id, tenantId: tenant.id });
69+
const result = await db.post.create({
70+
data: {
71+
likes: {
72+
createMany: {
73+
data: [
74+
{
75+
userId: user.id,
76+
},
77+
],
78+
},
79+
},
80+
},
81+
include: {
82+
likes: true,
83+
},
84+
});
85+
expect(result.likes[0].tenantId).toBe(tenant.id);
86+
});
87+
});

0 commit comments

Comments
 (0)