Create a Node.js Express server with two endpoints: one for uploading images (JPEG or PNG) and another for retrieving the uploaded images by their unique ID. Store the images in a local directory using their MD5 hash as the file name. Limit the maximum file size of uploads to 500 KB.
PLAINFORMAT
const express = require('express');
const multer = require('multer');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const app = express();
const upload = multer({ limits: { fileSize: 500 * 1024 } }); // Limit file size to 500 KB

// Create directory for storing images if it doesn't exist
const imageDir = 'images';
if (!fs.existsSync(imageDir)) {
  fs.mkdirSync(imageDir);
}

// Function to generate MD5 hash of a file
function md5File(file) {
  const buffer = fs.readFileSync(file.path);
  return crypto.createHash('md5').update(buffer).digest('hex');
}

// Upload endpoint
app.post('/upload', upload.single('image'), (req, res) => {
  if (!req.file) {
    return res.status(400).send('No file uploaded.');
  }

  const allowedMimeTypes = ['image/jpeg', 'image/png'];
  if (!allowedMimeTypes.includes(req.file.mimetype)) {
    fs.unlinkSync(req.file.path); // Delete the temporary file
    return res.status(400).send('Invalid file type. Only JPEG and PNG are allowed.');
  }

  const md5hash = md5File(req.file);
  const ext = path.extname(req.file.originalname);
  const newPath = path.join(imageDir, md5hash + ext);

  fs.renameSync(req.file.path, newPath); // Move the temporary file to the new path
  res.send({ id: md5hash });
});

// Retrieve image endpoint
app.get('/image/:id', (req, res) => {
  const { id } = req.params;
  const imagePathJpeg = path.join(imageDir, id + '.jpeg');
  const imagePathPng = path.join(imageDir, id + '.png');

  if (fs.existsSync(imagePathJpeg)) {
    res.sendFile(path.resolve(imagePathJpeg));
  } else if (fs.existsSync(imagePathPng)) {
    res.sendFile(path.resolve(imagePathPng));
  } else {
    res.status(404).send('Image not found.');
  }
});

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server running on port ${port}`));