Release 2.8.1
This commit is contained in:
@@ -236,7 +236,14 @@ async function syncUserRoles(pool, userId, roleIds) {
|
||||
|
||||
await pool.query('DELETE FROM a_user_roles WHERE user_id = ?', [userId]);
|
||||
for (const roleId of uniqueRoleIds) {
|
||||
await pool.query('INSERT IGNORE INTO a_user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
await pool.query(
|
||||
`INSERT INTO a_user_roles (user_id, role_id, created_by, modified_by)
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM a_user_roles WHERE user_id = ? AND role_id = ?
|
||||
)`,
|
||||
[userId, roleId, null, null, userId, roleId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +256,14 @@ async function syncRoleUsers(pool, roleId, userIds) {
|
||||
|
||||
await pool.query('DELETE FROM a_user_roles WHERE role_id = ?', [roleId]);
|
||||
for (const userId of uniqueUserIds) {
|
||||
await pool.query('INSERT IGNORE INTO a_user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
await pool.query(
|
||||
`INSERT INTO a_user_roles (user_id, role_id, created_by, modified_by)
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM a_user_roles WHERE user_id = ? AND role_id = ?
|
||||
)`,
|
||||
[userId, roleId, null, null, userId, roleId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +282,15 @@ async function syncRolePermissions(pool, roleId, permissionKeys) {
|
||||
|
||||
await pool.query('DELETE FROM a_role_permissions WHERE role_id = ?', [roleId]);
|
||||
for (const permissionRow of permissionRows) {
|
||||
await pool.query('INSERT IGNORE INTO a_role_permissions (role_id, permission_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [roleId, Number(permissionRow.id), null, null]);
|
||||
const permissionId = Number(permissionRow.id);
|
||||
await pool.query(
|
||||
`INSERT INTO a_role_permissions (role_id, permission_id, created_by, modified_by)
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM a_role_permissions WHERE role_id = ? AND permission_id = ?
|
||||
)`,
|
||||
[roleId, permissionId, null, null, roleId, permissionId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Admin RBAC route registration and permission management.
|
||||
const { DEFAULT_ROLE } = require('#src/rbac');
|
||||
|
||||
module.exports = function registerRbacRoutes(app, deps) {
|
||||
const pool = deps.pool;
|
||||
@@ -359,7 +360,7 @@
|
||||
excludeUserId: currentUserId
|
||||
});
|
||||
const users = mapUsersForView(data.users, viewModel.selectedUserIds);
|
||||
viewModel.role.inUse = String(viewModel.role.role_key || '') === 'administrators' || Number(viewModel.role.user_count) > 0;
|
||||
viewModel.role.inUse = String(viewModel.role.role_key || '') === DEFAULT_ROLE.key || String(viewModel.role.role_key || '') === 'administrators' || Number(viewModel.role.user_count) > 0;
|
||||
|
||||
res.send(pages.renderRbacEditPage(viewModel.role, req.query.message ? String(req.query.message) : '', req.currentUser, viewModel.permissionGroups, users, buildPagination(data.totalItems, data.currentPage, 'page', { search: search, sort: sort, direction: direction }, LIST_PAGE_SIZE, 'users', 'User pages')));
|
||||
} catch (error) {
|
||||
@@ -580,8 +581,8 @@
|
||||
if (!role) {
|
||||
return res.status(404).send('Role not found.');
|
||||
}
|
||||
if (String(role.role_key || '') === 'administrators') {
|
||||
return res.redirect('/settings/roles?message=' + encodeURIComponent('The built-in Administrators role cannot be deleted.'));
|
||||
if (String(role.role_key || '') === DEFAULT_ROLE.key || String(role.role_key || '') === 'administrators') {
|
||||
return res.redirect('/settings/roles?message=' + encodeURIComponent('The built-in Super Admin role cannot be deleted.'));
|
||||
}
|
||||
if (Number(role.user_count) > 0) {
|
||||
return res.redirect('/settings/roles?message=' + encodeURIComponent('Remove all users from this role before deleting it.'));
|
||||
|
||||
@@ -124,6 +124,9 @@ function buildRbacAddViewModel(message, currentUser, formValues, permissionGroup
|
||||
}
|
||||
|
||||
function buildRbacEditViewModel(role, message, currentUser, permissionGroups, users, pagination) {
|
||||
const roleKey = String(role && role.role_key || '').trim();
|
||||
const isProtectedRole = roleKey === 'super-admin' || roleKey === 'administrators';
|
||||
const deleteDisabled = isProtectedRole || Boolean(role && role.inUse);
|
||||
return {
|
||||
title: 'Edit role',
|
||||
active: 'rbac',
|
||||
@@ -135,13 +138,16 @@ function buildRbacEditViewModel(role, message, currentUser, permissionGroups, us
|
||||
footerCancelUrl: '/settings/roles',
|
||||
cancelConfirmMessage: "You've made changes. Are you sure you want to leave this page?",
|
||||
footerDeleteUrl: '/settings/roles/' + Number(role && role.id) + '/delete',
|
||||
footerDeleteDisabled: Boolean(role && role.inUse),
|
||||
footerDeleteTitle: role && role.inUse ? 'Delete is disabled while this role is assigned to users.' : '',
|
||||
footerDeleteDisabled: deleteDisabled,
|
||||
footerDeleteConfirmMessage: 'Delete ' + String(role && role.name || 'this role') + '?',
|
||||
footerDeleteTitle: isProtectedRole
|
||||
? 'The built-in Super Admin role cannot be deleted.'
|
||||
: (role && role.inUse ? 'Delete is disabled while this role is assigned to users.' : ''),
|
||||
footerShowDelete: true,
|
||||
message: message,
|
||||
currentUser: currentUser || null,
|
||||
role: role,
|
||||
inUse: Boolean(role && role.inUse),
|
||||
role: Object.assign({}, role, { isProtected: isProtectedRole }),
|
||||
inUse: deleteDisabled,
|
||||
permissionGroups: permissionGroups || [],
|
||||
permissionSections: buildPermissionSections(permissionGroups),
|
||||
users: users || [],
|
||||
|
||||
@@ -159,12 +159,23 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
}
|
||||
|
||||
if (selectedIds.length) {
|
||||
await pool.query(
|
||||
'INSERT INTO d_announcement_screens (announcement_id, screen_id, created_by, modified_by) VALUES ? ON DUPLICATE KEY UPDATE modified_at = CURRENT_TIMESTAMP, modified_by = VALUES(modified_by)',
|
||||
[selectedIds.map(function (screenId) {
|
||||
return [announcementId, screenId, actorId || null, actorId || null];
|
||||
})]
|
||||
);
|
||||
for (const screenId of selectedIds) {
|
||||
await pool.query(
|
||||
`UPDATE d_announcement_screens
|
||||
SET modified_at = CURRENT_TIMESTAMP, modified_by = ?
|
||||
WHERE announcement_id = ? AND screen_id = ?`,
|
||||
[actorId || null, announcementId, screenId]
|
||||
);
|
||||
await pool.query(
|
||||
`INSERT INTO d_announcement_screens (announcement_id, screen_id, created_by, modified_by)
|
||||
SELECT ?, ?, ?, ?
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM d_announcement_screens
|
||||
WHERE announcement_id = ? AND screen_id = ?
|
||||
)`,
|
||||
[announcementId, screenId, actorId || null, actorId || null, announcementId, screenId]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-end flex-wrap">
|
||||
<div class="btn-group" role="group" aria-label="Role actions">
|
||||
{{{saveActionButtons formId=formId saveUrl=footerSaveUrl cancelUrl=footerCancelUrl cancelConfirmMessage=cancelConfirmMessage deleteUrl=footerDeleteUrl deleteDisabled=footerDeleteDisabled deleteTitle=footerDeleteTitle showDelete=footerShowDelete}}}
|
||||
{{{saveActionButtons formId=formId saveUrl=footerSaveUrl cancelUrl=footerCancelUrl cancelConfirmMessage=cancelConfirmMessage deleteUrl=footerDeleteUrl deleteConfirmMessage=footerDeleteConfirmMessage deleteDisabled=footerDeleteDisabled deleteTitle=footerDeleteTitle showDelete=footerShowDelete}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user