Open In App

File Sharing Platform with Node.js and Express.js

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:

File sharing platform using node - preview

Preview of Final Application

Prerequisites:

Approach

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:

Screenshot-2024-04-07-001246

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

<!-- 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>
<!-- 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>
// 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)
// 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/

File sharing platform using node

Final preview of Platform


Article Tags :