CustomClaims in ID Token not available in first login

I have set a custom Action which appends Roles to ID Token as a Custom Claim:

exports.onExecutePostLogin = async (event, api) => {
  if (event.authorization) {
    api.idToken.setCustomClaim('rolesArray', event.authorization.roles);
  }
}

This action runs after a custom action which assigns a default role as seen in a video given by Auth0

exports.onExecutePostLogin = async (event, api) => {
  if(event.authorization && 
  event.authorization.roles &&
   event.authorization.roles.length===0){

  const ManagementClient = require('auth0').ManagementClient;

  const management = new ManagementClient({
  domain: event.secrets.domain,
  clientId: event.secrets.clientID,
  clientSecret: event.secrets.clientSecret,
  });

  const params = {id:event.user.user_id};
  const data  = {"roles":[<id of default role>]};

  try{
    await management.users.assignRoles(params,data);
  }catch(e){
    console.log(e)
  }
  }
};

Both of these actions are in the Login Flow in the following order:
DefaultRoleAssign → AppendRoleToIDToken
The problem is that even though the default role is assigned(I can see it in user management of Auth0 Dashboard) whenever a new user signs in with Google, the roles are not fetched to the application and the customClaim is an empty array. The roles are available in subsequent logins. How can I also ensure that the roles are fetched in the first login?
Thank you!

Hi @myself.vinayak2

Welcome to the Auth0 Community!

Thank you for posting your question. Can you try to run them under one Action? You can utilize the Action Templates for assigning roles to the user.

Thanks
Dawid

2 Likes

Thank you for the reply
I did end up figuring it out for my specific use case and yes I had to run them under one Action

 if(event.authorization){
    if (event.stats.logins_count === 1) {
        api.idToken.setCustomClaim("rolesArray", [<default role>]);
      } else {
        api.idToken.setCustomClaim("rolesArray", event.authorization.roles);
        console.log(event.authorization.roles);
      }
  }

although a little unrelated, I was thinking of adding the same email sign-up prevention in this action too to prevent sign-up in case there is already a user with that same email(from either native login or google-oauth). Although I can prevent the sign up but the account still gets made
this is the existing code for that:

   management.getUsers({q: `email:"${event.user.email}"` },function (err, users) {
    if (users.length >= 1) {
     event.user.user_id
     
      api.access.deny("The user with this email already exists");
    }
  });