Public Source Viewer
비나래아카이브 개발자 포털
실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.
src/config/multer.config.ts
공개 가능
1
import multer from 'multer';
2
import path from 'path';
3
import { randomUUID } from 'crypto';
4
import { PUBLIC_DIR } from '../utils/paths';
5
6
const IMAGE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
7
const IMAGE_MIME_TYPES = new Set(['image/jpeg', 'image/png', 'image/gif', 'image/webp']);
8
9
function imageFileFilter(_req: Express.Request, file: Express.Multer.File, cb: multer.FileFilterCallback): void {
10
const extension = path.extname(file.originalname).toLowerCase();
11
if (IMAGE_EXTENSIONS.has(extension) && IMAGE_MIME_TYPES.has(file.mimetype)) return cb(null, true);
12
cb(new Error('JPG, PNG, GIF 또는 WEBP 이미지만 업로드할 수 있습니다.'));
13
}
14
15
export const storage = multer.diskStorage({
16
destination: function (req, file, cb) {
17
cb(null, path.join(PUBLIC_DIR, 'uploads'));
18
},
19
filename: function (req, file, cb) {
20
cb(null, `${Date.now()}-${randomUUID()}${path.extname(file.originalname).toLowerCase()}`);
21
}
22
});
23
24
export const upload = multer({
25
storage,
26
fileFilter: imageFileFilter,
27
limits: { fileSize: 20 * 1024 * 1024, files: 1 }
28
});
29
30
const profileStorage = multer.diskStorage({
31
destination: function (req, file, cb) {
32
cb(null, path.join(PUBLIC_DIR, 'uploads', 'profiles'));
33
},
34
filename: function (req, file, cb) {
35
const username = (req as any).session?.username || 'unknown';
36
cb(null, `${username}_${Date.now()}${path.extname(file.originalname)}`);
37
}
38
});
39
40
export const profileUpload = multer({
41
storage: profileStorage,
42
fileFilter: (req, file, cb) => {
43
if (/\.(jpg|jpeg|png|gif|webp)$/i.test(path.extname(file.originalname))) {
44
cb(null, true);
45
} else {
46
cb(new Error('이미지 파일만 업로드 가능합니다.'));
47
}
48
},
49
limits: { fileSize: 2 * 1024 * 1024 }
50
});
51
52
export const memoryUpload = multer({
53
storage: multer.memoryStorage(),
54
fileFilter: (req, file, cb) => {
55
if (/\.(jpg|jpeg|png|gif|webp)$/i.test(path.extname(file.originalname))) {
56
cb(null, true);
57
} else {
58
cb(new Error('이미지 파일만 업로드 가능합니다.'));
59
}
60
},
61
limits: { fileSize: 10 * 1024 * 1024 }
62
});
63