diff --git a/backend/gestion/go.mod b/backend/gestion/go.mod index f4119b23..27fa329a 100644 --- a/backend/gestion/go.mod +++ b/backend/gestion/go.mod @@ -3,11 +3,16 @@ module gestion go 1.24.4 require ( + github.com/gabriel-vasile/mimetype v1.4.9 github.com/gin-contrib/cors v1.7.6 github.com/gin-contrib/sessions v1.0.4 github.com/gin-gonic/gin v1.11.0 + github.com/golang-jwt/jwt/v5 v5.3.0 + github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + github.com/redis/go-redis/v9 v9.17.0 + golang.org/x/crypto v0.40.0 ) require ( @@ -16,15 +21,12 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.27.0 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-yaml v1.18.0 // indirect - github.com/golang-jwt/jwt/v5 v5.3.0 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.4.0 // indirect @@ -37,12 +39,10 @@ require ( github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.54.0 // indirect - github.com/redis/go-redis/v9 v9.17.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.0 // indirect go.uber.org/mock v0.5.0 // indirect golang.org/x/arch v0.20.0 // indirect - golang.org/x/crypto v0.40.0 // indirect golang.org/x/mod v0.25.0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/sync v0.16.0 // indirect diff --git a/backend/gestion/go.sum b/backend/gestion/go.sum index fafa241f..9b9bdff2 100644 --- a/backend/gestion/go.sum +++ b/backend/gestion/go.sum @@ -1,3 +1,7 @@ +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= diff --git a/backend/gestion/handlers/product.go b/backend/gestion/handlers/product.go index a95634d1..a564e3bb 100644 --- a/backend/gestion/handlers/product.go +++ b/backend/gestion/handlers/product.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/gabriel-vasile/mimetype" "github.com/gin-gonic/gin" ) @@ -140,14 +141,16 @@ func validateFileMimeType(fileHeader *multipart.FileHeader) (string, error) { } defer file.Close() - // Lire les premiers 512 bytes pour détecter le type MIME - buffer := make([]byte, 512) - _, err = file.Read(buffer) + mtype, err := mimetype.DetectReader(file) if err != nil { return "", err } - mimeType := http.DetectContentType(buffer) + mimeType := mtype.String() + // Normaliser : couper les paramètres éventuels (ex: "video/mp4; codecs=...") + if idx := strings.Index(mimeType, ";"); idx != -1 { + mimeType = strings.TrimSpace(mimeType[:idx]) + } if !allowedMimeTypes[mimeType] { return "", fmt.Errorf("type de fichier non autorisé: %s", mimeType) diff --git a/frontend-admin/src/api/api_admin.ts b/frontend-admin/src/api/api_admin.ts index e1321146..854d9cd1 100644 --- a/frontend-admin/src/api/api_admin.ts +++ b/frontend-admin/src/api/api_admin.ts @@ -343,6 +343,7 @@ export const createProductAdmin = async (formData: FormData) => { formData, { headers: { "Content-Type": "multipart/form-data" }, + timeout: 120000, }, ); return { success: true, data: data.data, message: data.message }; @@ -460,7 +461,7 @@ export const uploadProductMediaAdmin = async ( const { data } = await apiClient.post( `${V2}/admin/protected/products/${productId}/media`, fd, - { headers: { "Content-Type": "multipart/form-data" } }, + { headers: { "Content-Type": "multipart/form-data" }, timeout: 120000 }, ); return { success: true, media: data.media, message: data.message }; };