Handling Dynamic Role Names in Different Environments with useRoleManagement Hook (Part 2)

Veaceslav - Sep 2 - - Dev Community

In the first part of this series, we explored the foundation of implementing role-based access control in React using the useRoleManagement hook. If you haven't read it yet, you can check it out here
Implementing Role-Based Access Control in React: A Deep Dive into useRoleManagement Hook.

In this second part, we'll dive deeper into managing dynamic role names depending on different environments, such as staging and production. This is crucial for maintaining consistent and secure role management across various stages of development.

Overview

When developing applications, it's common to have different role names or permissions configurations for various environments. For instance, you might use test or mock role names in development and real, production-ready role names in the production environment. Handling these dynamic role names correctly ensures that your application behaves consistently and securely across different stages of its lifecycle.

Environment-Specific Role Configuration

To manage role names dynamically, we can leverage environment variables. These variables allow us to define different role keys for different environments, which can then be used to load the appropriate permissions configuration.

Here’s how we can achieve this:

1. Define Environment Variables

In your .env.development and .env.production files, specify the role keys for each environment. For example:

  • .env.development
VITE_ROLE_KEYS_MANAGER=Manager_Test
VITE_ROLE_KEYS_USER=USER_Test
VITE_ROLE_KEYS_ADMIN=Admin_Test
Enter fullscreen mode Exit fullscreen mode
  • .env.production
VITE_ROLE_KEYS_MANAGER=Prod_Manager
VITE_ROLE_KEYS_USER=Prod_USER
VITE_ROLE_KEYS_ADMIN=Prod_Admin

Enter fullscreen mode Exit fullscreen mode

This setup ensures that your application uses appropriate role names depending on the environment it’s running in.

2. Update the permissions Object

Use these environment variables to define the permissions object dynamically. The permissions object maps role keys to specific permissions for each role:

const permissions: Record<string, UserPermissions> = {
  [import.meta.env.VITE_ROLE_KEYS_MANAGER]: {
    partners: { add: false, view: false, edit: false, deleteRow: true },
    // ... other permissions
  },
  [import.meta.env.VITE_ROLE_KEYS_USER]: {
    partners: { add: false, view: false, edit: false, deleteRow: false },
    // ... other permissions
  },

  [import.meta.env.VITE_ROLE_KEYS_ADMIN]: {
    partners: { add: true, view: true, edit: true, deleteRow: true },
    // ... other permissions
  },
};
Enter fullscreen mode Exit fullscreen mode

The import.meta.env syntax allows you to access environment variables defined in your .env files.

3. Use the useRoleManagement Hook

In the first part of this series, we explored the foundation of role-based access control in React using the useRoleManagement hook. If you haven't read it yet, you can check it out here.

The useRoleManagement hook extracts user roles from the decoded JWT token, maps them to permissions using the environment-specific role keys, and then returns the relevant permissions:

export function useRoleManagement() {
  const { pathname } = useLocation();

  const token = localStorage.getItem('token');

  let decodedToken: Realm | null = null;

  try {
    if (token) {
      decodedToken = jwtDecode<Realm>(token);
    }
  } catch (error) {
    console.error('Invalid token:', error);
  }

  const roles = decodedToken?.realm_access?.roles ?? [];

  const roleExists = ifRoleExists(roles);

  const rolePermissions = getPermissions(
    roleExists,
    pathname !== '/' ? pathname : '/partners',
  );

  if (!rolePermissions) {
    return {};
  }

  const {
    add,
    view,
    edit,
    deleteRow,
    confirm,
    include,
  } = rolePermissions as Permissions;

  return {
    add,
    view,
    edit,
    deleteRow,
    confirm,
    include,
  };
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

By dynamically managing role names through environment variables, you can ensure that your application's role-based access control behaves consistently across different environments. This approach provides flexibility and helps maintain a clear separation between development and production configurations.

. .
Terabox Video Player