assasa

📦 TempDownloads ⏱️

Temp Downloads is a secure, self-hosted, multi-user platform for sharing time-sensitive files. It provides a robust admin dashboard where users can upload assets and generate unique, encrypted download links that automatically expire. Perfect for teams sharing digital assets, client deliverables, or sensitive documents with full control over access and lifecycle.

✨ Features

  • 🗄️ Database Agnostic:Built to scale. Choose between zero-config SQLite for simplicity, or connect to enterprise-grade PostgreSQL or MySQL databases for high-availability deployments.
  • 👥 Multi-User Architecture: Full authentication system supporting user registration, secure login, and administrator approval workflows.
  • 👮 Role-Based Access Control: Granular permissions ensure regular users only see and manage their own files, while Super Admins have global oversight and user management tools.
  • 🛡️ Secure, Expiring Links: Create time-sensitive, tamper-proof, encrypted links that automatically expire after a configured period.
  • 🔥 Burn-on-Read: Optional "Self-Destruct" mode. Links and files are permanently deleted immediately after the first successful download.
  • 🔑 Password Protection: Add an extra layer of security by requiring a password to unlock specific download links.
  • 🔐 Encryption at Rest: Local uploads are now encrypted on-the-fly using AES-256-GCM before hitting the disk, ensuring physical theft protection.
  • 📜 Audit Logging: Comprehensive, immutable database logs tracking every action (Creation, Deletion, Download, Login) accessible via the Admin UI.
  • 📱 QR Code Generation: Instantly generate QR codes for landing pages to easily transfer files to mobile devices.
  • 🔍 File Integrity Checksums: Calculates SHA-256 checksums during upload to verify file integrity and prevent corruption.
  • 🌊 Stream Processing: Optimized upload pipeline using Node.js Streams to handle large files with minimal memory footprint.
  • 🔗 Clean, Shareable URLs: Landing pages use clean, human-readable URLs (e.g., /download/a8c2efb1) perfect for sharing, while the actual download is protected by a separate, secure token.
  • ⚡ Hybrid Storage Engine: Smart upload logic that streams local files efficiently or utilizes Presigned URLs/SAS Tokens for direct-to-cloud uploads (S3/Azure) to bypass server bottlenecks.
  • 🧙♂️ Magic Byte Validation: Security goes beyond file extensions. The system inspects the binary signature (Magic Bytes) of every upload to prevent spoofing and ensure file integrity.
  • 🧱 Brutalist UI: A sharp, functional interface built with Tailwind CSS.
  • ⚡ Alpine.js Interactive UI: Uses lightweight Alpine.js for a reactive, progressively enhanced user experience (handling uploads, progress bars, and UI state).
  • 👨💼 Admin User Management: A dedicated interface for Admins to approve new registrations, revoke access, promote users, or manually create accounts.
  • 🗓️ Custom Expiration: Set a link to expire in minutes, hours, days, years, or choose a specific custom date and time. Links can also be set to never expire.
  • 🔄 Secret Key Rotation: Support for multiple encryption keys allows you to rotate secrets without downtime or invalidating existing data.
  • 📄 Expanded File Type Support: Natively supports .zip, .7z, .pdf, .jpg, .png, and .gif files.
  • 📊 Scoped Usage Statistics: Track performance with per-link and site-wide statistics. Users see metrics for their own files; Admins see global system health.
  • 🎨 Flexible Download Experience: Choose between a direct file download or a professional landing page for each link, displaying file name, size, and expiration.
  • ✅ Strict Validation: All environment variables and request inputs are strictly validated using Zod, ensuring stability and type safety.
  • 🔒 Security Hardened:
    • Double-Submit CSRF: Modern CSRF protection for all state-changing actions.
    • Strict CSP & Reporting: Hardened Helmet configuration with strict Content Security Policy directives and a built-in violation reporting endpoint.
    • Trust Proxy: Configurable support for running behind load balancers (Nginx/Cloudflare) for accurate rate limiting.
  • 🕵️ Observability & Tracing: Logs include Request Correlation IDs (x-correlation-id) to trace specific user actions across the entire request lifecycle.
  • 📝 Hybrid & File Logging: Beautiful, human-readable emoji logs for development and structured JSON logs (Pino) for production.
  • 🩺 Deep Health Checks: Includes a /health endpoint that verifies Database connectivity, Storage connectivity, and Storage Write permissions.
  • 🏗️ Enterprise Architecture: Built on a scalable Controller-Service-Repository pattern, utilizing the Strategy Pattern for interchangeable storage providers.
  • ☁️ Multi-Cloud Storage: Native support for AWS S3, Cloudflare R2, Azure Blob Storage, and local disk storage, configurable via a simple switch.
  • 🔐 Authenticated Encryption: AES-256-GCM to ensure download tokens are not only encrypted but also tamper-proof.
  • 🗑️ Trash & Recovery: Deleted links are moved to a dedicated "Trash Can" UI instead of being lost immediately. Admins can restore files deleted by mistake or force a permanent deletion manually.
  • 🤖 Automated Maintenance: Cronjobs run in the background to proactively identify expired links and soft-deleted records, performing garbage collection on physical storage and database rows automatically.
  • 🌱 Zero-Config Bootstrap: Automatically seeds the initial Administrator account on the very first run using environment variables, removing the need for manual database setup.
  • 🐳 Docker Ready: Includes a production-ready Dockerfile and a docker-compose.yml for easy local development and deployment.

