Files
warpbox-dev/backend/libs/jobs/cleanup.go
Daniel Legt 10ed806153
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m38s
feat(security): add trusted proxies and abuse event cleanup
- Add `WARPBOX_TRUSTED_PROXIES` configuration to restrict accepted forwarded client IP headers to specific proxy IPs/CIDRs, securing client IP resolution.
- Integrate `BanService` into the background cleanup job to automatically purge expired abuse and ban evidence events.
- Update documentation with reverse proxy security guidelines and a production systemd deployment guide.
2026-05-31 21:52:56 +03:00

72 lines
2.1 KiB
Go

package jobs
import (
"log/slog"
"time"
"warpbox.dev/backend/libs/config"
"warpbox.dev/backend/libs/services"
)
func newCleanupJob(cfg config.Config, logger *slog.Logger, uploadService *services.UploadService, banService *services.BanService) job {
return job{
name: "cleanup",
enabled: cfg.CleanupEnabled,
interval: cfg.CleanupEvery,
run: func() {
cleaned, err := cleanupUnavailableBoxes(uploadService, logger)
if err != nil {
logger.Warn("cleanup job failed", "source", "housekeeping", "severity", "warn", "code", 4202, "error", err.Error())
return
}
if cleaned > 0 {
logger.Info("cleanup job complete", "source", "housekeeping", "severity", "user_activity", "code", 2202, "cleaned", cleaned)
}
if banService != nil {
cleanedEvents, err := banService.CleanupAbuseEvents(time.Now().UTC())
if err != nil {
logger.Warn("ban evidence cleanup failed", "source", "housekeeping", "severity", "warn", "code", 4203, "error", err.Error())
return
}
if cleanedEvents > 0 {
logger.Info("ban evidence cleaned", "source", "housekeeping", "severity", "user_activity", "code", 2203, "cleaned", cleanedEvents)
}
}
},
}
}
func RunCleanupNow(uploadService *services.UploadService, logger *slog.Logger) (int, error) {
return cleanupUnavailableBoxes(uploadService, logger)
}
func cleanupUnavailableBoxes(uploadService *services.UploadService, logger *slog.Logger) (int, error) {
boxes, err := uploadService.ListBoxes(0)
if err != nil {
return 0, err
}
now := time.Now().UTC()
cleaned := 0
for _, box := range boxes {
if !shouldDeleteBox(box, now) {
continue
}
if err := uploadService.DeleteBoxWithSource(box.ID, "housekeeping"); err != nil {
return cleaned, err
}
cleaned++
}
if cleaned > 0 {
logger.Info("unavailable boxes cleaned", "source", "housekeeping", "severity", "user_activity", "code", 2201, "cleaned", cleaned)
}
return cleaned, nil
}
func shouldDeleteBox(box services.Box, now time.Time) bool {
if !box.ExpiresAt.After(now) {
return true
}
return box.MaxDownloads > 0 && box.DownloadCount >= box.MaxDownloads
}