Skip to content

Commit 59e4d24

Browse files
author
Manus AI
committed
feat: production-ready hardening — GPS, i18n, nginx, security, mobile fixes
## Summary of Changes ### Backend (vera/app.py, config.py) - Add /location/update and /location/current endpoints for GPS support - Add /i18n/languages and /i18n/strings/{lang} endpoints for 19-language i18n - Add /info endpoint with server metadata for mobile/extension auto-discovery - Update FastAPI app title/description to eVera branding with full OpenAPI metadata - Fix ServerSettings defaults to production-ready values (CORS, rate limits) ### Frontend (vera/static/) - NEW: i18n.js — full internationalization module supporting 19 languages - Auto-detects browser language, persists to localStorage - RTL support for Arabic, applies strings to [data-i18n] attributes - NEW: geolocation.js — GPS location tracking module - Requests browser permission, sends updates to /location/update - Haversine distance filter (500m minimum movement) - 5-minute periodic update interval - Fix index.html CSP to allow connections to any HTTPS origin (not just localhost) - Add <script> tags for i18n.js and geolocation.js - Update PWA manifest.json: add lang, dir, id, display_override, screenshots, protocol_handlers, edge_side_panel, separate maskable icons - Update service worker sw.js: bump cache to evera-v2, add new static assets, stale-while-revalidate strategy, push notification support, offline fallback ### Chrome Extension (extension/) - Fix manifest.json host_permissions: add <all_urls> for production server support - Fix background.js: default server URL changed from localhost:8000 to https://evera-api.embeddedos.org - Fix options.js: default server URL updated to production endpoint ### Mobile App (mobile/) - Fix SettingsScreen.tsx: default host changed from 192.168.1.100 to evera-api.embeddedos.org with TLS enabled by default - Add GPS location tracking to ChatScreen.tsx using react-native-geolocation-service - Requests foreground permission, sends initial position, watches for 500m movement - Add updateLocation(), fetchServerInfo(), fetchI18nStrings() to api.ts ### Infrastructure - Dockerfile: add tini for proper PID 1 signal handling, add data/memory and data/logs directories, fix ENTRYPOINT order (tini before entrypoint script), add production ENV defaults for zone settings - docker-compose.yml: add nginx reverse proxy service, certbot TLS renewal, separate internal/public networks, security_opt no-new-privileges, JSON logging - docker-entrypoint.sh: add environment validation warnings, migrate command, production-safe set -euo pipefail - NEW: deploy/nginx/nginx.conf — production nginx config with rate limiting, gzip, security headers - NEW: deploy/nginx/conf.d/evera.conf — HTTPS virtual host with TLS 1.2/1.3, HSTS, WebSocket proxying, SSE no-buffer, static caching - .gitignore: comprehensive production entries (certs, logs, mobile builds) - .env.example: production defaults, all new variables documented - NEW: DEPLOYMENT.md — complete production deployment guide with TLS setup, environment reference, security checklist, API endpoint table, troubleshooting Fixes: hardcoded localhost URLs, missing GPS API, missing i18n API, CSP blocking production servers, extension host_permissions, mobile default IP, PWA manifest missing fields, SW cache stale
1 parent fe3168d commit 59e4d24

21 files changed

Lines changed: 1653 additions & 147 deletions

.env.example

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ VERA_SMTP_PASS=
6969

7070
# --- Server ---
7171

72-
VERA_SERVER_HOST=127.0.0.1
72+
# Set to 0.0.0.0 to accept connections from other machines or public internet
73+
VERA_SERVER_HOST=0.0.0.0
7374
VERA_SERVER_PORT=8000
74-
VERA_SERVER_CORS_ORIGINS=["http://localhost:8000","http://127.0.0.1:8000"]
75+
# Production domain configuration (add your hosted server domain here)
76+
VERA_SERVER_CORS_ORIGINS=["https://evera.embeddedos.org","https://evera-api.embeddedos.org","http://localhost:8000","http://127.0.0.1:8000"]
7577

