feat: add production configuration with environment variables

- Add .env file for production deployment with reverse proxy
- Add docker-compose.prod.yml for production profile
- Add docker-compose.override.yml for local development
- Update docker-compose.yml with all configurable variables
- Update frontend to use VITE_* environment variables
- Update backend to support CORS_ORIGINS and WEBHOOK_BASE_URL
- Add vite.config.ts allowedHosts for reverse proxy
- Add documentation for docker-compose and reverse proxy setup

All URLs are now configurable via environment variables:
- VITE_API_URL: Backend API endpoint
- VITE_WEBHOOK_BASE_URL: Webhook base URL
- VITE_INSTALL_SCRIPT_URL: Install script URL
- VITE_APP_URL: Frontend URL
- CORS_ORIGINS: Allowed CORS origins
- WEBHOOK_BASE_URL: Backend webhook base URL
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-03 18:49:53 +02:00
parent 92217897ca
commit 26879acba4
12 changed files with 607 additions and 39 deletions

41
.env Normal file
View File

@@ -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

View File

@@ -1,22 +1,64 @@
# LogWhispererAI - Environment Variables # 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 # Telegram Bot Configuration
# Ottieni questi valori seguendo le istruzioni in docs/telegram_setup.md # TELEGRAM_BOT_TOKEN=your_bot_token_here
TELEGRAM_BOT_TOKEN=your_bot_token_here # TELEGRAM_CHAT_ID=your_chat_id_here
TELEGRAM_CHAT_ID=your_chat_id_here
# n8n Configuration # 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 # AI Provider Configuration
OPENAI_API_KEY=your_openai_api_key_here # OPENAI_API_KEY=your_openai_api_key_here
# oppure # ANTHROPIC_API_KEY=your_anthropic_api_key_here
ANTHROPIC_API_KEY=your_anthropic_api_key_here
# Supabase Configuration (per autenticazione e database) # Supabase Configuration (per autenticazione e database)
SUPABASE_URL=https://your-project.supabase.co # SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_anon_key_here # SUPABASE_ANON_KEY=your_anon_key_here
# Stripe Configuration (per pagamenti) # Stripe Configuration (per pagamenti)
STRIPE_SECRET_KEY=sk_test_your_key_here # STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here # STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here

View File

@@ -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

31
docker-compose.prod.yml Normal file
View File

@@ -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}

View File

@@ -1,7 +1,19 @@
# Docker Compose - LogWhispererAI Development Environment # Docker Compose - LogWhispererAI Development Environment
# Usage: docker compose up -d # Usage: docker compose up -d
# Access Frontend: http://localhost:5173 # 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: services:
frontend: frontend:
@@ -17,9 +29,38 @@ services:
# Use named volume for node_modules to avoid conflicts with host # Use named volume for node_modules to avoid conflicts with host
- node_modules:/app/node_modules - node_modules:/app/node_modules
environment: environment:
- NODE_ENV=development # Node environment
- NODE_ENV=${NODE_ENV:-development}
- CHOKIDAR_USEPOLLING=true - 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 # Ensure container restarts on failure
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
@@ -38,11 +79,33 @@ services:
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: logwhisperer-fake-backend container_name: logwhisperer-fake-backend
ports: ports:
- "3000:3000" - "3001:3000"
environment: environment:
# Server port (internal)
- PORT=3000 - 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 restart: unless-stopped
healthcheck: healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))"] test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))"]

131
docs/docker-compose.md Normal file
View File

