Skip to main content
Modelence provides built-in support for user roles. You can define roles in startApp, assign them to users, and check them on both the server and client.

Defining Roles

Register the roles your app uses in your startApp call:
import { startApp } from 'modelence/server';

startApp({
  roles: {
    admin: { description: 'Full access to all features' },
    editor: { description: 'Can edit content' },
    viewer: {},
  },
});
Each role has an optional description that is shown in the Modelence Cloud dashboard.
Roles defined in startApp are synced to Modelence Cloud so you can assign them to users directly from the dashboard.

Checking Roles in Handlers

Use user.requireRole to throw an error if the user lacks a role, or user.hasRole for manual checking:
import { Module } from 'modelence/server';
import { AuthError } from 'modelence';

export default new Module('myModule', {
  mutations: {
    adminAction: {
      handler: async (args, { user }) => {
        if (!user) {
          throw new AuthError('Not authenticated');
        }

        // Throws if the user doesn't have the "admin" role
        user.requireRole('admin');

        // Admin-only logic here
      }
    },

    anotherAdminAction: {
      handler: async (args, { user }) => {
        if (!user) {
          throw new AuthError('Not authenticated');
        }

        // Check without throwing for custom error handling
        if (!user.hasRole('admin')) {
          throw new Error('Admin access required');
        }

        // Admin-only logic here
      }
    }
  }
});

Assigning Roles

The recommended way to assign roles is through the Modelence Cloud user management dashboard. If that is not available, you can update roles directly via the dbUsers collection:
import { dbUsers, ObjectId } from 'modelence/server';

// Add a role
await dbUsers.updateOne(
  { _id: new ObjectId(userId) },
  { $addToSet: { roles: 'admin' } }
);

// Add multiple roles
await dbUsers.updateOne(
  { _id: new ObjectId(userId) },
  { $addToSet: { roles: { $each: ['editor', 'viewer'] } } }
);

// Remove a role
await dbUsers.updateOne(
  { _id: new ObjectId(userId) },
  { $pull: { roles: 'admin' } }
);

Frontend Usage

Use useSession to check roles on the client and conditionally render UI:
import { useSession } from 'modelence/client';

function AdminPanel() {
  const { user } = useSession();

  if (!user?.hasRole('admin')) {
    return <div>Access denied</div>;
  }

  return <div>Admin content</div>;
}
import { useSession } from 'modelence/client';

function Navigation() {
  const { user } = useSession();

  return (
    <nav>
      <a href="/">Home</a>
      {user?.hasRole('admin') && <a href="/admin">Admin Panel</a>}
      {user?.hasRole('editor') && <a href="/editor">Editor</a>}
    </nav>
  );
}

API Reference

startApp options:
  • rolesRecord<string, RoleDefinition> — role definitions keyed by name
RoleDefinition:
  • description?: string — optional human-readable description shown in the Modelence Cloud dashboard
User methods:
  • user.roles: string[] — the roles assigned to the user
  • user.hasRole(role: string): boolean — check if user has a specific role
  • user.requireRole(role: string): void — throw error if user doesn’t have role