Tul xxx Tul
User / IP
:
216.73.216.146
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
comidarapidafran2
/
admin
/
Viewing: admin_permissions.php
<?php include '../components/connect.php'; require_once '../components/admin_roles.php'; session_start(); $admin_id = $_SESSION['admin_id'] ?? null; if (!$admin_id) { header('location:admin_login.php'); exit(); } ensureAdminRolesSchema($conn); $currentRole = getRoleBySession($conn); if (!adminHasPermission($currentRole, 'admin_accounts')) { enforceAdminPermission('admin_accounts'); } $roleLabels = getAvailableAdminRoles(); $permissionLabels = getAdminPermissionLabels(); $rolePermissionMatrix = getAdminRolePermissions(); $targetId = isset($_GET['id']) ? (int)$_GET['id'] : 0; if ($targetId <= 0) { addAdminFlashMessage('Selecciona un usuario válido para actualizar.'); header('location:admin_accounts.php'); exit(); } $targetStmt = $conn->prepare('SELECT id, name, role FROM `admin` WHERE id = ? LIMIT 1'); $targetStmt->execute([$targetId]); $targetAdmin = $targetStmt->fetch(PDO::FETCH_ASSOC); if (!$targetAdmin) { addAdminFlashMessage('El usuario seleccionado no existe.'); header('location:admin_accounts.php'); exit(); } $currentTargetRole = normalizeAdminRole($targetAdmin['role'] ?? null); [$storedCustomPermissions, $storedCustomMode] = getAdminCustomPermissionsFromDb($conn, $targetId); $formRole = $currentTargetRole; $formCustomMode = $storedCustomMode; $formPermissions = $formCustomMode ? $storedCustomPermissions : ($rolePermissionMatrix[$formRole] ?? []); $allPermissions = array_keys($permissionLabels); $errors = []; $targetInitial = strtoupper(substr((string)($targetAdmin['name'] ?? ''), 0, 1)); if (function_exists('mb_substr')) { $targetInitial = mb_strtoupper(mb_substr((string)($targetAdmin['name'] ?? ''), 0, 1, 'UTF-8'), 'UTF-8'); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $submittedRole = normalizeAdminRole($_POST['role'] ?? $formRole); $submittedCustomMode = isset($_POST['custom_mode']) && $_POST['custom_mode'] === '1'; $submittedPermissions = $submittedCustomMode ? normalizeAdminPermissionList($_POST['permissions'] ?? []) : null; $formRole = $submittedRole; $formCustomMode = $submittedCustomMode; $formPermissions = $formCustomMode ? $submittedPermissions : ($rolePermissionMatrix[$formRole] ?? []); $isLastOwner = $currentTargetRole === 'owner' && $submittedRole !== 'owner' && countAdminsByRole($conn, 'owner') <= 1; if ($isLastOwner) { $errors[] = 'No puedes remover el último Propietario del sistema.'; } if ($formCustomMode && empty($formPermissions)) { $errors[] = 'Selecciona al menos una sección cuando activas los permisos personalizados.'; } if (empty($errors)) { if ($submittedRole !== $currentTargetRole) { $updateRoleStmt = $conn->prepare('UPDATE `admin` SET role = ? WHERE id = ?'); $updateRoleStmt->execute([$submittedRole, $targetId]); $currentTargetRole = $submittedRole; } if ($formCustomMode) { saveAdminCustomPermissions($conn, $targetId, $formPermissions); } else { saveAdminCustomPermissions($conn, $targetId, null); } if ($targetId === (int)$admin_id) { refreshAdminAccess($conn, $targetId); } addAdminFlashMessage('Permisos actualizados correctamente.'); header('location:admin_accounts.php'); exit(); } } $businessName = getBusinessName($conn); $businessLogoVersion = getBusinessLogoVersion($conn); $iconHref = '../icon.php?size=64' . ($businessLogoVersion !== '' ? '&v=' . rawurlencode($businessLogoVersion) : ''); ?> <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Configuración de permisos | <?= htmlspecialchars($businessName); ?></title> <link rel="icon" href="<?= htmlspecialchars($iconHref); ?>" type="image/png"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> <link rel="stylesheet" href="../css/admin_style.css"> <style> body.permissions-page { background: linear-gradient(135deg, #f5f9ff 0%, #fff7f3 100%); min-height: 100vh; } .permissions-page .page-heading { padding: 24px 24px 0; } .permissions-page .heading-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; } .permissions-page .heading-title { margin: 0; font-size: 2.2rem; font-weight: 900; color: #181818; } .permissions-page .heading-subtitle { margin: 6px 0 0; color: rgba(24, 24, 24, 0.65); font-weight: 600; } .permissions-page .heading-back { display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 999px; text-decoration: none; font-weight: 700; color: rgba(48, 49, 73, 0.88); background: rgba(255, 255, 255, 0.75); border: 1px solid rgba(20, 20, 33, 0.12); box-shadow: 0 12px 28px rgba(17, 24, 39, 0.08); backdrop-filter: blur(10px); transition: transform .2s ease, box-shadow .2s ease; } .permissions-page .heading-back:hover { transform: translateY(-2px); box-shadow: 0 14px 34px rgba(17, 24, 39, 0.12); } .permissions-page .form-container { padding: 2.5rem 1.5rem 3.5rem; max-width: 920px; margin: 0 auto; } .permissions-page .form-card { position: relative; overflow: hidden; background: rgba(255, 255, 255, 0.82); border-radius: 20px; padding: 2.25rem 2.5rem; box-shadow: 0 22px 50px rgba(17, 24, 39, 0.14); border: 1px solid rgba(226, 232, 240, 0.95); backdrop-filter: blur(12px); } .permissions-page .form-card::before { content: ''; position: absolute; inset: -70% -55% auto auto; height: 260px; width: 260px; background: radial-gradient(150px at top right, rgba(14, 165, 233, 0.16), transparent 70%); transform: rotate(10deg); pointer-events: none; } .permissions-page .target-banner { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 14px 14px; border-radius: 18px; border: 1px solid rgba(20, 20, 33, 0.1); background: rgba(255, 255, 255, 0.7); box-shadow: 0 14px 30px rgba(15, 21, 45, 0.08); margin-bottom: 22px; } .permissions-page .target-left { display: flex; align-items: center; gap: 14px; } .permissions-page .target-meta { min-width: 0; } .permissions-page .target-banner > div:last-child { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; } .permissions-page .target-avatar { height: 52px; width: 52px; border-radius: 16px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-weight: 800; font-size: 1.4rem; background: linear-gradient(135deg, #0ea5e9, #2563eb); box-shadow: 0 12px 26px rgba(37, 99, 235, 0.22); } .permissions-page .target-meta h3 { margin: 0; font-size: 1.25rem; color: #141421; letter-spacing: .2px; } .permissions-page .target-meta p { margin: 4px 0 0; color: rgba(20, 20, 33, 0.62); font-weight: 600; } .permissions-page .pill { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; font-weight: 800; font-size: .85rem; border: 1px solid rgba(20, 20, 33, 0.12); background: rgba(255, 255, 255, 0.75); color: rgba(20, 20, 33, 0.86); } .permissions-page .pill--custom { border-color: rgba(46, 204, 113, 0.25); background: rgba(46, 204, 113, 0.12); color: #0f8f52; } .permissions-page .form-card h3 { margin-bottom: 1.5rem; font-size: 1.65rem; color: #1e1e1e; font-weight: 700; } .permissions-page .form-field { margin-bottom: 1.6rem; } .permissions-page .form-field label { display: block; font-weight: 600; margin-bottom: .55rem; color: #1e293b; } .permissions-page select.box, .permissions-page input.box, .permissions-page .box.inline { width: 100%; padding: .8rem .95rem; border-radius: .85rem; border: 1px solid rgba(20, 20, 33, 0.12); font-size: 1rem; transition: border-color .2s ease, box-shadow .2s ease; } .permissions-page select.box:focus, .permissions-page input.box:focus { border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18); } .permissions-page .custom-toggle { display: flex; align-items: center; gap: .75rem; background: rgba(255, 255, 255, 0.82); padding: 1rem 1.15rem; border-radius: .85rem; border: 1px solid rgba(20, 20, 33, 0.12); box-shadow: 0 14px 30px rgba(15, 21, 45, 0.08); backdrop-filter: blur(10px); } .permissions-page .custom-toggle input { width: 20px; height: 20px; accent-color: #2563eb; } .permissions-page .permissions-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .85rem; margin-top: 1rem; } .permissions-page .permissions-filter { margin-top: 1rem; display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 16px; background: rgba(255, 255, 255, 0.82); border: 1px solid rgba(20, 20, 33, 0.12); box-shadow: 0 12px 26px rgba(15, 21, 45, 0.08); backdrop-filter: blur(10px); } .permissions-page .permissions-filter i { color: rgba(48, 49, 73, 0.7); } .permissions-page .permissions-filter input { border: none; outline: none; background: transparent; width: 100%; min-width: 0; font-size: 1rem; font-weight: 600; color: #303149; } .permissions-page .permission-item { border: 1px solid #e2e8f0; border-radius: .85rem; padding: .95rem 1.05rem; display: flex; align-items: center; gap: .75rem; background: linear-gradient(145deg, #ffffff, #f8fafc); transition: border-color .2s ease, box-shadow .2s ease; min-width: 0; } .permissions-page .permission-item span { min-width: 0; overflow-wrap: anywhere; word-break: break-word; } .permissions-page .permission-item input[type="checkbox"] { width: 18px; height: 18px; accent-color: #2563eb; } .permissions-page .permission-item.disabled { opacity: .55; } .permissions-page .permission-item:not(.disabled):hover { border-color: rgba(14, 165, 233, 0.55); box-shadow: 0 12px 25px rgba(37, 99, 235, 0.16); } .permissions-page .note { margin-top: 1rem; font-size: .96rem; color: #64748b; line-height: 1.45; } .permissions-page .flex-btn { display: flex; flex-wrap: wrap; gap: .85rem; margin-top: 2.2rem; justify-content: flex-end; } .permissions-page .flex-btn .btn, .permissions-page .flex-btn .option-btn { min-width: 160px; text-align: center; } .permissions-page .flex-btn .btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; border-radius: 14px; border: none; background: linear-gradient(135deg, #0ea5e9, #2563eb); box-shadow: 0 14px 28px rgba(37, 99, 235, 0.22); transition: transform .2s ease, box-shadow .2s ease; } .permissions-page .flex-btn .btn:hover { transform: translateY(-2px); box-shadow: 0 16px 34px rgba(37, 99, 235, 0.28); } .permissions-page .flex-btn .option-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; border-radius: 14px; background: rgba(255, 255, 255, 0.86); border: 1px solid rgba(20, 20, 33, 0.12); color: rgba(20, 20, 33, 0.86); box-shadow: 0 12px 26px rgba(15, 21, 45, 0.08); transition: transform .2s ease, box-shadow .2s ease; } .permissions-page .flex-btn .option-btn:hover { transform: translateY(-2px); box-shadow: 0 14px 32px rgba(15, 21, 45, 0.12); } .permissions-page .error-box { background: #fef2f2; border: 1px solid #fca5a5; color: #b91c1c; padding: 1rem 1.2rem; border-radius: .85rem; margin-bottom: 1.6rem; } @media (max-width: 900px) { .permissions-page .page-heading { padding: 20px 20px 0; } .permissions-page .form-container { padding: 2rem 1.25rem 3rem; } .permissions-page .form-card { padding: 2rem 1.75rem; } } @media (max-width: 720px) { .permissions-page .form-card { padding: 1.75rem 1.5rem; } .permissions-page .permissions-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .permissions-page .custom-toggle { flex-direction: column; align-items: flex-start; gap: .55rem; } .permissions-page .flex-btn { justify-content: center; } } @media (max-width: 540px) { .permissions-page .page-heading { padding: 18px 18px 0; } .permissions-page .heading-row { flex-direction: column; align-items: stretch; } .permissions-page .heading-row > div { width: 100%; } .permissions-page .heading-back { width: 100%; justify-content: center; } .permissions-page .form-container { padding: 1.5rem 1rem 2.5rem; } .permissions-page .form-card { padding: 1.5rem 1.2rem; } .permissions-page .target-banner { align-items: flex-start; } .permissions-page .target-left { width: 100%; flex-wrap: wrap; } .permissions-page .target-banner > div:last-child { width: 100%; justify-content: flex-start; } .permissions-page .pill { max-width: 100%; white-space: normal; } .permissions-page .form-card h3 { font-size: 1.45rem; } .permissions-page .permissions-grid { grid-template-columns: minmax(0, 1fr); } .permissions-page .permission-item { padding: .85rem .95rem; } .permissions-page .flex-btn { flex-direction: column-reverse; align-items: stretch; } .permissions-page .flex-btn .btn, .permissions-page .flex-btn .option-btn { width: 100%; min-width: 0; } } </style> </head> <body class="permissions-page"> <?php include '../components/admin_header.php'; ?> <section class="page-heading"> <div class="heading-row"> <div> <h1 class="heading-title">Administrar Cuentas y Permisos</h1> <p class="heading-subtitle">Controla roles base y accesos personalizados por sección.</p> </div> <a href="admin_accounts.php" class="heading-back"><i class="fa-solid fa-arrow-left"></i> Volver</a> </div> </section> <section class="form-container"> <div class="form-card"> <div class="target-banner"> <div class="target-left"> <div class="target-avatar"><?= htmlspecialchars($targetInitial); ?></div> <div class="target-meta"> <h3><?= htmlspecialchars($targetAdmin['name']); ?></h3> <p>Configura el rol y el acceso a secciones.</p> </div> </div> <div> <span class="pill" id="role-pill"><i class="fa-solid fa-user-shield"></i>Rol: <?= htmlspecialchars($roleLabels[$formRole] ?? ucfirst($formRole)); ?></span> <?php if ($formCustomMode): ?> <span class="pill pill--custom" id="custom-pill"><i class="fa-solid fa-lock"></i>Personalizado</span> <?php else: ?> <span class="pill" id="custom-pill"><i class="fa-solid fa-layer-group"></i>Por rol</span> <?php endif; ?> </div> </div> <?php if (!empty($errors)): ?> <div class="error-box"> <ul> <?php foreach ($errors as $error): ?> <li><?= htmlspecialchars($error); ?></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> <form action="" method="POST" class="permission-form"> <div class="form-field"> <label for="role">Rol base</label> <select name="role" id="role" class="box"> <?php foreach ($roleLabels as $roleKey => $roleLabel): ?> <option value="<?= $roleKey; ?>" <?= $formRole === $roleKey ? 'selected' : ''; ?>><?= htmlspecialchars($roleLabel); ?></option> <?php endforeach; ?> </select> </div> <div class="form-field"> <label class="custom-toggle" for="custom-mode"> <input type="checkbox" name="custom_mode" id="custom-mode" value="1" <?= $formCustomMode ? 'checked' : ''; ?>> <span>Activar selección manual de secciones</span> </label> </div> <div class="form-field"> <label>Secciones disponibles</label> <div class="permissions-filter"> <i class="fa-solid fa-magnifying-glass"></i> <input type="text" id="perm-search" placeholder="Buscar sección..." autocomplete="off"> </div> <div class="permissions-grid" id="permissions-grid" data-enabled="<?= $formCustomMode ? '1' : '0'; ?>"> <?php $basePermissions = $rolePermissionMatrix[$formRole] ?? []; foreach ($allPermissions as $permissionKey): $isSelected = in_array($permissionKey, $formPermissions, true); $isDefault = in_array($permissionKey, $basePermissions, true); ?> <label class="permission-item <?= $formCustomMode ? '' : 'disabled'; ?>" data-permission="<?= $permissionKey; ?>"> <input type="checkbox" name="permissions[]" value="<?= $permissionKey; ?>" <?= $isSelected ? 'checked' : ''; ?> <?= $formCustomMode ? '' : 'disabled'; ?> data-default="<?= $isDefault ? '1' : '0'; ?>"> <span><?= htmlspecialchars($permissionLabels[$permissionKey]); ?></span> </label> <?php endforeach; ?> </div> <p class="note">Cuando la selección manual está desactivada el usuario heredará los permisos del rol base.</p> </div> <div class="flex-btn"> <a href="admin_accounts.php" class="option-btn"><i class="fa-solid fa-xmark"></i> Cancelar</a> <button type="submit" class="btn"><i class="fa-solid fa-floppy-disk"></i> Guardar cambios</button> </div> </form> </div> </section> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> const roleLabels = <?= json_encode($roleLabels, JSON_UNESCAPED_UNICODE); ?>; const formErrors = <?= json_encode(array_values($errors), JSON_UNESCAPED_UNICODE); ?>; const customToggle = document.getElementById('custom-mode'); const permissionsGrid = document.getElementById('permissions-grid'); const permissionInputs = permissionsGrid ? permissionsGrid.querySelectorAll('input[type="checkbox"]') : []; const roleSelect = document.getElementById('role'); const permSearch = document.getElementById('perm-search'); const rolePill = document.getElementById('role-pill'); const customPill = document.getElementById('custom-pill'); function updatePermissionState() { const enabled = customToggle.checked; permissionsGrid.dataset.enabled = enabled ? '1' : '0'; permissionsGrid.querySelectorAll('.permission-item').forEach((item) => { if (enabled) { item.classList.remove('disabled'); } else { item.classList.add('disabled'); } }); permissionInputs.forEach((input) => { input.disabled = !enabled; if (!enabled) { input.checked = input.dataset.default === '1'; } }); } function syncDefaultPermissionsFromRole() { if (!customToggle.checked) { const selectedRole = roleSelect.value; const defaults = {}; <?php foreach ($rolePermissionMatrix as $roleKey => $rolePerms): ?> defaults['<?= $roleKey; ?>'] = <?= json_encode(array_values($rolePerms)); ?>; <?php endforeach; ?> const defaultList = defaults[selectedRole] || []; permissionInputs.forEach((input) => { input.dataset.default = defaultList.includes(input.value) ? '1' : '0'; if (!customToggle.checked) { input.checked = input.dataset.default === '1'; } }); } } if (customToggle && permissionsGrid) { customToggle.addEventListener('change', () => { updatePermissionState(); }); } if (roleSelect) { roleSelect.addEventListener('change', () => { syncDefaultPermissionsFromRole(); updatePermissionState(); if(rolePill){ const label = roleLabels[roleSelect.value] || roleSelect.value; rolePill.innerHTML = `<i class="fa-solid fa-user-shield"></i>Rol: ${label}`; } }); } if (customToggle) { customToggle.addEventListener('change', () => { if(customPill){ if(customToggle.checked){ customPill.classList.add('pill--custom'); customPill.innerHTML = '<i class="fa-solid fa-lock"></i>Personalizado'; }else{ customPill.classList.remove('pill--custom'); customPill.innerHTML = '<i class="fa-solid fa-layer-group"></i>Por rol'; } } }); } if (permSearch && permissionsGrid) { permSearch.addEventListener('input', () => { const q = permSearch.value.trim().toLowerCase(); permissionsGrid.querySelectorAll('.permission-item').forEach((item) => { const label = (item.querySelector('span')?.textContent || '').toLowerCase(); item.style.display = q === '' || label.includes(q) ? '' : 'none'; }); }); } document.addEventListener('DOMContentLoaded', () => { const nodes = Array.from(document.querySelectorAll('.message')); if(nodes.length && window.Swal){ const texts = nodes.map(n => (n.querySelector('span')?.textContent || '').trim()).filter(Boolean); nodes.forEach(n => n.remove()); if(texts.length){ const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3200, timerProgressBar: true, }); texts.forEach((t) => Toast.fire({ icon: 'success', title: t })); } } if(formErrors.length && window.Swal){ Swal.fire({ title: 'Revisa el formulario', html: `<div style="text-align:left;">${formErrors.map(e => `- ${e}`).join('<br>')}</div>`, icon: 'error', confirmButtonText: 'Entendido', }); } }); updatePermissionState(); </script> </body> </html>
Coded With 💗 by
0x6ick