🛠️ Tech Stack

  • ⚙️ Backend: Node.js, Express.js
  • 🎨 Frontend: EJS, Tailwind CSS, Alpine.js
  • 🗄️ Database: SQLite, PostgreSQL, MySQL (via Knex.js)
  • 🏗️ Architecture: Controller-Service-Repository
  • 🛡️ Security: bcrypt, helmet, csrf-csrf, busboy
  • ✅ Validation: Zod
  • 📝 Logging: Pino

🚀 Getting Started

📋 Prerequisites

⚙️ Installation

  1. 📥 Clone the repository:

    git clone https://github.com/chrismccoy/tempdownloads.git
    cd tempdownloads
  2. 📦 Install dependencies:

    npm install
  3. 📝 Configure your environment:
    Copy the example file:

    cp .env.example .env

    Critical Step: You must configure the .env file. The application will fail to start if the keys are not the exact required length. See the Environment Variables section below for generator commands.

  4. 🚀 Run migrations:
    Initialize the database schema:

    npm run db:migrate
  5. ▶️ Start the server:

    • Development (Auto-restart + Emoji Logs):
      npm run dev
    • Production (JSON Logs):
      npm start
    • Note: On the first run, the system will check if the database is empty. If so, it will create the initial Admin account using the ADMIN_INITIAL_... credentials from your .env file.
  6. 🌐 Access:

🔐 Environment Variables (.env)

Run the commands below in your terminal to generate secure values.

