b6b345f245
- Refactor email verification and password reset utilities to use new email service. - Introduce email delivery queue and notification delivery model for better tracking. - Enhance file validation and storage services for improved security and ownership management. - Add cron job for cleaning inactive notifications with retention policy. - Update document worker to handle document generation and storage more efficiently. - Implement logging improvements in activity and log workers. - Create comprehensive documentation for new API endpoints and services. - Add unit tests for file validation and notification policies to ensure robustness.
20 lines
1.6 KiB
JavaScript
20 lines
1.6 KiB
JavaScript
const crypto = require("crypto");
|
|
const { extensionFor, sanitizeFilename } = require("./storage.service");
|
|
const detectMimeType = (buffer) => {
|
|
if (!Buffer.isBuffer(buffer) || !buffer.length) return null;
|
|
if (buffer.subarray(0, 3).equals(Buffer.from([0xff, 0xd8, 0xff]))) return "image/jpeg";
|
|
if (buffer.subarray(0, 8).equals(Buffer.from([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]))) return "image/png";
|
|
if (buffer.length >= 12 && buffer.toString("ascii", 0, 4) === "RIFF" && buffer.toString("ascii", 8, 12) === "WEBP") return "image/webp";
|
|
if (buffer.subarray(0, 5).toString("ascii") === "%PDF-") return "application/pdf";
|
|
if (buffer.subarray(0, 4).equals(Buffer.from([0x50,0x4b,0x03,0x04]))) return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
return null;
|
|
};
|
|
const validateUpload = (file) => {
|
|
if (!file?.buffer?.length) throw Object.assign(new Error("Empty files are not allowed"), { status: 400 });
|
|
if (file.buffer.length > Number(process.env.S3_MAX_UPLOAD_BYTES || 5242880)) throw Object.assign(new Error("File exceeds the upload size limit"), { status: 413 });
|
|
const mimeType = detectMimeType(file.buffer);
|
|
if (!mimeType || mimeType !== file.mimetype || !extensionFor(mimeType)) throw Object.assign(new Error("File content does not match an allowed type"), { status: 400 });
|
|
return { mimeType, size: file.buffer.length, checksum: crypto.createHash("sha256").update(file.buffer).digest("hex"), safeName: `${sanitizeFilename(file.originalname).replace(/\.[^.]+$/, "")}${extensionFor(mimeType)}` };
|
|
};
|
|
module.exports = { detectMimeType, validateUpload };
|