- Added AJAX functionality to fetch role permissions for copying. - Introduced system role management with permission checks for updates. - Implemented role deletion with confirmation modal and backend handling. - Enhanced user role assignment migration scripts to transition from legacy profiles to RBAC. - Created SQL migration scripts for user roles and permissions mapping. - Updated user interface to support new role management features including copy permissions and system role indicators.
539 lines
24 KiB
PHP
539 lines
24 KiB
PHP
<?php
|
|
defined(page_security_key) or exit;
|
|
|
|
if (debug && debug_id == $_SESSION['authorization']['id']){
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
}
|
|
|
|
include_once './assets/functions.php';
|
|
include_once './settings/settings_redirector.php';
|
|
|
|
//SET ORIGIN FOR NAVIGATION
|
|
$_SESSION['prev_origin_user_role'] = $_SERVER['REQUEST_URI'];
|
|
$page = 'user_role';
|
|
//Check if allowed
|
|
if (isAllowed($page,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'R') === 0){
|
|
header('location: index.php');
|
|
exit;
|
|
}
|
|
//PAGE Security
|
|
$page_manage = 'user_role_manage';
|
|
$update_allowed = isAllowed($page ,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'U');
|
|
$update_allowed_edit = isAllowed($page_manage ,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'U');
|
|
$delete_allowed = isAllowed($page_manage ,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'D');
|
|
$create_allowed = isAllowed($page_manage ,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'C');
|
|
$system_role_allowed = isAllowed('user_roles' ,$_SESSION['authorization']['permissions'],$_SESSION['authorization']['permission'],'D');
|
|
|
|
//Handle AJAX request for role permissions (copy functionality)
|
|
if (isset($_GET['action']) && $_GET['action'] === 'get_role_permissions' && isset($_GET['source_role_id'])) {
|
|
header('Content-Type: application/json');
|
|
$source_role_id = intval($_GET['source_role_id']);
|
|
$api_url = '/v2/role_access_permissions/role_id='.$source_role_id;
|
|
$role_perms = ioServer($api_url,'');
|
|
echo $role_perms;
|
|
exit;
|
|
}
|
|
|
|
//GET Details from URL
|
|
$GET_VALUES = urlGETdetails($_GET) ?? '';
|
|
|
|
//CALL TO API FOR General information
|
|
$api_url = '/v2/user_roles/'.$GET_VALUES;
|
|
$responses = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;}
|
|
$responses = $responses[0];
|
|
|
|
$role_id = $responses->rowID;
|
|
|
|
//CALL TO API FOR Role Permissions
|
|
$api_url = '/v2/role_access_permissions/role_id='.$role_id;
|
|
$permissions = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($permissions)){$permissions = json_decode($permissions);}else{$permissions = null;}
|
|
|
|
//CALL TO API FOR All Access Elements (no paging)
|
|
$api_url = '/v2/access_elements/all=';
|
|
$all_access_elements = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($all_access_elements)){$all_access_elements = json_decode($all_access_elements);}else{$all_access_elements = null;}
|
|
|
|
// Create lookup array for existing permissions
|
|
$permission_lookup = [];
|
|
if (!empty($permissions)){
|
|
foreach ($permissions as $perm){
|
|
$permission_lookup[$perm->access_id] = $perm;
|
|
}
|
|
}
|
|
|
|
//CALL TO API FOR User Role Assignments
|
|
$api_url = '/v2/user_role_assignments/role_id='.$role_id;
|
|
$assignments = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($assignments)){$assignments = json_decode($assignments);}else{$assignments = null;}
|
|
|
|
//CALL TO API FOR All User Roles (for copy dropdown)
|
|
$api_url = '/v2/user_roles/status=1&all=';
|
|
$all_roles = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($all_roles)){$all_roles = json_decode($all_roles);}else{$all_roles = null;}
|
|
|
|
//------------------------------
|
|
// Handle POST for inline edit
|
|
//------------------------------
|
|
if (isset($_POST['save_permissions']) && $update_allowed_edit === 1) {
|
|
// Update role info (name, description, status, system role)
|
|
$role_data_array = [
|
|
'rowID' => $role_id,
|
|
'name' => $_POST['name'] ?? '',
|
|
'description' => $_POST['description'] ?? '',
|
|
'is_active' => $_POST['is_active'] ?? 1
|
|
];
|
|
// Only allow is_system to be changed if user has delete permission on user_roles
|
|
if ($system_role_allowed === 1) {
|
|
$role_data_array['is_system'] = isset($_POST['is_system']) ? 1 : 0;
|
|
}
|
|
$role_data = json_encode($role_data_array, JSON_UNESCAPED_UNICODE);
|
|
ioServer('/v2/user_roles', $role_data);
|
|
|
|
// Process permission updates
|
|
$posted_permissions = $_POST['permissions'] ?? [];
|
|
|
|
// For each access element, update or create permission
|
|
foreach ($all_access_elements as $element) {
|
|
$access_id = $element->rowID;
|
|
$has_permission = isset($posted_permissions[$access_id]);
|
|
$existing_permission = $permission_lookup[$access_id] ?? null;
|
|
|
|
if ($has_permission) {
|
|
// Get CRUD values
|
|
$can_create = isset($posted_permissions[$access_id]['C']) ? 1 : 0;
|
|
$can_read = isset($posted_permissions[$access_id]['R']) ? 1 : 0;
|
|
$can_update = isset($posted_permissions[$access_id]['U']) ? 1 : 0;
|
|
$can_delete = isset($posted_permissions[$access_id]['D']) ? 1 : 0;
|
|
|
|
if ($existing_permission) {
|
|
// Update existing permission
|
|
$data = json_encode([
|
|
'rowID' => $existing_permission->rowID,
|
|
'role_id' => $role_id,
|
|
'access_id' => $access_id,
|
|
'can_create' => $can_create,
|
|
'can_read' => $can_read,
|
|
'can_update' => $can_update,
|
|
'can_delete' => $can_delete
|
|
], JSON_UNESCAPED_UNICODE);
|
|
} else {
|
|
// Insert new permission
|
|
$data = json_encode([
|
|
'role_id' => $role_id,
|
|
'access_id' => $access_id,
|
|
'can_create' => $can_create,
|
|
'can_read' => $can_read,
|
|
'can_update' => $can_update,
|
|
'can_delete' => $can_delete
|
|
], JSON_UNESCAPED_UNICODE);
|
|
}
|
|
ioServer('/v2/role_access_permissions', $data);
|
|
} else {
|
|
// If no permission checkboxes selected but had existing permission, delete it
|
|
if ($existing_permission) {
|
|
$data = json_encode([
|
|
'rowID' => $existing_permission->rowID,
|
|
'delete' => 'delete'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
ioServer('/v2/role_access_permissions', $data);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Redirect to refresh
|
|
header('Location: index.php?page=user_role&rowID='.$role_id.'&success_msg=2');
|
|
exit;
|
|
}
|
|
|
|
//------------------------------
|
|
// Handle POST for delete
|
|
//------------------------------
|
|
if (isset($_POST['delete_role']) && $delete_allowed === 1) {
|
|
$role_data = json_encode([
|
|
'rowID' => $role_id,
|
|
'delete' => 'delete'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
ioServer('/v2/user_roles', $role_data);
|
|
|
|
// Redirect to roles list with success message
|
|
header('Location: index.php?page='.$_SESSION['origin'].'&success_msg=3');
|
|
exit;
|
|
}
|
|
|
|
|
|
//------------------------------
|
|
//Variables
|
|
//------------------------------
|
|
$status_text = ($responses->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive');
|
|
$status_class = ($responses->is_active == 1) ? 'id1' : 'id0';
|
|
|
|
// Handle success messages
|
|
if (isset($_GET['success_msg'])) {
|
|
if ($_GET['success_msg'] == 1) {
|
|
$success_msg = ($message_role_1 ?? 'Role created successfully');
|
|
}
|
|
if ($_GET['success_msg'] == 2) {
|
|
$success_msg = ($message_role_2 ?? 'Role updated successfully');
|
|
}
|
|
if ($_GET['success_msg'] == 3) {
|
|
$success_msg = ($message_role_3 ?? 'Role deleted successfully');
|
|
}
|
|
}
|
|
|
|
template_header(($user_role_title ?? 'User Role'), 'user_role', 'view');
|
|
$view = '
|
|
<div class="content-title responsive-flex-wrap responsive-pad-bot-3">
|
|
<h2 class="responsive-width-100">'.($view_role_h2 ?? 'User Role').' - '.$responses->name.'</h2>
|
|
<a href="index.php?page='.$_SESSION['origin'].'&p='.$_SESSION['p'].$_SESSION['status'].$_SESSION['sort'].$_SESSION['search'].'" class="btn alt mar-right-2">←</a>
|
|
';
|
|
|
|
if ($update_allowed_edit === 1){
|
|
$view .= '<a href="javascript:void(0);" id="editBtn" class="btn mar-right-2" onclick="togglePermissionsEdit()">✏️</a>';
|
|
$view .= '<button type="submit" form="permissionsForm" id="saveBtn" class="btn mar-right-2" style="display:none;">💾</button>';
|
|
}
|
|
|
|
if ($delete_allowed === 1){
|
|
$view .= '<a href="javascript:void(0);" id="deleteBtn" class="btn alt" onclick="confirmDeleteRole()">🗑️</a>';
|
|
}
|
|
|
|
$view .= '</div>';
|
|
|
|
if (isset($success_msg)){
|
|
$view .= ' <div class="msg success">
|
|
<i class="fas fa-check-circle"></i>
|
|
<p>'.$success_msg.'</p>
|
|
<i class="fas fa-times"></i>
|
|
</div>';
|
|
}
|
|
|
|
// Delete form (hidden)
|
|
if ($delete_allowed === 1){
|
|
$view .= '<form id="deleteRoleForm" action="" method="post" style="display:none;">
|
|
<input type="hidden" name="delete_role" value="1">
|
|
<input type="hidden" name="rowID" value="'.$role_id.'">
|
|
</form>';
|
|
|
|
// Delete confirmation modal
|
|
$view .= '<div id="deleteModal" class="modal" style="display:none;">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3><i class="fa-solid fa-triangle-exclamation" style="color:#e74c3c;"></i> '.($confirm_delete_title ?? 'Confirm Delete').'</h3>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>'.($confirm_delete_role ?? 'Are you sure you want to delete this role?').'</p>
|
|
<p><strong>'.$responses->name.'</strong></p>
|
|
<p class="warning-text" style="color:#e74c3c; margin-top:10px;">'.($delete_role_warning ?? 'This will also remove all permissions and user assignments associated with this role.').'</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn alt" onclick="closeDeleteModal()">'.($cancel ?? 'Cancel').'</button>
|
|
<button type="button" class="btn danger" onclick="executeDeleteRole()">'.($delete ?? 'Delete').'</button>
|
|
</div>
|
|
</div>
|
|
</div>';
|
|
}
|
|
|
|
// Start form wrapper for edit mode
|
|
$view .= '<form id="permissionsForm" action="" method="post">
|
|
<input type="hidden" name="save_permissions" value="1">
|
|
<input type="hidden" name="rowID" value="'.$role_id.'">';
|
|
|
|
$view .= '<div class="content-block-wrapper">';
|
|
|
|
// Role Information Block
|
|
$view .= ' <div class="content-block order-details">
|
|
<div class="block-header">
|
|
<i class="fa-solid fa-circle-info"></i>'.($view_role_information ?? 'Role Information').'
|
|
</div>
|
|
<div class="order-detail">
|
|
<h3>'.($general_status ?? 'Status').'</h3>
|
|
<p>
|
|
<span class="view-mode status '.$status_class.'">'.$status_text.'</span>
|
|
<select class="edit-mode" name="is_active" style="display:none;">
|
|
<option value="1"'.($responses->is_active == 1 ? ' selected' : '').'>'.($enabled ?? 'Active').'</option>
|
|
<option value="0"'.($responses->is_active == 0 ? ' selected' : '').'>'.($disabled ?? 'Inactive').'</option>
|
|
</select>
|
|
</p>
|
|
</div>
|
|
<div class="order-detail">
|
|
<h3>'.($role_name ?? 'Role Name').'</h3>
|
|
<p>
|
|
<span class="view-mode">'.$responses->name.'</span>
|
|
<input type="text" class="edit-mode" name="name" value="'.$responses->name.'" style="display:none;" required>
|
|
</p>
|
|
</div>
|
|
<div class="order-detail">
|
|
<h3>'.($role_description ?? 'Description').'</h3>
|
|
<p>
|
|
<span class="view-mode">'.($responses->description ?? '-').'</span>
|
|
<textarea class="edit-mode" name="description" style="display:none;">'.($responses->description ?? '').'</textarea>
|
|
</p>
|
|
</div>
|
|
<div class="order-detail">
|
|
<h3>'.($role_system ?? 'System Role').'</h3>
|
|
<p>
|
|
<span class="'.($system_role_allowed === 1 ? 'view-mode' : '').'">'.($responses->is_system == 1 ? '<i class="fa-solid fa-check" style="color:green;"></i> '.($yes ?? 'Yes') : '<i class="fa-solid fa-times" style="color:red;"></i> '.($no ?? 'No')).'</span>
|
|
'.($system_role_allowed === 1 ? '<label class="edit-mode" style="display:none;">
|
|
<input type="checkbox" name="is_system" value="1"'.($responses->is_system == 1 ? ' checked' : '').'> '.($role_system_label ?? 'Mark as system role').'
|
|
</label>' : '').'
|
|
</p>
|
|
</div>
|
|
<div class="order-detail edit-mode-block" style="display:none;">
|
|
<h3>'.($copy_from_role ?? 'Copy Permissions From').'</h3>
|
|
<p>
|
|
<select id="copyFromRole" onchange="copyPermissionsFromRole(this.value)" style="width:100%; max-width:300px;">
|
|
<option value="">'.($select_role ?? '-- Select Role --').'</option>';
|
|
if (!empty($all_roles)){
|
|
foreach ($all_roles as $r){
|
|
if ($r->rowID != $role_id){
|
|
$view .= '<option value="'.$r->rowID.'">'.$r->name.'</option>';
|
|
}
|
|
}
|
|
}
|
|
$view .= ' </select>
|
|
<small style="display:block; margin-top:5px; color:#666;">'.($copy_permissions_hint ?? 'Selecting a role will override current permissions').'</small>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
// Role Assignments Block
|
|
$view .='<div class="content-block order-details">
|
|
<div class="block-header">
|
|
<i class="fa-solid fa-users fa-sm"></i>'.($view_role_assignments ?? 'Assigned Users').'
|
|
</div>';
|
|
|
|
if (!empty($assignments)){
|
|
foreach ($assignments as $assignment){
|
|
$assignment_status = ($assignment->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive');
|
|
$view .= '<div class="order-detail">
|
|
<h3>'.$assignment->username.'</h3>
|
|
<p>'.$assignment_status.((!empty($assignment->expires_at))? ' - '.($expires ?? 'Expires').': '.$assignment->expires_at : '').'</p>
|
|
</div>';
|
|
}
|
|
} else {
|
|
$view .= '<div class="order-detail">
|
|
<h3>-</h3>
|
|
<p>'.($no_users_assigned ?? 'No users assigned to this role').'</p>
|
|
</div>';
|
|
}
|
|
|
|
$view .= '</div>';
|
|
|
|
$view .= '</div>'; // Close content-block-wrapper
|
|
|
|
// Permissions Table Block
|
|
$view .= '<div class="content-block">
|
|
<div class="block-header">
|
|
<i class="fa-solid fa-key fa-sm"></i>'.($view_role_permissions ?? 'Role Permissions').'
|
|
</div>
|
|
<div class="table">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>'.($access_element_name ?? 'Access Element').'</th>
|
|
<th class="responsive-hidden">'.($access_element_path ?? 'Path').'</th>
|
|
<th class="responsive-hidden">'.($access_element_group ?? 'Group').'</th>
|
|
<th><span class="view-mode">'.($permission_create ?? 'C').'</span><a href="javascript:void(0);" class="edit-mode" style="display:none;" onclick="toggleColumn(\'C\')">'.($permission_create ?? 'C').'</a></th>
|
|
<th><span class="view-mode">'.($permission_read ?? 'R').'</span><a href="javascript:void(0);" class="edit-mode" style="display:none;" onclick="toggleColumn(\'R\')">'.($permission_read ?? 'R').'</a></th>
|
|
<th><span class="view-mode">'.($permission_update ?? 'U').'</span><a href="javascript:void(0);" class="edit-mode" style="display:none;" onclick="toggleColumn(\'U\')">'.($permission_update ?? 'U').'</a></th>
|
|
<th><span class="view-mode">'.($permission_delete ?? 'D').'</span><a href="javascript:void(0);" class="edit-mode" style="display:none;" onclick="toggleColumn(\'D\')">'.($permission_delete ?? 'D').'</a></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
|
|
if (!empty($all_access_elements)){
|
|
foreach ($all_access_elements as $element){
|
|
$access_id = $element->rowID;
|
|
$existing_perm = $permission_lookup[$access_id] ?? null;
|
|
|
|
// Determine current permission values
|
|
$has_create = ($existing_perm && $existing_perm->can_create == 1);
|
|
$has_read = ($existing_perm && $existing_perm->can_read == 1);
|
|
$has_update = ($existing_perm && $existing_perm->can_update == 1);
|
|
$has_delete = ($existing_perm && $existing_perm->can_delete == 1);
|
|
$has_any_permission = ($has_create || $has_read || $has_update || $has_delete);
|
|
|
|
// Row class - hide unassigned rows in view mode
|
|
$row_class = $has_any_permission ? '' : ' class="edit-only-row" style="display:none;"';
|
|
|
|
// View mode icons
|
|
$icon_create = $has_create ? '<i class="fa-solid fa-check" style="color:green;"></i>' : '<i class="fa-solid fa-times" style="color:red;"></i>';
|
|
$icon_read = $has_read ? '<i class="fa-solid fa-check" style="color:green;"></i>' : '<i class="fa-solid fa-times" style="color:red;"></i>';
|
|
$icon_update = $has_update ? '<i class="fa-solid fa-check" style="color:green;"></i>' : '<i class="fa-solid fa-times" style="color:red;"></i>';
|
|
$icon_delete = $has_delete ? '<i class="fa-solid fa-check" style="color:green;"></i>' : '<i class="fa-solid fa-times" style="color:red;"></i>';
|
|
|
|
// Edit mode checkboxes
|
|
$cb_create_checked = $has_create ? ' checked' : '';
|
|
$cb_read_checked = $has_read ? ' checked' : '';
|
|
$cb_update_checked = $has_update ? ' checked' : '';
|
|
$cb_delete_checked = $has_delete ? ' checked' : '';
|
|
|
|
$view .= '<tr'.$row_class.'>
|
|
<td>'.$element->access_name.'</td>
|
|
<td class="responsive-hidden">'.$element->access_path.'</td>
|
|
<td class="responsive-hidden">'.($element->access_group ?? '-').'</td>
|
|
<td>
|
|
<span class="view-mode">'.$icon_create.'</span>
|
|
<input type="checkbox" class="edit-mode" name="permissions['.$access_id.'][C]" value="1"'.$cb_create_checked.' style="display:none;">
|
|
</td>
|
|
<td>
|
|
<span class="view-mode">'.$icon_read.'</span>
|
|
<input type="checkbox" class="edit-mode" name="permissions['.$access_id.'][R]" value="1"'.$cb_read_checked.' style="display:none;">
|
|
</td>
|
|
<td>
|
|
<span class="view-mode">'.$icon_update.'</span>
|
|
<input type="checkbox" class="edit-mode" name="permissions['.$access_id.'][U]" value="1"'.$cb_update_checked.' style="display:none;">
|
|
</td>
|
|
<td>
|
|
<span class="view-mode">'.$icon_delete.'</span>
|
|
<input type="checkbox" class="edit-mode" name="permissions['.$access_id.'][D]" value="1"'.$cb_delete_checked.' style="display:none;">
|
|
</td>
|
|
</tr>';
|
|
}
|
|
} else {
|
|
$view .= '<tr>
|
|
<td colspan="7" style="text-align:center;">'.($no_access_elements ?? 'No access elements found').'</td>
|
|
</tr>';
|
|
}
|
|
|
|
$view .= ' </tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
// Metadata Block
|
|
$view .= '<div class="content-block">
|
|
<div class="block-header">
|
|
<i class="fa-solid fa-bars fa-sm"></i>'.($tab3 ?? 'Details').'
|
|
</div>
|
|
<div class="table order-table">
|
|
<table>
|
|
<tr>
|
|
<td style="width:25%;">'.($general_created ?? 'Created').'</td>
|
|
<td>'.getRelativeTime($responses->created).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:25%;">'.($general_updated ?? 'Updated').'</td>
|
|
<td>'.getRelativeTime($responses->updated).'</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
';
|
|
|
|
//OUTPUT
|
|
echo $view;
|
|
|
|
$js = 'var permissionsEditMode = false;
|
|
function togglePermissionsEdit() {
|
|
permissionsEditMode = !permissionsEditMode;
|
|
var editBtn = document.getElementById("editBtn");
|
|
var saveBtn = document.getElementById("saveBtn");
|
|
var viewElements = document.querySelectorAll(".view-mode");
|
|
var editElements = document.querySelectorAll(".edit-mode");
|
|
var editBlockElements = document.querySelectorAll(".edit-mode-block");
|
|
var editOnlyRows = document.querySelectorAll(".edit-only-row");
|
|
var i;
|
|
if (permissionsEditMode) {
|
|
for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "none"; }
|
|
for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "inline"; }
|
|
for (i = 0; i < editBlockElements.length; i++) { editBlockElements[i].style.display = "block"; }
|
|
for (i = 0; i < editOnlyRows.length; i++) { editOnlyRows[i].style.display = "table-row"; }
|
|
editBtn.style.display = "none";
|
|
saveBtn.style.display = "inline-block";
|
|
} else {
|
|
for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "inline"; }
|
|
for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "none"; }
|
|
for (i = 0; i < editBlockElements.length; i++) { editBlockElements[i].style.display = "none"; }
|
|
for (i = 0; i < editOnlyRows.length; i++) { editOnlyRows[i].style.display = "none"; }
|
|
editBtn.style.display = "inline-block";
|
|
saveBtn.style.display = "none";
|
|
}
|
|
}
|
|
function toggleColumn(type) {
|
|
var checkboxes = document.querySelectorAll("input[name$=\\"[" + type + "]\\"]");
|
|
var allChecked = true;
|
|
for (var i = 0; i < checkboxes.length; i++) {
|
|
if (!checkboxes[i].checked) {
|
|
allChecked = false;
|
|
break;
|
|
}
|
|
}
|
|
for (var i = 0; i < checkboxes.length; i++) {
|
|
checkboxes[i].checked = !allChecked;
|
|
}
|
|
}
|
|
async function copyPermissionsFromRole(roleId) {
|
|
if (!roleId) return;
|
|
|
|
if (!confirm("'.($confirm_copy_permissions ?? 'This will override all current permission settings. Continue?').'")) {
|
|
document.getElementById("copyFromRole").value = "";
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Call PHP page which will use ioServer to get permissions
|
|
const response = await fetch("index.php?page=user_role&action=get_role_permissions&source_role_id=" + roleId);
|
|
if (!response.ok) throw new Error("Failed to fetch");
|
|
const permissions = await response.json();
|
|
|
|
// Create a lookup map of permissions by access_id
|
|
var permMap = {};
|
|
if (permissions && permissions.length > 0) {
|
|
for (var i = 0; i < permissions.length; i++) {
|
|
permMap[permissions[i].access_id] = permissions[i];
|
|
}
|
|
}
|
|
|
|
// Get all permission checkboxes and reset them
|
|
var allCheckboxes = document.querySelectorAll("input[type=checkbox][name^=\\"permissions[\\"]");
|
|
for (var i = 0; i < allCheckboxes.length; i++) {
|
|
allCheckboxes[i].checked = false;
|
|
}
|
|
|
|
// Apply copied permissions
|
|
for (var accessId in permMap) {
|
|
var perm = permMap[accessId];
|
|
var cbCreate = document.querySelector("input[name=\\"permissions[" + accessId + "][C]\\"]");
|
|
var cbRead = document.querySelector("input[name=\\"permissions[" + accessId + "][R]\\"]");
|
|
var cbUpdate = document.querySelector("input[name=\\"permissions[" + accessId + "][U]\\"]");
|
|
var cbDelete = document.querySelector("input[name=\\"permissions[" + accessId + "][D]\\"]");
|
|
|
|
if (cbCreate && perm.can_create == 1) cbCreate.checked = true;
|
|
if (cbRead && perm.can_read == 1) cbRead.checked = true;
|
|
if (cbUpdate && perm.can_update == 1) cbUpdate.checked = true;
|
|
if (cbDelete && perm.can_delete == 1) cbDelete.checked = true;
|
|
}
|
|
|
|
// Reset dropdown
|
|
document.getElementById("copyFromRole").value = "";
|
|
|
|
} catch (error) {
|
|
console.error("Error copying permissions:", error);
|
|
alert("'.($error_copy_permissions ?? 'Failed to copy permissions. Please try again.').'");
|
|
document.getElementById("copyFromRole").value = "";
|
|
}
|
|
}
|
|
function confirmDeleteRole() {
|
|
document.getElementById("deleteModal").style.display = "flex";
|
|
}
|
|
function closeDeleteModal() {
|
|
document.getElementById("deleteModal").style.display = "none";
|
|
}
|
|
function executeDeleteRole() {
|
|
document.getElementById("deleteRoleForm").submit();
|
|
}';
|
|
|
|
template_footer($js);
|