diff --git a/src/channels/web/static/app.js b/src/channels/web/static/app.js
index ad148143..1438392d 100644
--- a/src/channels/web/static/app.js
+++ b/src/channels/web/static/app.js
@@ -4371,11 +4371,11 @@ function renderUsersList(users) {
var roleLabel = u.role === 'admin' ? 'admin' : 'member';
var actions = '';
if (u.status === 'active') {
- actions += ' ';
+ actions += ' ';
} else {
- actions += ' ';
+ actions += ' ';
}
- actions += '';
+ actions += '';
return '
'
+ '| ' + escapeHtml(u.id.substring(0, 8)) + '… | '
+ '' + escapeHtml(u.display_name) + ' | '
@@ -4425,10 +4425,17 @@ function showTokenBanner(tokenValue) {
});
}
-// Make functions accessible for delegated event handlers
-window.suspendUser = suspendUser;
-window.activateUser = activateUser;
-window.createTokenForUser = createTokenForUser;
+// Delegated click handler for user action buttons (CSP-safe, no inline onclick)
+document.getElementById('users-table')?.addEventListener('click', function(e) {
+ var btn = e.target.closest('[data-action]');
+ if (!btn) return;
+ var action = btn.getAttribute('data-action');
+ var userId = btn.getAttribute('data-user-id');
+ var userName = btn.getAttribute('data-user-name');
+ if (action === 'suspend-user') suspendUser(userId);
+ else if (action === 'activate-user') activateUser(userId);
+ else if (action === 'create-token') createTokenForUser(userId, userName || '');
+});
// Wire up Users tab create form
document.getElementById('users-create-btn')?.addEventListener('click', function() {