mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-09-16 06:35:29 +02:00
The Web UI startup banner always printed 127.0.0.1, even when server.host was bound to 0.0.0.0 or a specific interface. This made users believe the host setting was ignored (the actual listen binding was correct). Pass the configured host into the banner and expand wildcard binds to the machine's real addresses so LAN URLs are shown. Fixes #301 Co-authored-by: sycpro <sycpro@sycprodeMacBook-Pro.local>
115 lines
3.1 KiB
Go
115 lines
3.1 KiB
Go
package termout
|
||
|
||
import (
|
||
"fmt"
|
||
"io"
|
||
"net"
|
||
"os"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// StartupWebUIOptions configures the startup Web UI banner.
|
||
type StartupWebUIOptions struct {
|
||
Scheme string
|
||
Host string
|
||
Port int
|
||
SelfSigned bool
|
||
HTTPRedirect bool
|
||
}
|
||
|
||
// PrintConfigCreated prints a short notice when config.yaml is bootstrapped.
|
||
func PrintConfigCreated() {
|
||
s := New(os.Stdout)
|
||
s.Println("")
|
||
s.Println(s.Green("✔ ") + s.Bold("已创建 config.yaml") + s.Dim("(来自 config.example.yaml)"))
|
||
s.BlankLine()
|
||
}
|
||
|
||
// startupHosts 返回横幅应展示的访问地址。通配地址(含空 host)展开为回环地址
|
||
// 加本机非回环 IPv4;显式 host 原样展示。横幅此前硬编码 127.0.0.1,导致
|
||
// 绑定 0.0.0.0 的用户误以为 server.host 配置未生效(issue #301)。
|
||
func startupHosts(host string) []string {
|
||
host = strings.TrimSpace(host)
|
||
if host != "" && host != "0.0.0.0" && host != "::" && host != "[::]" {
|
||
return []string{host}
|
||
}
|
||
hosts := []string{"127.0.0.1"}
|
||
addrs, err := net.InterfaceAddrs()
|
||
if err != nil {
|
||
return hosts
|
||
}
|
||
for _, addr := range addrs {
|
||
ipNet, ok := addr.(*net.IPNet)
|
||
if !ok || ipNet.IP.IsLoopback() || ipNet.IP.To4() == nil {
|
||
continue
|
||
}
|
||
ip := ipNet.IP.String()
|
||
dup := false
|
||
for _, h := range hosts {
|
||
if h == ip {
|
||
dup = true
|
||
break
|
||
}
|
||
}
|
||
if !dup {
|
||
hosts = append(hosts, ip)
|
||
}
|
||
}
|
||
return hosts
|
||
}
|
||
|
||
// PrintStartupWebUI prints a colored startup banner for the Web UI.
|
||
func PrintStartupWebUI(opts StartupWebUIOptions) {
|
||
printStartupWebUI(os.Stdout, opts)
|
||
}
|
||
|
||
func printStartupWebUI(out io.Writer, opts StartupWebUIOptions) {
|
||
s := New(out)
|
||
scheme := opts.Scheme
|
||
if scheme == "" {
|
||
scheme = "http"
|
||
}
|
||
port := opts.Port
|
||
if port <= 0 {
|
||
port = 8080
|
||
}
|
||
hosts := startupHosts(opts.Host)
|
||
urlFor := func(h string) string {
|
||
return scheme + "://" + net.JoinHostPort(h, strconv.Itoa(port)) + "/"
|
||
}
|
||
|
||
s.BlankLine()
|
||
s.Println(s.Bold(s.Cyan("CYBERSTRIKE AI")) + s.Dim(" / secure workspace"))
|
||
s.Println(s.Dim(strings.Repeat("─", 60)))
|
||
s.Println(s.Green("● ONLINE") + " " + s.Bold(s.White(urlFor(hosts[0]))))
|
||
for _, h := range hosts[1:] {
|
||
s.Println(s.Dim(" Network ") + s.Bold(s.White(urlFor(h))))
|
||
}
|
||
if opts.SelfSigned {
|
||
s.Println(s.Dim(" TLS ") + s.Yellow("self-signed") + s.Dim(" · accept the browser warning once"))
|
||
}
|
||
if opts.HTTPRedirect {
|
||
s.Println(s.Dim(" Redirect ") + fmt.Sprintf("http://%s/ → HTTPS", net.JoinHostPort(hosts[0], strconv.Itoa(port))))
|
||
}
|
||
s.BlankLine()
|
||
}
|
||
|
||
// PrintBootstrapAdminCredentials prints the initial admin password banner.
|
||
func PrintBootstrapAdminCredentials(password string) {
|
||
password = strings.TrimSpace(password)
|
||
if password == "" {
|
||
return
|
||
}
|
||
|
||
s := New(os.Stdout)
|
||
s.Println(s.Bold(s.Yellow("ADMIN SETUP REQUIRED")))
|
||
s.Println(s.Dim(strings.Repeat("─", 60)))
|
||
s.Println(s.Dim(" Username ") + s.Bold(s.White("admin")))
|
||
s.Println(s.Dim(" Password ") + s.Bold(s.Yellow(password)))
|
||
s.BlankLine()
|
||
s.Println(s.Yellow(" ! ") + s.White("Store this password securely. It is shown only once."))
|
||
s.Println(s.Dim(" Change it in Settings immediately after signing in."))
|
||
s.BlankLine()
|
||
}
|