feat: initialisation complète du CORE ProxmoxPanel

Backend Go 1.23+ :
- API REST + WebSocket (chi, gorilla/websocket)
- Authentification PAM via SSH + JWT RS256
- Chiffrement AES-256-GCM pour secrets SQLite
- Pool SSH, client Proxmox REST, hub WebSocket pub/sub
- Système de modules compilés à initialisation conditionnelle
- Audit log, migrations SQLite versionnées

Frontend Vue 3 + Vite + TypeScript :
- Thème Neumorphism sombre/clair (CSS custom properties)
- Wizard d'installation, Dashboard drag-drop, Terminal xterm.js
- Toutes les vues CORE + stubs modules optionnels
- i18n EN/FR (vue-i18n v11)

Infrastructure :
- Docker multi-stage (Go → alpine, Node → nginx)
- docker-compose.yml, .gitattributes, LICENSE MIT, README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
enzo 2026-03-20 21:08:53 +01:00
commit 5dbcb1df07
66 changed files with 10370 additions and 0 deletions

View file

@ -0,0 +1,128 @@
// Configuration du routeur Vue — gère la navigation et la protection des routes.
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth.store'
const router = createRouter({
history: createWebHistory(),
routes: [
// Page d'installation (premier lancement)
{
path: '/install',
name: 'install',
component: () => import('@/views/Install.vue'),
meta: { public: true, hideLayout: true },
},
// Authentification
{
path: '/login',
name: 'login',
component: () => import('@/views/Login.vue'),
meta: { public: true, hideLayout: true },
},
// Application principale (protégée)
{
path: '/',
component: () => import('@/components/Layout.vue'),
meta: { requiresAuth: true },
children: [
{
path: '',
name: 'dashboard',
component: () => import('@/views/Dashboard.vue'),
},
{
path: 'proxmox',
name: 'proxmox',
component: () => import('@/views/Proxmox.vue'),
},
{
path: 'updates',
name: 'updates',
component: () => import('@/views/Updates.vue'),
},
{
path: 'files',
name: 'files',
component: () => import('@/views/Files.vue'),
meta: { module: 'files' },
},
{
path: 'terminal',
name: 'terminal',
component: () => import('@/views/Terminal.vue'),
meta: { module: 'terminal' },
},
{
path: 'logs',
name: 'logs',
component: () => import('@/views/Logs.vue'),
meta: { module: 'logs' },
},
{
path: 'services',
name: 'services',
component: () => import('@/views/Services.vue'),
meta: { module: 'services' },
},
{
path: 'settings',
name: 'settings',
component: () => import('@/views/Settings.vue'),
},
{
path: 'modules',
name: 'modules',
component: () => import('@/views/Modules.vue'),
meta: { requiresAdmin: true },
},
],
},
// Redirection 404
{
path: '/:pathMatch(.*)*',
redirect: '/',
},
],
})
// Guard de navigation : vérification authentification et installation
router.beforeEach(async (to) => {
const authStore = useAuthStore()
// Vérifier si l'application est installée (appel API au premier chargement)
if (!authStore.installChecked) {
await authStore.checkInstallation()
}
// Rediriger vers l'installation si pas encore configuré
if (!authStore.isInstalled && to.name !== 'install') {
return { name: 'install' }
}
// Si installé et route d'install → rediriger vers le dashboard
if (authStore.isInstalled && to.name === 'install') {
return { name: 'dashboard' }
}
// Routes publiques — passer directement
if (to.meta.public) return true
// Routes protégées — vérifier l'authentification
if (to.meta.requiresAuth || to.matched.some(r => r.meta.requiresAuth)) {
if (!authStore.isAuthenticated) {
return { name: 'login', query: { redirect: to.fullPath } }
}
}
// Routes admin uniquement
if (to.meta.requiresAdmin && !authStore.user?.is_admin) {
return { name: 'dashboard' }
}
return true
})
export default router