-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Link to reproduction
No response
Describe the Bug
Hooks manipulate and return a hard object, impossible to manipulate and runs in strange behaviour.
To Reproduce
I do have a fresh install of Payload CMS 2.30, I have a couple of collections, among them Organizations and Users, which relates to Organizations collection through the field organization. Out of the box, I'm using the authentication provided by the REST API at /users/login — Upon login, the response I get is this one:
{
"exp": 1729882853,
"message": "Auth Passed",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiY29sbGVjdGlvbiI6InVzZXJzIiwiZW1haWwiOiJlcmlrYS5tdXN0ZXJtYW5uQHN0YXJidWNrcy5kZSIsImlhdCI6MTcyOTg4MTk1MywiZXhwIjoxNzI5ODgyODUzfQ.SmM1wrsjhSWQSvlZbQfctmHzzgx55ESHiuzwJvehr6c",
"user": {
"id": 2,
"firstName": "Erika",
"lastName": "Mustermann",
"updatedAt": "2024-10-22T16:32:22.884Z",
"createdAt": "2024-07-26T19:54:11.004Z",
"email": "[email protected]",
"loginAttempts": 0
}
}At this point, there is no way to configure whether the response of the user object can be at a certain depth, like for example, including the associated fields, which leads me to use the hook afterLogin. When I use the hook, if I log user, I get this:
afterLogin: [
async ({ user }) => {
console.log(user.organization); // will log the correct relationship
return user; // this will return a "short" or "simplified" version of the user, just like the json response posted above;
// if I do this:
user.whateverName = 'hello world';
return user; // will return the "short" or "simplified" object, appending the "whateverName" to the user object, but I can't figrue HOW to make Payload to show the `organization` within the `user` object.
// If I do:
user.organization = 'hello world'; // this won't work and it won't show up under the `user` object, because I do have the impression that Payload is filtering out the property names that matches with associated fields to the collection.
},
],Since I can't get to update the response of /users/login, I want to rely on the method /users/me to query basic data like the user data, the organization field and other stuff, then again, /users/me returns the same "simplified" short version of the user data, without their fields like organization. So I am going to use afterRead hook, so I can "manipulate" the response. It turns out that when I do this:
afterRead: [
async ({ doc }) => {
console.log('doc', doc);
},
],the console outputs this:
// first time
doc {
id: 2,
firstName: 'Erika',
lastName: 'Mustermann',
roles: [ 'user' ],
organization: {
organization: {
id: 1,
name: 'Starbucks Deutschland GmbH',
logo: 'www.google.com',
updatedAt: '2024-10-02T19:15:21.088Z',
createdAt: '2024-07-26T19:53:31.064Z'
},
roles: [ 'admin' ]
},
updatedAt: '2024-10-22T16:32:22.884Z',
createdAt: '2024-07-26T19:54:11.004Z',
email: '[email protected]',
password: undefined,
loginAttempts: 0
}
// second time
doc {
id: 2,
firstName: 'Erika',
lastName: 'Mustermann',
updatedAt: '2024-10-22T16:32:22.884Z',
createdAt: '2024-07-26T19:54:11.004Z',
email: '[email protected]',
password: undefined,
loginAttempts: 0
}it runs TWICE, the first time with the full doc/collection in depth, and the second time with the "short" or "simplified" version, so then AGAIN, I can not update the response to the REST API as I want.
Can a good soul explain to me why is that? Is this a bug? (it seems so to me). Is there any way I can fix this without much overhead? Any help would be very much appreciated! <3 Thank you so much!
PS: To me, it doesn't make sense the criteria used to set up the API responses for the user collection at the REST endpoints. Just compare the response at the beginning of my message from /users/login versus this one: /users/refresh-token:
{
"message": "Token refresh successful",
"exp": 1729884498,
"refreshedToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiY29sbGVjdGlvbiI6InVzZXJzIiwiZW1haWwiOiJlcmlrYS5tdXN0ZXJtYW5uQHN0YXJidWNrcy5kZSIsImlhdCI6MTcyOTg4MzU5OCwiZXhwIjoxNzI5ODg0NDk4fQ.9zIN4TNhNxzZsmbp67sETTjcf1PON3cUyREXaJV8O6Q",
"strategy": "local-jwt",
"user": {
"id": 2,
"firstName": "Erika",
"lastName": "Mustermann",
"roles": [
"user"
],
"organization": {
"organization": {
"id": 1,
"name": "Starbucks Deutschland GmbH",
"logo": "www.google.com",
"updatedAt": "2024-10-02T19:15:21.088Z",
"createdAt": "2024-07-26T19:53:31.064Z"
},
"roles": [
"admin"
]
},
"updatedAt": "2024-10-22T16:32:22.884Z",
"createdAt": "2024-07-26T19:54:11.004Z",
"email": "[email protected]",
"loginAttempts": 0
}
}The refresh-token endpoint returns a full in depth user object, while the /users/login does not. Why would you like to have this information under refresh-token ? Far from questioning whether you need it or not under /users/refresh-token, my question is: Why it is not provided under /users/login ? Which is more crucial, in my opinion. Or even at /users/me!
Thx!
Payload Version
2.30.0
Adapters and Plugins
db-postgres, bundler-webpack