Hi, the code below is underlining
returnwith the TS error "Type 'boolean' is not assignable to type 'FieldAccess'.". From reading the docs FieldAccess should be able to accept boolean, and I haven't had issues with FieldAccess not accepting booleans before, I can't figure out where I'm going wrong exactly
export const isSuperadminOrNewspaperRoleFieldAccess = async (
args: { req: PayloadRequest },
role: User['newspapers'][number]['role']
): Promise<FieldAccess> => {
const {
req,
req: { user, payload },
} = args
// Allow super-admins through
if (checkUserRole(['super-admin'],user)) {
return true;
}
// ...FieldAccessis a function that returns a boolean or a
Promise<boolean>I think you mean
export const isSuperadminOrNewspaperRoleFieldAccess: FieldAccess = async () => rest...When I add
: FieldAccessto where you've put it, I get
isSuperadminOrNewspaperRoleFieldAccessunderlined with:
"Type '(args: { req: PayloadRequest; }, role: User['newspapers'][number]['role']) => Promise<boolean>' is not assignable to type 'FieldAccess'.
Target signature provides too few arguments. Expected 2 or more, but got 1."
Thank you for such a fast response by the way, I really appreciate how patient and swift to reply the Payload team are with community issues. I know I'm going the wrong way with this one, probably due to a bit of tiredness
Hey mate, can you share your full function and then the bit of how you're using as well please?
Also on latest payload?
Hi
@858693520012476436apologies for the delayed response. Below is the code. It mightn't be 100% right, I recall working on the Collection access version of it then copying it to make a field access version, and running into the error then. Took it from the multi-tenant example and adjusted it. Again it mightn't be 100% as I wasn't finished the collection version of it
export const isSuperadminOrNewspaperRoleFieldAccess: FieldAccess = async (
args: { req: PayloadRequest },
role: User['newspapers'][number]['role']
): Promise<boolean> => {
const {
req,
req: { user, payload },
} = args
// Allow super-admins through
if (checkUserRole(['super-admin'],user)) {
return true;
}
// Read `req.headers.host`, lookup the newspaper by `domain` to ensure it exists
if (logs) {
payload.logger.info(`isSuperadminOrNewspaperManager: Finding newspapers with host: '${req.headers.host}'`)
}
const foundNewspapers = await payload.find({
collection: 'newspapers',
where: {
'domains.domain': {
in: [req.headers.host],
},
},
depth: 0,
pagination: false,
})
// If this newspaper does not exist, deny access
if (foundNewspapers.totalDocs === 0) {
if (logs) {
payload.logger.info(`isSuperadminOrNewspaperManager: No newspaper found for ${req.headers.host}`)
}
return false
}
// Finally check if the user is a manager of this newspaper
const foundNewspaperIds = foundNewspapers.docs?.map(newspaperDoc => newspaperDoc.id)
const newspapersUserIsRoleOf = checkNewspaperRole(user,[role])
if (newspapersUserIsRoleOf == false) {
return false;
} else if (Array.isArray(newspapersUserIsRoleOf) && !newspapersUserIsRoleOf.length) {
if (newspapersUserIsRoleOf.some(newspaper => foundNewspaperIds.includes(newspaper))) {
if (logs) {
payload.logger.info(`isSuperadminOrNewspaperManager: User is a ${role} of the following newspapers: ${newspapersUserIsRoleOf.join(", ")}; allowing access through ${[req.headers.host]}`)
}
return true
}
}
// If all else fails return false
if (logs) {
payload.logger.info(`isSuperadminOrNewspaperManager: User is not a ${role} of any of the following newspapers: ${foundNewspaperIds.join(", ")}; denying access`)
}
return false;
}isSuperadminOrNewspaperRoleFieldAccessis underlined with the following:
"Type '(args: { req: PayloadRequest; }, role: User['newspapers'][number]['role']) => Promise<boolean>' is not assignable to type 'FieldAccess'.
Target signature provides too few arguments. Expected 2 or more, but got 1."
Ahh I just checked it, it's because you have an extra argument like
role: User['newspapers'][number]['role']but you assigned the whole function to FieldAccess which only accepts one argument
What you want to do instead is have a wrapper function that takes your role ^ and then returns another function with that bind
Alternatively you don't assign the function to FieldAccess
I understand, I'm still new to TS/JS, using Payload is my trial by fire for learning it. I'll figure out how to have a wrapper function to take the role
You can have a look in this plugin for how I did the wrapper function
https://github.com/NouanceLabs/payload-simple-rbac/blob/main/src/accessControl/hasRole.tsand
https://github.com/NouanceLabs/payload-simple-rbac/blob/main/src/accessControl/hasRoleField.tsI can't understanding what/where the wrapper is, or what it's doing, between those two files?
the second one is a function that returns another async function
the return type is
FieldAccessnot the type of the function itself
simplified
export function hasRoleField(
role: string,
): FieldAccess {
return async ({ req, id, data }) => {
const user = req.user;
// my logic
return false;
};
}Oh I'm sorry, I was looking at the export function line of each file. I'll try get it now
Got it, adjusted code below:
export const isSuperadminOrNewspaperRoleFieldAccess = (
role: User['newspapers'][number]['role']
): FieldAccess => async (args: { req: PayloadRequest }): Promise<boolean> => {
// Code
}Btw thanks very much
@858693520012476436, very swift replies and good help
Np mate, gonna mark this one as solved, feel free to reopen though!
Star
Discord
online
Get dedicated engineering support directly from the Payload team.