diff --git a/.env b/.env new file mode 100644 index 0000000..af4a295 --- /dev/null +++ b/.env @@ -0,0 +1,41 @@ +# LogWhispererAI - Production Environment Configuration +# Generated for deployment with reverse proxy +# Date: 2026-04-03 + +# ============================================ +# FRONTEND CONFIGURATION (VITE_* variables) +# These are exposed to the browser +# ============================================ + +# Backend API URL - HTTPS endpoint via reverse proxy +VITE_API_URL=https://srv-logwhispererai.lab.home.lucasacchi.net + +# Webhook base URL - public HTTPS endpoint for webhooks +VITE_WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook + +# Install script URL - public HTTPS endpoint for install script +VITE_INSTALL_SCRIPT_URL=https://logwhispererai.lab.home.lucasacchi.net/install.sh + +# Application identification +VITE_APP_NAME=LogWhispererAI + +# Application public URL - main frontend domain +VITE_APP_URL=https://logwhispererai.lab.home.lucasacchi.net + +# ============================================ +# BACKEND CONFIGURATION +# ============================================ + +# CORS Origins - restrict to frontend domain for security +# Only requests from this origin will be accepted by the backend +CORS_ORIGINS=https://logwhispererai.lab.home.lucasacchi.net + +# Webhook base URL - used for generating webhook URLs +# This should match VITE_WEBHOOK_BASE_URL +WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook + +# API delay simulation (milliseconds) - simulates AI processing time +DELAY_MS=1500 + +# Node environment +NODE_ENV=production diff --git a/.env.example b/.env.example index b4083ef..7ceaf2e 100644 --- a/.env.example +++ b/.env.example @@ -1,22 +1,64 @@ # LogWhispererAI - Environment Variables +# ============================================ +# FRONTEND CONFIGURATION (VITE_* variables) +# These are exposed to the browser +# ============================================ + +# Backend API URL - where the frontend will make API calls +# Example: https://srv-logwhispererai.lab.home.lucasacchi.net +VITE_API_URL=http://localhost:3001 + +# Webhook base URL - used for displaying webhook URLs to users +# Example: https://logwhispererai.lab.home.lucasacchi.net/webhook +VITE_WEBHOOK_BASE_URL=http://localhost:3001/webhook + +# Install script URL - the curl command shown to users +# Example: https://logwhispererai.lab.home.lucasacchi.net/install.sh +VITE_INSTALL_SCRIPT_URL=http://localhost:3001/install.sh + +# Application identification +VITE_APP_NAME=LogWhispererAI +VITE_APP_URL=http://localhost:5173 + +# ============================================ +# BACKEND CONFIGURATION +# ============================================ + +# CORS Origins - comma-separated list of allowed frontend origins +# Use '*' for development, set specific domains for production +# Example: https://logwhispererai.lab.home.lucasacchi.net +CORS_ORIGINS=* + +# Webhook base URL - used for generating webhook URLs +# Example: https://logwhispererai.lab.home.lucasacchi.net/webhook +WEBHOOK_BASE_URL=https://logwhisperer.ai/webhook + +# API delay simulation (milliseconds) +DELAY_MS=1500 + +# Node environment +NODE_ENV=development + +# ============================================ +# OPTIONAL: Third-party Services +# ============================================ + # Telegram Bot Configuration -# Ottieni questi valori seguendo le istruzioni in docs/telegram_setup.md -TELEGRAM_BOT_TOKEN=your_bot_token_here -TELEGRAM_CHAT_ID=your_chat_id_here +# TELEGRAM_BOT_TOKEN=your_bot_token_here +# TELEGRAM_CHAT_ID=your_chat_id_here # n8n Configuration -N8N_WEBHOOK_URL=https://your-n8n-instance.com/webhook/logwhisperer +# N8N_WEBHOOK_URL=https://your-n8n-instance.com/webhook/logwhisperer # AI Provider Configuration -OPENAI_API_KEY=your_openai_api_key_here -# oppure -ANTHROPIC_API_KEY=your_anthropic_api_key_here +# OPENAI_API_KEY=your_openai_api_key_here +# ANTHROPIC_API_KEY=your_anthropic_api_key_here # Supabase Configuration (per autenticazione e database) -SUPABASE_URL=https://your-project.supabase.co -SUPABASE_ANON_KEY=your_anon_key_here +# SUPABASE_URL=https://your-project.supabase.co +# SUPABASE_ANON_KEY=your_anon_key_here # Stripe Configuration (per pagamenti) -STRIPE_SECRET_KEY=sk_test_your_key_here -STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here +# STRIPE_SECRET_KEY=sk_test_your_key_here +# STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..c9b0c32 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,23 @@ +# Docker Compose Override - Local Development Configuration +# This file is automatically loaded by Docker Compose and overrides docker-compose.yml +# Use this for local development settings without modifying the main docker-compose.yml +# +# Usage: docker compose up -d (automatically loads this file) +# +# To use production configuration, create a .env file and run: +# docker compose -f docker-compose.yml up -d + +services: + frontend: + environment: + # Development defaults - override these in .env file for production + - VITE_API_URL=http://192.168.254.79:3001 + - VITE_WEBHOOK_BASE_URL=http://192.168.254.79:3001/webhook + - VITE_INSTALL_SCRIPT_URL=http://192.168.254.79:3001/install.sh + - VITE_APP_URL=http://192.168.254.79:5173 + + fake-backend: + environment: + # Development defaults + - CORS_ORIGINS=* + - WEBHOOK_BASE_URL=http://192.168.254.79:3001/webhook \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..61b8b42 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,31 @@ +# Docker Compose - Production Configuration +# Usage with reverse proxy: +# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d +# +# Required: Create a .env file with production values before running + +services: + frontend: + # In production, don't mount source volumes (use built image) + volumes: + - node_modules:/app/node_modules + + environment: + # Production API URLs - these must be set in .env file + - VITE_API_URL=${VITE_API_URL} + - VITE_WEBHOOK_BASE_URL=${VITE_WEBHOOK_BASE_URL} + - VITE_INSTALL_SCRIPT_URL=${VITE_INSTALL_SCRIPT_URL} + - VITE_APP_URL=${VITE_APP_URL} + - NODE_ENV=production + + fake-backend: + environment: + # Production CORS - restrict to frontend domain + - CORS_ORIGINS=${CORS_ORIGINS} + + # Production webhook URL + - WEBHOOK_BASE_URL=${WEBHOOK_BASE_URL} + + # Production settings + - NODE_ENV=production + - DELAY_MS=${DELAY_MS:-1500} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index d7accbc..c36273e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,19 @@ # Docker Compose - LogWhispererAI Development Environment # Usage: docker compose up -d # Access Frontend: http://localhost:5173 -# Access Fake Backend API: http://localhost:3000 +# Access Fake Backend API: http://localhost:3001 +# +# For production deployment with reverse proxy: +# 1. Copy .env.example to .env and customize values +# 2. Run: docker compose up -d +# +# Required environment variables for production: +# VITE_API_URL=https://srv-logwhispererai.lab.home.lucasacchi.net +# VITE_WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook +# VITE_INSTALL_SCRIPT_URL=https://logwhispererai.lab.home.lucasacchi.net/install.sh +# VITE_APP_URL=https://logwhispererai.lab.home.lucasacchi.net +# CORS_ORIGINS=https://logwhispererai.lab.home.lucasacchi.net +# WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook services: frontend: @@ -17,9 +29,38 @@ services: # Use named volume for node_modules to avoid conflicts with host - node_modules:/app/node_modules environment: - - NODE_ENV=development + # Node environment + - NODE_ENV=${NODE_ENV:-development} - CHOKIDAR_USEPOLLING=true - - VITE_API_URL=http://fake-backend:3000 + + # ============================================ + # FRONTEND CONFIGURATION (VITE_* variables) + # These are exposed to the browser + # ============================================ + + # Backend API URL - where the frontend will make API calls + # Default: http://fake-backend:3000 (internal Docker network) + # Production: https://srv-logwhispererai.lab.home.lucasacchi.net + - VITE_API_URL=${VITE_API_URL:-http://fake-backend:3000} + + # Webhook base URL - used for displaying webhook URLs to users + # Default: http://localhost:3001/webhook + # Production: https://logwhispererai.lab.home.lucasacchi.net/webhook + - VITE_WEBHOOK_BASE_URL=${VITE_WEBHOOK_BASE_URL:-http://localhost:3001/webhook} + + # Install script URL - the curl command shown to users + # Default: http://localhost:3001/install.sh + # Production: https://logwhispererai.lab.home.lucasacchi.net/install.sh + - VITE_INSTALL_SCRIPT_URL=${VITE_INSTALL_SCRIPT_URL:-http://localhost:3001/install.sh} + + # Application identification + - VITE_APP_NAME=${VITE_APP_NAME:-LogWhispererAI} + + # Application public URL + # Default: http://localhost:5173 + # Production: https://logwhispererai.lab.home.lucasacchi.net + - VITE_APP_URL=${VITE_APP_URL:-http://localhost:5173} + # Ensure container restarts on failure restart: unless-stopped depends_on: @@ -38,11 +79,33 @@ services: dockerfile: Dockerfile container_name: logwhisperer-fake-backend ports: - - "3000:3000" + - "3001:3000" environment: + # Server port (internal) - PORT=3000 - - DELAY_MS=1500 - - NODE_ENV=production + + # API delay simulation (milliseconds) + - DELAY_MS=${DELAY_MS:-1500} + + # Node environment + - NODE_ENV=${NODE_ENV:-production} + + # ============================================ + # BACKEND CONFIGURATION + # ============================================ + + # CORS origins - comma-separated list of allowed frontend origins + # Use '*' for development (allows all origins) + # Production: set to your frontend domain for security + # Example: https://logwhispererai.lab.home.lucasacchi.net + - CORS_ORIGINS=${CORS_ORIGINS:-*} + + # Webhook base URL - used for generating webhook URLs + # This should be the public URL that users see + # Default: https://logwhisperer.ai/webhook + # Production: https://logwhispererai.lab.home.lucasacchi.net/webhook + - WEBHOOK_BASE_URL=${WEBHOOK_BASE_URL:-https://logwhisperer.ai/webhook} + restart: unless-stopped healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))"] diff --git a/docs/docker-compose.md b/docs/docker-compose.md new file mode 100644 index 0000000..9c4e864 --- /dev/null +++ b/docs/docker-compose.md @@ -0,0 +1,131 @@ +# Docker Compose Configuration + +Questa directory contiene diverse configurazioni Docker Compose per vari ambienti. + +## File Disponibili + +| File | Scopo | Uso | +|------|-------|-----| +| `docker-compose.yml` | Configurazione base con variabili d'ambiente | Sviluppo e produzione | +| `docker-compose.override.yml` | Override per sviluppo locale | Caricato automaticamente | +| `docker-compose.prod.yml` | Configurazione produzione | Da usare con `-f` | + +## Variabili d'Ambiente + +Tutte le variabili sono configurabili tramite file `.env` o variabili di sistema. + +### Frontend (VITE_*) + +| Variabile | Default | Descrizione | +|-----------|---------|-------------| +| `VITE_API_URL` | `http://fake-backend:3000` | URL del backend API | +| `VITE_WEBHOOK_BASE_URL` | `http://localhost:3001/webhook` | Base URL webhook | +| `VITE_INSTALL_SCRIPT_URL` | `http://localhost:3001/install.sh` | URL script installazione | +| `VITE_APP_NAME` | `LogWhispererAI` | Nome applicazione | +| `VITE_APP_URL` | `http://localhost:5173` | URL pubblico app | + +### Backend + +| Variabile | Default | Descrizione | +|-----------|---------|-------------| +| `PORT` | `3000` | Porta server (interna) | +| `DELAY_MS` | `1500` | Delay simulazione API | +| `NODE_ENV` | `production` | Ambiente Node | +| `CORS_ORIGINS` | `*` | Origini CORS consentite | +| `WEBHOOK_BASE_URL` | `https://logwhisperer.ai/webhook` | Base URL webhook | + +## Utilizzo + +### Sviluppo Locale (default) + +```bash +# Le variabili di docker-compose.override.yml vengono usate automaticamente +docker compose up -d +``` + +### Sviluppo con configurazione personalizzata + +```bash +# Crea un file .env nella root del progetto +cat > .env << 'EOF' +VITE_API_URL=http://192.168.254.79:3001 +VITE_WEBHOOK_BASE_URL=http://192.168.254.79:3001/webhook +CORS_ORIGINS=* +EOF + +# Avvia con le variabili dal file .env +docker compose up -d +``` + +### Produzione con Reverse Proxy + +```bash +# 1. Crea il file .env con i valori di produzione +cat > .env << 'EOF' +VITE_API_URL=https://srv-logwhispererai.lab.home.lucasacchi.net +VITE_WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook +VITE_INSTALL_SCRIPT_URL=https://logwhispererai.lab.home.lucasacchi.net/install.sh +VITE_APP_URL=https://logwhispererai.lab.home.lucasacchi.net +CORS_ORIGINS=https://logwhispererai.lab.home.lucasacchi.net +WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook +NODE_ENV=production +EOF + +# 2. Avvia con la configurazione di produzione +# (ignora docker-compose.override.yml) +docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d +``` + +### Solo Backend + +```bash +docker compose up fake-backend -d +``` + +### Solo Frontend + +```bash +docker compose up frontend -d +``` + +## Verifica Configurazione + +```bash +# Controlla le variabili caricate +docker compose config + +# Verifica il backend +curl https://srv-logwhispererai.lab.home.lucasacchi.net/health + +# Verifica la generazione webhook +curl -X POST https://srv-logwhispererai.lab.home.lucasacchi.net/api/webhook +``` + +## Troubleshooting + +### Cambiare le variabili + +Se modifichi il file `.env`, devi ricreare i container: + +```bash +docker compose down +docker compose up -d +``` + +### Vedere le variabili in uso + +```bash +# Frontend +docker exec logwhisperer-frontend-dev env | grep VITE + +# Backend +docker exec logwhisperer-fake-backend env | grep -E '(CORS|WEBHOOK)' +``` + +### Reset alla configurazione default + +```bash +docker compose down +rm .env # Rimuovi configurazione personalizzata +docker compose up -d # Userà i valori default +``` \ No newline at end of file diff --git a/docs/reverse_proxy_setup.md b/docs/reverse_proxy_setup.md new file mode 100644 index 0000000..8c706ff --- /dev/null +++ b/docs/reverse_proxy_setup.md @@ -0,0 +1,129 @@ +# Configurazione con Reverse Proxy + +Questa guida spiega come configurare LogWhispererAI con un reverse proxy SSL. + +## Scenario + +Hai configurato: +- **Frontend**: `https://logwhispererai.lab.home.lucasacchi.net` → `http://192.168.254.79:5173` +- **Backend**: `https://srv-logwhispererai.lab.home.lucasacchi.net` → `http://192.168.254.79:3001` + +## Configurazione + +### 1. Crea il file di configurazione + +Crea un file `.env` nella root del progetto: + +```bash +cp .env.example .env +``` + +Modifica il file `.env` con i tuoi valori: + +```env +# Frontend Configuration +VITE_API_URL=https://srv-logwhispererai.lab.home.lucasacchi.net +VITE_WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook +VITE_INSTALL_SCRIPT_URL=https://logwhispererai.lab.home.lucasacchi.net/install.sh +VITE_APP_NAME=LogWhispererAI +VITE_APP_URL=https://logwhispererai.lab.home.lucasacchi.net + +# Backend Configuration +CORS_ORIGINS=https://logwhispererai.lab.home.lucasacchi.net +WEBHOOK_BASE_URL=https://logwhispererai.lab.home.lucasacchi.net/webhook +DELAY_MS=1500 +NODE_ENV=production +``` + +### 2. Avvia i servizi + +```bash +# Ferma eventuali container esistenti +docker compose down + +# Avvia con le nuove variabili +docker compose up -d +``` + +### 3. Verifica la configurazione + +Testa i vari endpoint: + +```bash +# Health check backend +curl https://srv-logwhispererai.lab.home.lucasacchi.net/health + +# Genera un webhook +curl -X POST https://srv-logwhispererai.lab.home.lucasacchi.net/api/webhook + +# Analizza un log +curl -X POST https://srv-logwhispererai.lab.home.lucasacchi.net/api/analyze \ + -H "Content-Type: application/json" \ + -d '{"log": "FATAL: out of memory"}' +``` + +### 4. Verifica il frontend + +Apri `https://logwhispererai.lab.home.lucasacchi.net` nel browser e verifica che: +1. La demo interattiva funzioni (chiama il backend corretto) +2. Lo step 2 dell'onboarding generi webhook con l'URL corretto + +## Variabili d'Ambiente + +### Frontend (VITE_*) + +| Variabile | Descrizione | Esempio | +|-----------|-------------|---------| +| `VITE_API_URL` | URL del backend API | `https://srv-logwhispererai.lab.home.lucasacchi.net` | +| `VITE_WEBHOOK_BASE_URL` | Base URL per i webhook | `https://logwhispererai.lab.home.lucasacchi.net/webhook` | +| `VITE_INSTALL_SCRIPT_URL` | URL dello script di installazione | `https://logwhispererai.lab.home.lucasacchi.net/install.sh` | +| `VITE_APP_NAME` | Nome dell'applicazione | `LogWhispererAI` | +| `VITE_APP_URL` | URL pubblico dell'app | `https://logwhispererai.lab.home.lucasacchi.net` | + +### Backend + +| Variabile | Descrizione | Esempio | +|-----------|-------------|---------| +| `CORS_ORIGINS` | Origini CORS consentite (comma-separated) | `https://logwhispererai.lab.home.lucasacchi.net` | +| `WEBHOOK_BASE_URL` | Base URL per i webhook generati | `https://logwhispererai.lab.home.lucasacchi.net/webhook` | +| `DELAY_MS` | Delay simulato API (ms) | `1500` | +| `NODE_ENV` | Ambiente Node | `production` | + +## File Configurati + +- `frontend/.env` - Configurazione frontend per produzione +- `frontend/.env.development` - Configurazione per sviluppo locale +- `frontend/vite.config.ts` - Allow hosts per Vite +- `tools/fake-backend/server.js` - Supporto CORS dinamico e webhook URL configurabili +- `docker-compose.yml` - Passaggio variabili ai container + +## Troubleshooting + +### Errore "Blocked request" di Vite + +Se vedi questo errore: +``` +Blocked request. This host ("logwhispererai.lab.home.lucasacchi.net") is not allowed. +``` + +Aggiungi il dominio a `frontend/vite.config.ts`: +```typescript +server: { + allowedHosts: [ + 'logwhispererai.lab.home.lucasacchi.net', + ], +} +``` + +### Errore CORS + +Se il browser blocca le richieste API: +1. Verifica che `CORS_ORIGINS` includa il dominio del frontend +2. Ricostruisci il backend: `docker compose up fake-backend --build -d` + +### Webhook URL errati + +Se i webhook generati hanno URL sbagliati: +1. Verifica `WEBHOOK_BASE_URL` nel backend +2. Verifica `VITE_WEBHOOK_BASE_URL` nel frontend +3. Ricostruisci entrambi i servizi diff --git a/frontend/.env.development b/frontend/.env.development new file mode 100644 index 0000000..37bb518 --- /dev/null +++ b/frontend/.env.development @@ -0,0 +1,15 @@ +# LogWhispererAI - Frontend Environment Variables (Development) +# These variables are exposed to the browser (must start with VITE_) + +# Backend API URL +VITE_API_URL=http://192.168.254.79:3001 + +# Base URL for webhook endpoints +VITE_WEBHOOK_BASE_URL=http://192.168.254.79:3001/webhook + +# Install script URL +VITE_INSTALL_SCRIPT_URL=http://192.168.254.79:3001/install.sh + +# Application identification +VITE_APP_NAME=LogWhispererAI +VITE_APP_URL=http://192.168.254.79:5173 diff --git a/frontend/src/components/sections/InteractiveDemo.tsx b/frontend/src/components/sections/InteractiveDemo.tsx index 606d469..ed9f621 100644 --- a/frontend/src/components/sections/InteractiveDemo.tsx +++ b/frontend/src/components/sections/InteractiveDemo.tsx @@ -49,7 +49,8 @@ interface ApiResponse { message?: string; } -const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000'; +// Environment configuration +const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001'; export const InteractiveDemo: React.FC = () => { const [selectedLog, setSelectedLog] = useState(null); diff --git a/frontend/src/components/sections/OnboardingWizard.tsx b/frontend/src/components/sections/OnboardingWizard.tsx index 9557b72..102132c 100644 --- a/frontend/src/components/sections/OnboardingWizard.tsx +++ b/frontend/src/components/sections/OnboardingWizard.tsx @@ -22,21 +22,56 @@ export const OnboardingWizard: React.FC = ({ onComplete } const [isGenerating, setIsGenerating] = useState(false); const stepRef = useRef(null); - // Focus management for accessibility + // Focus management for accessibility - only when step changes, not on initial mount useEffect(() => { - if (stepRef.current) { - stepRef.current.focus(); + // Only focus if this is a step change (not initial mount) + // This prevents auto-scroll to the onboarding section on page load + if (stepRef.current && document.activeElement !== document.body) { + stepRef.current.focus({ preventScroll: true }); } }, [currentStep]); - const generateWebhook = () => { +// Environment configuration +const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001'; +const WEBHOOK_BASE_URL = import.meta.env.VITE_WEBHOOK_BASE_URL || `${API_URL}/webhook`; +const INSTALL_SCRIPT_URL = import.meta.env.VITE_INSTALL_SCRIPT_URL || `${API_URL}/install.sh`; +const APP_NAME = import.meta.env.VITE_APP_NAME || 'LogWhispererAI'; + + const generateWebhook = async () => { setIsGenerating(true); - // Simulate generation delay - setTimeout(() => { - const uuid = crypto.randomUUID(); - setWebhookUrl(`https://logwhisperer.ai/webhook/${uuid}`); + + try { + const response = await fetch(`${API_URL}/api/webhook`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + + if (data.success && data.uuid) { + // Use configured webhook base URL instead of API response + setWebhookUrl(`${WEBHOOK_BASE_URL}/${data.uuid}`); + } else { + throw new Error(data.message || 'Errore nella generazione del webhook'); + } + } catch (error) { + console.error('Error generating webhook:', error); + // Fallback: generate locally if API fails + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + const r = Math.random() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + setWebhookUrl(`${WEBHOOK_BASE_URL}/${uuid}`); + } finally { setIsGenerating(false); - }, 1000); + } }; const copyWebhook = () => { @@ -46,7 +81,7 @@ export const OnboardingWizard: React.FC = ({ onComplete } }; const copyCurlCommand = () => { - const command = `curl -fsSL https://logwhisperer.ai/install.sh | bash -s -- --webhook ${webhookUrl}`; + const command = `curl -fsSL ${INSTALL_SCRIPT_URL} | bash -s -- --webhook ${webhookUrl}`; navigator.clipboard.writeText(command); setCopied(true); setTimeout(() => setCopied(false), 2000); @@ -68,8 +103,8 @@ export const OnboardingWizard: React.FC = ({ onComplete } const getInstallCommand = () => { return webhookUrl - ? `curl -fsSL https://logwhisperer.ai/install.sh | bash -s -- --webhook ${webhookUrl}` - : 'curl -fsSL https://logwhisperer.ai/install.sh | bash'; + ? `curl -fsSL ${INSTALL_SCRIPT_URL} | bash -s -- --webhook ${webhookUrl}` + : `curl -fsSL ${INSTALL_SCRIPT_URL} | bash`; }; const steps = [ diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index cd7ad00..ec4be6f 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -10,5 +10,13 @@ export default defineConfig({ watch: { usePolling: true, }, + // Allow requests from reverse proxy host + // Add your production domain here + allowedHosts: [ + 'localhost', + '127.0.0.1', + '.lab.home.lucasacchi.net', // Allow all subdomains + 'logwhispererai.lab.home.lucasacchi.net', + ], }, }) diff --git a/tools/fake-backend/server.js b/tools/fake-backend/server.js index 73ff49f..e1f0ea3 100644 --- a/tools/fake-backend/server.js +++ b/tools/fake-backend/server.js @@ -15,12 +15,19 @@ const app = express(); const PORT = process.env.PORT || 3000; const DELAY_MS = parseInt(process.env.DELAY_MS) || 1500; -// Enable CORS for all origins (development only!) -app.use(cors({ - origin: '*', - methods: ['GET', 'POST'], - allowedHeaders: ['Content-Type'] -})); +// CORS configuration - supports multiple origins via env var +// CORS_ORIGINS can be comma-separated list or '*' for all +const corsOrigins = process.env.CORS_ORIGINS || '*'; +const corsOptions = corsOrigins === '*' + ? { origin: '*', methods: ['GET', 'POST'], allowedHeaders: ['Content-Type'] } + : { + origin: corsOrigins.split(',').map(o => o.trim()), + methods: ['GET', 'POST'], + allowedHeaders: ['Content-Type'], + credentials: true + }; + +app.use(cors(corsOptions)); // Parse JSON bodies app.use(express.json()); @@ -161,6 +168,47 @@ app.post('/api/analyze', (req, res) => { }, DELAY_MS); }); +// Environment configuration for webhook URLs +const WEBHOOK_BASE_URL = process.env.WEBHOOK_BASE_URL || 'https://logwhisperer.ai/webhook'; + +/** + * POST /api/webhook + * Generate a fake webhook URL for onboarding + */ +app.post('/api/webhook', (req, res) => { + // Simulate generation delay (500ms - 1s) + const delay = Math.floor(Math.random() * 500) + 500; + + setTimeout(() => { + try { + // Generate fake UUID v4 + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + const r = Math.random() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + + res.json({ + success: true, + webhookUrl: `${WEBHOOK_BASE_URL}/${uuid}`, + uuid: uuid, + meta: { + generatedAt: new Date().toISOString(), + expiresIn: '30 days' + } + }); + } catch (error) { + console.error('Error generating webhook:', error); + res.status(500).json({ + success: false, + error: 'Internal Server Error', + message: 'Errore durante la generazione del webhook', + timestamp: new Date().toISOString() + }); + } + }, delay); +}); + /** * GET /health * Health check endpoint @@ -202,8 +250,8 @@ app.use((err, req, res, next) => { }); }); -// Start server -app.listen(PORT, () => { +// Start server - listen on all interfaces (0.0.0.0) to allow external connections +app.listen(PORT, '0.0.0.0', () => { console.log(` ╔══════════════════════════════════════════════════════════════╗ ║ LogWhispererAI - Fake Backend Server ║ @@ -212,8 +260,9 @@ app.listen(PORT, () => { ║ 📖 Documentation: docs/tools_fake_backend.md ║ ║ ⏱️ Simulated delay: ${DELAY_MS}ms ║ ║ ║ -║ Endpoints: ║ + ║ Endpoints: ║ ║ POST /api/analyze - Analyze log and get mock AI response ║ +║ POST /api/webhook - Generate fake webhook URL ║ ║ GET /health - Health check ║ ║ ║ ║ Press Ctrl+C to stop ║