CollectionAfterLoginHook Usage

default discord avatar
shisue11 months ago
8

Hi,



I'm new to payload and I'm a bit unsure how to add auth based hooks to the collection. I have created the actual hook, but how do I link it with the collection? Other types of hook are added under "hooks" in the collection, but there is no "AfterLogin" type I can use. How exactly do I tie a CollectionAfterLoginHook to the document?



Thanks!

  • discord user avatar
    tylandavis
    11 months ago

    @shisue You should be able to add

    afterLogin

    and other Auth-enabled hooks the same way you would add in the other hooks.


    /**
     * Hooks to modify Payload functionality
     */
    hooks?: {
        beforeOperation?: BeforeOperationHook[];
        beforeValidate?: BeforeValidateHook[];
        beforeChange?: BeforeChangeHook[];
        afterChange?: AfterChangeHook[];
        beforeRead?: BeforeReadHook[];
        afterRead?: AfterReadHook[];
        beforeDelete?: BeforeDeleteHook[];
        afterDelete?: AfterDeleteHook[];
        afterError?: AfterErrorHook;
        beforeLogin?: BeforeLoginHook[];
        afterLogin?: AfterLoginHook[];
        afterLogout?: AfterLogoutHook[];
        afterMe?: AfterMeHook[];
        afterRefresh?: AfterRefreshHook[];
        afterForgotPassword?: AfterForgotPasswordHook[];
    };


    Could you share your collection config and hook code here? I can try to help you out

  • default discord avatar
    shisue11 months ago

    Thanks! This actually solved my issue, I was doing logic field-based but had to be collection-based everywhere.

  • discord user avatar
    tylandavis
    11 months ago

    Awesome, let me know if you run into anything else!

  • default discord avatar
    shisue11 months ago

    I'm running into a small other issue. I'm trying to create the Last Active field, and upon trying to deconstruct user I keep getting a type error:



    import type { User } from 'payload/generated-types' import type { CollectionAfterLoginHook } from 'payload/types' // ensure there is always a

    user

    role // do not let non-admins change roles export const lastLoggedIn: CollectionAfterLoginHook<User & { id: string }> = async ({ req, user, token }) => { return [...user, { lastLoggedIn: new Date() }]; }


    My Last Active field under users looks like this:



    { name: 'lastActive', label: 'Last Active', type: 'date', access: { read: () => true, update: () => true, create: () => false, }, saveToJWT: true, },
  • discord user avatar
    tylandavis
    11 months ago

    A couple things:


    - the Login operation isn't modifying a document, so you wouldn't return an updated

    user

    object here. (also, if you were, return an object instead of an array. That's likely the type error)


    - you can use the Local API to make an update to the document, here's a snippet of how that could work:



    hooks: {
      afterLogin: [
        async ({ user }) => {
          await payload.update({
            collection: 'users',
            id: user.id,
            data: {
              lastActive: new Date(),
            },
          });
        }
      ],
    },
  • default discord avatar
    shisue11 months ago

    Thanks!



    A followup question, is there a way to make fields required depending on a given role a user has without using hooks, or is hooks the way to go when enforcing this type of behavior?

  • discord user avatar
    tylandavis
    11 months ago

    Sure, you can create your own validation functions at the field level. Check out this example that makes a field required if the user has an

    admin

    role:


    {
      name: 'validation',
      type: 'text',
      label: 'validation',
      validate: (value, { user }) => {
        if (user.role === 'admin') {
          return value ? true : 'Please provide a value'
        }
        return true;
      },
    },

    I pass the

    validate

    property the

    value

    of the field, as well as the

    user

    object. If the user's role is

    admin

    it checks the value, and returns true if it exists, otherwise it returns 'Please provide a value' as an error statement.



    If a user's role is not

    admin

    , it does not require a value and returns true.



    The

    validate

    property can either return

    true

    or a string to use as the error that is returned if the validation is not passed.

  • default discord avatar
    shisue11 months ago

    Thanks!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

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