roles++
This commit is contained in:
parent
5494f1e4ee
commit
c08cfebf52
@ -16,7 +16,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$server_id = $channel['server_id'] ?? 0;
|
||||
|
||||
// Ensure @everyone role exists for this server
|
||||
$stmt = db()->prepare("SELECT id FROM roles WHERE server_id = ? AND (name = '@everyone' OR name = 'Everyone') LIMIT 1");
|
||||
$stmt = db()->prepare("SELECT id FROM roles WHERE server_id = ? AND (LOWER(name) = '@everyone' OR LOWER(name) = 'everyone') LIMIT 1");
|
||||
$stmt->execute([$server_id]);
|
||||
$everyone = $stmt->fetch();
|
||||
if (!$everyone && $server_id) {
|
||||
@ -46,18 +46,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_everyone && $everyone_role_id) {
|
||||
if (!$has_everyone && $everyone_role_id > 0) {
|
||||
$stmt = db()->prepare("SELECT name, color FROM roles WHERE id = ?");
|
||||
$stmt->execute([$everyone_role_id]);
|
||||
$r = $stmt->fetch();
|
||||
$permissions[] = [
|
||||
'channel_id' => (int)$channel_id,
|
||||
'role_id' => (int)$everyone_role_id,
|
||||
'allow_permissions' => 0,
|
||||
'deny_permissions' => 0,
|
||||
'role_name' => $r['name'],
|
||||
'role_color' => $r['color']
|
||||
];
|
||||
if ($r) {
|
||||
array_unshift($permissions, [
|
||||
'channel_id' => (int)$channel_id,
|
||||
'role_id' => (int)$everyone_role_id,
|
||||
'allow_permissions' => 0,
|
||||
'deny_permissions' => 0,
|
||||
'role_name' => $r['name'],
|
||||
'role_color' => $r['color']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'permissions' => $permissions]);
|
||||
@ -70,12 +72,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$allow = $data['allow'] ?? 0;
|
||||
$deny = $data['deny'] ?? 0;
|
||||
|
||||
// Check if user is owner of the server
|
||||
$stmt = db()->prepare("SELECT s.owner_id FROM servers s JOIN channels c ON s.id = c.server_id WHERE c.id = ?");
|
||||
// Check permissions: Owner or MANAGE_CHANNELS or ADMINISTRATOR
|
||||
require_once 'includes/permissions.php';
|
||||
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
|
||||
$stmt->execute([$channel_id]);
|
||||
$ch = $stmt->fetch();
|
||||
$server_id = $ch['server_id'] ?? 0;
|
||||
|
||||
$stmt = db()->prepare("SELECT owner_id FROM servers WHERE id = ?");
|
||||
$stmt->execute([$server_id]);
|
||||
$server = $stmt->fetch();
|
||||
|
||||
if ($server && $server['owner_id'] == $user_id) {
|
||||
$is_owner = ($server && $server['owner_id'] == $user_id);
|
||||
$can_manage = Permissions::hasPermission($user_id, $server_id, Permissions::MANAGE_CHANNELS) ||
|
||||
Permissions::hasPermission($user_id, $server_id, Permissions::ADMINISTRATOR);
|
||||
|
||||
if ($is_owner || $can_manage) {
|
||||
$stmt = db()->prepare("
|
||||
INSERT INTO channel_permissions (channel_id, role_id, allow_permissions, deny_permissions)
|
||||
VALUES (?, ?, ?, ?)
|
||||
@ -93,12 +105,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
|
||||
$channel_id = $data['channel_id'] ?? 0;
|
||||
$role_id = $data['role_id'] ?? 0;
|
||||
|
||||
// Check if user is owner
|
||||
$stmt = db()->prepare("SELECT s.owner_id FROM servers s JOIN channels c ON s.id = c.server_id WHERE c.id = ?");
|
||||
// Check permissions
|
||||
require_once 'includes/permissions.php';
|
||||
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
|
||||
$stmt->execute([$channel_id]);
|
||||
$ch = $stmt->fetch();
|
||||
$server_id = $ch['server_id'] ?? 0;
|
||||
|
||||
$stmt = db()->prepare("SELECT owner_id FROM servers WHERE id = ?");
|
||||
$stmt->execute([$server_id]);
|
||||
$server = $stmt->fetch();
|
||||
|
||||
if ($server && $server['owner_id'] == $user_id) {
|
||||
$is_owner = ($server && $server['owner_id'] == $user_id);
|
||||
$can_manage = Permissions::hasPermission($user_id, $server_id, Permissions::MANAGE_CHANNELS) ||
|
||||
Permissions::hasPermission($user_id, $server_id, Permissions::ADMINISTRATOR);
|
||||
|
||||
if ($is_owner || $can_manage) {
|
||||
$stmt = db()->prepare("DELETE FROM channel_permissions WHERE channel_id = ? AND role_id = ?");
|
||||
$stmt->execute([$channel_id, $role_id]);
|
||||
echo json_encode(['success' => true]);
|
||||
|
||||
@ -759,8 +759,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
channelPermissionsTabBtn?.addEventListener('click', async () => {
|
||||
const channelId = document.getElementById('edit-channel-id').value;
|
||||
currentSelectedOverrideRole = null;
|
||||
channelPermissionsSettings.style.display = 'none';
|
||||
noRoleSelectedView.style.display = 'flex';
|
||||
channelPermissionsSettings.classList.add('d-none');
|
||||
noRoleSelectedView.classList.remove('d-none');
|
||||
await loadChannelPermissions(channelId);
|
||||
await loadRolesForPermissions(channelId);
|
||||
});
|
||||
@ -776,37 +776,68 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
async function loadRolesForPermissions(channelId) {
|
||||
addPermRoleList.innerHTML = '';
|
||||
const resp = await fetch(`api_v1_roles.php?server_id=${activeServerId}`);
|
||||
const data = await resp.json();
|
||||
if (data.success) {
|
||||
// Filter out roles already in overrides
|
||||
const existingRoleIds = channelPermissionsData.map(p => parseInt(p.role_id));
|
||||
const availableRoles = data.roles.filter(role => !existingRoleIds.includes(parseInt(role.id)));
|
||||
if (!addPermRoleList) return;
|
||||
addPermRoleList.innerHTML = '<li><span class="dropdown-item text-muted">Loading roles...</span></li>';
|
||||
|
||||
try {
|
||||
const resp = await fetch(`api_v1_roles.php?server_id=${activeServerId}`);
|
||||
const data = await resp.json();
|
||||
|
||||
if (data.success) {
|
||||
addPermRoleList.innerHTML = '';
|
||||
|
||||
// Filter out roles already in overrides
|
||||
const existingRoleIds = channelPermissionsData.map(p => parseInt(p.role_id));
|
||||
const availableRoles = data.roles.filter(role => !existingRoleIds.includes(parseInt(role.id)));
|
||||
|
||||
if (availableRoles.length === 0) {
|
||||
addPermRoleList.innerHTML = '<li><span class="dropdown-item disabled text-muted">No more roles to add</span></li>';
|
||||
if (window.canManageServer) {
|
||||
const divider = document.createElement('li');
|
||||
divider.innerHTML = '<hr class="dropdown-divider border-secondary opacity-25">';
|
||||
addPermRoleList.appendChild(divider);
|
||||
const createLink = document.createElement('li');
|
||||
createLink.innerHTML = '<a class="dropdown-item small text-info" href="#" data-bs-toggle="modal" data-bs-target="#serverSettingsModal" style="font-size: 0.8em;"><i class="fa-solid fa-gear me-1"></i> Create roles in Server Settings</a>';
|
||||
addPermRoleList.appendChild(createLink);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (availableRoles.length === 0) {
|
||||
addPermRoleList.innerHTML = '<li><span class="dropdown-item disabled">No more roles to add</span></li>';
|
||||
return;
|
||||
// Add Roles section
|
||||
const header = document.createElement('li');
|
||||
header.innerHTML = '<h6 class="dropdown-header text-uppercase" style="font-size: 0.65em; color: #949ba4;">Roles</h6>';
|
||||
addPermRoleList.appendChild(header);
|
||||
|
||||
availableRoles.forEach(role => {
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `<a class="dropdown-item d-flex align-items-center gap-2 py-2" href="#">
|
||||
<div style="width: 12px; height: 12px; border-radius: 50%; background-color: ${role.color || '#99aab5'}; border: 1px solid rgba(255,255,255,0.1);"></div>
|
||||
<span style="color: #dbdee1; font-size: 0.9em;">${role.name}</span>
|
||||
</a>`;
|
||||
li.onclick = async (e) => {
|
||||
e.preventDefault();
|
||||
const postResp = await fetch('api_v1_channel_permissions.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ channel_id: channelId, role_id: role.id, allow: 0, deny: 0 })
|
||||
});
|
||||
const postData = await postResp.json();
|
||||
if (postData.success) {
|
||||
await loadChannelPermissions(channelId);
|
||||
await loadRolesForPermissions(channelId);
|
||||
selectOverrideRole(role.id, role.name);
|
||||
} else {
|
||||
alert("Error adding permission: " + (postData.error || "Unknown error"));
|
||||
}
|
||||
};
|
||||
addPermRoleList.appendChild(li);
|
||||
});
|
||||
} else {
|
||||
addPermRoleList.innerHTML = `<li><span class="dropdown-item text-danger">Error: ${data.error || 'Failed to load'}</span></li>`;
|
||||
}
|
||||
|
||||
availableRoles.forEach(role => {
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `<a class="dropdown-item d-flex align-items-center gap-2" href="#">
|
||||
<div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${role.color};"></div>
|
||||
${role.name}
|
||||
</a>`;
|
||||
li.onclick = async (e) => {
|
||||
e.preventDefault();
|
||||
await fetch('api_v1_channel_permissions.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ channel_id: channelId, role_id: role.id, allow: 0, deny: 0 })
|
||||
});
|
||||
await loadChannelPermissions(channelId);
|
||||
selectOverrideRole(role.id, role.name);
|
||||
};
|
||||
addPermRoleList.appendChild(li);
|
||||
});
|
||||
} catch (err) {
|
||||
addPermRoleList.innerHTML = '<li><span class="dropdown-item text-danger">Network error</span></li>';
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,11 +850,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// Sort: @everyone always at top, then by name
|
||||
const sortedData = [...channelPermissionsData].sort((a, b) => {
|
||||
const isAEveryone = a.role_name.toLowerCase().includes('everyone');
|
||||
const isBEveryone = b.role_name.toLowerCase().includes('everyone');
|
||||
const nameA = (a.role_name || '').toLowerCase();
|
||||
const nameB = (b.role_name || '').toLowerCase();
|
||||
const isAEveryone = nameA.includes('everyone');
|
||||
const isBEveryone = nameB.includes('everyone');
|
||||
if (isAEveryone && !isBEveryone) return -1;
|
||||
if (!isAEveryone && isBEveryone) return 1;
|
||||
return a.role_name.localeCompare(b.role_name);
|
||||
return nameA.localeCompare(nameB);
|
||||
});
|
||||
|
||||
sortedData.forEach(p => {
|
||||
@ -831,10 +864,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
item.className = `list-group-item list-group-item-action bg-transparent text-white border-0 mb-1 p-2 small d-flex align-items-center ${currentSelectedOverrideRole == p.role_id ? 'active' : ''}`;
|
||||
item.style.cursor = 'pointer';
|
||||
item.innerHTML = `
|
||||
<div style="width: 8px; height: 8px; border-radius: 50%; background-color: ${p.role_color}; margin-right: 8px; flex-shrink: 0;"></div>
|
||||
<span class="flex-grow-1 text-truncate">${p.role_name}</span>
|
||||
<div style="width: 8px; height: 8px; border-radius: 50%; background-color: ${p.role_color || '#99aab5'}; margin-right: 8px; flex-shrink: 0;"></div>
|
||||
<span class="flex-grow-1 text-truncate">${p.role_name || 'Unknown Role'}</span>
|
||||
`;
|
||||
item.onclick = () => selectOverrideRole(p.role_id, p.role_name);
|
||||
item.onclick = () => selectOverrideRole(p.role_id, p.role_name || 'Unknown Role');
|
||||
channelPermissionsRolesList.appendChild(item);
|
||||
});
|
||||
}
|
||||
@ -847,8 +880,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
renderRoleOverridesList(channelId);
|
||||
|
||||
selectedPermRoleName.textContent = roleName;
|
||||
noRoleSelectedView.style.display = 'none';
|
||||
channelPermissionsSettings.style.display = 'block';
|
||||
noRoleSelectedView.classList.add('d-none');
|
||||
channelPermissionsSettings.classList.remove('d-none');
|
||||
|
||||
// Load existing permissions for this role
|
||||
const p = channelPermissionsData.find(perm => perm.role_id == roleId) || { allow_permissions: 0, deny_permissions: 0 };
|
||||
@ -881,8 +914,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
|
||||
currentSelectedOverrideRole = null;
|
||||
channelPermissionsSettings.style.display = 'none';
|
||||
noRoleSelectedView.style.display = 'flex';
|
||||
channelPermissionsSettings.classList.add('d-none');
|
||||
noRoleSelectedView.classList.remove('d-none');
|
||||
loadChannelPermissions(channelId);
|
||||
});
|
||||
|
||||
@ -951,6 +984,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
modal.querySelector('#edit-channel-name').value = channelName;
|
||||
modal.querySelector('#header-channel-name').textContent = channelName;
|
||||
modal.querySelector('#edit-channel-type').value = channelType;
|
||||
|
||||
// Force switch to Overview tab
|
||||
const overviewTabBtn = modal.querySelector('[data-bs-target="#edit-channel-general"]');
|
||||
if (overviewTabBtn) {
|
||||
bootstrap.Tab.getOrCreateInstance(overviewTabBtn).show();
|
||||
}
|
||||
|
||||
modal.querySelector('#edit-channel-files').checked = btn.dataset.files == '1';
|
||||
modal.querySelector('#edit-channel-limit').value = btn.dataset.limit || '';
|
||||
modal.querySelector('#edit-channel-status').value = btn.dataset.status || '';
|
||||
|
||||
BIN
assets/pasted-20260215-214239-79c3300e.png
Normal file
BIN
assets/pasted-20260215-214239-79c3300e.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
23
index.php
23
index.php
@ -1270,14 +1270,13 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
<div class="p-3 border-bottom border-secondary d-flex justify-content-between align-items-center">
|
||||
<span class="small fw-bold text-uppercase" style="font-size: 0.7em; color: #dbdee1;">Roles / Members</span>
|
||||
<div class="dropdown">
|
||||
|
||||
<button class="btn btn-sm btn-link text-white p-0" type="button" data-bs-toggle="dropdown" style="text-decoration: none;">
|
||||
<i class="fa-solid fa-plus-circle"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-dark shadow" id="add-permission-role-list" style="max-height: 300px; overflow-y: auto;">
|
||||
<!-- Roles loaded here -->
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-link text-white p-0" type="button" data-bs-toggle="dropdown" title="Add Role or Member" style="text-decoration: none; opacity: 0.8;">
|
||||
<i class="fa-solid fa-plus-circle" style="font-size: 1.1rem;"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-dark shadow border-secondary" id="add-permission-role-list" style="max-height: 300px; overflow-y: auto; min-width: 200px;">
|
||||
<!-- Roles loaded here -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="channel-permissions-roles-list" class="list-group list-group-flush overflow-auto flex-grow-1" style="max-height: 350px; overflow-x: hidden;">
|
||||
<!-- List of roles with overrides -->
|
||||
@ -1286,7 +1285,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
|
||||
<!-- Main: Permission Settings -->
|
||||
<div class="col-8 d-flex flex-column" style="background-color: #313338;">
|
||||
<div id="channel-permissions-settings" style="display: none;" class="h-100 d-flex flex-column">
|
||||
<div id="channel-permissions-settings" class="h-100 d-flex flex-column d-none">
|
||||
<div class="p-3 border-bottom border-secondary d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0 fw-bold" id="selected-perm-role-name">Role Name</h6>
|
||||
<button class="btn btn-sm btn-outline-danger py-0 px-2" id="remove-selected-perm-role" style="font-size: 0.75em;">Clear Overrides</button>
|
||||
@ -1580,6 +1579,12 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
if (iconSelect) iconSelect.value = btn.dataset.icon || '';
|
||||
if (categorySelect) categorySelect.value = btn.dataset.category || '';
|
||||
|
||||
// Force switch to Overview tab
|
||||
const overviewTabBtn = modal.querySelector('[data-bs-target="#edit-channel-general"]');
|
||||
if (overviewTabBtn && typeof bootstrap !== 'undefined') {
|
||||
bootstrap.Tab.getOrCreateInstance(overviewTabBtn).show();
|
||||
}
|
||||
|
||||
// Also fill delete ID
|
||||
const deleteIdInput = document.getElementById('delete-channel-id');
|
||||
if (deleteIdInput) deleteIdInput.value = btn.dataset.id || '';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user