File Sharing Platform with Node.js and Express.js
Last Updated :
25 Apr, 2024
In today’s digital age, the need for efficient File sharing platforms has become increasingly prevalent. Whether it’s sharing documents for collaboration or distributing media files, having a reliable solution can greatly enhance productivity and convenience. In this article, we’ll explore how to create a file-sharing platform using Node.js and Express.js, two powerful technologies for building web applications.
Output Preview:
Preview of Final Application
Prerequisites:
Approach
- Initialize an Express.js server to handle HTTP requests and responses.
- Use Multer middleware to handle file uploads and store uploaded files in a designated directory.
- Define a Mongoose schema for storing file metadata including path, original name, password (if protected), and download count.
- Create routes for uploading files, encrypting passwords using bcrypt, and handling password-protected file downloads.
- Set up EJS templates to render HTML views for file upload form, password prompt, and success/error messages.
- Implement security measures such as validating input data, handling errors gracefully, and protecting sensitive information.
Steps to Create the Project
Step 1: Type the following command in the terminal to initialize the nodejs project.
npm init -y
Step 2: Install the necessary packages:
npm i bcrypt nodemon express multer dotenv ejs mongoose
Step 3: Define the start scripts in package.json file:
"scripts": {
"start": "nodemon server.js"
},
Step 4: Create a .env file and add the mongo db connection URI as well as define your PORT. I have kept it 3000.
MONGO = your mongodb URI
PORT = 3000
Project Structure:
Folder structure
The updated dependencies in package.json file will look like:
"dependencies": {
"bcrypt": "^5.1.1",
"dotenv": "^16.4.5",
"ejs": "^3.1.9",
"express": "^4.19.2",
"mongoose": "^8.3.1",
"multer": "^1.4.5-lts.1",
"nodemon": "^3.1.0",
"pug": "^3.0.2"
}
Example: Implementation to show the code for file sharing platform
HTML
<!-- index.ejs -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>File Share</title>
</head>
<body>
<h1 style="text-align: center;
margin-bottom: 50px;">
File Sharing Application
</h1>
<% if(locals.fileLink !=null) { %>
<div style="margin-bottom: 1rem;">
Your file is uploaded
<a href="<%= locals.fileLink %>">
<%= locals.fileLink %>
</a>
</div>
<% } %>
<form action="/upload" method="post"
style="display: grid; gap: 0.5rem;
grid-template-columns: auto 1fr;
max-width: 500px; margin: 0 auto;"
enctype="multipart/form-data">
<label for="file">File:</label>
<input type="file" name="file" id="file" required>
<label for="password">Password:</label>
<input type="password" name="password"
id="password" required>
<button style="grid-column: span 2;" type="submit">
Share
</button>
</form>
</body>
</html>
HTML
<!-- password.ejs -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>File Share</title>
</head>
<body>
<h1 style="text-align: center;
margin-bottom: 50px;">
Enter Password
</h1>
<% if(locals.error) { %>
<div style="color: red; margin-bottom: 1rem;">
Incorrect password
</div>
<% } %>
<form method="post"
style="display: grid; gap: 0.5rem;
grid-template-columns: auto 1fr;
max-width: 500px; margin: 0 auto;">
<label for="password">Password:</label>
<input type="password" name="password"
id="password" required>
<button style="grid-column: span 2;"
type="submit">
Download
</button>
</form>
</body>
</html>
JavaScript
// server.js
const express = require("express")
const multer = require("multer")
const app = express()
app.use(express.urlencoded({ extended: true }));
const mongoose = require("mongoose")
require("dotenv").config()
const upload = multer({ dest: "uploads" })
const bcrypt = require("bcrypt")
const File = require("./models/File.js")
mongoose.connect(process.env.MONGO)
app.set("view engine", "ejs")
app.get("/", (req, res) => {
res.render("index")
})
app.post("/upload",
upload.single("file"), async (req, res) => {
const fileData = {
path: req.file.path,
originalName: req.file.originalname
}
if (req.body.password != null &&
req.body.password !== "") {
fileData.password =
await bcrypt.hash(req.body.password, 10)
}
const file = await File.create(fileData)
res.render("index",
{ fileLink: `${req.headers.origin}/file/${file.id}` })
})
app.get("/file/:id", handleDownload)
app.post("/file/:id", handleDownload)
async function handleDownload(req, res) {
const file = await File.findById(req.params.id)
if (file.password != null) {
if (req.body.password == null) {
res.render("password")
return
}
if (!(await bcrypt.compare(
req.body.password, file.password))) {
res.render("password", { error: true })
return
}
}
file.downloadCount++
await file.save()
res.download(file.path, file.originalName)
}
app.listen(process.env.PORT)
JavaScript
// File.js
const mongoose = require("mongoose")
const File = new mongoose.Schema({
path: {
type: String,
required: true
},
originalName: {
type: String,
required: true
},
password: String,
downloadCount: {
type: Number,
required: true,
default: 0
}
})
module.exports = mongoose.model("File", File)
Step to Run Application:Â Run the application using the following command from the root directory of the project
node server.js
Output:Â Your project will be shown in the URL http://localhost:3000/
Final preview of Platform
Share your thoughts in the comments
Please Login to comment...