Files
tnyr.me/README.md
2025-12-29 01:52:23 +01:00

3.2 KiB

https://tnyr.me - Privacy-First URL Shortener

License: MIT

A secure, self-hosted URL shortener with custom passwordless encryption. Perfect for privacy-conscious users and organizations.

Screenshot

Key Features

🔒 Passwordless Encryption
📡 No Tracking
🌐 Modern Web Interface

Encryption Process

  1. ID Generation

    • Unique random ID created for each link (e.g. iA4y6jMjFk)
    • Example: google.comtnyr.me/#iA4y6jMjFk
  2. Hashing

    • Two Scrypt hashes are calculated by using different salts
    • Original URL encrypted with AES-256 using Hash 2
    • The whole encryption and decryption process happens in the browser
  3. Storage

    • Only Hash 1 (storage key) and the encrypted URL are saved in database

Self Hosting and Development

Prerequisites

  • Docker (and optionally Docker Compose)

1) Generate salts (only if you hosted tnyr.me before Dec 30, 2025)

python3 backend/generate_salts.py --env

2) Run with Docker Compose (no secrets required)

mkdir -p data
export TNYR_PUBLIC_URL=https://example.com  # (or http://1.2.3.4:5502)
docker compose up -d --build

Required env vars:

  • TNYR_PUBLIC_URL (example https://example.com, http://1.2.3.4:5502)

Optional env vars:

  • TNYR_DB_PATH (defaults to /data/urls.db in the container via compose)
  • TNYR_DELETION_TOKEN (set to enable POST /delete-url)
  • Legacy link support (only if you hosted tnyr.me before Dec 30, 2025):
    • TNYR_SALT1_HEX (16 bytes = 32 hex chars)
    • TNYR_SALT2_HEX (16 bytes = 32 hex chars)
    • TNYR_ARGON2_TIME_COST (default 3)
    • TNYR_ARGON2_MEMORY_COST (default 65536)
    • TNYR_ARGON2_PARALLELISM (default 1)
    • TNYR_ARGON2_HASH_LENGTH (default 32)

Note: Creating new legacy links via POST /shorten-server is disabled. The legacy env vars above are only for resolving existing old /<id> links.

3) Or run with plain Docker

docker build -t tnyr .
docker run --rm \
  -p 5502:5502 \
  -v "$PWD/data:/data" \
  -e TNYR_PUBLIC_URL="${TNYR_PUBLIC_URL:-http://localhost:5502}" \
  -e TNYR_DB_PATH="/data/urls.db" \
  tnyr

Then open http://localhost:5502.

Note: On container start, the entrypoint will initialize the SQLite schema (if missing) and replace %VITE_PUBLIC_URL% / %VITE_DOMAIN% placeholders in backend/dist based on TNYR_PUBLIC_URL.

Development

  1. Start development server:

    cd frontend
    npm run dev
    
  2. Start backend server:

    cd backend
    pip install -r requirements.txt
    # Required:
    export TNYR_PUBLIC_URL=https://example.com
    # Optional (legacy server-side mode only):
    # export TNYR_SALT1_HEX=...  # 32 hex chars
    # export TNYR_SALT2_HEX=...  # 32 hex chars
    python main.py
    

Why Choose tnyr.me?

  • Privacy by Design: We literally can't view your links
  • No Tracking: Zero cookies, analytics, or fingerprinting
  • Self-Hostable: Full control over your data