Fix RBAC client action visibility
Publish Docker Image / build-and-push (push) Successful in 27s

This commit is contained in:
2026-07-21 21:39:56 +01:00
parent 5eff70755b
commit cfca5bfe3b
6 changed files with 38 additions and 10 deletions
+1
View File
@@ -28,6 +28,7 @@ const PERMISSION_SECTIONS = [
{ key: 'read', name: 'Read', description: 'View the screen list and open screen details.' },
{ key: 'create', name: 'Create', description: 'Create new screens.' },
{ key: 'edit', name: 'Update', description: 'Edit screens and send screen commands.' },
{ key: 'allow', name: 'Allow', description: 'Use the connected client actions on the screen page.' },
{ key: 'delete', name: 'Delete', description: 'Delete screens.' }
]
},
+23 -3
View File
@@ -206,6 +206,28 @@
}
}
function syncClientActionCell(row, client, hasActionsColumn) {
if (!row || !row.cells) {
return;
}
if (!hasActionsColumn) {
if (row.cells.length > 6) {
row.deleteCell(row.cells.length - 1);
}
return;
}
var actionCell = row.cells.length > 6 ? row.cells[6] : null;
if (!actionCell) {
actionCell = row.insertCell(-1);
actionCell.setAttribute('data-label', 'Actions');
actionCell.className = 'text-end';
}
updateClientActionCell(actionCell, client);
}
function renderClientRow(client, hasActionsColumn) {
var connectedAt = client.connectedAt ? '<div>' + escapeHtml(client.connectedAtLabel || formatDashboardDate(client.connectedAt) || client.connectedAt) + '</div>' + (client.lastSeenAt ? '<div class="subtle">' + escapeHtml(client.lastSeenAtLabel || formatDashboardDate(client.lastSeenAt) || client.lastSeenAt) + '</div>' : '') : '<span class="empty">Unknown</span>';
var clientIpValue = normalizeDisplayIp(client.clientIp);
@@ -317,9 +339,7 @@
row.cells[3].innerHTML = clientIp;
row.cells[4].innerHTML = viewport;
row.cells[5].innerHTML = connectedAt;
if (hasActionsColumn && row.cells.length >= 7) {
updateClientActionCell(row.cells[6], client);
}
syncClientActionCell(row, client, hasActionsColumn);
}
var referenceNode = tbody.children[index] || null;
+8 -1
View File
@@ -234,7 +234,14 @@ module.exports = function registerAdminRbacRoutes(app, deps) {
return res.status(404).send('Role not found.');
}
res.send(pages.renderRbacEditPage(viewModel.role, req.query.message ? String(req.query.message) : '', req.currentUser, viewModel.permissionGroups, viewModel.users));
const currentUserId = req.currentUser ? Number(req.currentUser.id) : null;
const users = Array.isArray(viewModel.users)
? viewModel.users.filter(function (user) {
return Number(user && user.id) !== currentUserId;
})
: [];
res.send(pages.renderRbacEditPage(viewModel.role, req.query.message ? String(req.query.message) : '', req.currentUser, viewModel.permissionGroups, users));
} catch (error) {
next(error);
}
+1 -1
View File
@@ -6,7 +6,7 @@ module.exports = function registerAdminScreenCommandRoutes(app, deps) {
const withClientNameReservation = deps.withClientNameReservation;
const requirePermission = deps.requirePermission;
app.post('/admin/screens/:slug/commands', requirePermission('clients.allow'), async function (req, res, next) {
app.post('/admin/screens/:slug/commands', requirePermission('screens.allow'), async function (req, res, next) {
try {
const slug = String(req.params.slug || '').trim();
const command = String((req.body && req.body.command) || req.query.command || '').trim().toLowerCase();
+4 -4
View File
@@ -10,7 +10,7 @@
<h3 class="card-title">Active connections</h3>
</div>
<div class="card-body table-responsive p-0">
<table id="dashboard-clients-table" class="table table-striped w-100 mb-0" data-has-actions-column="{{#if (hasPermission currentUser 'clients.allow')}}true{{else}}false{{/if}}">
<table id="dashboard-clients-table" class="table table-striped w-100 mb-0" data-has-actions-column="{{#if (hasPermission currentUser 'screens.allow')}}true{{else}}false{{/if}}">
<thead>
<tr>
<th>Client</th>
@@ -19,7 +19,7 @@
<th>IP</th>
<th>Viewport</th>
<th>Connected/Updated</th>
{{#if (hasPermission currentUser 'clients.allow')}}<th>Actions</th>{{/if}}
{{#if (hasPermission currentUser 'screens.allow')}}<th>Actions</th>{{/if}}
</tr>
</thead>
<tbody id="dashboard-clients-table-body">
@@ -57,7 +57,7 @@
<span class="empty">Unknown</span>
{{/if}}
</td>
{{#if (hasPermission currentUser 'clients.allow')}}
{{#if (hasPermission currentUser 'screens.allow')}}
<td data-label="Actions" class="text-end">
<div class="actions justify-content-end">
<form method="post" action="/admin/screens/{{screen_slug}}/commands" class="inline-form" data-confirm-message="Reloading will restart the player page. Continue?" data-async-command>
@@ -95,7 +95,7 @@
</tr>
{{/each}}
{{else}}
<tr><td colspan="{{#if (hasPermission currentUser 'clients.allow')}}7{{else}}6{{/if}}" class="empty">No connected clients yet.</td></tr>
<tr><td colspan="{{#if (hasPermission currentUser 'screens.allow')}}7{{else}}6{{/if}}" class="empty">No connected clients yet.</td></tr>
{{/if}}
</tbody>
</table>
+1 -1
View File
@@ -61,7 +61,7 @@
<td>
<input class="form-check-input" type="checkbox" name="user_ids[]" value="{{id}}" {{#if isSelected}}checked{{/if}} />
</td>
<td><strong>{{name}}</strong></td>
<td>{{name}}</td>
<td class="text-body-secondary">{{username}}</td>
<td class="text-body-secondary">{{#if roleNames}}{{roleNames}}{{else}}No roles assigned{{/if}}</td>
</tr>