fix: token 改为配置文件读取,不再自动生成;UI 全部汉化
This commit is contained in:
@@ -11,3 +11,7 @@ doubao:
|
|||||||
server:
|
server:
|
||||||
port: 8443 # env: PORT
|
port: 8443 # env: PORT
|
||||||
tls_auto: true # env: TLS_AUTO — 自动 TLS (AnyIP + 自签名降级)
|
tls_auto: true # env: TLS_AUTO — 自动 TLS (AnyIP + 自签名降级)
|
||||||
|
|
||||||
|
# 安全配置
|
||||||
|
security:
|
||||||
|
token: "" # 留空则不需要认证;填写后访问需携带 token 参数
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ type DoubaoConfig struct {
|
|||||||
ResourceID string `yaml:"resource_id"`
|
ResourceID string `yaml:"resource_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SecurityConfig holds authentication settings.
|
||||||
|
type SecurityConfig struct {
|
||||||
|
Token string `yaml:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
// ServerConfig holds server settings.
|
// ServerConfig holds server settings.
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
@@ -21,6 +26,7 @@ type ServerConfig struct {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Doubao DoubaoConfig `yaml:"doubao"`
|
Doubao DoubaoConfig `yaml:"doubao"`
|
||||||
Server ServerConfig `yaml:"server"`
|
Server ServerConfig `yaml:"server"`
|
||||||
|
Security SecurityConfig `yaml:"security"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaults returns a Config with default values.
|
// defaults returns a Config with default values.
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,13 +19,3 @@ func GetLANIP() (string, error) {
|
|||||||
return "", fmt.Errorf("no LAN IP found")
|
return "", fmt.Errorf("no LAN IP found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateToken creates a cryptographically random token for WS auth.
|
|
||||||
func GenerateToken() string {
|
|
||||||
b := make([]byte, 16)
|
|
||||||
if _, err := rand.Read(b); err != nil {
|
|
||||||
slog.Error("failed to generate token", "error", err)
|
|
||||||
// Fallback to a less secure but functional token
|
|
||||||
return "voicepaste-fallback-token"
|
|
||||||
}
|
|
||||||
return hex.EncodeToString(b)
|
|
||||||
}
|
|
||||||
|
|||||||
28
main.go
28
main.go
@@ -49,8 +49,8 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate auth token
|
// Read token from config (empty = no auth required)
|
||||||
token := server.GenerateToken()
|
token := cfg.Security.Token
|
||||||
|
|
||||||
// TLS setup
|
// TLS setup
|
||||||
var tlsResult *vpTLS.Result
|
var tlsResult *vpTLS.Result
|
||||||
@@ -67,24 +67,34 @@ func main() {
|
|||||||
host = tlsResult.Host
|
host = tlsResult.Host
|
||||||
}
|
}
|
||||||
// Build URL
|
// Build URL
|
||||||
url := fmt.Sprintf("%s://%s:%d/?token=%s", scheme, host, cfg.Server.Port, token)
|
var url string
|
||||||
|
if token != "" {
|
||||||
|
url = fmt.Sprintf("%s://%s:%d/?token=%s", scheme, host, cfg.Server.Port, token)
|
||||||
|
} else {
|
||||||
|
url = fmt.Sprintf("%s://%s:%d/", scheme, host, cfg.Server.Port)
|
||||||
|
}
|
||||||
// Print connection info
|
// Print connection info
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("╔══════════════════════════════════════╗")
|
fmt.Println("╔══════════════════════════════════════╗")
|
||||||
fmt.Println("║ VoicePaste Ready ║")
|
fmt.Println("║ VoicePaste 就绪 ║")
|
||||||
fmt.Println("╚══════════════════════════════════════╝")
|
fmt.Println("╚══════════════════════════════════════╝")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" URL: %s\n", url)
|
fmt.Printf(" 地址: %s\n", url)
|
||||||
if tlsResult != nil && tlsResult.AnyIP {
|
if tlsResult != nil && tlsResult.AnyIP {
|
||||||
fmt.Println(" TLS: AnyIP (browser-trusted)")
|
fmt.Println(" 证书: AnyIP(浏览器信任)")
|
||||||
} else if cfg.Server.TLSAuto {
|
} else if cfg.Server.TLSAuto {
|
||||||
fmt.Println(" TLS: self-signed (browser will warn)")
|
fmt.Println(" 证书: 自签名(浏览器会警告)")
|
||||||
|
}
|
||||||
|
if token != "" {
|
||||||
|
fmt.Println(" 认证: 已启用")
|
||||||
|
} else {
|
||||||
|
fmt.Println(" 认证: 未启用(无需 token)")
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
printQRCode(url)
|
printQRCode(url)
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" Scan QR code with your phone to connect.")
|
fmt.Println(" 用手机扫描二维码连接")
|
||||||
fmt.Println(" Press Ctrl+C to stop.")
|
fmt.Println(" 按 Ctrl+C 停止服务")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
// Create and start server
|
// Create and start server
|
||||||
webContent, _ := fs.Sub(webFS, "web")
|
webContent, _ := fs.Sub(webFS, "web")
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
<h1>VoicePaste</h1>
|
<h1>VoicePaste</h1>
|
||||||
<div id="status" class="status disconnected">
|
<div id="status" class="status disconnected">
|
||||||
<span class="dot"></span>
|
<span class="dot"></span>
|
||||||
<span id="status-text">Connecting...</span>
|
<span id="status-text">连接中…</span>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section id="preview-section">
|
<section id="preview-section">
|
||||||
<div id="preview" class="preview-box">
|
<div id="preview" class="preview-box">
|
||||||
<p id="preview-text" class="placeholder">Press and hold to speak</p>
|
<p id="preview-text" class="placeholder">按住说话…</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@
|
|||||||
|
|
||||||
<section id="history-section">
|
<section id="history-section">
|
||||||
<div class="history-header">
|
<div class="history-header">
|
||||||
<h2>History</h2>
|
<h2>历史记录</h2>
|
||||||
<button id="clear-history" class="text-btn">Clear</button>
|
<button id="clear-history" class="text-btn">清空</button>
|
||||||
</div>
|
</div>
|
||||||
<ul id="history-list"></ul>
|
<ul id="history-list"></ul>
|
||||||
<p id="history-empty" class="placeholder">No history yet</p>
|
<p id="history-empty" class="placeholder">暂无记录</p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user