Files
intelaide/intelaide-backend/controllers/fileController.js
2026-01-20 04:54:10 +00:00

162 lines
5.2 KiB
JavaScript

// backend/controllers/fileController.js
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import pool from '../config/db.js';
import File from '../models/File.js';
// Configure Multer storage with a dynamic destination based on req.userId
const storage = multer.diskStorage({
destination: (req, file, cb) => {
// Create a directory like "documents/user_{userId}"
const userId = req.userId;
const dest = path.join(process.cwd(), 'documents', `user_${userId}`);
fs.mkdirSync(dest, { recursive: true });
cb(null, dest);
},
filename: (req, file, cb) => {
// Sanitize the original file name and append a timestamp to avoid collisions
const parsed = path.parse(file.originalname);
const sanitizedName = parsed.name.replace(/[^a-zA-Z0-9]/g, '_');
const fileName = `${sanitizedName}_${Date.now()}${parsed.ext}`;
cb(null, fileName);
},
});
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max file size
});
const allowedExtensions = ['txt', 'md'];
/**
* Upload multiple files.
* The files will be stored in a directory based on the authenticated user's ID.
*/
export const uploadFiles = (req, res) => {
// Use multer's array middleware to handle multiple files under the field 'files'
upload.array('files')(req, res, async (err) => {
if (err) {
return res.status(400).json({ message: err.message });
}
try {
// Process each uploaded file
for (let file of req.files) {
console.log('Uploaded file:', file);
console.log('User ID from token:', req.userId);
// Check if the file extension is allowed
const fileExtension = path.extname(file.originalname)
.substring(1)
.toLowerCase();
if (!allowedExtensions.includes(fileExtension)) {
return res.status(400).json({ message: 'Only .txt and .md files are allowed' });
}
// Prepare file data for the database; file_path includes the user-specific folder
const fileData = {
user_id: req.userId,
file_name: file.filename,
file_path: file.path,
file_type: fileExtension,
status: 'uploaded',
};
await File.createFile(fileData);
}
res.json({
message: 'Files uploaded successfully',
files: req.files.map(file => file.filename)
});
} catch (error) {
console.error('Error uploading files:', error);
res.status(500).json({ message: 'Database error. Please try again.' });
}
});
};
/**
* Get all files for the authenticated user.
*/
export const getUserFiles = async (req, res) => {
try {
const files = await File.getUserFiles(req.userId);
if (!files.length) {
return res.status(404).json({ message: 'No files found' });
}
res.json(files);
} catch (error) {
console.error('Error retrieving files:', error);
res.status(500).json({ message: 'Database error. Please try again.' });
}
};
/**
* Get a single file by its ID (if needed).
*/
export const getFileById = async (req, res) => {
const { id } = req.params;
try {
const file = await File.findById(id, req.userId);
if (!file) {
return res.status(404).json({ message: 'File not found or unauthorized' });
}
res.json(file);
} catch (error) {
console.error('Error retrieving file:', error);
res.status(500).json({ message: 'Database error. Please try again.' });
}
};
export const previewFile = (req, res) => {
// Use the authenticated user's ID from the token
const userId = req.userId;
// Get the filename from the route parameter
const { filename } = req.params;
// Construct the full file path (matches the location used in the multer storage)
const filePath = path.join(process.cwd(), 'documents', `user_${userId}`, filename);
console.log(`Previewing file for user ${userId} from path: ${filePath}`);
res.sendFile(filePath, (err) => {
if (err) {
console.error('Error sending file:', err);
return res.status(404).send('File not found');
}
});
};
/**
* Delete a file.
* This endpoint removes the file from the filesystem and then deletes its record from the database.
*/
export const deleteFile = async (req, res) => {
const { id } = req.params;
const user_id = req.userId;
try {
// Retrieve the file's path from the database
const [file] = await pool.execute(
'SELECT file_path FROM files WHERE id = ? AND user_id = ?',
[id, user_id]
);
if (file.length === 0) {
return res.status(404).json({ message: 'File not found or unauthorized' });
}
// Remove the file from the filesystem
fs.unlink(path.resolve(file[0].file_path), async (err) => {
if (err) {
console.error('Error deleting file from disk:', err);
return res.status(500).json({ message: 'Error deleting file from disk' });
}
// Delete the file record from the database
await pool.execute('DELETE FROM files WHERE id = ? AND user_id = ?', [id, user_id]);
res.json({ message: 'File deleted successfully' });
});
} catch (error) {
console.error('Error deleting file:', error);
res.status(500).json({ message: 'Database error. Please try again.' });
}
};