I'm trying to give a user a role in this GraphQL request, but it doesn't work. It's not an authorization/permission/access issue, but it comes back without any roles in the response... Obviously I have the actual user id and actual role id in the respective spots.
Mutation:
mutation GiveUserDeveloperRole {
updateUser(id: "<user_id>", data: { roles: ["<role_id>"] }) {
roles {
id
name
}
}
}
Response:
{
"data": {
"updateUser": {
"roles": []
}
}
}
Any insight as to why this might not be working?
roles
is a relationship field.
hmmmmm
if it's not an access thing, i'm not sure tbh
we might need a minimally reproducible repo to help on this one
I'll do some more digging myself and if I get really stuck I'll try making a minimum reproducible repo. For some more info I'm running Payload v1.6.32 and making that request via the GraphQL Playground.
Honestly I don't have time to make a new repo, pretty busy at work. I will say I just updated to Payload v1.7.2 and it is still an issue. For now I was able to access the database and add the role I needed directly (this role then gives me permissions to update other roles so only need to do it once).
@jesschow @patrikkozak can either of you two help try and reproduce this?
@jmikrut @TheDunco Yeah, I'll look into this
🙏
Hey @TheDunco - quick question - your
roles
relationship field has a
relationTo
to what exactly? A roles collection? If so, what does that look like?
Yep, to a roles collection:
export const Roles: CollectionConfig = {
slug: 'roles',
admin: {
useAsTitle: 'name',
},
access: {
read: () => true,
readVersions: () => true,
create: developerRole,
delete: developerRole,
update: developerRole,
},
fields: [
{
name: 'name',
type: 'text',
required: true,
unique: true,
},
],
timestamps: false,
};
So for this one I removed the API access function but I previously had it such that if it had a correct authorization header it would be let through from the api. I can try just setting all the access to
() => true
to see if the access is blocking it?
Yeah, I tried and it's not the access that's the issue since it would give me an error in the response if that was the case
And that access function looks like this...
import { Access, FieldAccess, RelationshipField } from 'payload/types';
const isUserDeveloper = (user: any) => {
if (!user) {
return false;
}
// Use role.name field because the id might be different depending on the environment
if (user?.roles?.find((role: RelationshipField) => role.name === 'Developer')) {
return true;
}
return false;
};
export const developerRole: Access = ({ req: { user } }) => {
return isUserDeveloper(user);
};
export const developerFieldRole: FieldAccess = ({ req: { user } }) => {
return isUserDeveloper(user);
};
What does your
roles
relationship field look like? Does it have
hasMany: true
on it?
{
type: 'relationship',
name: 'roles',
hasMany: true,
relationTo: 'roles',
access: {
create: developerFieldRole,
update: developerFieldRole,
read: () => true,
},
}
Oh, so the
developerFieldRole
access here might be the issue then? I'd still expect an error related to access if that's the issue though
if access fails on a field level, then it just disregards the value
it doesn't throw an error
this is probably it
Ah... Interesting... Is that documented anywhere? Did I just miss that?
hmm, you mean
what happensif a user tries to update a field that they don't have access to?
we could add that to field-level access control docs for sure
@zubricks can you open a documentation issue to add some detail to those docs?
we should explicitly mention that if a user has access to update a doc, but does NOT have access to update a certain field, and they attempt to update a field, the field data will just be omitted from the update operation without throwing an error
Thanks all!
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.