From 1363913352722a03e051b15297f72bf16d80106f Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Fri, 7 Nov 2025 17:39:36 +0900
Subject: (김준회) 돌체 업로드 MIME 타입 검증 문제 확장자로 처리
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../ship-vendor-document/new-revision-dialog.tsx   | 51 +++++++++++++++++++++-
 1 file changed, 49 insertions(+), 2 deletions(-)

(limited to 'components/ship-vendor-document/new-revision-dialog.tsx')

diff --git a/components/ship-vendor-document/new-revision-dialog.tsx b/components/ship-vendor-document/new-revision-dialog.tsx
index 91694827..bdbb1bc6 100644
--- a/components/ship-vendor-document/new-revision-dialog.tsx
+++ b/components/ship-vendor-document/new-revision-dialog.tsx
@@ -83,10 +83,46 @@ function FileUploadArea({
 }) {
   const fileInputRef = React.useRef<HTMLInputElement>(null)
 
+  // 파일 검증 함수
+  const validateFiles = (filesToValidate: File[]): { valid: File[], invalid: string[] } => {
+    const MAX_FILE_SIZE = 1024 * 1024 * 1024 // 1GB
+    const FORBIDDEN_EXTENSIONS = ['exe', 'com', 'dll', 'vbs', 'js', 'asp', 'aspx', 'bat', 'cmd']
+    
+    const valid: File[] = []
+    const invalid: string[] = []
+    
+    filesToValidate.forEach(file => {
+      // 파일 크기 검증
+      if (file.size > MAX_FILE_SIZE) {
+        invalid.push(`${file.name}: 파일 크기가 1GB를 초과합니다 (${formatFileSize(file.size)})`)
+        return
+      }
+      
+      // 파일 확장자 검증
+      const extension = file.name.split('.').pop()?.toLowerCase()
+      if (extension && FORBIDDEN_EXTENSIONS.includes(extension)) {
+        invalid.push(`${file.name}: 금지된 파일 형식입니다 (.${extension})`)
+        return
+      }
+      
+      valid.push(file)
+    })
+    
+    return { valid, invalid }
+  }
+
   const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
     const selectedFiles = Array.from(event.target.files || [])
     if (selectedFiles.length > 0) {
-      onFilesChange([...files, ...selectedFiles])
+      const { valid, invalid } = validateFiles(selectedFiles)
+      
+      if (invalid.length > 0) {
+        invalid.forEach(msg => toast.error(msg))
+      }
+      
+      if (valid.length > 0) {
+        onFilesChange([...files, ...valid])
+      }
     }
   }
 
@@ -94,7 +130,15 @@ function FileUploadArea({
     event.preventDefault()
     const droppedFiles = Array.from(event.dataTransfer.files)
     if (droppedFiles.length > 0) {
-      onFilesChange([...files, ...droppedFiles])
+      const { valid, invalid } = validateFiles(droppedFiles)
+      
+      if (invalid.length > 0) {
+        invalid.forEach(msg => toast.error(msg))
+      }
+      
+      if (valid.length > 0) {
+        onFilesChange([...files, ...valid])
+      }
     }
   }
 
@@ -132,6 +176,9 @@ function FileUploadArea({
         <p className="text-xs text-orange-600 mt-1">
           Note: File names cannot contain these characters: &lt; &gt; : &quot; &apos; | ? *
         </p>
+        <p className="text-xs text-red-600 mt-1 font-medium">
+          Forbidden file types: .exe, .com, .dll, .vbs, .js, .asp, .aspx, .bat, .cmd
+        </p>
         <input
           ref={fileInputRef}
           type="file"
-- 
cgit v1.2.3

