i am quite new to programing I'm trying to create application where user send gltf file to node where it compressed, encrypted and stored in mongoodb gridfr and when user requests file it is fetched from mongoodb and sent to react where it is decrypted and decompressed but problem is when i decrypt and decompress it shows "incorrect header check"
this is where user upload gltf
import React, { useState } from 'react';
import axios from 'axios';
export const GltfUploader = () => {
const [files, setFiles] = useState([]);
const handleFileChange = (event) => {
setFiles([...files, ...event.target.files]);
};
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
try {
const response = await axios.post('http://192.168.0.186:3500/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
console.log('File uploaded successfully:', response.data);
} catch (error) {
console.error('Error uploading file:', error);
}
};
const uploadFiles = () => {
files.forEach(uploadFile);
};
return (
<div>
<input type="file" onChange={handleFileChange} multiple />
<button onClick={uploadFiles}>Upload Files</button>
</div>
);
};
this how node recives and sends it to gridfs
const express = require('express');
const multer = require('multer');
const glTFModel = require('../schemas/GltfSchema');
const mongoose = require('mongoose');
const CryptoJS = require("crypto-js");
const { GridFSBucket } = require('mongodb');
const zlib = require('zlib');
const router = express.Router();
// const upload = multer();
// Multer configuration for file upload
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
// Reuse the existing MongoDB connection established in app.js
const connection = mongoose.connection;
router.post('/', upload.single('file'), async (req, res) => {
try {
const { file } = req; // Uploaded file
const fileInfo = {
filename: file.originalname,
contentType: file.mimetype
};
zlib.gzip(file.buffer, async (err, compressedData) => {
if (err) {
console.error('Compression error:', err);
return res.status(500).json({ error: 'Internal server error' });
}
// Encrypt compressed data
const encryptionKey = 'topsecret'; // Replace with your encryption key
const encryptedData = CryptoJS.AES.encrypt(compressedData.toString(), encryptionKey).toString();
// Convert encrypted data back to buffer
const encryptedBuffer = Buffer.from(encryptedData);
const bucket = new GridFSBucket(connection.db);
// Store encrypted file using GridFS
const uploadStream = bucket.openUploadStream(fileInfo.filename);
// Pipe encrypted data from encryptedBuffer to uploadStream
uploadStream.end(encryptedBuffer);
// Once the upload is complete, send a success response
uploadStream.on('finish', async () => {
console.log('File uploaded successfully to GridFS');
// Create file metadata in database
const fileMetadata = await glTFModel.create({
filename: fileInfo.filename,
contentType: fileInfo.contentType,
fileId: uploadStream.id
});
res.status(200).json({ message: 'File uploaded successfully', fileId: fileMetadata.fileId });
});
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;
This is how i send to react from node
const express = require('express');
const glTFModel = require('../schemas/GltfSchema');
const { GridFSBucket } = require('mongodb');
const mongoose = require('mongoose');
const router = express.Router();
// Reuse the existing MongoDB connection established in app.js
const connection = mongoose.connection;
router.get('/:fileId', async (req, res) => {
try {
const { fileId } = req.params;
const bucket = new GridFSBucket(connection.db);
const file = await glTFModel.findOne({ fileId: fileId });
if (!file) {
return res.status(404).json({ error: 'File not found' });
}
const downloadStream = bucket.openDownloadStream(file.fileId);
res.set({
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${fileId}.gltf"`
});
downloadStream.pipe(res);
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;
this part shows how i fetch the data then decrypt and decompress
import { useState } from 'react';
import React from 'react';
import axios from 'axios';
import CryptoJS from 'crypto-js';
import zlib from "react-zlib-js";
const GltfDownloader = () => {
const[fileId, setFieldID] = useState('');
const handleDownload = async () => {
try {
const response = await axios.get(`http://192.168.0.186:3500/download/${fileId}`);
const encryptedData = await response.data;
let blob;
var nosalt = CryptoJS.lib.WordArray.random(0);
console.log(encryptedData);
const bytes = CryptoJS.AES.decrypt(encryptedData,'topsecret', { salt: nosalt });
console.log(bytes);
const decryptedData = bytes.toString(CryptoJS.enc.Base64);
console.log(decryptedData);
zlib.gunzip(decryptedData, (err, decompressedData) => {
if (err) {
console.error('Decompression error:', err);
} else {
blob = new Blob([decompressedData], { type: 'application/json' });
console.log('Decompressed data:', decompressedData.toString());
}
});
// Create URL for Blob
const url = URL.createObjectURL(blob);
// Create anchor element
const a = document.createElement('a');
a.href = url;
a.download = 'file.gltf'; // Specify filename here
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
} catch (error) {
console.error('Error downloading file:', error);
}
};
return (
<div>
<input onChange={(e)=>{setFieldID(e.target.value)}}></input>
<button onClick={handleDownload}>Download File</button>
</div>
);
};
export default GltfDownloader;
can some one please show me correct working code for my need. if my code looks too messy forgive me. I'm new it is really frustrating