feat: add Docker infrastructure, migrations, CI/CD client, session cleanup, tests
Docker & Deployment: - Add Dockerfile (multi-stage, alpine, non-root) - Add docker-compose.yml (caddy, backend, postgres, watchtower) - Add Caddyfile (TLS, file_server, reverse proxy) - Add .env.example Database: - Add migrations/001_init.sql (all tables + indexes) CI/CD: - Add cmd/ci-release/main.go (launcher binary upload tool) Session management: - Add internal/session/cleanup.go (background expired session cleanup) - Integrate cleanup worker into main.go Bug fixes: - Fix launcherLatest download URL to include version segment - Fix serveLauncherAsset path to match route pattern - Add Content-Type detection from file extension in CAS serveFile - Add empty-field validation in webLogin - Format string fix in ci-release (%d → %s for resp.Status) Tests: - Add internal/auth/auth_test.go (8 tests) - Add internal/cas/cas_test.go (7 tests) - Add internal/session/cleanup_test.go (1 test) - Add internal/api/api_test.go (5 tests) - All tests passing, go vet clean Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -64,7 +64,7 @@ func (h *Handler) RegisterRoutes(mux *http.ServeMux) {
|
||||
mux.HandleFunc("GET /api/web/profile/{uuid}", h.getProfile)
|
||||
|
||||
// Skin serving.
|
||||
mux.HandleFunc("GET /skins/{hash}.png", h.serveSkin)
|
||||
mux.HandleFunc("GET /skins/{hash}", h.serveSkin)
|
||||
}
|
||||
|
||||
// ── Request / Response types ──────────────────────────────────
|
||||
@@ -211,6 +211,11 @@ func (h *Handler) webLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.Username == "" || req.Password == "" {
|
||||
writeError(w, http.StatusBadRequest, "Username and password are required")
|
||||
return
|
||||
}
|
||||
|
||||
var user database.User
|
||||
err = h.db.Pool().QueryRow(r.Context(),
|
||||
`SELECT id, username, password_hash, uuid FROM users
|
||||
@@ -442,8 +447,8 @@ func (h *Handler) launcherLatest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
downloadURL := fmt.Sprintf("%s/files/launcher/%s/%s/%s",
|
||||
h.cfg.BaseURL, osParam, archParam, filepath.Base(release.FilePath))
|
||||
downloadURL := fmt.Sprintf("%s/files/launcher/%s/%s/%s/%s",
|
||||
h.cfg.BaseURL, release.Version, osParam, archParam, filepath.Base(release.FilePath))
|
||||
|
||||
writeJSON(w, http.StatusOK, launcherLatestResponse{
|
||||
Version: release.Version,
|
||||
|
||||
Reference in New Issue
Block a user