diff --git a/api/update_theme.php b/api/update_theme.php new file mode 100644 index 0000000..5c7fe8d --- /dev/null +++ b/api/update_theme.php @@ -0,0 +1,26 @@ + false, 'error' => 'Not authenticated']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); +$theme = $data['theme'] ?? 'light'; + +// Validate theme +$allowed_themes = ['light', 'dark', 'midnight', 'forest']; +if (!in_array($theme, $allowed_themes)) { + echo json_encode(['success' => false, 'error' => 'Invalid theme']); + exit; +} + +try { + $stmt = db()->prepare("UPDATE users SET theme = ? WHERE id = ?"); + $stmt->execute([$theme, $_SESSION['user_id']]); + echo json_encode(['success' => true]); +} catch (PDOException $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/db/migrations/008_add_password_reset.sql b/db/migrations/008_add_password_reset.sql new file mode 100644 index 0000000..d4dca13 --- /dev/null +++ b/db/migrations/008_add_password_reset.sql @@ -0,0 +1,3 @@ +-- Add password reset token columns to users table +ALTER TABLE users ADD COLUMN reset_token VARCHAR(100) NULL; +ALTER TABLE users ADD COLUMN reset_token_expiry DATETIME NULL; diff --git a/db/migrations/009_add_theme_to_users.sql b/db/migrations/009_add_theme_to_users.sql new file mode 100644 index 0000000..370cb28 --- /dev/null +++ b/db/migrations/009_add_theme_to_users.sql @@ -0,0 +1,2 @@ +-- Migration: Add theme to users +ALTER TABLE users ADD COLUMN theme VARCHAR(20) DEFAULT 'light'; diff --git a/db/migrations/010_add_granular_permissions.sql b/db/migrations/010_add_granular_permissions.sql new file mode 100644 index 0000000..37d53bf --- /dev/null +++ b/db/migrations/010_add_granular_permissions.sql @@ -0,0 +1,11 @@ +-- Migration: Add granular permissions to users table +ALTER TABLE users +ADD COLUMN can_view TINYINT(1) DEFAULT 1, +ADD COLUMN can_add TINYINT(1) DEFAULT 0, +ADD COLUMN can_edit TINYINT(1) DEFAULT 0, +ADD COLUMN can_delete TINYINT(1) DEFAULT 0; + +-- Set defaults for existing roles +UPDATE users SET can_view = 1, can_add = 1, can_edit = 1, can_delete = 1 WHERE role = 'admin'; +UPDATE users SET can_view = 1, can_add = 1, can_edit = 1, can_delete = 0 WHERE role = 'clerk'; +UPDATE users SET can_view = 1, can_add = 0, can_edit = 0, can_delete = 0 WHERE role = 'staff'; diff --git a/forgot_password.php b/forgot_password.php new file mode 100644 index 0000000..9d0ce7e --- /dev/null +++ b/forgot_password.php @@ -0,0 +1,150 @@ +query("SELECT * FROM charity_settings WHERE id = 1"); +$charity = $stmt->fetch(); + +// Check if we are in reset mode (token in URL) +$token = $_GET['token'] ?? ''; +if ($token) { + $stmt = db()->prepare("SELECT * FROM users WHERE reset_token = ? AND reset_token_expiry > NOW()"); + $stmt->execute([$token]); + $user = $stmt->fetch(); + + if ($user) { + $step = 'reset'; + } else { + $error = 'رابط استعادة كلمة المرور غير صالح أو منتهي الصلاحية.'; + $step = 'request'; + } +} + +// Handle POST requests +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + if (isset($_POST['request_reset'])) { + $email = trim($_POST['email'] ?? ''); + if (filter_var($email, FILTER_VALIDATE_EMAIL)) { + $stmt = db()->prepare("SELECT id, full_name FROM users WHERE email = ?"); + $stmt->execute([$email]); + $user = $stmt->fetch(); + + if ($user) { + $newToken = bin2hex(random_bytes(32)); + $expiry = date('Y-m-d H:i:s', strtotime('+1 hour')); + + $update = db()->prepare("UPDATE users SET reset_token = ?, reset_token_expiry = ? WHERE id = ?"); + $update->execute([$newToken, $expiry, $user['id']]); + + $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; + $host = $_SERVER['HTTP_HOST']; + $resetLink = "$protocol://$host/forgot_password.php?token=$newToken"; + + $subject = "استعادة كلمة المرور - " . ($charity['charity_name'] ?? 'الجمعية الخيرية'); + $html = " +
+