7678
# Security: API key for authenticating requests (set a strong random key)
7779
VERA_SERVER_API_KEY=

.gitignore

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,108 @@
1-
# Data and secrets
2-
data/
1+
# ============================================================
2+
# eVera — .gitignore
3+
# ============================================================
4+
5+
# --- Secrets & Credentials ---
36
.env
7+
.env.*
8+
!.env.example
49
*.key
5-
*.db
10+
*.pem
11+
*.p12
12+
*.pfx
13+
*.crt
14+
*.cer
15+
secrets/
16+
credentials/
17+
18+
# --- Data directories ---
19+
data/
20+
/deploy/certbot/conf/
21+
/deploy/certbot/www/
622

7-
# Python
23+
# --- Python ---
824
__pycache__/
9-
*.pyc
25+
*.py[cod]
26+
*$py.class
27+
*.so
28+
.Python
29+
build/
30+
develop-eggs/
31+
dist/
32+
downloads/
33+
eggs/
34+
.eggs/
35+
lib/
36+
lib64/
37+
parts/
38+
sdist/
39+
var/
40+
wheels/
41+
share/python-wheels/
1042
*.egg-info/
43+
.installed.cfg
44+
*.egg
45+
MANIFEST
46+
*.pyc
47+
48+
# --- Virtual environments ---
1149
.venv/
1250
venv/
13-
dist/
14-
build/
51+
env/
52+
ENV/
53+
env.bak/
54+
venv.bak/
1555

16-
# Test artifacts
56+
# --- Testing ---
57+
.pytest_cache/
58+
.coverage
59+
coverage.xml
60+
htmlcov/
61+
.tox/
62+
.nox/
63+
nosetests.xml
64+
*.cover
65+
*.py,cover
1766
MagicMock/
1867

19-
# Executables
20-
*.exe
68+
# --- IDEs ---
69+
.vscode/
70+
.idea/
71+
*.swp
72+
*.swo
73+
*~
74+
.DS_Store
75+
Thumbs.db
2176

77+
# --- Node.js (mobile) ---
2278
node_modules/
23-
*.pyc
24-
__pycache__/
25-
.env
79+
npm-debug.log*
80+
yarn-debug.log*
81+
yarn-error.log*
82+
.pnp
83+
.pnp.js
84+
mobile/.expo/
85+
mobile/android/
86+
mobile/ios/
87+
mobile/build/
2688

89+
# --- Build artifacts ---
2790
build-*/
2891
target/
29-
.pytest_cache/
30-
.DS_Store
92+
*.exe
93+
*.dll
94+
*.dylib
95+
96+
# --- Logs ---
97+
*.log
98+
logs/
99+
*.log.*
100+
101+
# --- Docker ---
102+
.dockerignore.local
103+
104+
# --- Misc ---
105+
*.tmp
106+
*.bak
107+
*.swp
108+
.cache/

