Sign inSign up

certyiknofetch/linknest

By certyiknofetch

โ€ขUpdated 7 months ago

Image
0

2.9K

certyiknofetch/linknest repository overview


โ ๐Ÿ”– LinkNest

Cross-Browser Bookmark Sync.
Self-hosted server ยท Browser extension ยท PostgreSQL / MongoDB


License Version Size Pulls Stars


โ Table of Contents


โ Features

CategoryDetails
SyncBidirectional merge sync (push + pull), soft-delete propagation, auto-sync with periodic alarms and change listeners
BrowsersChrome, Firefox, Edge, Brave, Opera, Vivaldi โ€” any Chromium MV3 or Firefox MV2 browser
AuthJWT access + rotating refresh tokens with reuse detection, family-based revocation
2FATOTP setup with QR code + manual secret, backup codes, enforced login challenge
DatabasePostgreSQL (recommended) or MongoDB โ€” switchable via DB_PROVIDER
SecurityOWASP-aligned: Helmet, rate limiting, bcrypt, HTTPS enforcement, encrypted 2FA secrets (AES-256-GCM)
DeploymentDocker multi-arch (amd64 + arm64), Docker Compose, or bare Node.js
UI ProtectionServer URL locked behind identity verification, Clear Server requires TOTP/password

โ Quick Start with Docker

docker run -d \
  --name linknest \
  -p 3000:3000 \
  -e DB_PROVIDER=postgres \
  -e POSTGRES_URL=postgresql://user:pass@your-db-host:5432/linknest \
  -e JWT_SECRET=$(openssl rand -base64 32) \
  -e REFRESH_JWT_SECRET=$(openssl rand -base64 32) \
  -e TWO_FACTOR_CHALLENGE_SECRET=$(openssl rand -base64 32) \
  -e TWO_FACTOR_ENCRYPTION_KEY=$(openssl rand -base64 32) \
  -e REQUIRE_HTTPS=true \
  -e CORS_ORIGINS=https://your-domain.com \
  certyiknofetch/linknest:1.1

The image supports linux/amd64 and linux/arm64 (Apple Silicon, Raspberry Pi, AWS Graviton).

# Pull the latest
docker pull certyiknofetch/linknest:latest

# Or a specific version
docker pull certyiknofetch/linknest:1.1

โ Docker Compose โ€” with Database

Full stack with a bundled PostgreSQL instance:

git clone https://github.com/certyiknofetch/linknest.git
cd linknest
cp server/.env.example .env

Edit .env with your secrets (see Environment Variablesโ ), then:

docker compose up -d

docker-compose.yml:

services:
  linknest:
    image: certyiknofetch/linknest:1.1
    container_name: linknest-server
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file: .env
    environment:
      - DB_PROVIDER=postgres
      - POSTGRES_URL=postgresql://linknest:${POSTGRES_PASSWORD:-changeme}@db:5432/linknest
      - POSTGRES_SSL=false
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16-alpine
    container_name: linknest-db
    restart: unless-stopped
    volumes:
      - linknest_pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: linknest
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
      POSTGRES_DB: linknest
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U linknest -d linknest"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  linknest_pgdata:

โ Docker Compose โ€” External Database

Use this when you already have a PostgreSQL or MongoDB instance:

docker compose -f docker-compose.no-db.yml up -d

Set POSTGRES_URL or MONGODB_URI in your .env file pointing to your existing database.


โ Environment Variables

Create a .env file from the example:

cp server/.env.example .env
VariableRequiredDefaultDescription
PORTNo3000Server listen port
DB_PROVIDERYesmongodbDatabase type: postgres or mongodb
POSTGRES_URLIf postgresโ€”PostgreSQL connection string
POSTGRES_SSLNofalseEnable SSL for PostgreSQL connection
POSTGRES_SSL_REJECT_UNAUTHORIZEDNofalseReject unauthorized SSL certificates
MONGODB_URIIf mongodbโ€”MongoDB connection string
JWT_SECRETYesโ€”Secret for signing access tokens
ACCESS_JWT_EXPIRES_INNo15mAccess token lifetime
REFRESH_JWT_SECRETYesโ€”Secret for signing refresh tokens
REFRESH_JWT_EXPIRES_INNo30dRefresh token lifetime
TWO_FACTOR_CHALLENGE_SECRETYesโ€”Secret for 2FA challenge tokens
TWO_FACTOR_CHALLENGE_EXPIRES_INNo5m2FA challenge window
TWO_FACTOR_ENCRYPTION_KEYYesโ€”AES-256-GCM key for TOTP secret encryption
REQUIRE_HTTPSNotrueReject non-HTTPS requests (except localhost)
CORS_ORIGINSNoโ€”Comma-separated allowed origins
โ Generating Secrets
# Generate strong random secrets (run each one separately)
openssl rand -base64 32   # JWT_SECRET
openssl rand -base64 32   # REFRESH_JWT_SECRET
openssl rand -base64 32   # TWO_FACTOR_CHALLENGE_SECRET
openssl rand -base64 32   # TWO_FACTOR_ENCRYPTION_KEY

โ Extension Setup

โ Chromium Browsers (Chrome, Edge, Brave, Opera, Vivaldi)
  1. Download from HEREโ  or build linknest-chrome.zip
  2. Extract to a folder
  3. Open chrome://extensions/ (or edge://extensions/, etc.)
  4. Enable Developer Mode
  5. Click Load unpacked โ†’ select the extracted folder
  6. Click the LinkNest icon โ†’ go to Settings โ†’ set your server URL
  7. Register or login
โ Firefox
  1. Download from HEREโ  or build linknest-firefox.zip
  2. Extract to a folder
  3. Open about:debugging#/runtime/this-firefox
  4. Click Load Temporary Add-on โ†’ select manifest.json from the extracted folder
  5. Click the LinkNest icon โ†’ go to Settings โ†’ set your server URL
  6. Register or login

Note: Firefox temporary add-ons are removed on restart. For permanent installation, use about:addons with a signed .xpi file or use Firefox Developer Edition with xpinstall.signatures.required set to false.

โ Building Extension ZIPs
# From the project root
rm -rf dist && mkdir -p dist/chromium dist/firefox

# Chromium
cp -R extension/. dist/chromium/
rm -f dist/chromium/manifest.firefox.json
(cd dist/chromium && zip -qr ../linknest-chromium.zip .)

# Firefox
cp -R extension/. dist/firefox/
cp extension/manifest.firefox.json dist/firefox/manifest.json
rm -f dist/firefox/manifest.firefox.json
(cd dist/firefox && zip -qr ../linknest-firefox.zip .)

โ Reverse Proxy (Nginx Proxy Manager)

If you're running LinkNest behind a reverse proxy:

  1. Add a new Proxy Host in Nginx Proxy Manager
  2. Domain: linknest.yourdomain.com
  3. Forward Hostname: linknest-server (Docker service name) or localhost
  4. Forward Port: 3000
  5. SSL: Request a Let's Encrypt certificate

Set in .env:

CORS_ORIGINS=https://linknest.yourdomain.com
REQUIRE_HTTPS=true

โ License

This project is open source and available under the terms specified in the LICENSEโ  file.

For contributions, usage rights, and restrictions, please refer to the full license text in the repository.


Tag summary

Content type

Image

Digest

sha256:2d0564820โ€ฆ

Size

54 MB

Last updated

7 months ago

docker pull certyiknofetch/linknest