Files
Classeo/frontend/vite.config.ts
Mathias STRASSER b9d9f48305 feat: Connexion utilisateur avec sécurité renforcée
Implémente la Story 1.4 du système d'authentification avec plusieurs
couches de protection contre les attaques par force brute.

Sécurité backend :
- Authentification JWT avec access token (15min) + refresh token (7j)
- Rotation automatique des refresh tokens avec détection de replay
- Rate limiting progressif par IP (délai Fibonacci après échecs)
- Intégration Cloudflare Turnstile CAPTCHA après 5 tentatives
- Alerte email à l'utilisateur après blocage temporaire
- Isolation multi-tenant (un utilisateur ne peut se connecter que sur
  son établissement)

Frontend :
- Page de connexion avec feedback visuel des délais et erreurs
- Composant TurnstileCaptcha réutilisable
- Gestion d'état auth avec stockage sécurisé des tokens
- Tests E2E Playwright pour login, tenant isolation, et activation

Infrastructure :
- Configuration Symfony Security avec json_login + jwt
- Cache pools séparés (filesystem en test, Redis en prod)
- NullLoginRateLimiter pour environnement de test (évite blocage CI)
- Génération des clés JWT en CI après démarrage du backend
2026-02-01 14:43:12 +01:00

84 lines
1.8 KiB
TypeScript

import { sveltekit } from '@sveltejs/kit/vite';
import { SvelteKitPWA } from '@vite-pwa/sveltekit';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [
sveltekit(),
SvelteKitPWA({
srcDir: 'src',
mode: 'development',
strategies: 'generateSW',
scope: '/',
base: '/',
manifest: {
name: 'Classeo',
short_name: 'Classeo',
description: 'Application de gestion scolaire',
theme_color: '#3b82f6',
background_color: '#ffffff',
display: 'standalone',
start_url: '/',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable'
}
]
},
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,webp,woff,woff2}']
},
devOptions: {
enabled: false,
type: 'module',
navigateFallback: '/'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}) as any
],
test: {
include: ['src/**/*.{test,spec}.{js,ts}', 'tests/**/*.{test,spec}.{js,ts}'],
globals: true,
environment: 'jsdom',
server: {
deps: {
inline: [/svelte/]
}
},
alias: {
$lib: '/src/lib',
$app: '/node_modules/@sveltejs/kit/src/runtime/app'
}
},
resolve: {
conditions: ['browser']
},
server: {
host: '0.0.0.0',
port: 5173,
strictPort: true,
// Autorise les sous-domaines pour le multi-tenant (dev + prod)
allowedHosts: ['.classeo.local', '.classeo.fr', 'localhost']
},
preview: {
host: '0.0.0.0',
port: 4173,
strictPort: true,
// Autorise les sous-domaines pour les tests E2E multi-tenant
allowedHosts: ['.classeo.local', '.classeo.fr', 'localhost']
}
});