feat: add admin panel with multi-chain support and notification system

- Add full admin REST API: auth, API keys, chains, chain tokens, wallets,
  orders, RPC nodes, settings, dashboard stats, notifications
- Add JWT-based admin authentication and API key auth middleware
- Add multi-chain listeners: BSC, ETH, Polygon, Plasma, EVM WebSocket
- Add RPC node health check job with automatic failover
- Add Telegram notification channel for order events
- Add installer for first-run database initialization
- Add new DB models: admin_user, api_key, chain, chain_token,
  rpc_node, settings, notification_channel
- Add order statistics aggregation (daily/monthly/by-chain)
- Serve built admin SPA from embedded www/ assets
- Add comprehensive test coverage for all new features
This commit is contained in:
line-6000
2026-04-22 02:28:31 +08:00
parent 097c716714
commit 6bb47d4b00
247 changed files with 9933 additions and 1279 deletions
+30
View File
@@ -0,0 +1,30 @@
package http
import (
"os"
"path/filepath"
"strings"
)
// ResolveSPAFilePath normalizes a wildcard SPA path and maps it under wwwRoot.
// It strips any leading slash and blocks path traversal outside wwwRoot.
// The second return value indicates whether the caller should try os.Stat
// against the returned path (true) or directly fall back to index.html (false).
func ResolveSPAFilePath(wwwRoot, wildcard string) (string, bool) {
indexPath := filepath.Join(wwwRoot, "index.html")
cleaned := strings.TrimPrefix(filepath.Clean(wildcard), "/")
if cleaned == "" || cleaned == "." {
return indexPath, false
}
requestedPath := filepath.Join(wwwRoot, cleaned)
base := filepath.Clean(wwwRoot)
resolved := filepath.Clean(requestedPath)
if resolved != base && !strings.HasPrefix(resolved, base+string(os.PathSeparator)) {
return indexPath, false
}
return requestedPath, true
}