feat: 补齐第一批已知缺口(关闭握手 / 定时备份 / Origin 白名单 / DTO 收敛)
- httpapi:新增 POST /api/shutdown(admin 会话或 X-Shutdown-Token 常量时间比对) 与 GET /api/rules/switches(recorder 可读,只回布尔开关);settings/standings 的 重复 DTO 收敛到 internal/dto;standings.showIndividualMedals 贯通到设置读写与前端 - export:抽出 export.Service,新增自动备份定时任务(backup.intervalMinutes/keep), 自动、手动、发布前三类备份共用同一把互斥锁与滚动清理 - realtime:/ws 去掉 InsecureSkipVerify,改用 OriginPatterns(同源与无 Origin 放行, 跨站需命中 server.allowedOrigins) - console:停止服务改走 POST /api/shutdown 优雅关闭(5 秒宽限后回退强杀), 服务管理器新增「已连接的大屏实例」卡片 - deploy:build.bat 改用 for /f 读内部署名——set /p 在 chcp 65001 下返回空, 导致最近这次构建的 exe 里根本没注入署名 - docs:备份策略、关闭超时、Origin 配置的说明与实现对齐
This commit is contained in:
1 parent
4d56c73ae6
commit
2c9ff65fc4
42 files changed
+1271
-275
No files matched your search
@@ -6,10 +6,12 @@ import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/auth"
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/export"
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/middleware"
|
||||
"git.yeij.top/AskaEth/Scoreboard/server/internal/webui"
|
||||
)
|
||||
@@ -31,6 +33,11 @@ type Options struct {
|
||||
Auth *auth.Service
|
||||
// DataDir 用于备份目录 data/backups。
|
||||
DataDir string
|
||||
// Backup 可选,手动/发布前备份共用的服务;为空时按 System/Event/DataDir 自动构建。
|
||||
Backup *export.Service
|
||||
// Shutdown 可选,由 main 注入:触发与 SIGINT/SIGTERM 相同的优雅关闭流程。
|
||||
// 为空时 POST /api/shutdown 返回 503,避免把「没接关闭」误报成已受理。
|
||||
Shutdown func()
|
||||
// Display 可选,实时层接入后传入。
|
||||
Display DisplaySender
|
||||
// Realtime 可选,实时层接入后传入:写事务提交后推送变更,并提供在线大屏实例。
|
||||
@@ -51,6 +58,8 @@ type server struct {
|
||||
auth *auth.Service
|
||||
dataDir string
|
||||
projectDir string
|
||||
backups *export.Service
|
||||
shutdown func()
|
||||
display DisplaySender
|
||||
realtime Realtime
|
||||
idem *idempotencyStore
|
||||
@@ -66,6 +75,14 @@ func New(opts Options) http.Handler {
|
||||
if svc == nil {
|
||||
svc = auth.New(opts.System, auth.Options{Logger: logger})
|
||||
}
|
||||
backups := opts.Backup
|
||||
if backups == nil {
|
||||
dir := ""
|
||||
if strings.TrimSpace(opts.DataDir) != "" {
|
||||
dir = filepath.Join(opts.DataDir, "backups")
|
||||
}
|
||||
backups = export.NewService(opts.System, opts.Event, dir, 0, logger)
|
||||
}
|
||||
|
||||
s := &server{
|
||||
logger: logger,
|
||||
@@ -75,6 +92,8 @@ func New(opts Options) http.Handler {
|
||||
auth: svc,
|
||||
dataDir: opts.DataDir,
|
||||
projectDir: opts.ProjectDir,
|
||||
backups: backups,
|
||||
shutdown: opts.Shutdown,
|
||||
display: opts.Display,
|
||||
realtime: opts.Realtime,
|
||||
idem: newIdempotencyStore(10 * time.Minute),
|
||||
|
||||
Reference in new issue
Block a user