diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..09f0df1 --- /dev/null +++ b/.env.example @@ -0,0 +1,29 @@ +# SentinelForge Environment Configuration Example +# Copy this file to .env and populate with production values. Do NOT commit .env. + +# Cesium Ion personal access token for 3D globe tiles and imagery +CESIUM_ION_TOKEN=replace_with_cesium_ion_token + +# Internal API authentication key for SentinelForge REST endpoints +SF_API_KEY=replace_with_internal_api_key + +# API key required in the X-API-Key header for /api/nlp +NLP_API_KEY=replace_with_nlp_api_key + +# Google Gemini API key for natural language command interpretation +GEMINI_API_KEY=replace_with_gemini_api_key + +# Comma-separated list of allowed CORS origins for serverless endpoints +ALLOWED_ORIGINS=https://example.invalid + +# PostgreSQL / PostGIS database connection URL +DATABASE_URL=replace_with_database_connection_url + +# PostgreSQL password for catalog store +POSTGIS_PASSWORD=replace_with_database_password + +# Mutual TLS SSL private key content for Kafka transport +KAFKA_SSL_KEY=replace_with_kafka_private_key + +# Optional path to PyTorch weights for thermospheric density MLP +DENSITY_MODEL_PATH=/path/to/density_mlp.pth diff --git a/.gitignore b/.gitignore index 6328d2b..34a7439 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,8 @@ fix*.ps1 data/real_frame.fits data/synthetic_frame.raw benchmarks/benchmark_results.json + +# Environment variables and secrets +.env +.env.* +!.env.example diff --git a/api/config.js b/api/config.js new file mode 100644 index 0000000..d53dfe4 --- /dev/null +++ b/api/config.js @@ -0,0 +1,33 @@ +// Vercel Serverless Function — Public Configuration Provider +export default async function handler(req, res) { + const origin = req.headers.origin; + const allowedOrigins = (process.env.ALLOWED_ORIGINS || 'https://sentinelforge.vercel.app') + .split(',') + .map(s => s.trim()) + .filter(Boolean); + + if (origin) { + if (allowedOrigins.includes(origin)) { + res.setHeader('Access-Control-Allow-Origin', origin); + res.setHeader('Vary', 'Origin'); + } else { + return res.status(403).json({ error: 'Origin not allowed' }); + } + } + + res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + res.setHeader('Cache-Control', 'no-store'); + + if (req.method === 'OPTIONS') { + return res.status(204).end(); + } + + if (req.method !== 'GET') { + return res.status(405).json({ error: 'GET only' }); + } + + return res.status(200).json({ + cesiumIonToken: process.env.CESIUM_ION_TOKEN || '' + }); +} diff --git a/frontend/digital_twin.html b/frontend/digital_twin.html index 33740ce..f081197 100644 --- a/frontend/digital_twin.html +++ b/frontend/digital_twin.html @@ -66,28 +66,7 @@