I am unable to add the role which was added during the first login to the access token

I have the following actions in my Login flow:

  1. Assign Role On First Login:
exports.onExecutePostLogin = async (event, api) => {
  if (event.stats.logins_count !== 1) {
    return;
  }

  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" : ["rol_7OQ4PJQWyE0R0eQC"]};

  try {
    const res = await management.assignRolestoUser(params, data)
  } catch (e) {
    console.log(e)
    // Handle error
  }
};
  1. Enrich Access Token
exports.onExecutePostLogin = async (event, api) => {
  if (event.authorization){
    api.accessToken.setCustomClaim("user_id", event.user.user_id);
    api.accessToken.setCustomClaim("user_name", event.user.name);
    api.accessToken.setCustomClaim("user_email", event.user.email);

    const hasuraClaims = {
      "x-hasura-user-id": event.user.user_id
    };

    let roles;
    if (event.stats.logins_count === 1) {
      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};

      try {
        roles = await management.getUserRoles(params)
      } catch (e) {
        console.log(e)
        // Handle error
      }
    }
    else {
      roles = event.authorization.roles.map(role => role.toLowerCase());
    }
    
    if (roles && roles.length > 0) {
      api.idToken.setCustomClaim("user_roles", roles);
      api.accessToken.setCustomClaim("user_roles", roles);

      const defaultRole = roles.reduce((highestRole, currentRole) => {
        if (currentRole === "admin") {
          return currentRole;
        }
        if (currentRole === "manager" && highestRole !== "admin") {
          return currentRole;
        }
        if (currentRole === "editor" && highestRole !== "admin" && highestRole !== "manager") {
          return currentRole;
        }
        if (currentRole === "viewer" && highestRole !== "admin" && highestRole !== "manager" && highestRole !== "editor") {
          return currentRole;
        }
        return highestRole;
      }, "");

      hasuraClaims["x-hasura-default-role"] = defaultRole;
      hasuraClaims["x-hasura-allowed-roles"] = roles;
    }
    
    api.accessToken.setCustomClaim("https://hasura.io/jwt/claims", hasuraClaims);
  }
};

The first action successfully adds the role on the first login. However, in the second action during the first login, event.authorization.roles does not contain the role that was added in the previous action. To get around this, I tried to use the management API to getUserRoles, but this does not seem to be working as expected.

What is the recommended approach here? Is there some way to add the added role to the event from the first action so it can be consumed normally by the second action? Should I be using the management API in the second action to get the user roles (like I’m currently trying to do, but in the correct way)?

Please advise. Thanks!

Disregard… I figured it out. The issue is that the Machine to Machine application I am using to connect to the Management API needed the read:users permission (which I didn’t have) along with the read:roles permission (which I did have). It also needs the update:roles permission to be able to set the role from the first action. Here is the updated second action:

exports.onExecutePostLogin = async (event, api) => {
  if (event.authorization){
    api.accessToken.setCustomClaim("user_id", event.user.user_id);
    api.accessToken.setCustomClaim("user_name", event.user.name);
    api.accessToken.setCustomClaim("user_email", event.user.email);

    const hasuraClaims = {
      "x-hasura-user-id": event.user.user_id
    };

    let roles;
    if (event.stats.logins_count === 1) {
      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};

      try {
        const userRoles = await management.getUserRoles(params);
        roles = userRoles.map((role) => role.name.toLowerCase());
      } catch (e) {
        console.log(e);
        // Handle error
      }
    }
    else {
      roles = event.authorization.roles.map(role => role.toLowerCase());
    }
    
    if (roles && roles.length > 0) {
      api.idToken.setCustomClaim("user_roles", roles);
      api.accessToken.setCustomClaim("user_roles", roles);

      const defaultRole = roles.reduce((highestRole, currentRole) => {
        if (currentRole === "admin") {
          return currentRole;
        }
        if (currentRole === "manager" && highestRole !== "admin") {
          return currentRole;
        }
        if (currentRole === "editor" && highestRole !== "admin" && highestRole !== "manager") {
          return currentRole;
        }
        if (currentRole === "viewer" && highestRole !== "admin" && highestRole !== "manager" && highestRole !== "editor") {
          return currentRole;
        }
        return highestRole;
      }, "");

      hasuraClaims["x-hasura-default-role"] = defaultRole;
      hasuraClaims["x-hasura-allowed-roles"] = roles;
    }
    
    api.accessToken.setCustomClaim("https://hasura.io/jwt/claims", hasuraClaims);
  }
};
1 Like

I am unable to add the role which was added during the first login to the access token. This issue suggests a challenge in integrating newly assigned roles into existing access tokens effectively. Addressing this requires reevaluating the token generation process to ensure it dynamically reflects updated user roles for secure and efficient access management.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.