mirror of
https://github.com/dyzulk/trustlab-api.git
synced 2026-01-26 05:15:35 +07:00
fix: allow owner role to access all admin api endpoints and see stats
This commit is contained in:
@@ -40,14 +40,14 @@ class DashboardController extends Controller
|
|||||||
|
|
||||||
// Tickets (Role Based)
|
// Tickets (Role Based)
|
||||||
$ticketQuery = Ticket::query()->whereIn('status', ['open', 'answered']);
|
$ticketQuery = Ticket::query()->whereIn('status', ['open', 'answered']);
|
||||||
if (!$user->isAdmin()) {
|
if (!$user->isAdminOrOwner()) {
|
||||||
$ticketQuery->where('user_id', $user->id);
|
$ticketQuery->where('user_id', $user->id);
|
||||||
}
|
}
|
||||||
$activeTickets = $ticketQuery->count();
|
$activeTickets = $ticketQuery->count();
|
||||||
|
|
||||||
// Previous Tickets (Role Based)
|
// Previous Tickets (Role Based)
|
||||||
$prevTicketQuery = Ticket::query()->whereIn('status', ['open', 'answered'])->where('created_at', '<', $currentMonth);
|
$prevTicketQuery = Ticket::query()->whereIn('status', ['open', 'answered'])->where('created_at', '<', $currentMonth);
|
||||||
if (!$user->isAdmin()) {
|
if (!$user->isAdminOrOwner()) {
|
||||||
$prevTicketQuery->where('user_id', $user->id);
|
$prevTicketQuery->where('user_id', $user->id);
|
||||||
}
|
}
|
||||||
$prevActiveTickets = $prevTicketQuery->count();
|
$prevActiveTickets = $prevTicketQuery->count();
|
||||||
@@ -76,7 +76,7 @@ class DashboardController extends Controller
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Admin only stats
|
// Admin only stats
|
||||||
if ($user->isAdmin()) {
|
if ($user->isAdminOrOwner()) {
|
||||||
$totalUsers = User::count();
|
$totalUsers = User::count();
|
||||||
$prevUsers = User::where('created_at', '<', $currentMonth)->count();
|
$prevUsers = User::where('created_at', '<', $currentMonth)->count();
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class DashboardController extends Controller
|
|||||||
->latest()
|
->latest()
|
||||||
->take(10);
|
->take(10);
|
||||||
|
|
||||||
if (!$user->isAdmin()) {
|
if (!$user->isAdminOrOwner()) {
|
||||||
$activityLogQuery->where('user_id', $user->id);
|
$activityLogQuery->where('user_id', $user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ class DashboardController extends Controller
|
|||||||
for ($i = 6; $i >= 0; $i--) {
|
for ($i = 6; $i >= 0; $i--) {
|
||||||
$date = now()->subDays($i)->format('Y-m-d');
|
$date = now()->subDays($i)->format('Y-m-d');
|
||||||
$countQuery = Certificate::whereDate('created_at', $date);
|
$countQuery = Certificate::whereDate('created_at', $date);
|
||||||
if (!$user->isAdmin()) {
|
if (!$user->isAdminOrOwner()) {
|
||||||
$countQuery->where('user_id', $user->id);
|
$countQuery->where('user_id', $user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ class InquiryController extends Controller
|
|||||||
$inquiry = Inquiry::create($request->all());
|
$inquiry = Inquiry::create($request->all());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Notify all admins
|
// Notify all admins and owners
|
||||||
$admins = User::where('role', 'admin')->get();
|
$admins = User::whereIn('role', [User::ROLE_ADMIN, User::ROLE_OWNER])->get();
|
||||||
Notification::send($admins, new NewInquiryNotification($inquiry));
|
Notification::send($admins, new NewInquiryNotification($inquiry));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// Log the error but fail silently to the user, as the inquiry was saved.
|
// Log the error but fail silently to the user, as the inquiry was saved.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class RootCaApiController extends Controller
|
|||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->authorizeAdmin();
|
$this->authorizeAdminOrOwner();
|
||||||
|
|
||||||
$certificates = CaCertificate::all()->map(function($cert) {
|
$certificates = CaCertificate::all()->map(function($cert) {
|
||||||
$cert->status = $cert->valid_to->isFuture() ? 'valid' : 'expired';
|
$cert->status = $cert->valid_to->isFuture() ? 'valid' : 'expired';
|
||||||
@@ -33,7 +33,7 @@ class RootCaApiController extends Controller
|
|||||||
|
|
||||||
public function renew(Request $request, CaCertificate $certificate)
|
public function renew(Request $request, CaCertificate $certificate)
|
||||||
{
|
{
|
||||||
$this->authorizeAdmin();
|
$this->authorizeAdminOrOwner();
|
||||||
|
|
||||||
$days = (int) $request->input('days', 3650);
|
$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') {
|
if (!auth()->user()->isAdminOrOwner()) {
|
||||||
abort(403, 'Unauthorized action.');
|
abort(403, 'Unauthorized action. Admin/Owner access required.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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']);
|
$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
|
// 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
|
// No additional where clause needed
|
||||||
} else {
|
} else {
|
||||||
// Everyone else (including admins in personal view) only sees their own
|
// Everyone else (including admins in personal view) only sees their own
|
||||||
@@ -96,7 +96,7 @@ class TicketController extends Controller
|
|||||||
|
|
||||||
// Notify Admins
|
// Notify Admins
|
||||||
try {
|
try {
|
||||||
$admins = User::where('role', 'admin')
|
$admins = User::whereIn('role', ['admin', 'owner'])
|
||||||
->where('id', '!=', $user->id)
|
->where('id', '!=', $user->id)
|
||||||
->get();
|
->get();
|
||||||
if ($admins->isNotEmpty()) {
|
if ($admins->isNotEmpty()) {
|
||||||
@@ -126,7 +126,7 @@ class TicketController extends Controller
|
|||||||
$user = $request->user();
|
$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);
|
$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);
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class TicketController extends Controller
|
|||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$ticket = Ticket::findOrFail($id);
|
$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);
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ class TicketController extends Controller
|
|||||||
|
|
||||||
// Update ticket status & Notify
|
// Update ticket status & Notify
|
||||||
try {
|
try {
|
||||||
if ($user->isAdmin()) {
|
if ($user->isAdminOrOwner()) {
|
||||||
$ticket->update(['status' => 'answered']);
|
$ticket->update(['status' => 'answered']);
|
||||||
// Notify Customer
|
// Notify Customer
|
||||||
$ticketUser = $ticket->user;
|
$ticketUser = $ticket->user;
|
||||||
@@ -192,19 +192,19 @@ class TicketController extends Controller
|
|||||||
$ticketUser->notify(new TicketReplyNotification($ticket, $reply, true));
|
$ticketUser->notify(new TicketReplyNotification($ticket, $reply, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also notify OTHER admins
|
// Also notify OTHER admins/owners
|
||||||
$otherAdmins = User::where('role', 'admin')
|
$otherStaff = User::whereIn('role', ['admin', 'owner'])
|
||||||
->where('id', '!=', $user->id)
|
->where('id', '!=', $user->id)
|
||||||
->get();
|
->get();
|
||||||
if ($otherAdmins->isNotEmpty()) {
|
if ($otherStaff->isNotEmpty()) {
|
||||||
Notification::send($otherAdmins, new TicketReplyNotification($ticket, $reply, true));
|
Notification::send($otherStaff, new TicketReplyNotification($ticket, $reply, true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$ticket->update(['status' => 'open']);
|
$ticket->update(['status' => 'open']);
|
||||||
// Notify All Admins
|
// Notify All Staff (Admins & Owners)
|
||||||
$admins = User::where('role', 'admin')->get();
|
$staff = User::whereIn('role', ['admin', 'owner'])->get();
|
||||||
if ($admins->isNotEmpty()) {
|
if ($staff->isNotEmpty()) {
|
||||||
Notification::send($admins, new TicketReplyNotification($ticket, $reply, false));
|
Notification::send($staff, new TicketReplyNotification($ticket, $reply, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
@@ -225,7 +225,7 @@ class TicketController extends Controller
|
|||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$ticket = Ticket::findOrFail($id);
|
$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);
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ class AdminMiddleware
|
|||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if (!$request->user() || !$request->user()->isAdminOrOwner()) {
|
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);
|
return $next($request);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
*/
|
*/
|
||||||
public function isOwner(): bool
|
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
|
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
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user