From c720d663f126924b88adf96077b740826616dc82 Mon Sep 17 00:00:00 2001 From: tinkle-community Date: Tue, 9 Dec 2025 18:04:42 +0800 Subject: [PATCH] feat: add TRANSPORT_ENCRYPTION toggle for easier deployment - Add TRANSPORT_ENCRYPTION env config (default: false) - Allow HTTP/IP access when transport encryption is disabled - Add /api/crypto/config endpoint to expose encryption status - Update WebCryptoEnvironmentCheck with 'disabled' status - Update ExchangeConfigModal and AITradersPage to allow form submission when disabled - Add i18n translations for disabled status (EN/CN) - Update README with two deployment modes documentation --- .env.example | 11 ++++ README.md | 55 +++++++++++++++++++ api/crypto_handler.go | 29 ++++++++-- api/server.go | 1 + config/config.go | 11 ++++ docs/i18n/zh-CN/README.md | 55 +++++++++++++++++++ web/src/components/AITradersPage.tsx | 5 +- .../components/WebCryptoEnvironmentCheck.tsx | 35 ++++++++++-- .../traders/ExchangeConfigModal.tsx | 5 +- web/src/i18n/translations.ts | 6 ++ web/src/lib/crypto.ts | 25 ++++++++- 11 files changed, 225 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 3c88c0ce..1b31c050 100644 --- a/.env.example +++ b/.env.example @@ -37,6 +37,17 @@ DATA_ENCRYPTION_KEY=your-base64-encoded-32-byte-key # Note: Replace newlines with \n for single-line format RSA_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END RSA PRIVATE KEY----- +# =========================================== +# Security Options +# =========================================== + +# Transport encryption for API keys (default: false) +# When enabled, browser uses Web Crypto API to encrypt API keys before sending +# Requires HTTPS or localhost to work +# Set to true for enhanced security (HTTPS required) +# Set to false for easier deployment (HTTP/IP access allowed) +TRANSPORT_ENCRYPTION=false + # =========================================== # Optional: External Services # =========================================== diff --git a/README.md b/README.md index 5025c731..75a318fc 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,61 @@ Access Web Interface: **http://localhost:3000** --- +## Server Deployment + +### Quick Deploy (HTTP via IP) + +By default, transport encryption is **disabled**, allowing you to access NOFX via IP address without HTTPS: + +```bash +# Deploy to your server +curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bash +``` + +Access via `http://YOUR_SERVER_IP:3000` - works immediately. + +### Enhanced Security (HTTPS) + +For enhanced security, enable transport encryption in `.env`: + +```bash +TRANSPORT_ENCRYPTION=true +``` + +When enabled, browser uses Web Crypto API to encrypt API keys before transmission. This requires: +- `https://` - Any domain with SSL +- `http://localhost` - Local development + +### Quick HTTPS Setup with Cloudflare + +1. **Add your domain to Cloudflare** (free plan works) + - Go to [dash.cloudflare.com](https://dash.cloudflare.com) + - Add your domain and update nameservers + +2. **Create DNS record** + - Type: `A` + - Name: `nofx` (or your subdomain) + - Content: Your server IP + - Proxy status: **Proxied** (orange cloud) + +3. **Configure SSL/TLS** + - Go to SSL/TLS settings + - Set encryption mode to **Flexible** + + ``` + User ──[HTTPS]──→ Cloudflare ──[HTTP]──→ Your Server:3000 + ``` + +4. **Enable transport encryption** + ```bash + # Edit .env and set + TRANSPORT_ENCRYPTION=true + ``` + +5. **Done!** Access via `https://nofx.yourdomain.com` + +--- + ## Initial Setup (Web Interface) After starting the system, configure through the web interface: diff --git a/api/crypto_handler.go b/api/crypto_handler.go index fbbf0fa6..c78022bc 100644 --- a/api/crypto_handler.go +++ b/api/crypto_handler.go @@ -3,6 +3,7 @@ package api import ( "log" "net/http" + "nofx/config" "nofx/crypto" "github.com/gin-gonic/gin" @@ -20,15 +21,35 @@ func NewCryptoHandler(cryptoService *crypto.CryptoService) *CryptoHandler { } } +// ==================== Crypto Config Endpoint ==================== + +// HandleGetCryptoConfig Get crypto configuration +func (h *CryptoHandler) HandleGetCryptoConfig(c *gin.Context) { + cfg := config.Get() + c.JSON(http.StatusOK, gin.H{ + "transport_encryption": cfg.TransportEncryption, + }) +} + // ==================== Public Key Endpoint ==================== // HandleGetPublicKey Get server public key func (h *CryptoHandler) HandleGetPublicKey(c *gin.Context) { - publicKey := h.cryptoService.GetPublicKeyPEM() + cfg := config.Get() + if !cfg.TransportEncryption { + c.JSON(http.StatusOK, gin.H{ + "public_key": "", + "algorithm": "", + "transport_encryption": false, + }) + return + } - c.JSON(http.StatusOK, map[string]string{ - "public_key": publicKey, - "algorithm": "RSA-OAEP-2048", + publicKey := h.cryptoService.GetPublicKeyPEM() + c.JSON(http.StatusOK, gin.H{ + "public_key": publicKey, + "algorithm": "RSA-OAEP-2048", + "transport_encryption": true, }) } diff --git a/api/server.go b/api/server.go index ef652274..ed131adb 100644 --- a/api/server.go +++ b/api/server.go @@ -95,6 +95,7 @@ func (s *Server) setupRoutes() { api.GET("/config", s.handleGetSystemConfig) // Crypto related endpoints (no authentication required) + api.GET("/crypto/config", s.cryptoHandler.HandleGetCryptoConfig) api.GET("/crypto/public-key", s.cryptoHandler.HandleGetPublicKey) api.POST("/crypto/decrypt", s.cryptoHandler.HandleDecryptSensitiveData) diff --git a/config/config.go b/config/config.go index 3b550dcb..163ab491 100644 --- a/config/config.go +++ b/config/config.go @@ -16,6 +16,11 @@ type Config struct { APIServerPort int JWTSecret string RegistrationEnabled bool + + // Security configuration + // TransportEncryption enables browser-side encryption for API keys + // Requires HTTPS or localhost. Set to false for HTTP access via IP. + TransportEncryption bool } // Init initializes global configuration (from .env) @@ -43,6 +48,12 @@ func Init() { } } + // Transport encryption: default false for easier deployment + // Set TRANSPORT_ENCRYPTION=true to enable (requires HTTPS or localhost) + if v := os.Getenv("TRANSPORT_ENCRYPTION"); v != "" { + cfg.TransportEncryption = strings.ToLower(v) == "true" + } + global = cfg } diff --git a/docs/i18n/zh-CN/README.md b/docs/i18n/zh-CN/README.md index e908686d..10a63f33 100644 --- a/docs/i18n/zh-CN/README.md +++ b/docs/i18n/zh-CN/README.md @@ -167,6 +167,61 @@ npm run dev --- +## 服务器部署 + +### 快速部署 (HTTP/IP 访问) + +默认情况下,传输加密已**禁用**,可直接通过 IP 地址访问 NOFX: + +```bash +# 部署到你的服务器 +curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bash +``` + +通过 `http://你的服务器IP:3000` 访问 - 立即可用。 + +### 增强安全 (HTTPS) + +如需增强安全性,在 `.env` 中启用传输加密: + +```bash +TRANSPORT_ENCRYPTION=true +``` + +启用后,浏览器会使用 Web Crypto API 在传输前加密 API 密钥。此功能需要: +- `https://` - 任何有 SSL 证书的域名 +- `http://localhost` - 本地开发 + +### Cloudflare 快速配置 HTTPS + +1. **添加域名到 Cloudflare** (免费计划即可) + - 访问 [dash.cloudflare.com](https://dash.cloudflare.com) + - 添加域名并更新 DNS 服务器 + +2. **创建 DNS 记录** + - 类型: `A` + - 名称: `nofx` (或你的子域名) + - 内容: 你的服务器 IP + - 代理状态: **已代理** (橙色云朵) + +3. **配置 SSL/TLS** + - 进入 SSL/TLS 设置 + - 加密模式选择 **灵活** + + ``` + 用户 ──[HTTPS]──→ Cloudflare ──[HTTP]──→ 你的服务器:3000 + ``` + +4. **启用传输加密** + ```bash + # 编辑 .env 并设置 + TRANSPORT_ENCRYPTION=true + ``` + +5. **完成!** 通过 `https://nofx.你的域名.com` 访问 + +--- + ## 初始配置 (Web 界面) 启动系统后,通过 Web 界面进行配置: diff --git a/web/src/components/AITradersPage.tsx b/web/src/components/AITradersPage.tsx index 7c02f961..3192a220 100644 --- a/web/src/components/AITradersPage.tsx +++ b/web/src/components/AITradersPage.tsx @@ -1844,7 +1844,10 @@ function ExchangeConfigModal({ color: '#EAECEF', }} aria-label={t('selectExchange', language)} - disabled={webCryptoStatus !== 'secure'} + disabled={ + webCryptoStatus !== 'secure' && + webCryptoStatus !== 'disabled' + } required >