Skip to main content

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 stringNumeric valueDescription
room_owner1World owner, highest world permission
admin2Administrative privileges
editor3Content editing privileges
moderator4Reserved, not assigned by the platform
user5Standard user
guest6Lowest 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.

Which checks to use

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 become 6 (guest).
  • Number to string: uses the role hierarchy table (1 becomes room_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);
}