feat: support HTTPS en mode production

- Ajout support HTTPS au serveur Express avec certificats auto-signés
- Variable d'environnement ENABLE_HTTPS pour activer/désactiver HTTPS
- start.sh active automatiquement HTTPS en mode production (pas --dev)
- Messages d'aide clarifiés avec URLs HTTPS et avertissement certificat
- WebSocket Audio Levels supporte wss:// en mode HTTPS

Mode dev : HTTPS sur port 5173 (Vite) + HTTP API sur 3000
Mode prod : HTTPS sur port 3000 (Express sert client + API)
This commit is contained in:
2026-05-27 15:36:52 +02:00
parent 244aadcf8b
commit 6b13981dad
2 changed files with 77 additions and 37 deletions
+46 -17
View File
@@ -2,6 +2,8 @@
import 'dotenv/config'; import 'dotenv/config';
import express from 'express'; import express from 'express';
import https from 'https';
import http from 'http';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import { readFileSync, existsSync } from 'fs'; import { readFileSync, existsSync } from 'fs';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
@@ -67,6 +69,7 @@ const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || 'secret';
const USE_LOCAL_LIVEKIT = process.env.USE_LOCAL_LIVEKIT === 'true'; const USE_LOCAL_LIVEKIT = process.env.USE_LOCAL_LIVEKIT === 'true';
const SERVER_PORT = parseInt(process.env.PORT || config.server.port, 10); const SERVER_PORT = parseInt(process.env.PORT || config.server.port, 10);
const SERVER_HOST = config.server.host; const SERVER_HOST = config.server.host;
const ENABLE_HTTPS = process.env.ENABLE_HTTPS === 'true';
// Configuration URL LiveKit // Configuration URL LiveKit
let LIVEKIT_URL = process.env.LIVEKIT_URL || config.server.livekit.url; let LIVEKIT_URL = process.env.LIVEKIT_URL || config.server.livekit.url;
@@ -181,18 +184,13 @@ app.use((req, res, next) => {
next(); next();
}); });
// Middleware redirection HTTP → HTTPS (développement uniquement) // Middleware redirection HTTP → HTTPS (si activé)
// En développement, redirige vers le serveur Vite HTTPS (5173)
// En production réelle, utiliser nginx/caddy pour HTTPS
app.use((req, res, next) => { app.use((req, res, next) => {
const clientDistPath = join(__dirname, '..', 'client', 'dist'); // Si HTTPS activé et requête en HTTP, rediriger
const isProd = existsSync(clientDistPath); if (ENABLE_HTTPS && req.protocol === 'http' && req.hostname !== 'localhost') {
const httpsUrl = `https://${req.hostname}:${SERVER_PORT}${req.url}`;
// Mode dev : rediriger HTTP → HTTPS (Vite) log('debug', `↪️ Redirection HTTPS: ${httpsUrl}`);
if (!isProd && req.protocol === 'http' && req.hostname !== 'localhost') { return res.redirect(301, httpsUrl);
const devHttpsUrl = `https://${req.hostname}:5173${req.url}`;
log('debug', `↪️ Redirection dev HTTPS: ${devHttpsUrl}`);
return res.redirect(301, devHttpsUrl);
} }
next(); next();
@@ -409,31 +407,62 @@ async function start() {
log('warn', '⚠️ Pour utiliser LiveKit local, définir USE_LOCAL_LIVEKIT=true dans .env'); log('warn', '⚠️ Pour utiliser LiveKit local, définir USE_LOCAL_LIVEKIT=true dans .env');
} }
// 2. Démarrer API REST // 2. Démarrer API REST (HTTP ou HTTPS selon config)
const server = app.listen(SERVER_PORT, SERVER_HOST, () => { let server;
if (ENABLE_HTTPS) {
// Charger certificats SSL (mêmes que Vite)
const certPath = join(__dirname, '..', 'client');
const httpsOptions = {
key: readFileSync(join(certPath, 'localhost+3-key.pem')),
cert: readFileSync(join(certPath, 'localhost+3.pem'))
};
server = https.createServer(httpsOptions, app);
server.listen(SERVER_PORT, SERVER_HOST, () => {
log('info', `✓ API REST démarrée sur https://${SERVER_HOST}:${SERVER_PORT}`);
log('info', '');
log('info', 'Serveur prêt !');
log('info', `Groupes configurés: ${config.groups.map(g => g.name).join(', ')}`);
log('info', '');
// Afficher URLs d'accès
if (networkIP && networkIP !== 'localhost') {
const prodUrl = `https://${networkIP}:${SERVER_PORT}`;
log('info', '📱 Accès réseau WiFi :');
log('info', '');
log('info', ` Prod : ${prodUrl}`);
log('info', '');
}
});
} else {
server = http.createServer(app);
server.listen(SERVER_PORT, SERVER_HOST, () => {
log('info', `✓ API REST démarrée sur http://${SERVER_HOST}:${SERVER_PORT}`); log('info', `✓ API REST démarrée sur http://${SERVER_HOST}:${SERVER_PORT}`);
log('info', ''); log('info', '');
log('info', 'Serveur prêt !'); log('info', 'Serveur prêt !');
log('info', `Groupes configurés: ${config.groups.map(g => g.name).join(', ')}`); log('info', `Groupes configurés: ${config.groups.map(g => g.name).join(', ')}`);
log('info', ''); log('info', '');
// Afficher URLs d'accès avec QR code // Afficher URLs d'accès
if (networkIP && networkIP !== 'localhost') { if (networkIP && networkIP !== 'localhost') {
const clientUrl = `https://${networkIP}:5173`; // Dev mode const clientUrl = `https://${networkIP}:5173`; // Dev mode
const prodUrl = `http://${networkIP}:${SERVER_PORT}`; // Prod mode (redirigera vers HTTPS) const prodUrl = `http://${networkIP}:${SERVER_PORT}`; // Prod mode HTTP
log('info', '📱 Accès réseau WiFi :'); log('info', '📱 Accès réseau WiFi :');
log('info', ''); log('info', '');
log('info', ` Dev : ${clientUrl}`); log('info', ` Dev : ${clientUrl}`);
log('info', ` Prod : ${prodUrl} (redirige → HTTPS)`); log('info', ` Prod : ${prodUrl}`);
log('info', ''); log('info', '');
} }
}); });
}
// 2.5 Démarrer WebSocket Audio Levels (même port que l'API) // 2.5 Démarrer WebSocket Audio Levels (même port que l'API)
const audioLevelsServer = new AudioLevelsServer({ server }); const audioLevelsServer = new AudioLevelsServer({ server });
audioLevelsServer.start(); audioLevelsServer.start();
log('info', `✓ WebSocket Audio Levels démarré sur ws://${SERVER_HOST}:${SERVER_PORT}`); const wsProtocol = ENABLE_HTTPS ? 'wss' : 'ws';
log('info', `✓ WebSocket Audio Levels démarré sur ${wsProtocol}://${SERVER_HOST}:${SERVER_PORT}`);
// 3. Démarrer Audio Bridge Manager (Phase 2.5) // 3. Démarrer Audio Bridge Manager (Phase 2.5)
log('info', ''); log('info', '');
+20 -9
View File
@@ -84,6 +84,11 @@ echo ""
cd server cd server
# En mode production (pas --dev), activer HTTPS
if [ "$1" != "--dev" ]; then
export ENABLE_HTTPS=true
fi
# Lancer le serveur en background silencieux # Lancer le serveur en background silencieux
npm start > ../server.log 2>&1 & npm start > ../server.log 2>&1 &
SERVER_PID=$! SERVER_PID=$!
@@ -134,12 +139,15 @@ if [ "$1" == "--dev" ]; then
echo "✅ PTT Live démarré (mode dev)" echo "✅ PTT Live démarré (mode dev)"
echo "==================================${NC}" echo "==================================${NC}"
echo "" echo ""
echo "🌐 Accès client :" echo -e "${BLUE}🌐 ACCÈS CLIENT (HTTPS) :${NC}"
echo " Local : https://localhost:5173" echo -e "${GREEN} 👉 Local : https://localhost:5173${NC}"
echo " Réseau : https://${NETWORK_IP}:5173" echo -e "${GREEN} 👉 Réseau : https://${NETWORK_IP}:5173${NC}"
echo "" echo ""
echo "📊 API serveur : http://${NETWORK_IP}:3000 (→ redirige vers HTTPS)" echo -e "${YELLOW}⚠️ Acceptez le certificat auto-signé dans votre navigateur${NC}"
echo "🎛️ Interface admin : https://${NETWORK_IP}:5173/admin" echo -e "${YELLOW} (Cliquez sur 'Avancé' puis 'Continuer')${NC}"
echo ""
echo "📊 API serveur (HTTP uniquement) : http://localhost:3000"
echo "🎛️ Interface admin : https://localhost:5173/admin"
echo "" echo ""
echo "📝 Logs serveur : tail -f server.log" echo "📝 Logs serveur : tail -f server.log"
echo "" echo ""
@@ -168,11 +176,14 @@ else
echo "✅ PTT Live démarré (production)" echo "✅ PTT Live démarré (production)"
echo "==================================${NC}" echo "==================================${NC}"
echo "" echo ""
echo "🌐 Accès :" echo -e "${BLUE}🌐 ACCÈS CLIENT (HTTPS) :${NC}"
echo " Local : http://localhost:3000" echo -e "${GREEN} 👉 Local : https://localhost:3000${NC}"
echo " Réseau : http://${NETWORK_IP}:3000" echo -e "${GREEN} 👉 Réseau : https://${NETWORK_IP}:3000${NC}"
echo "" echo ""
echo "🎛️ Interface admin : http://${NETWORK_IP}:3000/admin" echo -e "${YELLOW}⚠️ Acceptez le certificat auto-signé dans votre navigateur${NC}"
echo -e "${YELLOW} (Cliquez sur 'Avancé' puis 'Continuer')${NC}"
echo ""
echo "🎛️ Interface admin : https://localhost:3000/admin"
echo "" echo ""
echo "📝 Logs serveur : tail -f server.log" echo "📝 Logs serveur : tail -f server.log"
echo "" echo ""