package middleware import ( "crypto/subtle" "net/http" "strings" "haixun-backend/internal/config" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/response" ) const WorkerSecretHeader = "X-Worker-Secret" // WorkerSecretMiddleware enforces X-Worker-Secret on internal worker routes. // The secret is REQUIRED: when InternalWorker.Secret is empty the middleware // rejects every request (fail closed) instead of passing through, so the // internal worker endpoints can never be exposed unauthenticated. type WorkerSecretMiddleware struct { cfg config.InternalWorkerConf } func NewWorkerSecretMiddleware(cfg config.InternalWorkerConf) *WorkerSecretMiddleware { return &WorkerSecretMiddleware{cfg: cfg} } func (m *WorkerSecretMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { secret := strings.TrimSpace(m.cfg.Secret) if secret == "" { response.Write(r.Context(), w, nil, app.For(code.Auth).AuthForbidden("internal worker secret is not configured")) return } provided := r.Header.Get(WorkerSecretHeader) if subtle.ConstantTimeCompare([]byte(provided), []byte(secret)) != 1 { response.Write(r.Context(), w, nil, app.For(code.Auth).AuthUnauthorized("invalid worker secret")) return } next(w, r) } }