继续更新 update 门户站点界面和功能
build-winui / winui (push) Has been cancelled

This commit is contained in:
QWQLwToo
2026-06-26 20:17:34 +08:00
parent f525e5f3ba
commit 2513eb2903
68 changed files with 5586 additions and 3195 deletions
@@ -3,6 +3,7 @@ package feedback
import (
"archive/zip"
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
@@ -26,8 +27,25 @@ import (
const PackageMagic = "YMHUTFB1"
const (
ErrorTooLarge = "TOO_LARGE"
ErrorMissingField = "MISSING_FIELD"
ErrorInvalidPayload = "INVALID_PAYLOAD"
ErrorInvalidTimestamp = "INVALID_TIMESTAMP"
ErrorInvalidSignature = "INVALID_SIGNATURE"
ErrorInvalidPackage = "INVALID_PACKAGE"
ErrorInvalidEncryptedPackage = "INVALID_ENCRYPTED_PACKAGE"
ErrorDecryptFailed = "DECRYPT_FAILED"
ErrorHashMismatch = "HASH_MISMATCH"
ErrorServerConfig = "SERVER_CONFIG"
)
var feedbackCodePattern = regexp.MustCompile(`^FB-[0-9]{8}-[A-F0-9]{6}$`)
type requestContextKey string
const duplicateContextKey requestContextKey = "ymhut.feedback.duplicate"
type Service struct {
cfg *config.Config
store *db.Store
@@ -64,7 +82,7 @@ func (s *Service) Submit(r *http.Request) (db.Feedback, error) {
if strings.Contains(contentType, "multipart/form-data") {
if item, err := s.submitMultipart(r); err == nil {
return item, nil
} else if hasSignedFields(r) {
} else if hasSignedFields(r) || !strings.Contains(strings.ToLower(err.Error()), "signed multipart fields are required") {
return db.Feedback{}, err
}
}
@@ -151,6 +169,7 @@ func (s *Service) submitMultipart(r *http.Request) (db.Feedback, error) {
code = db.NewFeedbackCode()
}
if existing, err := s.store.GetFeedback(code); err == nil {
setDuplicateSubmission(r, true)
return existing, nil
}
file, _, err := r.FormFile("package")
@@ -197,9 +216,48 @@ func (s *Service) submitMultipart(r *http.Request) (db.Feedback, error) {
return db.Feedback{}, err
}
item := buildRecord(code, payload, info, encryptedPath, packagePath, packageSha256, strings.ToLower(payload.PlainPackageSha256), r.RemoteAddr)
setDuplicateSubmission(r, false)
return item, s.store.InsertFeedback(item)
}
func DuplicateSubmission(r *http.Request) bool {
duplicate, _ := r.Context().Value(duplicateContextKey).(bool)
return duplicate
}
func setDuplicateSubmission(r *http.Request, duplicate bool) {
*r = *r.WithContext(context.WithValue(r.Context(), duplicateContextKey, duplicate))
}
func LegacyError(err error) (string, int) {
if err == nil {
return "", http.StatusOK
}
lower := strings.ToLower(err.Error())
switch {
case strings.Contains(lower, "too large"):
return ErrorTooLarge, http.StatusRequestEntityTooLarge
case strings.Contains(lower, "signed multipart fields") || strings.Contains(lower, "missing package"):
return ErrorMissingField, http.StatusBadRequest
case strings.Contains(lower, "timestamp outside"):
return ErrorInvalidTimestamp, http.StatusBadRequest
case strings.Contains(lower, "invalid request signature"):
return ErrorInvalidSignature, http.StatusUnauthorized
case strings.Contains(lower, "hash mismatch") || strings.Contains(lower, "invalid package hash"):
return ErrorHashMismatch, http.StatusBadRequest
case strings.Contains(lower, "encrypted package format") || strings.Contains(lower, "encrypted package is required"):
return ErrorInvalidEncryptedPackage, http.StatusBadRequest
case strings.Contains(lower, "message authentication failed") || strings.Contains(lower, "decrypt"):
return ErrorDecryptFailed, http.StatusBadRequest
case strings.Contains(lower, "payload") || strings.Contains(lower, "json"):
return ErrorInvalidPayload, http.StatusBadRequest
case strings.Contains(lower, "zip") || strings.Contains(lower, "package"):
return ErrorInvalidPackage, http.StatusBadRequest
default:
return ErrorServerConfig, http.StatusBadRequest
}
}
func hasSignedFields(r *http.Request) bool {
if r.MultipartForm == nil {
return false