feat: bitwise RBAC engine with channel-level permission overrides
Replace string-based role checks (role === 'admin') with a bitwise BigInt permission system. Adds computePermissions() resolution engine following Discord's model: @everyone base → role union → admin shortcut → channel overrides (role deny/allow → member deny/allow). Ready payload now filters channels by VIEW_CHANNEL and attaches per-user myPermissions to each server and channel. Includes channel_overrides table, @everyone role auto-creation, migration for existing servers, and override CRUD API.
This commit is contained in:
@@ -11,6 +11,7 @@ import { Avatar } from '../ui/Avatar';
|
||||
import { wsSend } from '../../hooks/useWebSocket';
|
||||
import { getActiveRoom } from '../../hooks/useLiveKit';
|
||||
import { AudioManager } from '../../audio/AudioManager';
|
||||
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
|
||||
|
||||
export function ChannelSidebar() {
|
||||
const servers = useServerStore((s) => s.servers);
|
||||
@@ -65,9 +66,10 @@ export function ChannelSidebar() {
|
||||
}
|
||||
};
|
||||
|
||||
const serverPermissions = useServerStore((s) => s.serverPermissions);
|
||||
const server = servers.find(s => s.id === currentServerId);
|
||||
const currentMember = members.find(m => m.userId === user?.id);
|
||||
const isAdminUser = currentMember?.role === 'admin' || currentMember?.role === 'owner';
|
||||
const myServerPerms = currentServerId ? serverPermissions.get(currentServerId) : undefined;
|
||||
const canManageChannels = hasPermissionBit(myServerPerms, PermissionBits.MANAGE_CHANNELS);
|
||||
|
||||
const textChannels = channels.filter(c => c.type === 'text');
|
||||
const voiceChannels = channels.filter(c => c.type === 'voice' || c.type === 'video');
|
||||
@@ -306,7 +308,7 @@ export function ChannelSidebar() {
|
||||
</svg>
|
||||
<span className="text-[12px] font-bold uppercase tracking-wider">Text Channels</span>
|
||||
</div>
|
||||
{isAdminUser && (
|
||||
{canManageChannels && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
@@ -358,7 +360,7 @@ export function ChannelSidebar() {
|
||||
</svg>
|
||||
<span className="text-[12px] font-bold uppercase tracking-wider">Voice Channels</span>
|
||||
</div>
|
||||
{isAdminUser && (
|
||||
{canManageChannels && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
Reference in New Issue
Block a user