Skip to content

Commit 6a2531c

Browse files
committed
considering auth() without selector
1 parent 258b56b commit 6a2531c

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { lowerCaseFirst } from 'lower-case-first';
33
/**
44
* An access key in the user context object (e.g. `profile.picture.url`)
55
*/
6-
export type AuthContextSelector = string | undefined;
6+
export type AuthContextSelector = string;
77

88
/**
99
* Runtime information of a data model or field attribute

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,21 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
5656
throw new Error(`Invalid user context`);
5757
}
5858
const fields = this.options.modelMeta.fields[model];
59-
const defaultAuthSelectorFields: Record<string, AuthContextSelector> = Object.fromEntries(
60-
Object.entries(fields)
61-
.filter(([_, fieldInfo]) => this.isDefaultAuthField(fieldInfo))
62-
.map(([field, fieldInfo]) => [field, this.getAuthSelector(fieldInfo)])
63-
);
59+
const defaultAuthSelectorFields: Record<string, { fieldType: string; selector: AuthContextSelector }> =
60+
Object.fromEntries(
61+
Object.entries(fields)
62+
.filter(([_, fieldInfo]) => this.isDefaultAuthField(fieldInfo))
63+
.map(([field, fieldInfo]) => [
64+
field,
65+
{ fieldType: fieldInfo.type, selector: this.getAuthSelector(fieldInfo) },
66+
])
67+
);
6468
const defaultAuthFields = Object.fromEntries(
65-
Object.entries(defaultAuthSelectorFields).map(([field, authSelector]) => [
66-
field,
67-
deepGet(userContext, authSelector, userContext),
68-
])
69+
Object.entries(defaultAuthSelectorFields).map(([field, { fieldType, selector }]) => {
70+
// if field type is String, we expect auth() to return the whole user context as string
71+
const defaultValue = fieldType === 'String' ? JSON.stringify(userContext) : userContext;
72+
return [field, deepGet(userContext, selector, defaultValue)];
73+
})
6974
);
7075
console.log('defaultAuthFields :', defaultAuthFields);
7176
newArgs = { ...args, data: { ...defaultAuthFields, ...args.data } };

packages/sdk/src/model-meta-generator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
isStringLiteral,
1111
ReferenceExpr,
1212
} from '@zenstackhq/language/ast';
13-
import type { RuntimeAttribute } from '@zenstackhq/runtime';
13+
import type { AuthContextSelector, RuntimeAttribute } from '@zenstackhq/runtime';
1414
import { lowerCaseFirst } from 'lower-case-first';
1515
import { CodeBlockWriter, Project, VariableDeclarationKind } from 'ts-morph';
1616
import {
@@ -215,7 +215,7 @@ function getFieldAttributes(field: DataModelField): RuntimeAttribute[] {
215215
attr.args[0].value.$cstNode?.text.startsWith('auth()')
216216
) {
217217
const authValue = attr.args[0].value.$cstNode?.text;
218-
const authSelector = authValue === 'auth()' ? authValue : authValue.slice('auth().'.length);
218+
const authSelector: AuthContextSelector = authValue.slice('auth().'.length);
219219
args.push({ name: 'auth()', value: authSelector });
220220
} else {
221221
// non-literal args are ignored

tests/integration/tests/enhancements/with-policy/auth.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,43 @@ describe('With Policy: auth() test', () => {
416416
await expect(userDb.post.count({ where: { authorName: overrideName } })).resolves.toBe(1);
417417
});
418418

419+
it('Default auth() return user context', async () => {
420+
const { enhance, modelMeta } = await loadSchema(
421+
`
422+
model User {
423+
id String @id
424+
name String
425+
426+
}
427+
428+
model Post {
429+
id String @id @default(uuid())
430+
authorName String? @default(auth().name)
431+
userDetailsAsString String? @default(auth())
432+
userDetailsAsJson Json? @default(auth())
433+
434+
@@allow('all', true)
435+
}
436+
`,
437+
{
438+
provider: 'postgresql',
439+
compile: true,
440+
}
441+
);
442+
443+
const userContext = { id: '1', name: 'user1' };
444+
const db = enhance(userContext);
445+
const userDetailsAttributes = modelMeta.fields.post.userDetails.attributes;
446+
expect(userDetailsAttributes).toHaveProperty('0.name', '@default');
447+
expect(userDetailsAttributes).toHaveProperty('0.args.0.name', 'auth()');
448+
expect(userDetailsAttributes).toHaveProperty('0.args.0.value', '');
449+
await expect(db.post.create({ data: {} })).toResolveTruthy();
450+
await expect(db.post.count()).resolves.toBe(1);
451+
const post = await db.post.findFirst();
452+
expect(post?.userDetailsAsString).toEqual(JSON.stringify(userContext));
453+
expect(post?.userDetailsAsJson).toEqual(userContext);
454+
});
455+
419456
it('Default auth() with foreign key', async () => {
420457
const { enhance, modelMeta } = await loadSchema(
421458
`

0 commit comments

Comments
 (0)