upload tài liệu

This commit is contained in:
2026-08-06 10:44:25 +07:00
parent 92bcb04682
commit 26094ee4d6
10 changed files with 620 additions and 8 deletions

View File

@@ -9,7 +9,10 @@ const {
encryptSensitiveValue,
decryptSensitiveValue,
hashSessionToken,
normalizeOptionalHttpUrl
normalizeOptionalHttpUrl,
isPdfBuffer,
sanitizeDocumentFileName,
getDocumentContentDisposition
} = require('../backend/server');
async function withTestServer(run) {
@@ -55,6 +58,26 @@ test('application URLs accept only HTTP and HTTPS protocols', () => {
assert.match(normalizeOptionalHttpUrl('https://example.com/path'), /^https:\/\/example\.com\/path/);
});
test('PDF uploads require a PDF header and end-of-file marker', () => {
assert.equal(isPdfBuffer(Buffer.from('%PDF-1.7\nbody\n%%EOF')), true);
assert.equal(isPdfBuffer(Buffer.from('%PDF-1.7\nbody without trailer')), false);
assert.equal(isPdfBuffer(Buffer.from('<html>not a pdf</html>')), false);
});
test('document filenames and response headers cannot inject control characters', () => {
const safeName = sanitizeDocumentFileName('bao/cao\r\nInjected: value');
const longName = sanitizeDocumentFileName('a'.repeat(300));
const disposition = getDocumentContentDisposition('Báo cáo tháng 8.pdf');
assert.equal(safeName, 'bao_caoInjected_ value.pdf');
assert.equal(longName.length, 255);
assert.match(longName, /\.pdf$/);
assert.match(disposition, /^inline; filename="/);
assert.match(disposition, /filename\*=UTF-8''/);
assert.equal(disposition.includes('\r'), false);
assert.equal(disposition.includes('\n'), false);
});
test('forged legacy identity headers cannot bypass protected APIs', async () => {
await withTestServer(async baseUrl => {
const response = await fetch(`${baseUrl}/api/users`, {