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:
118
frontend/src/views/settings/SecurityHub.vue
Normal file
118
frontend/src/views/settings/SecurityHub.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="security-hub">
|
||||
<div class="hub-header">
|
||||
<h2>Access & Security</h2>
|
||||
<p class="description">Manage authentication, API tokens, users, roles, and audit logs</p>
|
||||
</div>
|
||||
|
||||
<div class="tabs">
|
||||
<router-link
|
||||
:to="{ name: 'security-authentication' }"
|
||||
class="tab"
|
||||
:class="{ active: $route.name === 'security-authentication' }"
|
||||
>
|
||||
Authentication
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'security-tokens' }"
|
||||
class="tab"
|
||||
:class="{ active: $route.name === 'security-tokens' }"
|
||||
>
|
||||
API Tokens
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'security-users' }"
|
||||
class="tab"
|
||||
:class="{ active: $route.name === 'security-users' }"
|
||||
>
|
||||
Users & Roles
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'security-audit' }"
|
||||
class="tab"
|
||||
:class="{ active: $route.name === 'security-audit' }"
|
||||
>
|
||||
Audit Settings
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'security-auditlogs' }"
|
||||
class="tab"
|
||||
:class="{ active: $route.name === 'security-auditlogs' }"
|
||||
>
|
||||
Audit Logs
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="tab-content">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
if (route.name === 'security') {
|
||||
router.replace({ name: 'security-authentication' })
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.security-hub {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hub-header {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.hub-header h2 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0;
|
||||
color: var(--text-light);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
background: var(--bg-secondary);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
color: var(--text);
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: var(--primary);
|
||||
border-bottom-color: var(--primary);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
/* Content styled by child components */
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user