first commit
This commit is contained in:
commit
c9fb67e751
423 files changed
+53287
No files matched your search
@@ -0,0 +1,122 @@
|
||||
import { createHash } from 'crypto';
|
||||
import { ExifTool } from 'exiftool-vendored';
|
||||
import imageSize from 'image-size';
|
||||
import PDFParser from 'pdf2json';
|
||||
import { detectFileType } from 'detect-file-type';
|
||||
|
||||
export class FileValidator {
|
||||
private exiftool: ExifTool;
|
||||
|
||||
constructor() {
|
||||
this.exiftool = new ExifTool();
|
||||
}
|
||||
|
||||
async validateFile(file: Buffer, mimeType: string) {
|
||||
// Validação básica de integridade
|
||||
const basicValidation = await this.performBasicValidation(file);
|
||||
if (!basicValidation.valid) {
|
||||
return basicValidation;
|
||||
}
|
||||
|
||||
// Validação específica por tipo
|
||||
switch (mimeType) {
|
||||
case 'application/pdf':
|
||||
return await this.validatePDF(file);
|
||||
case 'image/jpeg':
|
||||
case 'image/png':
|
||||
return await this.validateImage(file, mimeType);
|
||||
default:
|
||||
return { valid: false, error: 'Tipo de arquivo não suportado' };
|
||||
}
|
||||
}
|
||||
|
||||
private async performBasicValidation(file: Buffer) {
|
||||
// Verificar tamanho mínimo
|
||||
if (file.length < 100) {
|
||||
return { valid: false, error: 'Arquivo muito pequeno ou vazio' };
|
||||
}
|
||||
|
||||
// Verificar assinatura do arquivo
|
||||
const fileType = await detectFileType(file);
|
||||
if (!fileType) {
|
||||
return { valid: false, error: 'Tipo de arquivo não reconhecido' };
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
private async validatePDF(file: Buffer) {
|
||||
return new Promise((resolve) => {
|
||||
const pdfParser = new PDFParser();
|
||||
|
||||
pdfParser.on('pdfParser_dataReady', () => {
|
||||
resolve({ valid: true, metadata: pdfParser.getAllFieldsTypes() });
|
||||
});
|
||||
|
||||
pdfParser.on('pdfParser_dataError', (error) => {
|
||||
resolve({ valid: false, error: `PDF inválido: ${error}` });
|
||||
});
|
||||
|
||||
pdfParser.parseBuffer(file);
|
||||
});
|
||||
}
|
||||
|
||||
private async validateImage(file: Buffer, mimeType: string) {
|
||||
try {
|
||||
// Verificar dimensões
|
||||
const dimensions = imageSize(file);
|
||||
if (!dimensions.width || !dimensions.height) {
|
||||
return { valid: false, error: 'Dimensões da imagem inválidas' };
|
||||
}
|
||||
|
||||
// Extrair metadados EXIF
|
||||
const metadata = await this.exiftool.readBuffer(file);
|
||||
|
||||
// Verificações específicas para JPEG
|
||||
if (mimeType === 'image/jpeg') {
|
||||
if (!metadata.FileType || metadata.FileType !== 'JPEG') {
|
||||
return { valid: false, error: 'Assinatura JPEG inválida' };
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
metadata: {
|
||||
dimensions,
|
||||
exif: metadata
|
||||
}
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
return { valid: false, error: `Erro na validação da imagem: ${error.message}` };
|
||||
}
|
||||
}
|
||||
|
||||
async validateMetadata(metadata: any) {
|
||||
const requiredFields = ['userAgent', 'ipAddress', 'timestamp'];
|
||||
const missingFields = requiredFields.filter(field => !metadata[field]);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `Campos obrigatórios ausentes: ${missingFields.join(', ')}`
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
generateHashes(file: Buffer) {
|
||||
return {
|
||||
sha256: createHash('sha256').update(file).digest('hex'),
|
||||
sha512: createHash('sha512').update(file).digest('hex'),
|
||||
md5: createHash('md5').update(file).digest('hex'),
|
||||
blake2b: createHash('blake2b512').update(file).digest('hex'), // Hash adicional
|
||||
whirlpool: createHash('whirlpool').update(file).digest('hex'), // Hash adicional
|
||||
};
|
||||
}
|
||||
|
||||
async cleanup() {
|
||||
await this.exiftool.end();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user