user-role System
An A-Frame system that manages scene-wide user roles and permissions. It supports role-based access control (RBAC) using either string roles or numeric permission levels.
Lower numeric values represent higher permission.
User Roles
Role hierarchy
| Role string | Numeric value | Description |
|---|---|---|
room_owner | 1 | World owner, highest world permission |
admin | 2 | Administrative privileges |
editor | 3 | Content editing privileges |
moderator | 4 | Reserved, not assigned by the platform |
user | 5 | Standard user |
guest | 6 | Lowest permission |
owner is accepted as an alias for room_owner (value 1).
UserRole type
type UserRole =
| "room_owner"
| "owner"
| "admin"
| "editor"
| "moderator"
| "user"
| "guest";
Overview
The user-role system:
- Stores the current user role at the scene level
- Normalizes numeric and string role values
- Provides helpers for permission checks
- Emits events when roles change
- Automatically converts numeric values to role strings
In a W3DGE world, the role is set for you when the world loads, based on the visitor's role in that world. The world's in-world editor is shown to editor and higher.
For permission gates in your scripts, check for editor or higher, for example hasPermission('editor'), isEditor(), isAdmin() or isOwner(). These match the roles that can edit the world. See Roles & Permissions.
API Reference
Get the system from the scene:
const roleSystem = this.el.sceneEl.systems["user-role"];
getRole(): UserRole
Returns the current role as a string.
roleSystem.getRole(); // 'admin'
getRoleNumber(): number
Returns the numeric permission level (1–6).
roleSystem.getRoleNumber(); // 2
getRoleAsInt(): number
Alias for getRoleNumber().
roleSystem.getRoleAsInt(); // 2
setRole(role: UserRole | number | string): void
Sets the role using either a string or number and automatically normalizes numeric values. Unknown values fall back to 'guest'.
Also emits a role-changed event on the scene.
roleSystem.setRole("editor");
roleSystem.setRole(3);
roleSystem.setRole("6"); // -> 'guest'
Emitted event: role-changed
Payload:
{
role: "admin";
}
Listener example:
this.el.sceneEl.addEventListener("role-changed", (e) => {
console.log("Role changed to:", e.detail.role);
});
hasPermission(requiredRole: UserRole | number): boolean
Checks whether the current user has equal or higher permission than the required role.
Permission logic:
currentRoleNumber <= requiredRoleNumber
Examples:
roleSystem.hasPermission("editor"); // true for owner/admin/editor
roleSystem.hasPermission(3); // numeric equivalent
Convenience role checks
Each check returns true for the named role or any higher role.
isOwner(): boolean
true for room_owner (1) or higher.
roleSystem.isOwner();
isAdmin(): boolean
true for admin (2) or higher.
roleSystem.isAdmin();
isEditor(): boolean
true for editor (3) or higher.
roleSystem.isEditor();
isModerator(): boolean
true for moderator (4) or higher.
roleSystem.isModerator();
Role conversion rules
The system converts between role strings and numbers internally. These conversion helpers aren't exported; use getRoleNumber() and setRole() instead.
- String to number: uses the role hierarchy table. Numbers and numeric strings (such as
"2") are used as they are. Unknown strings become6(guest). - Number to string: uses the role hierarchy table (
1becomesroom_owner). Unknown numbers become'guest'and log a console warning.
Initialization behavior
- The default role is
guest. - You can set the initial role on the scene, as a string or a number:
<a-scene user-role="role: admin"></a-scene>
<a-scene user-role="role: 2"></a-scene>
- On system initialization, numeric role values are normalized to strings
- Console logs indicate role initialization and updates
Example: Permission-gated component
The role can be updated after the world has loaded (for example once the visitor's world role is known), so update the component on role-changed too:
init() {
const roleSystem = this.el.sceneEl.systems['user-role'];
const update = () => {
this.el.setAttribute('visible', roleSystem.hasPermission('admin'));
};
update();
this.el.sceneEl.addEventListener('role-changed', update);
}