مرحباً {$user['full_name']}

+

لقد طلبت استعادة كلمة المرور الخاصة بك. يرجى الضغط على الرابط أدناه لإعادة تعيينها:

+

إعادة تعيين كلمة المرور

+

هذا الرابط صالح لمدة ساعة واحدة فقط.

+

إذا لم تطلب هذا، يرجى تجاهل هذه الرسالة.

+
+ "; + + $res = MailService::sendMail($email, $subject, $html); + if ($res['success']) { + $success = 'تم إرسال رابط استعادة كلمة المرور إلى بريدك الإلكتروني.'; + } else { + $error = 'فشل إرسال البريد الإلكتروني. يرجى المحاولة لاحقاً أو التواصل مع الإدارة.'; + } + } else { + // For security, don't reveal if email exists, but here we can be more helpful if it's a closed admin panel + $error = 'البريد الإلكتروني غير مسجل لدينا.'; + } + } else { + $error = 'يرجى إدخال بريد إلكتروني صحيح.'; + } + } elseif (isset($_POST['reset_password'])) { + $password = $_POST['password'] ?? ''; + $confirm = $_POST['confirm_password'] ?? ''; + + if (strlen($password) < 6) { + $error = 'كلمة المرور يجب أن تكون 6 أحرف على الأقل.'; + } elseif ($password !== $confirm) { + $error = 'كلمات المرور غير متطابقة.'; + } else { + $hashed = password_hash($password, PASSWORD_DEFAULT); + $update = db()->prepare("UPDATE users SET password = ?, reset_token = NULL, reset_token_expiry = NULL WHERE id = ?"); + $update->execute([$hashed, $user['id']]); + $success = 'تم تغيير كلمة المرور بنجاح. يمكنك الآن تسجيل الدخول.'; + $step = 'completed'; + } + } +} +?> + +
+
+
+
+ + Logo + +

استعادة كلمة المرور

+

بريد

