diff --git a/.gitignore b/.gitignore index 59f9409..97e4f61 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ client/.env # Build outputs dist/ build/ +dev-dist/ *.log # OS files diff --git a/install/linux.sh b/install/linux.sh index 7bf0801..7a29b82 100755 --- a/install/linux.sh +++ b/install/linux.sh @@ -331,9 +331,9 @@ print_summary() { echo " Terminal 2 : cd $PROJECT_ROOT/client && npm run dev" echo "" echo "🌐 Accès après démarrage :" - echo " • Développement local : http://localhost:5173" - echo " • Depuis autre appareil (WiFi) : http://${NETWORK_IP}:5173" - echo " • Production : http://${NETWORK_IP}:3000" + echo " • Développement local : https://localhost:5173" + echo " • Depuis smartphone (WiFi) : https://${NETWORK_IP}:5173" + echo " • Admin : https://${NETWORK_IP}:5173/admin" echo "" echo "💡 Configuration réseau :" echo " IP serveur détectée : ${NETWORK_IP}" diff --git a/install/macos.sh b/install/macos.sh index 69d5b92..996b8b9 100755 --- a/install/macos.sh +++ b/install/macos.sh @@ -167,8 +167,8 @@ echo " Terminal 2 : cd client && npm run dev" echo "" echo "🌐 Accès après démarrage :" echo " • Développement local : https://localhost:5173" -echo " • Depuis autre appareil (WiFi) : https://${NETWORK_IP}:5173" -echo " • Production : http://${NETWORK_IP}:3000" +echo " • Depuis smartphone (WiFi) : https://${NETWORK_IP}:5173" +echo " • Admin : https://${NETWORK_IP}:5173/admin" echo "" echo "💡 Configuration réseau :" echo " IP serveur détectée : ${NETWORK_IP}" diff --git a/server/index.js b/server/index.js index 64f7341..159e7ec 100644 --- a/server/index.js +++ b/server/index.js @@ -3,12 +3,13 @@ import 'dotenv/config'; import express from 'express'; import { spawn } from 'child_process'; -import { readFileSync } from 'fs'; +import { readFileSync, existsSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { networkInterfaces } from 'os'; import YAML from 'yaml'; import { AccessToken } from 'livekit-server-sdk'; +import qrcode from 'qrcode-terminal'; import adminRouter, { registerUser, addLog } from './api/admin.js'; import configManager from './config/ConfigManager.js'; import audioBridgeManager from './bridge/AudioBridgeManager.js'; @@ -181,6 +182,23 @@ app.use((req, res, next) => { next(); }); +// Middleware redirection HTTP → HTTPS (développement uniquement) +// En développement, redirige vers le serveur Vite HTTPS (5173) +// En production réelle, utiliser nginx/caddy pour HTTPS +app.use((req, res, next) => { + const clientDistPath = join(__dirname, '..', 'client', 'dist'); + const isProd = existsSync(clientDistPath); + + // Mode dev : rediriger HTTP → HTTPS (Vite) + if (!isProd && req.protocol === 'http' && req.hostname !== 'localhost') { + const devHttpsUrl = `https://${req.hostname}:5173${req.url}`; + log('debug', `↪️ Redirection dev HTTPS: ${devHttpsUrl}`); + return res.redirect(301, devHttpsUrl); + } + + next(); +}); + // Middleware logging app.use((req, res, next) => { log('debug', `${req.method} ${req.path}`); @@ -190,7 +208,6 @@ app.use((req, res, next) => { // ========== Servir fichiers statiques client (production) ========== // En production, servir le build client depuis ../client/dist -import { existsSync } from 'fs'; const clientDistPath = join(__dirname, '..', 'client', 'dist'); if (existsSync(clientDistPath)) { @@ -399,6 +416,31 @@ async function start() { 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 avec QR code + if (networkIP && networkIP !== 'localhost') { + const clientUrl = `https://${networkIP}:5173`; // Dev mode + const prodUrl = `http://${networkIP}:${SERVER_PORT}`; // Prod mode (redirigera vers HTTPS) + + log('info', '📱 Accès réseau WiFi :'); + log('info', ''); + log('info', ` Dev : ${clientUrl}`); + log('info', ` Prod : ${prodUrl} (redirige → HTTPS)`); + log('info', ''); + log('info', '📲 Scannez le QR code avec votre smartphone :'); + log('info', ''); + + // Générer QR code (utilise URL dev par défaut, ou prod si dist existe) + const clientDistPath = join(__dirname, '..', 'client', 'dist'); + const qrUrl = existsSync(clientDistPath) ? prodUrl : clientUrl; + + qrcode.generate(qrUrl, { small: true }, (qr) => { + console.log(qr); + }); + + log('info', ''); + } }); // 2.5 Démarrer WebSocket Audio Levels (même port que l'API) diff --git a/server/package.json b/server/package.json index 4d59aae..3c8992b 100644 --- a/server/package.json +++ b/server/package.json @@ -24,6 +24,7 @@ "express": "^4.19.2", "livekit-server-sdk": "^2.6.0", "opusscript": "^0.1.1", + "qrcode-terminal": "^0.12.0", "ws": "^8.17.0", "yaml": "^2.4.2" }, diff --git a/start.sh b/start.sh index 2faf420..8d3a5b6 100755 --- a/start.sh +++ b/start.sh @@ -115,12 +115,12 @@ if [ "$1" == "--dev" ]; then echo "✅ PTT Live démarré (mode dev)" echo "==================================${NC}" echo "" - echo "🌐 Accès :" + echo "🌐 Accès client :" echo " • Local : https://localhost:5173" echo " • Réseau : https://${NETWORK_IP}:5173" echo "" - echo "📊 API serveur : http://${NETWORK_IP}:3000" - echo "🎛️ Interface admin : http://${NETWORK_IP}:3000/admin" + echo "📊 API serveur : http://${NETWORK_IP}:3000 (→ redirige vers HTTPS)" + echo "🎛️ Interface admin : https://${NETWORK_IP}:5173/admin" echo "" echo -e "${YELLOW}Appuyez sur Ctrl+C pour arrêter${NC}" echo ""