diff --git a/src/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeStudio.vue b/src/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeStudio.vue index 1a14b660..eb09dd67 100644 --- a/src/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeStudio.vue +++ b/src/views/dashboards/departmentDashboard/modules/self-serve/DepartmentSelfServeStudio.vue @@ -483,6 +483,9 @@ const graphStats = computed(() => { }); const permissions = computed(() => graphPayload.value?.permissions || {}); +const canEditVehicleTypeProduct = computed(() => + Boolean(permissions.value.can_edit) && SessionUser.canAccessSuperUser() +); const destructiveGatewayActions = new Set(["rotate_credentials", "uninstall"]); const canManageGateways = computed(() => Boolean(permissions.value.can_manage_gateways)); const canRunGatewayDestructiveActions = computed(() => @@ -4687,6 +4690,11 @@ const deleteSelected = async () => { }; const saveVehicleTypeProduct = async () => { + if (!canEditVehicleTypeProduct.value) { + toast.error("Only superusers can update vehicle type product catalog fields."); + return; + } + const id = parseNullableInt( inspectorForm.value.id || selectedRaw.value.product || selectedRaw.value.product_id || selectedRaw.value.id ); @@ -8054,7 +8062,7 @@ onBeforeUnmount(() => { /> Wash product - diff --git a/tests/unit/self-serve-studio-managed-inspector.spec.js b/tests/unit/self-serve-studio-managed-inspector.spec.js index 28d07644..fd196256 100644 --- a/tests/unit/self-serve-studio-managed-inspector.spec.js +++ b/tests/unit/self-serve-studio-managed-inspector.spec.js @@ -35,14 +35,27 @@ describe("self-serve studio managed inspector", () => { expect(source).toContain("const normalizeVehicleTypeForm = (raw = {}) => {"); expect(source).toContain("const saveVehicleTypeProduct = async () => {"); + expect(source).toContain("if (!canEditVehicleTypeProduct.value) {"); expect(source).toContain('await requestPut("/products", {'); expect(source).toContain('data-testid="studio-vehicle-type-form"'); expect(source).toContain('data-testid="studio-vehicle-type-name"'); + expect(source).toContain(':disabled="!canEditVehicleTypeProduct"'); expect(source).toContain("const normalizeMachineTypeForm = (raw = {}) => {"); expect(source).toContain("const saveMachineType = async () => {"); expect(source).toContain('await requestPut("/department/selfserve/machine-types", {'); }); + it("requires superuser access before saving vehicle type product catalog fields", () => { + const source = studioSource(); + + expect(source).toContain("const canEditVehicleTypeProduct = computed(() =>"); + expect(source).toContain("Boolean(permissions.value.can_edit) && SessionUser.canAccessSuperUser()"); + expect(source.indexOf("if (!canEditVehicleTypeProduct.value) {")).toBeLessThan( + source.indexOf('await requestPut("/products", {') + ); + expect(source).toContain("Only superusers can update vehicle type product catalog fields."); + }); + it("manages virtual hardware from selected gateway and relay binding nodes", () => { const source = studioSource();