@@ -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
```

129
docs/reverse_proxy_setup.md Normal file
View File

@@ -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

15
frontend/.env.development Normal file
View File

@@ -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

View File

@@ -49,7 +49,8 @@ interface ApiResponse {
message?: string; 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 = () => { export const InteractiveDemo: React.FC = () => {
const [selectedLog, setSelectedLog] = useState<string | null>(null); const [selectedLog, setSelectedLog] = useState<string | null>(null);

View File

@@ -22,21 +22,56 @@ export const OnboardingWizard: React.FC<OnboardingWizardProps> = ({ onComplete }
const [isGenerating, setIsGenerating] = useState(false); const [isGenerating, setIsGenerating] = useState(false);
const stepRef = useRef<HTMLDivElement>(null); const stepRef = useRef<HTMLDivElement>(null);
// Focus management for accessibility // Focus management for accessibility - only when step changes, not on initial mount
useEffect(() => { useEffect(() => {
if (stepRef.current) { // Only focus if this is a step change (not initial mount)
stepRef.current.focus(); // This prevents auto-scroll to the onboarding section on page load
if (stepRef.current && document.activeElement !== document.body) {
stepRef.current.focus({ preventScroll: true });
} }
}, [currentStep]); }, [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); setIsGenerating(true);
// Simulate generation delay
setTimeout(() => { try {
const uuid = crypto.randomUUID(); const response = await fetch(`${API_URL}/api/webhook`, {
setWebhookUrl(`https://logwhisperer.ai/webhook/${uuid}`); 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); setIsGenerating(false);
}, 1000); }
}; };
const copyWebhook = () => { const copyWebhook = () => {
@@ -46,7 +81,7 @@ export const OnboardingWizard: React.FC<OnboardingWizardProps> = ({ onComplete }
}; };
const copyCurlCommand = () => { 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); navigator.clipboard.writeText(command);
setCopied(true); setCopied(true);
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
@@ -68,8 +103,8 @@ export const OnboardingWizard: React.FC<OnboardingWizardProps> = ({ onComplete }
const getInstallCommand = () => { const getInstallCommand = () => {
return webhookUrl return webhookUrl
? `curl -fsSL https://logwhisperer.ai/install.sh | bash -s -- --webhook ${webhookUrl}` ? `curl -fsSL ${INSTALL_SCRIPT_URL} | bash -s -- --webhook ${webhookUrl}`
: 'curl -fsSL https://logwhisperer.ai/install.sh | bash'; : `curl -fsSL ${INSTALL_SCRIPT_URL} | bash`;
}; };
const steps = [ const steps = [

View File

@@ -10,5 +10,13 @@ export default defineConfig({
watch: { watch: {
usePolling: true, 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',
],
}, },
}) })

View File

@@ -15,12 +15,19 @@ const app = express();
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
const DELAY_MS = parseInt(process.env.DELAY_MS) || 1500; const DELAY_MS = parseInt(process.env.DELAY_MS) || 1500;
// Enable CORS for all origins (development only!) // CORS configuration - supports multiple origins via env var
app.use(cors({ // CORS_ORIGINS can be comma-separated list or '*' for all
origin: '*', 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'], methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type'] allowedHeaders: ['Content-Type'],
})); credentials: true
};
app.use(cors(corsOptions));
// Parse JSON bodies // Parse JSON bodies
app.use(express.json()); app.use(express.json());
@@ -161,6 +168,47 @@ app.post('/api/analyze', (req, res) => {
}, DELAY_MS); }, 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 * GET /health
* Health check endpoint * Health check endpoint
@@ -202,8 +250,8 @@ app.use((err, req, res, next) => {
}); });
}); });
// Start server // Start server - listen on all interfaces (0.0.0.0) to allow external connections
app.listen(PORT, () => { app.listen(PORT, '0.0.0.0', () => {
console.log(` console.log(`
╔══════════════════════════════════════════════════════════════╗ ╔══════════════════════════════════════════════════════════════╗
║ LogWhispererAI - Fake Backend Server ║ ║ LogWhispererAI - Fake Backend Server ║
@@ -214,6 +262,7 @@ app.listen(PORT, () => {
║ ║ ║ ║
║ Endpoints: ║ ║ Endpoints: ║
║ POST /api/analyze - Analyze log and get mock AI response ║ ║ POST /api/analyze - Analyze log and get mock AI response ║
║ POST /api/webhook - Generate fake webhook URL ║
║ GET /health - Health check ║ ║ GET /health - Health check ║
║ ║ ║ ║
║ Press Ctrl+C to stop ║ ║ Press Ctrl+C to stop ║