Files
gongxue-base/apps/server/src/common/mime.spec.ts
wangziqi 99ea931409 fix(security): 认证/越权/注入/上传/凭据全链路加固
由 OCR(open-codereview.ai,deepseek-v4-flash)审查驱动修复:
- JWT 生产必填、密码 8-72 字节、防枚举;全局 ValidationPipe
- classes/dashboard/schedules/students/attendance/archive/exams 越权与 IDOR 修复
- LIKE 通配符转义(14 处);上传 10MB 上限 + MIME 白名单 + 附件 XSS
- 集成配置 appSecret AES 加密 + 回填脚本;审计 best-effort;IP 来源防伪造

Reviewed-by: OCR (open-codereview.ai)
2026-08-09 21:29:22 +08:00

53 lines
2.2 KiB
TypeScript

import { normalizeMimeType, isInlineSafeMimeType } from './mime';
describe('normalizeMimeType', () => {
it.each([
['report.pdf', 'application/pdf'],
['photo.png', 'image/png'],
['pic.jpeg', 'image/jpeg'],
['pic.jpg', 'image/jpeg'],
['anim.webp', 'image/webp'],
['doc.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
['sheet.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
['data.csv', 'text/csv'],
['notes.txt', 'text/plain'],
])('maps %s to %s by extension', (filename, expected) => {
expect(normalizeMimeType(filename)).toBe(expected);
});
it('is case-insensitive for the extension', () => {
expect(normalizeMimeType('REPORT.PDF')).toBe('application/pdf');
expect(normalizeMimeType('Photo.JPG')).toBe('image/jpeg');
});
it('ignores a spoofed client mimeType', () => {
expect(normalizeMimeType('evil.png', 'text/html')).toBe('image/png');
expect(normalizeMimeType('evil.html', 'image/png')).toBe('application/octet-stream');
});
it('falls back to octet-stream for unknown/unsafe extensions', () => {
expect(normalizeMimeType('script.svg')).toBe('application/octet-stream');
expect(normalizeMimeType('payload.html')).toBe('application/octet-stream');
expect(normalizeMimeType('virus.exe')).toBe('application/octet-stream');
expect(normalizeMimeType('noextension')).toBe('application/octet-stream');
expect(normalizeMimeType('')).toBe('application/octet-stream');
});
});
describe('isInlineSafeMimeType', () => {
it('allows images and pdf', () => {
expect(isInlineSafeMimeType('application/pdf')).toBe(true);
expect(isInlineSafeMimeType('image/png')).toBe(true);
expect(isInlineSafeMimeType('image/jpeg')).toBe(true);
expect(isInlineSafeMimeType('image/webp')).toBe(true);
});
it('rejects document, archive and scriptable types', () => {
expect(isInlineSafeMimeType('application/octet-stream')).toBe(false);
expect(isInlineSafeMimeType('text/html')).toBe(false);
expect(isInlineSafeMimeType('image/svg+xml')).toBe(false);
expect(isInlineSafeMimeType('text/plain')).toBe(false);
expect(isInlineSafeMimeType('')).toBe(false);
});
});