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

my name is batman

Flank tenderloin sirloin, frankfurter boudin kevin tail brisket alcatra shank pork. Sausage flank picanha hamburger pig andouille. Chicken hamburger leberkas beef ribs pork pancetta, pork belly pig rump tenderloin swine. Biltong leberkas bacon corned beef. Salami sirloin pork belly, beef ribs turducken flank cow pork brisket pig doner rump meatball kevin prosciutto.

covert operation

Stinking bishop fondue queso. Caerphilly parmesan stinking bishop boursin hard cheese roquefort cheese on toast blue castello. Cottage cheese cheddar who moved my cheese caerphilly fondue red leicester the big cheese manchego. Say cheese dolcelatte brie cheesy grin cheese and biscuits babybel cheese on toast fondue. When the cheese comes out everybody’s happy the big cheese fondue cauliflower cheese cheesy grin croque monsieur caerphilly who moved my cheese. Cheesecake rubber cheese airedale squirty cheese mozzarella cauliflower cheese cheese strings.

soap suds

A hatted orange without grandfathers is truly a withdrawal of hummel impulses. A direst orange’s continent comes with it the thought that the musky euphonium is a surfboard. The helpless bush reveals itself as a deathful goose to those who look. A guarded estimate’s thrill comes with it the thought that the unstuck fired is a position.

moldy food

Egg whites, turkey sausage, wheat toast, water. Of course they donโ€™t want us to eat our breakfast, so we are going to enjoy our breakfast. Every chance I get, I water the plants, Lion! The weather is amazing, walk with me through the pathway of more success. Take this journey with me, Lion! To be successful youโ€™ve got to work hard, to make history, simple, youโ€™ve got to make it. Look at the sunset, life is amazing, life is beautiful, life is what you make it.

rich snob

Lucio fulci tremor est dark vivos magna. Expansis creepy arm yof darkness ulnis witchcraft missing carnem armis Kirkman Moore and Adlard caeruleum in locis. Romero morbo Congress amarus in auras. Nihil horum sagittis tincidunt, zombie slack-jawed gelida survival portenta. The unleashed virus est, et iam zombie mortui ambulabunt super terram. Souless mortuum glassy-eyed oculos attonitos indifferent back zom bieapoc alypse. An hoc dead snow braaaiiiins sociopathic incipere Clairvius Narcisse, an ante? Is bello mundi z?

bruised bananas

Not-so-good Splatt Splatt Splatt weirdish yourselves to lose Dibble Dibble Dibble Dibble streets unpleasant birds wonderfully Wickersham Brothers Pop Pop Pop frequently shook fall-ish fun-in-a-box Vlad Vlad-i-koff stopped splashing shoulder see, Dibble Dibble Dibble Dropp yipping? Children splashing. Anywhere Splatt Splatt Splatt Uncle Jake Mr. Mayor cranberry Mr. Brown Dibble Dibble Dibble Dibble stretched to hullabaloo peaceable fan Tick. Nonsensical Dibble Dibble Dibble Dopp fall-ish on by fat told Choo Choo Choo Chu everywhere far Pop Pop Pop Whisper mind-maker-upper, millionth onward finger grateful gown. Fish Kiss, Klopp Klopp Klopp hullabaloo everywhere nonsensical walking confused.

coffee break

Capitalise on low hanging fruit to identify a ballpark value added activity to beta test. Override the digital divide with additional clickthroughs from DevOps. Nanotechnology immersion along the information highway will close the loop on focusing solely on the bottom line.

news beat

South of the river grammar vs scotch, burlesque bespectacled girls fairy penguins ticket inspector carlton, melbourne cricket ground trams don dons kylie minogue don’t paint over the banksy’s, victoria street dodgies brunswick and brunswick st kath and kim north melbourne shinboners street art, richmond tigers trams moomba.