keystonejs / keystonejs/keystone

Access operation function called with no session during successful login

Open
#9,753 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
10k
Forks
1.3k
Avg merge
19h 14m
Merged PRs (30d)
19

Description

Hi,
The access operation function is been called with undefined session during a successful login. Here the steps to get where I am:

### 1.
Create and empty project with:
```
npm create keystone-app@latest
```
This creates a new project with:
```
"dependencies": {
"@keystone-6/auth": "^8.0.0",
"@keystone-6/core": "^6.0.0",
"@keystone-6/fields-document": "^9.0.0",
"typescript": "^5.5.0"
}
```
### 2.
Introduce the `isAdmin` checkbox, like shown in “Authentication and Access Control” guide. That means in `schema.ts` to add `isAdmin` field to the `User` list:
```
isAdmin: checkbox(),
```
and in `auth.ts` set
```
sessionData: 'id name isAdmin',
```
and
```
itemData: {isAdmin: true}
```

### 3.
Introduce the `Company` list defined as follows:
```
Company: list({
access: {
operation({ operation, session }){
const data = session?.data;
const userId = data?.id;
const isAdmin = data?.isAdmin;
return typeof userId == "string" && (isAdmin || operation == 'query');
}
},
fields: {
name: text(),
allowFeatureA: checkbox(),
allowFeatureB: checkbox(),
users: relationship({ ref: 'User.company', many: true }),
}
}),

```
This references a new relationship in `User` too:
```
company: relationship({ ref: 'Company.users', many: false }),
```
### 4.
That’s all. Now access the Admin UI and create a first admin user. Create a company for your user. Then logout and execute the following login:
```
mutation loginMutation($email: String!, $password: String!) {
authenticateUserWithPassword(email: $email, password: $password) {
... on UserAuthenticationWithPasswordSuccess {
item {
id
name
email
company {
id
name
allowFeatureA
allowFeatureB
}
}
}
}
}
```
providing the good `email` and `password`.

### Expected behavior
- the `Company` list access operation is called with a `session` with loaded data.
- the result of the mutation depends on final authentication state, not on previous authentication state.

### Occurring behavior
- the `Company` list access operation is called with an `undefined` `session`.
- the result of the mutation depends on previous authentication state, not on final authentication state.

### Notes
- the `Company` list access operation is called with `operation=="query"`, which it is fine since it is not related to the running mutation but it is related to walking a relationship.
- When I'm already logged in and I'm performing an useless login, it returns my company in `item`.

### Questions
- Is this the expected behavior from Keystone?
- How can I get session data as result of a successful login mutation?

Thanks a lot!

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue from the steps using the generated schema.ts and auth.ts, then run the supplied login mutation after logging out. Trace the authentication flow and the Company relationship query to compare the session used during login with the final authenticated session. Done means the access operation receives the final session data and the mutation result does not depend on the previous authentication state.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, node.js, typescript
Domain
api, authentication, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.