메일관리 콘솔로그 주석처리 세이브

This commit is contained in:
leeheejin
2025-10-02 18:22:58 +09:00
parent bf58e0c878
commit b4c5be1f17
28 changed files with 3081 additions and 460 deletions

View File

@@ -0,0 +1,111 @@
import multer from 'multer';
import path from 'path';
import fs from 'fs';
// 업로드 디렉토리 경로
const UPLOAD_DIR = path.join(__dirname, '../../uploads/mail-attachments');
// 디렉토리 생성 (없으면)
if (!fs.existsSync(UPLOAD_DIR)) {
fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}
// 간단한 파일명 정규화 함수 (한글-분석.txt 방식)
function normalizeFileName(filename: string): string {
if (!filename) return filename;
try {
// NFC 정규화만 수행 (복잡한 디코딩 제거)
return filename.normalize('NFC');
} catch (error) {
console.error(`Failed to normalize filename: ${filename}`, error);
return filename;
}
}
// 파일 저장 설정
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, UPLOAD_DIR);
},
filename: (req, file, cb) => {
try {
// 파일명 정규화 (한글-분석.txt 방식)
file.originalname = file.originalname.normalize('NFC');
console.log('File upload - Processing:', {
original: file.originalname,
originalHex: Buffer.from(file.originalname).toString('hex'),
});
// UUID + 확장자로 유니크한 파일명 생성
const uniqueId = Date.now() + '-' + Math.round(Math.random() * 1e9);
const ext = path.extname(file.originalname);
const filename = `${uniqueId}${ext}`;
console.log('Generated filename:', {
original: file.originalname,
generated: filename,
});
cb(null, filename);
} catch (error) {
console.error('Filename processing error:', error);
const fallbackFilename = `${Date.now()}-${Math.round(Math.random() * 1e9)}_error.tmp`;
cb(null, fallbackFilename);
}
},
});
// 파일 필터 (허용할 파일 타입)
const fileFilter = (req: any, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
// 파일명 정규화 (fileFilter가 filename보다 먼저 실행되므로 여기서 먼저 처리)
try {
// NFD를 NFC로 정규화만 수행
file.originalname = file.originalname.normalize('NFC');
} catch (error) {
console.warn('Failed to normalize filename in fileFilter:', error);
}
// 위험한 파일 확장자 차단
const dangerousExtensions = ['.exe', '.bat', '.cmd', '.sh', '.ps1', '.msi'];
const ext = path.extname(file.originalname).toLowerCase();
if (dangerousExtensions.includes(ext)) {
console.log(`❌ 차단된 파일 타입: ${ext}`);
cb(new Error(`보안상의 이유로 ${ext} 파일은 첨부할 수 없습니다.`));
return;
}
cb(null, true);
};
// Multer 설정
export const uploadMailAttachment = multer({
storage,
fileFilter,
limits: {
fileSize: 10 * 1024 * 1024, // 10MB 제한
files: 5, // 최대 5개 파일
},
});
// 첨부파일 정보 추출 헬퍼
export interface AttachmentInfo {
filename: string;
originalName: string;
size: number;
path: string;
mimetype: string;
}
export const extractAttachmentInfo = (files: Express.Multer.File[]): AttachmentInfo[] => {
return files.map((file) => ({
filename: file.filename,
originalName: file.originalname,
size: file.size,
path: file.path,
mimetype: file.mimetype,
}));
};