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:
roles — Record<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