package server import ( "crypto/rand" "encoding/hex" "fmt" "log/slog" "net" ) // GetLANIP returns the first non-loopback IPv4 address. func GetLANIP() (string, error) { addrs, err := net.InterfaceAddrs() if err != nil { return "", err } for _, addr := range addrs { if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil { return ipNet.IP.String(), nil } } 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) }