Release 4.0.0+1: rebrand Navis → EvilFox; centralized Remnawave auto-provisioning (panel credentials baked into binary); remove Remnawave API UI; Windows 4.0.0.1.
Keep dist/navis-release/ path and ship Navis.exe as a same-hash alias of EvilFox.exe so 3.x clients can still update from the Windows branch feed.
This commit is contained in:
@@ -183,7 +183,7 @@ func doGET(ctx context.Context, client *http.Client, s Settings, endpoint string
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", "Navis/3.9 (Remnawave)")
|
||||
req.Header.Set("User-Agent", "EvilFox/4.0 (Remnawave)")
|
||||
req.Header.Set("Accept", "*/*")
|
||||
if auth && s.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+s.Token)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package remnawave
|
||||
|
||||
// Centralized (NordVPN-style) provisioning: the panel address and API token
|
||||
// are baked into the binary at build time, so every user gets configs
|
||||
// automatically and cannot change the panel.
|
||||
//
|
||||
// build.bat copies configs/remnawave-api.json into embeddedcfg/ before
|
||||
// `go build`; the copy is gitignored so credentials never land in the repo.
|
||||
// Without the embedded file the app falls back to the external
|
||||
// configs/remnawave-api.json (developer mode).
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"embed"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:embed embeddedcfg
|
||||
var embeddedCfgFS embed.FS
|
||||
|
||||
// EmbeddedAdminConfig returns the admin config baked into the binary,
|
||||
// or nil when this build has no embedded credentials.
|
||||
func EmbeddedAdminConfig() *AdminConfig {
|
||||
data, err := embeddedCfgFS.ReadFile("embeddedcfg/remnawave-api.json")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
cfg, err := parseAdminConfig(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// GenerateUsername makes a unique panel username for silent auto-provisioning
|
||||
// (users never type anything): "fox_" + 10 hex chars, e.g. fox_3fa9c02b71.
|
||||
func GenerateUsername() string {
|
||||
var b [5]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
// Keep within Remnawave's 6–34 char username limit.
|
||||
s := fmt.Sprintf("fox_%x%x", os.Getpid()&0xffff, time.Now().UnixNano()&0xffffffff)
|
||||
if len(s) > 34 {
|
||||
s = s[:34]
|
||||
}
|
||||
return s
|
||||
}
|
||||
return "fox_" + hex.EncodeToString(b[:])
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"_comment": "build.bat overwrites remnawave-api.json here from configs/ before go build. This placeholder keeps the embed directory non-empty for go build without credentials."
|
||||
}
|
||||
@@ -47,12 +47,26 @@ func AdminConfigPath(cfgPath string) string {
|
||||
return filepath.Join(filepath.Dir(cfgPath), "remnawave-api.json")
|
||||
}
|
||||
|
||||
// ResolveAdminConfig prefers the baked-in (embedded) panel credentials;
|
||||
// falls back to configs/remnawave-api.json for local/developer builds.
|
||||
func ResolveAdminConfig(cfgPath string) (*AdminConfig, error) {
|
||||
if cfg := EmbeddedAdminConfig(); cfg != nil {
|
||||
return cfg, nil
|
||||
}
|
||||
return LoadAdminConfig(AdminConfigPath(cfgPath))
|
||||
}
|
||||
|
||||
// LoadAdminConfig reads and validates the admin API config file.
|
||||
func LoadAdminConfig(path string) (*AdminConfig, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("нет файла %s (скопируйте remnawave-api.example.json и вставьте ключ)", filepath.Base(path))
|
||||
}
|
||||
return parseAdminConfig(data)
|
||||
}
|
||||
|
||||
// parseAdminConfig validates raw remnawave-api.json bytes (file or embedded).
|
||||
func parseAdminConfig(data []byte) (*AdminConfig, error) {
|
||||
var cfg AdminConfig
|
||||
if err := json.Unmarshal(bytes.TrimPrefix(data, []byte{0xEF, 0xBB, 0xBF}), &cfg); err != nil {
|
||||
return nil, fmt.Errorf("remnawave-api.json: некорректный JSON: %w", err)
|
||||
@@ -252,7 +266,7 @@ func adminDo(ctx context.Context, client *http.Client, cfg *AdminConfig, method,
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
req.Header.Set("User-Agent", "Navis/3.10 (Remnawave provision)")
|
||||
req.Header.Set("User-Agent", "EvilFox/4.0 (Remnawave provision)")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
Reference in New Issue
Block a user