mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 20:40:55 +00:00
fix(auth): list every route key on the class-level guard
Nest runs class and method guards together, so a class gate naming only the view key silently required view AND action. Staff granted just an action were denied before their key was checked. Each class gate now names every key its routes use, and FleetView accepts an array so the fleet controllers keep their coarse fallback. Drops the one-off grant mapping SQL with it: already applied to dev, and this fix removes the companion-view rule that was its recurring part.
This commit is contained in:
@@ -20,7 +20,12 @@ import { FilterInvoiceDto } from "./dto/filter-invoice.dto";
|
||||
|
||||
@ApiTags("billing")
|
||||
@Controller("billing")
|
||||
@BookingStaff(FREIGHT_PERMS.invoices.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.invoices.view,
|
||||
FREIGHT_PERMS.invoices.export,
|
||||
])
|
||||
@ApiBearerAuth()
|
||||
export class BillingController {
|
||||
constructor(
|
||||
|
||||
@@ -20,7 +20,14 @@ import { CargoesService } from './cargoes.service';
|
||||
|
||||
@ApiTags('cargoes')
|
||||
@Controller('cargoes')
|
||||
@FleetView(FREIGHT_PERMS.cargoes.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.cargoes.view,
|
||||
FREIGHT_PERMS.cargoes.create,
|
||||
FREIGHT_PERMS.cargoes.update,
|
||||
FREIGHT_PERMS.cargoes.delete,
|
||||
])
|
||||
export class CargoesController {
|
||||
constructor(private readonly cargoesService: CargoesService) {}
|
||||
|
||||
|
||||
@@ -11,7 +11,12 @@ import { ComplianceType } from './entities/compliance-record.entity';
|
||||
|
||||
@ApiTags('Vehicle Compliance')
|
||||
@Controller('compliance')
|
||||
@BookingStaff(FREIGHT_PERMS.compliance.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.compliance.view,
|
||||
FREIGHT_PERMS.compliance.manage,
|
||||
])
|
||||
export class ComplianceController {
|
||||
constructor(private readonly complianceService: ComplianceService) {}
|
||||
|
||||
|
||||
@@ -17,7 +17,12 @@ import { FilterConsignmentDto } from "./dto/filter-consignment.dto";
|
||||
|
||||
@ApiTags("consignments")
|
||||
@Controller("consignments")
|
||||
@FleetView(FREIGHT_PERMS.consignments.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.consignments.view,
|
||||
FREIGHT_PERMS.consignments.create,
|
||||
])
|
||||
export class ConsignmentsController {
|
||||
constructor(private readonly consignmentsService: ConsignmentsService) {}
|
||||
|
||||
|
||||
@@ -19,7 +19,14 @@ import { ContainersService } from './containers.service';
|
||||
|
||||
@ApiTags('containers')
|
||||
@Controller('containers')
|
||||
@FleetView(FREIGHT_PERMS.containers.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.containers.view,
|
||||
FREIGHT_PERMS.containers.create,
|
||||
FREIGHT_PERMS.containers.update,
|
||||
FREIGHT_PERMS.containers.delete,
|
||||
])
|
||||
export class ContainersController {
|
||||
constructor(private readonly containersService: ContainersService) {}
|
||||
|
||||
|
||||
@@ -24,7 +24,14 @@ import { FleetHistoryService } from '../fleet-history/fleet-history.service';
|
||||
@ApiTags('drivers')
|
||||
@ApiBearerAuth()
|
||||
@Controller('drivers')
|
||||
@BookingStaff(FREIGHT_PERMS.drivers.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.drivers.view,
|
||||
FREIGHT_PERMS.drivers.create,
|
||||
FREIGHT_PERMS.drivers.update,
|
||||
FREIGHT_PERMS.drivers.delete,
|
||||
])
|
||||
export class DriversController {
|
||||
constructor(
|
||||
private readonly driversService: DriversService,
|
||||
|
||||
@@ -10,7 +10,12 @@ import { FacilitiesService } from './facilities.service';
|
||||
|
||||
@ApiTags('Facilities')
|
||||
@Controller('facilities')
|
||||
@BookingStaff(FREIGHT_PERMS.facilities.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.facilities.view,
|
||||
FREIGHT_PERMS.facilities.manage,
|
||||
])
|
||||
export class FacilitiesController {
|
||||
constructor(private readonly facilitiesService: FacilitiesService) {}
|
||||
|
||||
|
||||
@@ -19,7 +19,12 @@ import { RegisterDeviceDto, UpdateDeviceDto } from './dto/gps-device.dto';
|
||||
@ApiTags('gps-tracking')
|
||||
@ApiBearerAuth()
|
||||
@Controller('gps')
|
||||
@BookingStaff(FREIGHT_PERMS.tracking.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.tracking.view,
|
||||
FREIGHT_PERMS.tracking.manage,
|
||||
])
|
||||
export class GpsTrackingController {
|
||||
constructor(private readonly gps: GpsTrackingService) {}
|
||||
|
||||
|
||||
@@ -22,7 +22,14 @@ import { IncidentStatus, IncidentType } from './entities/incident.entity';
|
||||
// No incidents-specific permission exists in the registry, so this reuses the
|
||||
// (real) drivers.* fleet-road keys — incident records are driver-safety data
|
||||
// (driver stats / incident history). TODO: add a dedicated incidents:* key.
|
||||
@BookingStaff(FREIGHT_PERMS.drivers.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.drivers.view,
|
||||
FREIGHT_PERMS.drivers.create,
|
||||
FREIGHT_PERMS.drivers.update,
|
||||
FREIGHT_PERMS.drivers.delete,
|
||||
])
|
||||
export class IncidentsController {
|
||||
constructor(private readonly incidentsService: IncidentsService) {}
|
||||
|
||||
|
||||
@@ -15,7 +15,14 @@ import { InterchangeDocumentsService } from './interchange-documents.service';
|
||||
@ApiBearerAuth()
|
||||
@Controller('interchange-documents')
|
||||
// Class-level view guard; each write route adds its own manage permission below.
|
||||
@BookingStaff(FREIGHT_PERMS.interchangeDocuments.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.interchangeDocuments.view,
|
||||
FREIGHT_PERMS.interchangeDocuments.generate,
|
||||
FREIGHT_PERMS.interchangeDocuments.acknowledge,
|
||||
FREIGHT_PERMS.interchangeDocuments.dispute,
|
||||
])
|
||||
export class InterchangeDocumentsController {
|
||||
constructor(private readonly service: InterchangeDocumentsService) {}
|
||||
|
||||
|
||||
@@ -13,7 +13,14 @@ import {
|
||||
|
||||
@ApiTags('Procurement & Asset Lifecycle')
|
||||
@Controller('procurement')
|
||||
@BookingStaff(FREIGHT_PERMS.procurement.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.procurement.view,
|
||||
FREIGHT_PERMS.procurement.vendorManage,
|
||||
FREIGHT_PERMS.procurement.acquisitionManage,
|
||||
FREIGHT_PERMS.procurement.disposalManage,
|
||||
])
|
||||
export class ProcurementController {
|
||||
constructor(private readonly procurementService: ProcurementService) {}
|
||||
|
||||
|
||||
@@ -27,7 +27,15 @@ import { RoutesService } from './routes.service';
|
||||
@ApiTags('routes')
|
||||
@ApiBearerAuth()
|
||||
@Controller('routes')
|
||||
@FleetView(FREIGHT_PERMS.routes.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.routes.view,
|
||||
FREIGHT_PERMS.routes.create,
|
||||
FREIGHT_PERMS.routes.update,
|
||||
FREIGHT_PERMS.routes.hardDelete,
|
||||
FREIGHT_PERMS.routes.delete,
|
||||
])
|
||||
export class RoutesController {
|
||||
constructor(private readonly routesService: RoutesService) {}
|
||||
|
||||
|
||||
@@ -31,7 +31,15 @@ import { TrainBuilderService } from './train-builder.service';
|
||||
@ApiTags('train-builder')
|
||||
@ApiBearerAuth()
|
||||
@Controller('train-builder')
|
||||
@FleetView(FREIGHT_PERMS.trains.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.trains.view,
|
||||
FREIGHT_PERMS.trains.create,
|
||||
FREIGHT_PERMS.trains.update,
|
||||
FREIGHT_PERMS.trains.assignWagons,
|
||||
FREIGHT_PERMS.trains.delete,
|
||||
])
|
||||
export class TrainBuilderController {
|
||||
constructor(private readonly trainBuilderService: TrainBuilderService) {}
|
||||
|
||||
|
||||
@@ -19,7 +19,14 @@ import { TrainsService } from "./trains.service";
|
||||
|
||||
@ApiTags("trains")
|
||||
@Controller("trains")
|
||||
@FleetView(FREIGHT_PERMS.trains.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@FleetView([
|
||||
FREIGHT_PERMS.trains.view,
|
||||
FREIGHT_PERMS.trains.create,
|
||||
FREIGHT_PERMS.trains.update,
|
||||
FREIGHT_PERMS.trains.delete,
|
||||
])
|
||||
export class TrainsController {
|
||||
constructor(private readonly trainsService: TrainsService) {}
|
||||
|
||||
|
||||
@@ -20,7 +20,14 @@ import { FleetHistoryService } from '../fleet-history/fleet-history.service';
|
||||
@ApiTags('vehicles')
|
||||
@ApiBearerAuth()
|
||||
@Controller('vehicles')
|
||||
@BookingStaff(FREIGHT_PERMS.vehicles.view)
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.vehicles.view,
|
||||
FREIGHT_PERMS.vehicles.create,
|
||||
FREIGHT_PERMS.vehicles.update,
|
||||
FREIGHT_PERMS.vehicles.delete,
|
||||
])
|
||||
export class VehiclesController {
|
||||
constructor(
|
||||
private readonly vehiclesService: VehiclesService,
|
||||
|
||||
@@ -23,9 +23,13 @@ import { WarehouseInspectionService } from './warehouse-inspection.service';
|
||||
// Baseline read: inspection reports are opened from inventory screens too —
|
||||
// either view permission grants reads; writes stack their own per route.
|
||||
@Controller()
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.warehouseInspectionReports.view,
|
||||
FREIGHT_PERMS.warehouseInventory.view,
|
||||
FREIGHT_PERMS.warehouseInspectionReports.create,
|
||||
FREIGHT_PERMS.warehouseInspectionReports.update,
|
||||
])
|
||||
export class WarehouseInspectionController {
|
||||
constructor(private readonly inspectionService: WarehouseInspectionService) {}
|
||||
|
||||
@@ -12,7 +12,13 @@ import { WarehouseZonesService } from './warehouse-zones.service';
|
||||
// receive/move pickers) — either view permission grants reads; writes stack
|
||||
// their specific permission per route.
|
||||
@Controller('warehouse-zones')
|
||||
@BookingStaff([FREIGHT_PERMS.warehouseZones.view, FREIGHT_PERMS.warehouseInventory.view])
|
||||
// Class gate lists every key its routes use: Nest runs class AND method
|
||||
// guards, so a key missing here would deny before the route's own key runs.
|
||||
@BookingStaff([
|
||||
FREIGHT_PERMS.warehouseZones.view,
|
||||
FREIGHT_PERMS.warehouseInventory.view,
|
||||
FREIGHT_PERMS.warehouseZones.update,
|
||||
])
|
||||
export class WarehouseZonesController {
|
||||
constructor(private readonly zonesService: WarehouseZonesService) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user