Access control function with undefined user

default discord avatar
andrew_a
2 months ago
34

Hi 🖐️



In my access control function, the console.log of the user is showing undefined and hence it shows the error in the screenshot



export const isAdminOrSelf: Access = ({ req: { user } }) => { console.log(user); if (user) { if (user.roles?.includes("admin")) { return true; } return { id: { equals: user.id, }, }; }

I am using it on my collection like this:




import { CollectionConfig } from "payload/types"; import { isAdmin, isAdminFieldLevel } from "../access/isAdmin"; import { isAdminOrSelf, isAdminOrSelfFieldLevel } from "../access/isAdminOrSelf"; const Users: CollectionConfig = { slug: "users", auth: true, admin: { useAsTitle: "email", }, access: { create: isAdmin, read: isAdminOrSelf, update: isAdminOrSelf, delete: isAdminOrSelf, }, fields: [ // Email added by default { name: "firstName", type: "text", }, { name: "lastName", type: "text", }, { name: "roles", type: "select", hasMany: true, defaultValue: ["public"], required: true, access: { read: isAdminOrSelfFieldLevel, create: isAdminFieldLevel, update: isAdminFieldLevel, }, options: ["admin", "public"], }, ], }; export default Users; return false; };
  • default discord avatar
    notchr
    2 months ago

    Good afternoon @andrew_a !



    I recently saw a post that had this same issue with an admin or self function



    Are you able to access user on the default access function?

  • default discord avatar
    andrew_a
    2 months ago

    Hi there! What is default access function?



    or where would I find it

  • default discord avatar
    notchr
    2 months ago

    @andrew_a Hello Andrew



    technically defualt would just be omitting the access property I believe



    but for testing, granting open access would be



    access: {
            read: () => true,
            create  () => true,
            update: () => true,
          },


    etc

  • default discord avatar
    andrew_a
    2 months ago

    Yes, when I do

    () => true

    it works well.



    access: { create: isAdmin, read: isAdminOrSelf, update: () => true, delete: isAdminOrSelf, },

    However, it's not working with

    isAdminOrSelf

    using this



    export const isAdminOrSelf: Access = ({ req: { user } }) => { console.log(user); if (user) { if (user.roles?.includes("admin")) { return true; } return { id: { equals: user.id, }, }; }


    I still can't figure this one out. Any help is welcome.



    @jesschow 🙏

  • default discord avatar
    notchr
    2 months ago

    @andrew_a Does user come back as expected?



    I would first check the user, then check to make sure each condition returns a boolean



    Also I would make sure user.roles is indeed an array of roles



    (or a single role)

  • default discord avatar
    andrew_a
    2 months ago

    When I put a console.log here



    export const isAdminOrSelf: Access = ({ req: { user } }) => { console.log(user); if (user) { if (user.roles?.includes("admin")) { return true; } return { id: { equals: user.id, }, }; }

    the function gets called many times.


    The first time it gets called, the user is undefined.


    The following function calls have the user-defined and pass all the checks.



    Should I make a recording of this? 🙂

  • default discord avatar
    notchr
    2 months ago

    @andrew_a hmm, what does the logged user object look like, specifically user.roles

  • default discord avatar
    andrew_a
    2 months ago

    It logs "undefined"



    It is like the req is not coming with the user attached.

    image.png
  • default discord avatar
    notchr
    2 months ago

    @andrew_a can we check out the

    isAdminOrSelfFieldLevel

    function



    that is controlling access on the .roles field

  • default discord avatar
    andrew_a
    2 months ago

    Sure



    export const isAdminOrSelfFieldLevel: FieldAccess<{ id: string }, unknown, User> = ({ req: { user }, id, }) => { // Return true or false based on if the user has an admin role if (user?.roles?.includes("admin")) return true; if (user?.id === id) return true; return false; };


    The main problem that I see is that user comes as undefined from req

  • default discord avatar
    notchr
    2 months ago

    That is odd...



    @andrew_a the req.user would only be undefined if you're not logged in



    Are you checking the access after you're logged in?



    Are you making a call with REST?



    Give me some more context on the situation and I think we can narrow this down

  • default discord avatar
    andrew_a
    2 months ago

    Sometimes I see also this on the console.



    I am logged in within the admin



    I will record a quick video which I think can be useful 🙂

    image.png
  • default discord avatar
    notchr
    2 months ago

    Can you copy the JSON output of the admin user



    from the bottom right of the user screen

  • default discord avatar
    andrew_a
    2 months ago

    yes



    // 20230719214150


    //

    http://localhost:3300/api/users/6466368dea691180c682dd1d?locale=en

    {


    "id": "6466368dea691180c682dd1d",


    "name": "Andres",


    "email": "andres@netzstrategen.com",


    "createdAt": "2023-05-18T14:30:37.734Z",


    "updatedAt": "2023-07-19T19:41:21.616Z",


    "roles": [


    "admin"


    ]


    }

  • default discord avatar
    notchr
    2 months ago

    hmm



    What are you trying to do when you get the error

  • default discord avatar
    andrew_a
    2 months ago

    I cannot perform any action.


    If I try to change my name I get an error:



    If I try to create a user I get an error, If I try to create a post I get an error



    I think I will be better off If I do a fresh installation. But it is an interesting bug

    image.png
  • default discord avatar
    notchr
    2 months ago

    Well...



    If we check out the CMS example



    this is the comparable access check



    https://github.com/payloadcms/payload/blob/master/examples/auth/cms/src/collections/access/adminsAndUser.ts


    it uses the following checkRoles function:

    https://github.com/payloadcms/payload/blob/master/examples/auth/cms/src/collections/access/checkRole.ts


    So for instance, to check for an admin, you could do



    export const admins: Access = ({ req: { user } }) => checkRole(['admin'], user)


    If we then



    look at the Users collection access control

  • default discord avatar
    andrew_a
    2 months ago

    Yeah, but as mentioned that weird thing is that user is coming out as undefined

  • default discord avatar
    notchr
    2 months ago
      access: {
        read: adminsAndUser,
        create: anyone,
        update: adminsAndUser,
        delete: admins,
        admin: ({ req: { user } }) => checkRole(['admin'], user),
      },
  • default discord avatar
    andrew_a
    2 months ago

    when console logging the full req response, user is just not there 🙂

  • default discord avatar
    notchr
    2 months ago

    Ahhhhh



    ok sec

  • default discord avatar
    andrew_a
    2 months ago

    I appreciate your help by the way

  • default discord avatar
    notchr
    2 months ago

    Of course!



    I have another idea, but it may not work

  • default discord avatar
    andrew_a
    2 months ago

    Lets go for it



    maybe there is something wrong with my collection



    import { CollectionConfig } from "payload/types";


    import { isAdmin, isAdminFieldLevel } from "../access/isAdmin";


    import { isAdminOrSelf, isAdminOrSelfFieldLevel } from "../access/isAdminOrSelf";



    const Users: CollectionConfig = {


    slug: "users",


    auth: true,


    admin: {


    useAsTitle: "email",


    },


    access: {


    create: isAdmin,


    read: isAdminOrSelf,


    update: isAdminOrSelf,


    delete: isAdminOrSelf,


    },


    fields: [


    // Email added by default


    {


    name: "firstName",


    type: "text",


    },


    {


    name: "lastName",


    type: "text",


    },


    {


    name: "roles",


    type: "select",


    hasMany: true,


    defaultValue: ["public"],


    required: true,


    access: {


    read: isAdminOrSelfFieldLevel,


    create: isAdminFieldLevel,


    update: isAdminFieldLevel,


    },


    options: ["admin", "public"],


    },


    ],


    };



    export default Users;

  • default discord avatar
    notchr
    2 months ago

    It doesn't seem wrong



    Hmmm



    What if you logout and login, is possible you've altered the auth and it didnt update?

  • default discord avatar
    andrew_a
    2 months ago

    how can one alter the auth?

  • default discord avatar
    notchr
    2 months ago

    Well the auth sets a cookie when you login



    I wasn't sure if the cookie didnt update or something automatically

  • default discord avatar
    andrew_a
    2 months ago

    Let me log out



    and send a screenshot of the cookies

  • default discord avatar
    notchr
    2 months ago

    I actually have to head home from work, but I'll be on when I get home and I can help further



    😄



    Do update this thread though, I'll be checking back

  • default discord avatar
    andrew_a
    2 months ago

    I get this cookie:



    Sure thing, thanks a lot.

    image.png
  • default discord avatar
    notchr.is
    2 months ago

    hmm



    that should be OK, can you copy the value



    @andrew_a and then paste it in

    https://jwt.io
  • default discord avatar
    andrew_a
    2 months ago


    image.png
    image.png
  • default discord avatar
    notchr
    2 months ago

    @andrew_a Good morning!



    So that actually looks normal



    Let me know when your'e back on and I can help resolve further 😄

  • default discord avatar
    andrew_a
    2 months ago

    I have fixed the issue by reinstalling the whole project 🙂



    thanks for your help tho

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.