This commit is contained in:
@@ -9,8 +9,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
)
|
||||
|
||||
type AuthHandler struct {
|
||||
@@ -168,7 +168,7 @@ func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func setSessionCookie(w http.ResponseWriter, r *http.Request, sessionID string) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "fonu_session",
|
||||
Name: "havline_session",
|
||||
Value: sessionID,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
@@ -197,7 +197,7 @@ func clientIP(r *http.Request) string {
|
||||
|
||||
func clearSessionCookie(w http.ResponseWriter, r *http.Request) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "fonu_session",
|
||||
Name: "havline_session",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
|
||||
@@ -10,19 +10,19 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/backup"
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/db"
|
||||
"github.com/fonu/fonu/internal/discovery"
|
||||
"github.com/fonu/fonu/internal/certificate"
|
||||
"github.com/fonu/fonu/internal/proxy"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/backup"
|
||||
"github.com/havline/havline/internal/certificate"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/db"
|
||||
"github.com/havline/havline/internal/discovery"
|
||||
"github.com/havline/havline/internal/proxy"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
func TestAuthSetupAndLoginFlow(t *testing.T) {
|
||||
conn, err := db.Open(filepath.Join(t.TempDir(), "fonu.db"))
|
||||
conn, err := db.Open(filepath.Join(t.TempDir(), "havline.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("open db: %v", err)
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func TestAuthSetupAndLoginFlow(t *testing.T) {
|
||||
}
|
||||
|
||||
cookie := loginRec.Result().Cookies()[0]
|
||||
if cookie.Name != "fonu_session" || cookie.HttpOnly == false {
|
||||
if cookie.Name != "havline_session" || cookie.HttpOnly == false {
|
||||
t.Fatal("expected httponly session cookie")
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fonu/fonu/internal/backup"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/backup"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
type BackupHandler struct {
|
||||
@@ -52,7 +52,7 @@ func (h *BackupHandler) Restore(w http.ResponseWriter, r *http.Request) {
|
||||
defer file.Close()
|
||||
|
||||
// 上传文件名完全由客户端控制:不能拼进临时路径(../ 可逃出临时目录),交给 CreateTemp 生成
|
||||
out, err := os.CreateTemp("", "fonu-restore-*.tar.gz")
|
||||
out, err := os.CreateTemp("", "havline-restore-*.tar.gz")
|
||||
if err != nil {
|
||||
writeError(r, w, http.StatusInternalServerError, "保存上传文件失败")
|
||||
return
|
||||
@@ -72,7 +72,7 @@ func (h *BackupHandler) Restore(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
_ = os.Remove(tmpPath)
|
||||
writeJSON(w, http.StatusOK, map[string]string{"message": "备份已恢复,建议重启 Fonu"})
|
||||
writeJSON(w, http.StatusOK, map[string]string{"message": "备份已恢复,建议重启 Havline"})
|
||||
}
|
||||
|
||||
// ListArchives 列出留在磁盘上的备份(自动备份 + 手动「立即备份」)。
|
||||
@@ -150,7 +150,7 @@ func (h *BackupHandler) RestoreArchive(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(r, w, http.StatusBadRequest, err.Error(), err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]string{"message": "备份已恢复,建议重启 Fonu"})
|
||||
writeJSON(w, http.StatusOK, map[string]string{"message": "备份已恢复,建议重启 Havline"})
|
||||
}
|
||||
|
||||
// DeleteArchive 删除指定备份
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fonu/fonu/internal/acme"
|
||||
"github.com/havline/havline/internal/acme"
|
||||
)
|
||||
|
||||
type CertHandler struct {
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/chinacidr"
|
||||
"github.com/havline/havline/internal/chinacidr"
|
||||
)
|
||||
|
||||
type ChinaCIDRHandler struct {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fonu/fonu/internal/cloudflared"
|
||||
"github.com/havline/havline/internal/cloudflared"
|
||||
)
|
||||
|
||||
type CloudflareHandler struct {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/fonu/fonu/internal/ddns"
|
||||
"github.com/havline/havline/internal/ddns"
|
||||
)
|
||||
|
||||
type DDNSHandler struct {
|
||||
|
||||
+15
-15
@@ -4,21 +4,21 @@ import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
|
||||
"github.com/fonu/fonu/internal/acme"
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/backup"
|
||||
"github.com/fonu/fonu/internal/chinacidr"
|
||||
"github.com/fonu/fonu/internal/cloudflared"
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/ddns"
|
||||
"github.com/fonu/fonu/internal/discovery"
|
||||
"github.com/fonu/fonu/internal/frp"
|
||||
"github.com/fonu/fonu/internal/metrics"
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/fonu/fonu/internal/traffic"
|
||||
"github.com/fonu/fonu/internal/updater"
|
||||
"github.com/havline/havline/internal/acme"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/backup"
|
||||
"github.com/havline/havline/internal/chinacidr"
|
||||
"github.com/havline/havline/internal/cloudflared"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/ddns"
|
||||
"github.com/havline/havline/internal/discovery"
|
||||
"github.com/havline/havline/internal/frp"
|
||||
"github.com/havline/havline/internal/metrics"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
"github.com/havline/havline/internal/traffic"
|
||||
"github.com/havline/havline/internal/updater"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/discovery"
|
||||
"github.com/havline/havline/internal/discovery"
|
||||
)
|
||||
|
||||
type DiscoveryHandler struct {
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/frp"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/frp"
|
||||
)
|
||||
|
||||
// FRPMultiHandler 承载多服务端 FRP 模块的 HTTP 接口(/api/frpmulti/*),
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/logstore"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/logstore"
|
||||
)
|
||||
|
||||
type LogsHandler struct {
|
||||
|
||||
@@ -9,20 +9,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/backup"
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/db"
|
||||
"github.com/fonu/fonu/internal/discovery"
|
||||
"github.com/fonu/fonu/internal/certificate"
|
||||
"github.com/fonu/fonu/internal/proxy"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/backup"
|
||||
"github.com/havline/havline/internal/certificate"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/db"
|
||||
"github.com/havline/havline/internal/discovery"
|
||||
"github.com/havline/havline/internal/proxy"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
func TestLogsAccessRoute(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
conn, err := db.Open(filepath.Join(dir, "fonu.db"))
|
||||
conn, err := db.Open(filepath.Join(dir, "havline.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("open db: %v", err)
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func TestLogsAccessRoute(t *testing.T) {
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/logs/access?limit=100", nil)
|
||||
req.AddCookie(&http.Cookie{Name: "fonu_session", Value: sessionID})
|
||||
req.AddCookie(&http.Cookie{Name: "havline_session", Value: sessionID})
|
||||
rec := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/metrics"
|
||||
"github.com/havline/havline/internal/metrics"
|
||||
)
|
||||
|
||||
type MetricsHandler struct {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
@@ -15,7 +15,7 @@ const sessionContextKey contextKey = "session_id"
|
||||
func SessionMiddleware(authSvc *auth.Service) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
cookie, err := r.Cookie("fonu_session")
|
||||
cookie, err := r.Cookie("havline_session")
|
||||
if err == nil && cookie.Value != "" {
|
||||
ctx := context.WithValue(r.Context(), sessionContextKey, cookie.Value)
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/db"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/db"
|
||||
)
|
||||
|
||||
func newTokenTestAuth(t *testing.T, scope string) (*auth.Service, string) {
|
||||
t.Helper()
|
||||
conn, err := db.Open(filepath.Join(t.TempDir(), "fonu.db"))
|
||||
conn, err := db.Open(filepath.Join(t.TempDir(), "havline.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("open db: %v", err)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/havline/havline/internal/service"
|
||||
)
|
||||
|
||||
type NginxHandler struct {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
)
|
||||
|
||||
type NotifyHandler struct {
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/logstore"
|
||||
"github.com/fonu/fonu/internal/proxy"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/traffic"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/logstore"
|
||||
"github.com/havline/havline/internal/proxy"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/traffic"
|
||||
)
|
||||
|
||||
type ProxyHandler struct {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/fonu/fonu/internal/proxy"
|
||||
"github.com/havline/havline/internal/proxy"
|
||||
)
|
||||
|
||||
type securityRequest struct {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
)
|
||||
|
||||
// routeSpec 是一条 API 路由的注册信息;测试据此遍历全部路由验证鉴权覆盖。
|
||||
|
||||
@@ -11,14 +11,14 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/fonu/fonu/internal/certificate"
|
||||
"github.com/fonu/fonu/internal/cloudflared"
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/db"
|
||||
"github.com/fonu/fonu/internal/frp"
|
||||
"github.com/fonu/fonu/internal/secret"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
"github.com/havline/havline/internal/certificate"
|
||||
"github.com/havline/havline/internal/cloudflared"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/db"
|
||||
"github.com/havline/havline/internal/frp"
|
||||
"github.com/havline/havline/internal/secret"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
var routeParamPattern = regexp.MustCompile(`\{[^}]+\}`)
|
||||
@@ -26,7 +26,7 @@ var routeParamPattern = regexp.MustCompile(`\{[^}]+\}`)
|
||||
// TestProtectedRoutesRequireAuth 遍历路由表:受保护路由匿名必须 401,公开路由不能被鉴权误拦。
|
||||
func TestProtectedRoutesRequireAuth(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
conn, err := db.Open(filepath.Join(dir, "fonu.db"))
|
||||
conn, err := db.Open(filepath.Join(dir, "havline.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("open db: %v", err)
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/fonu/fonu/internal/validate"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
"github.com/havline/havline/internal/validate"
|
||||
)
|
||||
|
||||
type SettingsHandler struct {
|
||||
|
||||
@@ -11,15 +11,15 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/acme"
|
||||
certstore "github.com/fonu/fonu/internal/certificate"
|
||||
"github.com/fonu/fonu/internal/cloudflared"
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/ddns"
|
||||
"github.com/fonu/fonu/internal/logstore"
|
||||
"github.com/fonu/fonu/internal/publicip"
|
||||
"github.com/fonu/fonu/internal/service"
|
||||
"github.com/fonu/fonu/internal/sysinfo"
|
||||
"github.com/havline/havline/internal/acme"
|
||||
certstore "github.com/havline/havline/internal/certificate"
|
||||
"github.com/havline/havline/internal/cloudflared"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/ddns"
|
||||
"github.com/havline/havline/internal/logstore"
|
||||
"github.com/havline/havline/internal/publicip"
|
||||
"github.com/havline/havline/internal/service"
|
||||
"github.com/havline/havline/internal/sysinfo"
|
||||
)
|
||||
|
||||
type StatusHandler struct {
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/cloudflared"
|
||||
"github.com/fonu/fonu/internal/frp"
|
||||
"github.com/fonu/fonu/internal/notify"
|
||||
"github.com/fonu/fonu/internal/settings"
|
||||
"github.com/havline/havline/internal/cloudflared"
|
||||
"github.com/havline/havline/internal/frp"
|
||||
"github.com/havline/havline/internal/notify"
|
||||
"github.com/havline/havline/internal/settings"
|
||||
)
|
||||
|
||||
// statusPageWindow / statusPageLimit 匿名访问的限流窗口与配额:
|
||||
@@ -99,7 +99,7 @@ func (h *StatusPageHandler) Get(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
payload := statusPagePayload{
|
||||
Title: "Fonu 服务状态",
|
||||
Title: "Havline 服务状态",
|
||||
CodeRequired: codeRequired,
|
||||
CheckedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Routes: make([]statusPageRoute, 0),
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fonu/fonu/internal/auth"
|
||||
"github.com/havline/havline/internal/auth"
|
||||
)
|
||||
|
||||
// 令牌管理挂在 AuthHandler 上:它已经持有 auth.Service,不必再加一层 handler。
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/updater"
|
||||
"github.com/havline/havline/internal/updater"
|
||||
)
|
||||
|
||||
type UpdateHandler struct {
|
||||
|
||||
@@ -3,14 +3,14 @@ package api
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/version"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/version"
|
||||
)
|
||||
|
||||
type versionResponse struct {
|
||||
Version string `json:"version"`
|
||||
NginxHTTPPort int `json:"nginx_http_port"`
|
||||
NginxHTTPSPort int `json:"nginx_https_port"`
|
||||
Version string `json:"version"`
|
||||
NginxHTTPPort int `json:"nginx_http_port"`
|
||||
NginxHTTPSPort int `json:"nginx_https_port"`
|
||||
}
|
||||
|
||||
func Version(cfg config.Config) http.HandlerFunc {
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/fonu/fonu/internal/config"
|
||||
"github.com/fonu/fonu/internal/version"
|
||||
"github.com/havline/havline/internal/config"
|
||||
"github.com/havline/havline/internal/version"
|
||||
)
|
||||
|
||||
func TestVersionEndpoint(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user