Secure File Share - A safer way to share sensitive files online

Menard Maranan - Oct 13 - - Dev Community

This is a submission for the The Pinata Challenge

What I Built

I've developed "Secure File Share", an open-source, self-hostable file sharing solution that addresses a common need in our digital world: the secure sharing of sensitive files without relying on third-party services.

Inspiration

Being a developer working with a remote team, it is very common for us to share sensitive company files online, which is at risk of accidentally leaking to the outside world. Files have been scattered over email attachments, chat threads, and anywhere we communicate. For now, we adopted the password-protected files sharing feature of Google Drive but we're always looking for solutions without any 3rd party involvement and where we can have full control over our files, especially if we can self-host it. Our DevOps guy is working on a solution, but if I were to build that solution, this is how I imagine it to be.

This is also heavily inspired by Onetimesecret. This is like one time secret, but for files.

How it Works

  1. Upload a file you want to share
  2. Set a passphrase and expiration, then click Create Share Link
  3. Send the share link to your intended recipient/s. It's recommended to share the passphrase separately.

The uploaded file as well as its records will all be deleted upon the specified expiration date. Upon viewing the file, the set expiration will be overwritten and will be set to 5 minutes before it's totally gone.

Key features of Secure File Transfer include:

  1. Disposable and password protected share links
  2. No sign-up required.
  3. Fully self-hostable

Demo

(Update: I already took down the demo as I'm getting a lot of traffic and I don't wanna end up with a huge bill in fly.io or redis cloud😅 besides, this project is intended to be self-hosted, so that's what I encourage everyone intending to use this to do. There are hosting services out there with generous free-tier like fly.io. I highly recommend self hosting this if you're intending to use it for full security and control over your sensitive files. I'm taking down the demo but the source code will always be available. You're free to fork it, make your own modifications if you'd like, and self-host it. I left a docker-compose file there if you don't want a separate redis server, especially if you're hosting this in a VPS.

Quick Peek

Hero Image

Upload Page

Share Page

File View Request page

File View Page

My Code

Secure File Transfer

Express TypeScript AlpineJS Prisma Redis

A Dev x Pinata hackathon project for secure file sharing via password-protected disposable share links.

Overview

"Secure File Transfer" is an open-source, self-hostable file sharing solution that allows users to generate secure, password-protected file share links with customizable expiration dates. This application doesn't require any logins or signups - it's designed for simple, secure file sharing.

This app mainly solves the issue of sharing sensitive information online, without the need of signing up from any 3rd party app. Since this can be self-hosted, you can have full control over your files.

How it Works

  1. Upload a file you want to share
  2. Set a passphrase and expiration, then click Create Share Link
  3. Send the share link to your intended recipient/s. It's recommended to share the passphrase separately.

Key Features

  • Generate secure, password-protected file share links
  • Set custom expiration dates for shared links
  • No user accounts or logins required

(NOTE: You can read the README for more info)

Tech Stack

  • Backend: Express.js with TypeScript
  • Frontend: EJS templates, Bulma CSS framework, Alpine.js
  • Database: SQLite with Prisma ORM (easily replaceable if needed)
  • File Storage: Pinata cloud
  • Background Tasks: BullMQ with Redis

I tried to be as light weight as possible when choosing the techstack and to not over engineer this. That said, I just have a simple express ts backend, ejs templates with Alpine.js (for minimal frontend interactivity) and Bulma as the CSS framework. The database is just an sqlite file since I don't see a need for a full blown database in this hackathon project, but this can be easily changed since I used Prisma ORM for it. Just modify the datasource. I use BullMQ with Redis for background tasks (handling file expiration). And of course, Pinata cloud. I hosted this in fly.io as they have a generous free tier plan but this can be hosted anywhere, like in VPS (there's a docker compose you can use).

More Details

Pinata plays a pivotal role in this project as all the shared files need to be stored somewhere, and that's where Pinata fits.

Here's the myPinata.ts file where I primarily interacted with Pinata via the Files SDK

import { FileObject, PinataSDK } from "pinata";
import dotenv from "dotenv";

dotenv.config();

const pinata = new PinataSDK({
    pinataJwt: process.env.PINATA_JWT,
    pinataGateway: process.env.PINATA_GATEWAY
});

export async function uploadFile(file: FileObject) {
    try {
        const upload = await pinata.upload.file(file);
        return upload;
    } catch (error) {
        console.error(error);
    }
}

export async function getFileUrl(cid: string, expires=1800) {
    try {
        const signedUrl = await pinata.gateways.createSignedURL({
            cid,
            expires // defaults to 30 minutes (1800 seconds)
        });
        return signedUrl;
    } catch (error) {
        console.error(error);
    }
}

export async function deleteFile(fileId: string) {
    try {
        const deleted = await pinata.files.delete([fileId]);
        return deleted;
    } catch (error) {
        console.error(error);
    }
}
Enter fullscreen mode Exit fullscreen mode

I use these three functions in my endpoint handlers to handle file operations with Pinata. My background tasks also use the deleteFile function, since these background tasks are used for dispatching deletion jobs at the set expiration of the files.

. . . . . . . . . . . . . . . . . . .
Terabox Video Player