DEPLOYMENT.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# eVera — Production Deployment Guide
2+
3+
This guide covers deploying eVera to a production server with HTTPS, nginx reverse proxy, and Docker.
4+
5+
---
6+
7+
## Quick Start (Cloud / VPS)
8+
9+
### 1. Prerequisites
10+
11+
- A Linux server (Ubuntu 22.04+ recommended) with Docker and Docker Compose installed
12+
- A domain name pointing to your server (e.g., `evera.yourdomain.com`)
13+
- At least one LLM API key (OpenAI, Gemini, Anthropic, or Groq)
14+
15+
### 2. Clone and Configure
16+
17+
```bash
18+
git clone https://github.com/embeddedos-org/eVera.git
19+
cd eVera
20+
cp .env.example .env
21+
```
22+
23+
Edit `.env` and set:
24+
25+
```env
26+
# Required: at least one LLM provider
27+
VERA_LLM_OPENAI_API_KEY=sk-...
28+
29+
# Required for production security
30+
VERA_SERVER_API_KEY=your-strong-random-key-here
31+
32+
# Your production domain
33+
VERA_SERVER_CORS_ORIGINS=["https://evera.yourdomain.com"]
34+
```
35+
36+
### 3. Configure Nginx
37+
38+
Edit `deploy/nginx/conf.d/evera.conf` and replace `evera.embeddedos.org` with your domain.
39+
40+
### 4. Obtain TLS Certificate
41+
42+
```bash
43+
# First, start nginx in HTTP-only mode to get the cert
44+
docker compose up -d nginx
45+
46+
# Get certificate
47+
docker compose run --rm certbot certonly \
48+
--webroot -w /var/www/certbot \
49+
-d evera.yourdomain.com \
50+
--email your@email.com \
51+
--agree-tos --no-eff-email
52+
53+
# Restart nginx with TLS enabled
54+
docker compose restart nginx
55+
```
56+
57+
### 5. Start All Services
58+
59+
```bash
60+
docker compose up -d
61+
```
62+
63+
### 6. Verify
64+
65+
```bash
66+
curl https://evera.yourdomain.com/health
67+
# Expected: {"status": "ok", ...}
68+
```
69+
70+
---
71+
72+
## Environment Variables Reference
73+
74+
| Variable | Default | Description |
75+
|---|---|---|
76+
| `VERA_SERVER_HOST` | `0.0.0.0` | Bind address (`0.0.0.0` for all interfaces) |
77+
| `VERA_SERVER_PORT` | `8000` | Internal port (nginx proxies to this) |
78+
| `VERA_SERVER_API_KEY` | _(empty)_ | API key for authentication — **set this in production** |
79+
| `VERA_SERVER_CORS_ORIGINS` | `["https://evera.embeddedos.org",...]` | Allowed CORS origins |
80+
| `VERA_SERVER_ZONE_WWW_ENABLED` | `true` | Allow public internet connections |
81+
| `VERA_SERVER_ZONE_WWW_AUTH_REQUIRED` | `true` | Require API key for public connections |
82+
| `VERA_SERVER_ZONE_WWW_RATE_LIMIT_RPM` | `60` | Rate limit: requests per minute per IP |
83+
| `VERA_LLM_OPENAI_API_KEY` | _(empty)_ | OpenAI API key |
84+
| `VERA_LLM_GEMINI_API_KEY` | _(empty)_ | Google Gemini API key |
85+
| `VERA_LLM_ANTHROPIC_API_KEY` | _(empty)_ | Anthropic Claude API key |
86+
| `VERA_LLM_GROQ_API_KEY` | _(empty)_ | Groq API key (fast inference) |
87+
| `VERA_LLM_FALLBACK_ORDER` | `ollama,openai,gemini` | LLM provider fallback order |
88+
89+
---
90+
91+
## Network Zones
92+
93+
eVera uses a three-zone security model:
94+
95+
| Zone | Source | Auth Required | Rate Limited |
96+
|---|---|---|---|
97+
| **LOCAL** | `127.0.0.1`, `::1` | No | No |
98+
| **LAN** | `10.x`, `172.16-31.x`, `192.168.x` | Yes (API key) | No |
99+
| **WWW** | Public internet | Yes (API key) | Yes (60 rpm) |
100+
101+
---
102+
103+
## Chrome Extension
104+
105+
The extension defaults to `https://evera-api.embeddedos.org`. Users can change the server URL in the extension Options page.
106+
107+
To use your own server:
108+
1. Open extension Options
109+
2. Set **Server URL** to `https://evera.yourdomain.com`
110+
3. Set **API Key** if authentication is enabled
111+
4. Click **Save**
112+
113+
---
114+
115+
## Mobile App
116+
117+
The mobile app defaults to `evera-api.embeddedos.org:443` with HTTPS.
118+
119+
To use your own server:
120+
1. Open the app Settings screen
121+
2. Set **Server IP / Hostname** to your domain
122+
3. Enable **Use HTTPS/WSS**
123+
4. Tap **Test & Connect**
124+
125+
---
126+
127+
## GPS / Location Support
128+
129+
eVera supports GPS location for location-aware agents (weather, travel, nearby search).
130+
131+
- **Web**: The browser will prompt for location permission on first visit. Location is sent to `/location/update` and stored in semantic memory.
132+
- **Mobile**: The app requests foreground location permission and sends updates automatically.
133+
- **Privacy**: Location data is stored only in the server's in-memory semantic store and is not persisted to disk by default.
134+
135+
---
136+
137+
## i18n / Language Support
138+
139+
eVera supports 19 languages:
140+
141+
| Code | Language | Code | Language |
142+
|---|---|---|---|
143+
| `en` | English | `ar` | Arabic |
144+
| `es` | Spanish | `de` | German |
145+
| `fr` | French | `pt` | Portuguese |
146+
| `hi` | Hindi | `ja` | Japanese |
147+
| `zh` | Chinese | `ko` | Korean |
148+
| `ru` | Russian | `it` | Italian |
149+
| `te` | Telugu | `ta` | Tamil |
150+
| `nl` | Dutch | `pl` | Polish |
151+
| `tr` | Turkish | `vi` | Vietnamese |
152+
| `th` | Thai | | |
153+
154+
The UI language is auto-detected from the browser's `navigator.language` setting and can be changed via the language selector in the header.
155+
156+
---
157+
158+
## API Endpoints
159+
160+
| Endpoint | Method | Description |
161+
|---|---|---|
162+
| `/` | GET | Web UI |
163+
| `/health` | GET | Health check |
164+
| `/info` | GET | Server information |
165+
| `/status` | GET | Detailed status |
166+
| `/docs` | GET | Interactive API docs (Swagger) |
167+
| `/ws` | WS | Real-time chat WebSocket |
168+
| `/chat` | POST | REST chat endpoint |
169+
| `/agents` | GET | List all agents |
170+
| `/models` | GET | List available LLM models |
171+
| `/location/update` | POST | Update GPS location |
172+
| `/location/current` | GET | Get current GPS location |
173+
| `/i18n/languages` | GET | List supported languages |
174+
| `/i18n/strings/{lang}` | GET | Get UI strings for a language |
175+
| `/events/stream` | GET | SSE event stream |
176+
| `/agents/stream` | GET | SSE agent status stream |
177+
178+
---
179+
180+
## Security Checklist
181+
182+
- [ ] Set `VERA_SERVER_API_KEY` to a strong random value
183+
- [ ] Configure TLS with Let's Encrypt
184+
- [ ] Set `VERA_SERVER_CORS_ORIGINS` to your domain only
185+
- [ ] Keep `VERA_SERVER_ZONE_WWW_AUTH_REQUIRED=true`
186+
- [ ] Regularly rotate API keys
187+
- [ ] Monitor `/alerts` endpoint for anomalies
188+
- [ ] Keep Docker images updated
189+
190+
---
191+
192+
## Monitoring
193+
194+
- **Health**: `GET /health` — deep health check of all subsystems
195+
- **Metrics**: `GET /metrics` — request counts, latency, error rates
196+
- **Alerts**: `GET /alerts` — active and resolved alert conditions
197+
- **Network**: `GET /network/zones` — zone configuration and your IP's zone
198+
199+
---
200+
201+
## Troubleshooting
202+
203+
**Connection refused from mobile/extension:**
204+
- Ensure `VERA_SERVER_HOST=0.0.0.0` in `.env`
205+
- Check firewall allows port 443 (HTTPS) or 8000 (direct)
206+
- Verify nginx is running: `docker compose ps`
207+
208+
**Authentication errors (403):**
209+
- Set `VERA_SERVER_API_KEY` in `.env`
210+
- Pass the key as `Authorization: Bearer <key>` header or `?api_key=<key>` query param
211+
212+
**WebSocket disconnects:**
213+
- Check nginx `proxy_read_timeout` is set to at least 3600s
214+
- Ensure `Upgrade` and `Connection` headers are forwarded by nginx

0 commit comments

Comments
 (0)