+
+ + +
+ + +
+ + + +
+
+ + +
أدخل البريد الإلكتروني المرتبط بحسابك.
+
+
+ +
+ +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + + +
+
+
+ + diff --git a/inbound.php b/inbound.php index 37e7aff..f06ee37 100644 --- a/inbound.php +++ b/inbound.php @@ -2,6 +2,11 @@ require_once __DIR__ . '/includes/header.php'; require_once __DIR__ . '/mail/MailService.php'; +// Check if user has view permission +if (!canView()) { + redirect('index.php'); +} + $error = ''; $success = ''; $user_id = $_SESSION['user_id']; @@ -47,62 +52,72 @@ function sendAssignmentNotification($assigned_to_id, $ref_no, $subject) { // Handle actions if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; - $type = 'inbound'; - $ref_no = $_POST['ref_no'] ?? ''; - $date_registered = $_POST['date_registered'] ?? date('Y-m-d'); - $due_date = !empty($_POST['due_date']) ? $_POST['due_date'] : null; - $sender = $_POST['sender'] ?? ''; - $recipient = $_POST['recipient'] ?? ''; - $subject = $_POST['subject'] ?? ''; - $description = $_POST['description'] ?? ''; - $status_id = $_POST['status_id'] ?? $default_status_id; - $assigned_to = !empty($_POST['assigned_to']) ? $_POST['assigned_to'] : null; - $id = $_POST['id'] ?? 0; - - if ($ref_no && $subject) { - try { - if ($action === 'add') { - $stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, due_date, sender, recipient, subject, description, status_id, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$type, $ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $user_id]); - - if ($assigned_to) { - sendAssignmentNotification($assigned_to, $ref_no, $subject); - } - - $success = 'تمت إضافة البريد بنجاح'; - } elseif ($action === 'edit') { - // Get previous assigned_to to check if it changed - $stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?"); - $stmt_old->execute([$id]); - $old_assigned_to = $stmt_old->fetchColumn(); - - $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, due_date = ?, sender = ?, recipient = ?, subject = ?, description = ?, status_id = ?, assigned_to = ? WHERE id = ? AND type = 'inbound'"); - $stmt->execute([$ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $id]); - - if ($assigned_to && $assigned_to != $old_assigned_to) { - sendAssignmentNotification($assigned_to, $ref_no, $subject); - } - - $success = 'تم تحديث البيانات بنجاح'; - } - } catch (PDOException $e) { - if ($e->getCode() == 23000) { - $error = 'رقم القيد مستخدم مسبقاً'; - } else { - $error = 'حدث خطأ: ' . $e->getMessage(); - } - } + + // Permission checks for POST actions + if (($action === 'add' && !canAdd()) || ($action === 'edit' && !canEdit())) { + $error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء'; } else { - $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; + $type = 'inbound'; + $ref_no = $_POST['ref_no'] ?? ''; + $date_registered = $_POST['date_registered'] ?? date('Y-m-d'); + $due_date = !empty($_POST['due_date']) ? $_POST['due_date'] : null; + $sender = $_POST['sender'] ?? ''; + $recipient = $_POST['recipient'] ?? ''; + $subject = $_POST['subject'] ?? ''; + $description = $_POST['description'] ?? ''; + $status_id = $_POST['status_id'] ?? $default_status_id; + $assigned_to = !empty($_POST['assigned_to']) ? $_POST['assigned_to'] : null; + $id = $_POST['id'] ?? 0; + + if ($ref_no && $subject) { + try { + if ($action === 'add') { + $stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, due_date, sender, recipient, subject, description, status_id, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$type, $ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $user_id]); + + if ($assigned_to) { + sendAssignmentNotification($assigned_to, $ref_no, $subject); + } + + $success = 'تمت إضافة البريد بنجاح'; + } elseif ($action === 'edit') { + // Get previous assigned_to to check if it changed + $stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?"); + $stmt_old->execute([$id]); + $old_assigned_to = $stmt_old->fetchColumn(); + + $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, due_date = ?, sender = ?, recipient = ?, subject = ?, description = ?, status_id = ?, assigned_to = ? WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $id]); + + if ($assigned_to && $assigned_to != $old_assigned_to) { + sendAssignmentNotification($assigned_to, $ref_no, $subject); + } + + $success = 'تم تحديث البيانات بنجاح'; + } + } catch (PDOException $e) { + if ($e->getCode() == 23000) { + $error = 'رقم القيد مستخدم مسبقاً'; + } else { + $error = 'حدث خطأ: ' . $e->getMessage(); + } + } + } else { + $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; + } } } // Delete action if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) { - $id = $_GET['id']; - $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'inbound'"); - $stmt->execute([$id]); - $success = 'تم حذف البريد بنجاح'; + if (!canDelete()) { + $error = 'عذراً، ليس لديك الصلاحية لحذف السجلات'; + } else { + $id = $_GET['id']; + $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$id]); + $success = 'تم حذف البريد بنجاح'; + } } $search = $_GET['search'] ?? ''; @@ -137,9 +152,11 @@ $users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")- // Handle Deep Link for Edit $deepLinkData = null; if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) { - $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'inbound'"); - $stmt->execute([$_GET['id']]); - $deepLinkData = $stmt->fetch(); + if (canEdit()) { + $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$_GET['id']]); + $deepLinkData = $stmt->fetch(); + } } function getStatusBadgeInList($mail) { @@ -158,9 +175,11 @@ function getStatusBadgeInList($mail) {

البريد الوارد