Variable Description Value / How to Generate
NODE_ENV The environment mode. development or production
PORT The port the server listens on. Default: 3000
APP_URL The public URL used for generating links. e.g., http://localhost:3000
TRUST_PROXY Proxy trust settings (Critical for Rate Limiting). loopback, linklocal, or IP range.
CORRELATION_HEADER Header used for request tracing IDs. Default: x-correlation-id
DB_CLIENT The database driver to use. sqlite, pg (Postgres), or mysql.
DB_HOST Database Host (Required if not sqlite). 127.0.0.1
DB_PORT Database Port (Required if not sqlite). 5432 (PG) or 3306 (MySQL)
DB_USER Database Username. postgres, root, etc.
DB_PASSWORD Database Password. Your DB password.
DB_NAME Database Name. tempdownloads
STORAGE_PROVIDER Where files are stored. local, s3, or azure (Default: local)
AWS_ACCESS_KEY_ID AWS/R2 Access Key. Required if STORAGE_PROVIDER=s3
AWS_SECRET_ACCESS_KEY AWS/R2 Secret Key. Required if STORAGE_PROVIDER=s3
AWS_BUCKET_NAME Name of the S3/R2 Bucket. Required if STORAGE_PROVIDER=s3
AWS_REGION Region (or auto for R2). Required if STORAGE_PROVIDER=s3
AWS_ENDPOINT Custom endpoint for R2/MinIO. Optional (Leave empty for real AWS)
AZURE_STORAGE_CONNECTION_STRING Azure Connection String. Required if STORAGE_PROVIDER=azure
AZURE_CONTAINER_NAME Name of the Azure Blob Container. Required if STORAGE_PROVIDER=azure
ADMIN_INITIAL_USERNAME Seeding Only: Username for the first admin. Default: admin. Used only on first boot.
ADMIN_INITIAL_PASSWORD Seeding Only: Password for the first admin. Used only on first boot.
SESSION_SECRET Random string for signing session cookies. node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
ENCRYPTION_KEYS Must be exactly 32 chars. Comma-separate for rotation. node -e "console.log(require('crypto').randomBytes(16).toString('hex'))"
ENCRYPTION_IV Must be exactly 16 chars. Used for AES-256. node -e "console.log(require('crypto').randomBytes(8).toString('hex'))"
TRASH_RETENTION_DAYS Days to keep items in trash before auto-purge. Default: 7
RATE_LIMIT_WINDOW_MINUTES Time window for login rate limiting. Default: 15
RATE_LIMIT_MAX_REQUESTS Max login attempts per IP in window. Default: 100
LOG_TO_CONSOLE Write logs to stdout. true or false
LOG_TO_FILE Write logs to logs/app.log. true or false

Example .env file:

NODE_ENV=development
PORT=3000
APP_URL=http://localhost:3000
TRUST_PROXY=loopback
CORRELATION_HEADER=x-correlation-id

# Database (Choose One)
# Option 1: SQLite
DB_CLIENT=sqlite

# Option 2: PostgreSQL
# DB_CLIENT=pg
# DB_HOST=127.0.0.1
# DB_PORT=5432
# DB_USER=postgres
# DB_PASSWORD=secret
# DB_NAME=tempdownloads

# Storage (local, s3, azure)
STORAGE_PROVIDER=local

# Initial Seed Credentials (Used only once to create the first user)
ADMIN_INITIAL_USERNAME=admin
ADMIN_INITIAL_PASSWORD=changeme12345

# Security Keys
SESSION_SECRET=long_random_string_here
# Single key or comma-separated list for rotation
ENCRYPTION_KEYS=a1b2c3d4e5f678901234567890abcdef
ENCRYPTION_IV=1234567890abcdef

# Trash Configuration
TRASH_RETENTION_DAYS=7

# Rate Limiting
RATE_LIMIT_WINDOW_MINUTES=15
RATE_LIMIT_MAX_REQUESTS=100

# Logging
LOG_TO_CONSOLE=true
LOG_TO_FILE=true

📜 Available Scripts

  • 👨💻 npm run dev: Starts the application in development mode using nodemon for auto-restarts and provides styled, human-readable logs.
  • ▶️ npm run start: Starts the application in production mode.
  • ➡️ npm run db:migrate: Runs all pending database migrations to bring the schema up to date.
  • ⬅️ npm run db:rollback: Reverts the most recent database migration.
  • 🎨 npm run build:css: Compiles and minifies the Tailwind CSS for production.
  • 👀 npm run watch:css: Starts a process to watch for changes in your CSS and automatically recompile.
  • 🎨 npm run build:all: Creates the Initial Databases and Compiles and minifies the Tailwind CSS for production.
  • 🎨 npm run build:run: Creates the Initial Databases and Compiles and minifies the Tailwind CSS for production, and runs server.
  • ✨ npm run format: Automatically formats all project files (.js, .ejs, .json, etc.) using Prettier.
  • ✨ npm run format:check: Check which files will be formatted when running through Prettier