ds2api / internal /httpapi /admin /version /handler_version.go
luckfun233
feat: 增强管理员登录安全性,添加IP失败计数器以防止字典攻击,限制请求体大小,优化配置文件权限
33b8f8e
Raw
History Blame Contribute Delete
2.3 kB
package version
import (
"encoding/json"
"net/http"
"os"
"strings"
"time"
"ds2api/internal/version"
)
// defaultReleaseRepo 是默认用于版本检查的 GitHub 仓库(owner/repo)。
// 可通过环境变量 DS2API_VERSION_CHECK_REPO 覆盖。
const defaultReleaseRepo = "luckfun233/ds2api"
func latestReleaseAPIURL() string {
repo := strings.TrimSpace(os.Getenv("DS2API_VERSION_CHECK_REPO"))
if repo == "" {
repo = defaultReleaseRepo
}
return "https://api.github.com/repos/" + repo + "/releases/latest"
}
type latestReleasePayload struct {
TagName string `json:"tag_name"`
HTMLURL string `json:"html_url"`
PublishedAt string `json:"published_at"`
}
func (h *Handler) getVersion(w http.ResponseWriter, _ *http.Request) {
current, source := version.Current()
resp := map[string]any{
"success": true,
"current_version": current,
"current_tag": version.Tag(current),
"source": source,
"checked_at": time.Now().UTC().Format(time.RFC3339),
}
req, err := http.NewRequest(http.MethodGet, latestReleaseAPIURL(), nil)
if err != nil {
resp["check_error"] = err.Error()
writeJSON(w, http.StatusOK, resp)
return
}
req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("User-Agent", "ds2api-version-check")
client := &http.Client{Timeout: 4 * time.Second}
r, err := client.Do(req)
if err != nil {
resp["check_error"] = err.Error()
writeJSON(w, http.StatusOK, resp)
return
}
defer func() { _ = r.Body.Close() }()
if r.StatusCode < 200 || r.StatusCode >= 300 {
resp["check_error"] = "github api status: " + r.Status
writeJSON(w, http.StatusOK, resp)
return
}
var data latestReleasePayload
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
resp["check_error"] = err.Error()
writeJSON(w, http.StatusOK, resp)
return
}
latest := strings.TrimSpace(data.TagName)
if latest == "" {
resp["check_error"] = "missing latest tag"
writeJSON(w, http.StatusOK, resp)
return
}
latestVersion := strings.TrimPrefix(latest, "v")
resp["latest_tag"] = latest
resp["latest_version"] = latestVersion
resp["release_url"] = data.HTMLURL
resp["published_at"] = data.PublishedAt
resp["has_update"] = version.Compare(current, latestVersion) < 0
writeJSON(w, http.StatusOK, resp)
}