+ +
@@ -243,11 +262,17 @@ function getStatusBadgeInList($mail) { + + + + + + @@ -261,6 +286,7 @@ function getStatusBadgeInList($mail) { + + + + + diff --git a/includes/header.php b/includes/header.php index 501fe57..d1af3ba 100644 --- a/includes/header.php +++ b/includes/header.php @@ -10,12 +10,30 @@ function isAdmin() { return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin'; } +function canView() { + return isAdmin() || (isset($_SESSION['can_view']) && $_SESSION['can_view'] == 1); +} + +function canAdd() { + return isAdmin() || (isset($_SESSION['can_add']) && $_SESSION['can_add'] == 1); +} + +function canEdit() { + return isAdmin() || (isset($_SESSION['can_edit']) && $_SESSION['can_edit'] == 1); +} + +function canDelete() { + return isAdmin() || (isset($_SESSION['can_delete']) && $_SESSION['can_delete'] == 1); +} + function redirect($path) { header("Location: $path"); exit; } -if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php') { +// Allowed pages when not logged in +$allowed_pages = ['login.php', 'forgot_password.php']; +if (!isLoggedIn() && !in_array(basename($_SERVER['PHP_SELF']), $allowed_pages)) { redirect('login.php'); } @@ -29,13 +47,20 @@ $charity_favicon = $charity['charity_favicon'] ?? null; // Fetch current user info if logged in $current_user = null; if (isLoggedIn()) { - $stmt = db()->prepare("SELECT full_name, profile_image FROM users WHERE id = ?"); + $stmt = db()->prepare("SELECT full_name, profile_image, theme, can_view, can_add, can_edit, can_delete FROM users WHERE id = ?"); $stmt->execute([$_SESSION['user_id']]); $current_user = $stmt->fetch(); + + // Update session permissions + $_SESSION['can_view'] = $current_user['can_view']; + $_SESSION['can_add'] = $current_user['can_add']; + $_SESSION['can_edit'] = $current_user['can_edit']; + $_SESSION['can_delete'] = $current_user['can_delete']; } +$user_theme = $current_user['theme'] ?? 'light'; ?> - + @@ -56,42 +81,136 @@ if (isLoggedIn()) { -
+
@@ -178,7 +335,19 @@ if (isLoggedIn()) { الملف الشخصي -
  • +
    المظهر
    +
    +
    +
    +
    +
    +
    +
  • + +
    + + -
    \ No newline at end of file + +
    diff --git a/login.php b/login.php index bf9fe69..76f2c06 100644 --- a/login.php +++ b/login.php @@ -25,6 +25,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $_SESSION['username'] = $user['username']; $_SESSION['full_name'] = $user['full_name']; $_SESSION['user_role'] = $user['role']; + + // Set permissions in session immediately + $_SESSION['can_view'] = $user['can_view'] ?? 1; + $_SESSION['can_add'] = $user['can_add'] ?? 0; + $_SESSION['can_edit'] = $user['can_edit'] ?? 0; + $_SESSION['can_delete'] = $user['can_delete'] ?? 0; + redirect('index.php'); } else { $error = 'اسم المستخدم أو كلمة المرور غير صحيحة'; @@ -70,4 +77,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    - \ No newline at end of file + diff --git a/outbound.php b/outbound.php index 3844434..5e7b26f 100644 --- a/outbound.php +++ b/outbound.php @@ -2,6 +2,11 @@ require_once __DIR__ . '/includes/header.php'; require_once __DIR__ . '/mail/MailService.php'; +// Check if user has view permission +if (!canView()) { + redirect('index.php'); +} + // Safe truncation helper if (!function_exists('truncate_text')) { function truncate_text($text, $limit = 100) { @@ -59,86 +64,96 @@ function sendAssignmentNotification($assigned_to_id, $ref_no, $subject) { // Handle actions if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; - $type = 'outbound'; - $ref_no = $_POST['ref_no'] ?? ''; - $date_registered = $_POST['date_registered'] ?? date('Y-m-d'); - $due_date = !empty($_POST['due_date']) ? $_POST['due_date'] : null; - $sender = $_POST['sender'] ?? ''; - $recipient = $_POST['recipient'] ?? ''; - $subject = $_POST['subject'] ?? ''; - $description = $_POST['description'] ?? ''; - $status_id = $_POST['status_id'] ?? $default_status_id; - $assigned_to = !empty($_POST['assigned_to']) ? $_POST['assigned_to'] : null; - $id = $_POST['id'] ?? 0; + + // Permission checks for POST actions + if (($action === 'add' && !canAdd()) || ($action === 'edit' && !canEdit())) { + $error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء'; + } else { + $type = 'outbound'; + $ref_no = $_POST['ref_no'] ?? ''; + $date_registered = $_POST['date_registered'] ?? date('Y-m-d'); + $due_date = !empty($_POST['due_date']) ? $_POST['due_date'] : null; + $sender = $_POST['sender'] ?? ''; + $recipient = $_POST['recipient'] ?? ''; + $subject = $_POST['subject'] ?? ''; + $description = $_POST['description'] ?? ''; + $status_id = $_POST['status_id'] ?? $default_status_id; + $assigned_to = !empty($_POST['assigned_to']) ? $_POST['assigned_to'] : null; + $id = $_POST['id'] ?? 0; - if ($ref_no && $subject) { - try { - db()->beginTransaction(); - if ($action === 'add') { - $stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, due_date, sender, recipient, subject, description, status_id, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$type, $ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $user_id]); - $mail_id = db()->lastInsertId(); - - if ($assigned_to) { - sendAssignmentNotification($assigned_to, $ref_no, $subject); + if ($ref_no && $subject) { + try { + db()->beginTransaction(); + if ($action === 'add') { + $stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, due_date, sender, recipient, subject, description, status_id, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$type, $ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $user_id]); + $mail_id = db()->lastInsertId(); + + if ($assigned_to) { + sendAssignmentNotification($assigned_to, $ref_no, $subject); + } + + $success = 'تمت إضافة البريد الصادر بنجاح'; + } elseif ($action === 'edit') { + $mail_id = $id; + + // Get previous assigned_to to check if it changed + $stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?"); + $stmt_old->execute([$id]); + $old_assigned_to = $stmt_old->fetchColumn(); + + $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, due_date = ?, sender = ?, recipient = ?, subject = ?, description = ?, status_id = ?, assigned_to = ? WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $mail_id]); + + if ($assigned_to && $assigned_to != $old_assigned_to) { + sendAssignmentNotification($assigned_to, $ref_no, $subject); + } + + $success = 'تم تحديث البيانات بنجاح'; } - - $success = 'تمت إضافة البريد الصادر بنجاح'; - } elseif ($action === 'edit') { - $mail_id = $id; - - // Get previous assigned_to to check if it changed - $stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?"); - $stmt_old->execute([$id]); - $old_assigned_to = $stmt_old->fetchColumn(); - $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, due_date = ?, sender = ?, recipient = ?, subject = ?, description = ?, status_id = ?, assigned_to = ? WHERE id = ? AND type = 'outbound'"); - $stmt->execute([$ref_no, $date_registered, $due_date, $sender, $recipient, $subject, $description, $status_id, $assigned_to, $mail_id]); - - if ($assigned_to && $assigned_to != $old_assigned_to) { - sendAssignmentNotification($assigned_to, $ref_no, $subject); - } - - $success = 'تم تحديث البيانات بنجاح'; - } + // Handle Attachments + if (!empty($_FILES['attachments']['name'][0])) { + $upload_dir = 'uploads/attachments/'; + if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true); - // Handle Attachments - if (!empty($_FILES['attachments']['name'][0])) { - $upload_dir = 'uploads/attachments/'; - if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true); - - foreach ($_FILES['attachments']['name'] as $key => $name) { - if ($_FILES['attachments']['error'][$key] === 0) { - $file_name = time() . '_' . basename($name); - $target_path = $upload_dir . $file_name; - if (move_uploaded_file($_FILES['attachments']['tmp_name'][$key], $target_path)) { - $stmt = db()->prepare("INSERT INTO attachments (mail_id, display_name, file_path, file_name, file_size) VALUES (?, ?, ?, ?, ?)"); - $stmt->execute([$mail_id, $name, $target_path, $name, $_FILES['attachments']['size'][$key]]); + foreach ($_FILES['attachments']['name'] as $key => $name) { + if ($_FILES['attachments']['error'][$key] === 0) { + $file_name = time() . '_' . basename($name); + $target_path = $upload_dir . $file_name; + if (move_uploaded_file($_FILES['attachments']['tmp_name'][$key], $target_path)) { + $stmt = db()->prepare("INSERT INTO attachments (mail_id, display_name, file_path, file_name, file_size) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$mail_id, $name, $target_path, $name, $_FILES['attachments']['size'][$key]]); + } } } } - } - db()->commit(); - } catch (PDOException $e) { - db()->rollBack(); - if ($e->getCode() == 23000) { - $error = 'رقم القيد مستخدم مسبقاً'; - } else { - $error = 'حدث خطأ: ' . $e->getMessage(); + db()->commit(); + } catch (PDOException $e) { + db()->rollBack(); + if ($e->getCode() == 23000) { + $error = 'رقم القيد مستخدم مسبقاً'; + } else { + $error = 'حدث خطأ: ' . $e->getMessage(); + } } + } else { + $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; } - } else { - $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; } } // Delete action if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) { - $id = $_GET['id']; - $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'outbound'"); - $stmt->execute([$id]); - $success = 'تم حذف البريد بنجاح'; + if (!canDelete()) { + $error = 'عذراً، ليس لديك الصلاحية لحذف السجلات'; + } else { + $id = $_GET['id']; + $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$id]); + $success = 'تم حذف البريد بنجاح'; + } } $search = $_GET['search'] ?? ''; @@ -173,9 +188,11 @@ $users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")- // Handle Deep Link for Edit $deepLinkData = null; if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) { - $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'outbound'"); - $stmt->execute([$_GET['id']]); - $deepLinkData = $stmt->fetch(); + if (canEdit()) { + $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$_GET['id']]); + $deepLinkData = $stmt->fetch(); + } } function getStatusBadgeInList($mail) { @@ -194,9 +211,11 @@ function getStatusBadgeInList($mail) {

    البريد الصادر

    + +
    @@ -279,11 +298,17 @@ function getStatusBadgeInList($mail) { + + + + + + @@ -297,6 +322,7 @@ function getStatusBadgeInList($mail) { + - - + +
    @@ -197,8 +210,10 @@ function getStatusBadge($mail) {
    مهامي المسندة
    @@ -253,7 +268,7 @@ function getStatusBadge($mail) {
    -
    +
    @@ -287,4 +302,4 @@ function getStatusBadge($mail) {
    - \ No newline at end of file + diff --git a/users.php b/users.php index e16a602..0dc1ce0 100644 --- a/users.php +++ b/users.php @@ -15,13 +15,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $role = $_POST['role'] ?? 'staff'; $password = $_POST['password'] ?? ''; $id = $_POST['id'] ?? 0; + + // Permissions + $can_view = isset($_POST['can_view']) ? 1 : 0; + $can_add = isset($_POST['can_add']) ? 1 : 0; + $can_edit = isset($_POST['can_edit']) ? 1 : 0; + $can_delete = isset($_POST['can_delete']) ? 1 : 0; if ($action === 'add') { if ($username && $password && $full_name) { $hashed_password = password_hash($password, PASSWORD_DEFAULT); try { - $stmt = db()->prepare("INSERT INTO users (username, password, full_name, role) VALUES (?, ?, ?, ?)"); - $stmt->execute([$username, $hashed_password, $full_name, $role]); + $stmt = db()->prepare("INSERT INTO users (username, password, full_name, role, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$username, $hashed_password, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete]); $success = 'تم إضافة المستخدم بنجاح'; } catch (PDOException $e) { if ($e->getCode() == 23000) { @@ -38,11 +44,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { if ($password) { $hashed_password = password_hash($password, PASSWORD_DEFAULT); - $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, password = ? WHERE id = ?"); - $stmt->execute([$username, $full_name, $role, $hashed_password, $id]); + $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, password = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?"); + $stmt->execute([$username, $full_name, $role, $hashed_password, $can_view, $can_add, $can_edit, $can_delete, $id]); } else { - $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ? WHERE id = ?"); - $stmt->execute([$username, $full_name, $role, $id]); + $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?"); + $stmt->execute([$username, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete, $id]); } $success = 'تم تحديث بيانات المستخدم بنجاح'; } catch (PDOException $e) { @@ -77,7 +83,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) ?>
    -

    إدارة المستخدمين

    +

    إدارة المستخدمين والصلاحيات

    @@ -106,6 +112,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) الاسم الكامل اسم المستخدم الدور + الصلاحيات تاريخ الإنشاء الإجراءات @@ -124,6 +131,14 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) موظف + +
    + ع + إ + ت + ح +
    +