diff --git a/app/Http/Controllers/Api/DashboardController.php b/app/Http/Controllers/Api/DashboardController.php index e89b728..f36d65b 100644 --- a/app/Http/Controllers/Api/DashboardController.php +++ b/app/Http/Controllers/Api/DashboardController.php @@ -40,14 +40,14 @@ class DashboardController extends Controller // Tickets (Role Based) $ticketQuery = Ticket::query()->whereIn('status', ['open', 'answered']); - if (!$user->isAdmin()) { + if (!$user->isAdminOrOwner()) { $ticketQuery->where('user_id', $user->id); } $activeTickets = $ticketQuery->count(); // Previous Tickets (Role Based) $prevTicketQuery = Ticket::query()->whereIn('status', ['open', 'answered'])->where('created_at', '<', $currentMonth); - if (!$user->isAdmin()) { + if (!$user->isAdminOrOwner()) { $prevTicketQuery->where('user_id', $user->id); } $prevActiveTickets = $prevTicketQuery->count(); @@ -76,7 +76,7 @@ class DashboardController extends Controller ]; // Admin only stats - if ($user->isAdmin()) { + if ($user->isAdminOrOwner()) { $totalUsers = User::count(); $prevUsers = User::where('created_at', '<', $currentMonth)->count(); @@ -108,7 +108,7 @@ class DashboardController extends Controller ->latest() ->take(10); - if (!$user->isAdmin()) { + if (!$user->isAdminOrOwner()) { $activityLogQuery->where('user_id', $user->id); } @@ -128,7 +128,7 @@ class DashboardController extends Controller for ($i = 6; $i >= 0; $i--) { $date = now()->subDays($i)->format('Y-m-d'); $countQuery = Certificate::whereDate('created_at', $date); - if (!$user->isAdmin()) { + if (!$user->isAdminOrOwner()) { $countQuery->where('user_id', $user->id); } diff --git a/app/Http/Controllers/Api/InquiryController.php b/app/Http/Controllers/Api/InquiryController.php index a4da1c7..a0ccf7b 100644 --- a/app/Http/Controllers/Api/InquiryController.php +++ b/app/Http/Controllers/Api/InquiryController.php @@ -34,8 +34,8 @@ class InquiryController extends Controller $inquiry = Inquiry::create($request->all()); try { - // Notify all admins - $admins = User::where('role', 'admin')->get(); + // Notify all admins and owners + $admins = User::whereIn('role', [User::ROLE_ADMIN, User::ROLE_OWNER])->get(); Notification::send($admins, new NewInquiryNotification($inquiry)); } catch (\Exception $e) { // Log the error but fail silently to the user, as the inquiry was saved. diff --git a/app/Http/Controllers/Api/RootCaApiController.php b/app/Http/Controllers/Api/RootCaApiController.php index d68b658..ef787c6 100644 --- a/app/Http/Controllers/Api/RootCaApiController.php +++ b/app/Http/Controllers/Api/RootCaApiController.php @@ -18,7 +18,7 @@ class RootCaApiController extends Controller public function index() { - $this->authorizeAdmin(); + $this->authorizeAdminOrOwner(); $certificates = CaCertificate::all()->map(function($cert) { $cert->status = $cert->valid_to->isFuture() ? 'valid' : 'expired'; @@ -33,7 +33,7 @@ class RootCaApiController extends Controller public function renew(Request $request, CaCertificate $certificate) { - $this->authorizeAdmin(); + $this->authorizeAdminOrOwner(); $days = (int) $request->input('days', 3650); @@ -60,10 +60,10 @@ class RootCaApiController extends Controller } } - protected function authorizeAdmin() + protected function authorizeAdminOrOwner() { - if (auth()->user()->role !== 'admin') { - abort(403, 'Unauthorized action.'); + if (!auth()->user()->isAdminOrOwner()) { + abort(403, 'Unauthorized action. Admin/Owner access required.'); } } } diff --git a/app/Http/Controllers/Api/TicketController.php b/app/Http/Controllers/Api/TicketController.php index 00502a2..d474d43 100644 --- a/app/Http/Controllers/Api/TicketController.php +++ b/app/Http/Controllers/Api/TicketController.php @@ -28,7 +28,7 @@ class TicketController extends Controller $query = Ticket::with(['user:id,first_name,last_name,email,avatar', 'replies.user:id,first_name,last_name,avatar', 'replies.attachments']); // Only show all tickets if user is admin AND explicitly asks for all - if ($user->isAdmin() && $request->has('all')) { + if ($user->isAdminOrOwner() && $request->has('all')) { // No additional where clause needed } else { // Everyone else (including admins in personal view) only sees their own @@ -96,7 +96,7 @@ class TicketController extends Controller // Notify Admins try { - $admins = User::where('role', 'admin') + $admins = User::whereIn('role', ['admin', 'owner']) ->where('id', '!=', $user->id) ->get(); if ($admins->isNotEmpty()) { @@ -126,7 +126,7 @@ class TicketController extends Controller $user = $request->user(); $ticket = Ticket::with(['user:id,first_name,last_name,email,avatar', 'replies.user:id,first_name,last_name,avatar', 'replies.attachments'])->findOrFail($id); - if (!$user->isAdmin() && $ticket->user_id !== $user->id) { + if (!$user->isAdminOrOwner() && $ticket->user_id !== $user->id) { return response()->json(['message' => 'Unauthorized'], 403); } @@ -141,7 +141,7 @@ class TicketController extends Controller $user = $request->user(); $ticket = Ticket::findOrFail($id); - if (!$user->isAdmin() && $ticket->user_id !== $user->id) { + if (!$user->isAdminOrOwner() && $ticket->user_id !== $user->id) { return response()->json(['message' => 'Unauthorized'], 403); } @@ -184,7 +184,7 @@ class TicketController extends Controller // Update ticket status & Notify try { - if ($user->isAdmin()) { + if ($user->isAdminOrOwner()) { $ticket->update(['status' => 'answered']); // Notify Customer $ticketUser = $ticket->user; @@ -192,19 +192,19 @@ class TicketController extends Controller $ticketUser->notify(new TicketReplyNotification($ticket, $reply, true)); } - // Also notify OTHER admins - $otherAdmins = User::where('role', 'admin') + // Also notify OTHER admins/owners + $otherStaff = User::whereIn('role', ['admin', 'owner']) ->where('id', '!=', $user->id) ->get(); - if ($otherAdmins->isNotEmpty()) { - Notification::send($otherAdmins, new TicketReplyNotification($ticket, $reply, true)); + if ($otherStaff->isNotEmpty()) { + Notification::send($otherStaff, new TicketReplyNotification($ticket, $reply, true)); } } else { $ticket->update(['status' => 'open']); - // Notify All Admins - $admins = User::where('role', 'admin')->get(); - if ($admins->isNotEmpty()) { - Notification::send($admins, new TicketReplyNotification($ticket, $reply, false)); + // Notify All Staff (Admins & Owners) + $staff = User::whereIn('role', ['admin', 'owner'])->get(); + if ($staff->isNotEmpty()) { + Notification::send($staff, new TicketReplyNotification($ticket, $reply, false)); } } } catch (\Throwable $e) { @@ -225,7 +225,7 @@ class TicketController extends Controller $user = $request->user(); $ticket = Ticket::findOrFail($id); - if (!$user->isAdmin() && $ticket->user_id !== $user->id) { + if (!$user->isAdminOrOwner() && $ticket->user_id !== $user->id) { return response()->json(['message' => 'Unauthorized'], 403); } diff --git a/app/Http/Middleware/AdminMiddleware.php b/app/Http/Middleware/AdminMiddleware.php index fe35337..4d130ef 100644 --- a/app/Http/Middleware/AdminMiddleware.php +++ b/app/Http/Middleware/AdminMiddleware.php @@ -16,7 +16,10 @@ class AdminMiddleware public function handle(Request $request, Closure $next): Response { if (!$request->user() || !$request->user()->isAdminOrOwner()) { - return response()->json(['message' => 'Unauthorized. Admin access required.'], 403); + $role = $request->user() ? $request->user()->role : 'guest'; + return response()->json([ + 'message' => "Unauthorized. Admin access required. (Current role: {$role})" + ], 403); } return $next($request); diff --git a/app/Models/User.php b/app/Models/User.php index b77d59c..fcd9cb4 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -103,7 +103,7 @@ class User extends Authenticatable implements MustVerifyEmail */ public function isOwner(): bool { - return $this->role === self::ROLE_OWNER; + return strtolower($this->role) === self::ROLE_OWNER; } /** @@ -111,7 +111,7 @@ class User extends Authenticatable implements MustVerifyEmail */ public function isAdmin(): bool { - return $this->role === self::ROLE_ADMIN; + return strtolower($this->role) === self::ROLE_ADMIN; } /** @@ -119,7 +119,8 @@ class User extends Authenticatable implements MustVerifyEmail */ public function isAdminOrOwner(): bool { - return in_array($this->role, [self::ROLE_OWNER, self::ROLE_ADMIN]); + $role = strtolower($this->role); + return in_array($role, [self::ROLE_OWNER, self::ROLE_ADMIN]); } /**