Consolidate settings into 8 hubs and fix security vulnerabilities
Settings Consolidation (37+ pages to 8 hubs): - Asset Type Hub: Unified type management with plugin descriptors - Model Catalog Hub: Vendors, types, models, operating systems - Asset Configuration Hub: Statuses, relationships, fields, identifiers - Security Hub: Authentication, tokens, users, audit - Site Configuration Hub: Site settings, floor map, branding, imports - Integrations Hub: ServiceNow, Zabbix, Dell warranty - Locations Hub: Locations, business units, employees - Network Infrastructure Hub: VLANs, subnets Plugin Descriptor Pattern: - Add get_asset_type_descriptor hook to BasePlugin - Implement descriptors in 6 plugins (printers, computers, machines, network, measuringtools, locations) - Add /api/pluginui/asset-type-descriptors and core-type-descriptors endpoints - Generic SubtypesTab component renders CRUD UI from descriptor schema Security Fixes: - Fix stored XSS via javascript: URIs in Models and Support Teams - Add URL scheme validation (allow only http/https) in create/update endpoints - Fix plugin contract violations in endpoints plugin (use shopdb.api imports) - Add missing requiresAdmin guard to printer model supplies route - Add user-facing error messages to API token load failures Integration Improvements: - Add persistent tab navigation to ServiceNow, Zabbix, and Dell Warranty settings - Standardize integration settings UI across all three pages - Fix tab visibility when navigating between integrations Tested with 94-agent orchestrated review for ADR compliance and security.
This commit is contained in:
@@ -26,6 +26,12 @@ export default [
|
||||
component: () => import('./views/ZabbixSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/integrations/zabbix',
|
||||
name: 'integrations-zabbix',
|
||||
component: () => import('./views/ZabbixSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/printer-alerts',
|
||||
name: 'printer-alerts',
|
||||
@@ -61,7 +67,7 @@ export default [
|
||||
path: 'settings/modelsupplies',
|
||||
name: 'model-supplies',
|
||||
component: () => import('./views/ModelSuppliesList.vue'),
|
||||
meta: { requiresAuth: true, plugin: 'printers' }
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/printerdrivers',
|
||||
|
||||
@@ -1,7 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="page-header">
|
||||
<h2>Zabbix Supplies</h2>
|
||||
<h2>Integrations</h2>
|
||||
<p class="header-description">Configure external service connections and APIs</p>
|
||||
</div>
|
||||
|
||||
<div class="integration-tabs">
|
||||
<router-link
|
||||
:to="{ name: 'servicenow-settings' }"
|
||||
class="integration-tab"
|
||||
:class="{ active: $route.name === 'servicenow-settings' }"
|
||||
>
|
||||
ServiceNow
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'zabbix-settings' }"
|
||||
class="integration-tab"
|
||||
:class="{ active: $route.name === 'zabbix-settings' }"
|
||||
>
|
||||
Zabbix Supplies
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'dell-warranty-settings' }"
|
||||
class="integration-tab"
|
||||
:class="{ active: $route.name === 'dell-warranty-settings' }"
|
||||
>
|
||||
Dell Warranty
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="section-card">
|
||||
@@ -88,3 +113,39 @@ const zabbixMessage = computed(() => {
|
||||
|
||||
onMounted(loadSettings)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.header-description {
|
||||
margin: 0.5rem 0 0;
|
||||
color: var(--text-light);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.integration-tabs {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
background: var(--bg-secondary);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.integration-tab {
|
||||
padding: 0.75rem 1.5rem;
|
||||
text-decoration: none;
|
||||
color: var(--text-light);
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: all 0.15s;
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.integration-tab:hover {
|
||||
color: var(--text);
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.integration-tab.active {
|
||||
color: var(--primary);
|
||||
border-bottom-color: var(--primary);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -678,3 +678,16 @@ class PrintersPlugin(BasePlugin):
|
||||
return None
|
||||
# _computer_by_hostname returns the (Computer, Asset) pair.
|
||||
return row[1].assetid
|
||||
|
||||
def get_asset_type_descriptor(self):
|
||||
"""Return descriptor for printer types management in Asset Type Hub."""
|
||||
return {
|
||||
'assettype': 'printer',
|
||||
'subtype_endpoint': '/printers/types',
|
||||
'subtype_id_field': 'printertypeid',
|
||||
'subtype_label_field': 'printertype',
|
||||
'subtype_description_field': 'description',
|
||||
'subtype_color_field': 'color',
|
||||
'optional_tabs': [],
|
||||
'edit_permission': 'printers.manage',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user