6bb47d4b00
- 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
31 lines
892 B
Go
31 lines
892 B
Go
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
|
|
}
|