Skip to content

Latest commit

 

History

History
181 lines (133 loc) · 5.32 KB

File metadata and controls

181 lines (133 loc) · 5.32 KB

Local development setup

This walks through getting RuneVault running locally end-to-end.

Prerequisites

  • Go 1.22+go version
  • Node 22+node --version
  • Docker and Docker Composedocker --version
  • PostgreSQL client (optional, for direct DB access) — psql --version
  • A Steam account that owns Quinfall, only if you want the live game connection working. The HTTP API and most features work without one (see "Headless mode" below).

1. Clone and configure

git clone https://github.com/Velm14/runevault.git
cd runevault
cp .env.example .env

Open .env in your editor and set, at minimum:

# Two 64-hex-char secrets — never reuse examples:
JWT_SECRET=$(openssl rand -hex 32)
TOKEN_ENCRYPTION_KEY=$(openssl rand -hex 32)

DB_PASSWORD=<pick anything strong>

Discord OAuth (required for login)

  1. Go to https://discord.com/developers/applicationsNew Application.
  2. Under OAuth2 → General:
    • Copy the Client ID into DISCORD_CLIENT_ID.
    • Click Reset Secret, copy into DISCORD_CLIENT_SECRET.
    • Add a Redirect URI: http://localhost:8080/api/auth/discord/callback.
  3. In .env, set DISCORD_REDIRECT_URI to the same URI exactly.
  4. FRONTEND_URL=http://localhost:5174 (where users land after login).

Steam credentials (only if you want the live game connection)

STEAM_USER=your_steam_username
STEAM_PASS=your_steam_password
GAME_TOKEN=<capture from a real Quinfall client>
HW_FINGERPRINT=<capture from a real Quinfall client>
GAME_SERVER=<host:port of the Quinfall game server>

GAME_TOKEN and HW_FINGERPRINT are values your real Quinfall client sends during login. You'll need to capture them with packet inspection of a real session — see docs/protocol/reverse-engineering-report.md for the framing details. The repo does not ship these values.

Headless mode (no Steam account)

If you don't have Quinfall, set:

SKIP_PUBLIC_CONNECTION=true

The backend boots without attempting the shared game-server login. Auction search will return an error (no live connection), but everything else (Discord login, alerts CRUD, price-history queries against scraped data, the frontend UI) works. The steam-auth-public sidecar container still starts under Docker Compose, but its credentials check fails fast and it idles harmlessly.

2. Build + start the stack

docker compose up -d --build backend app-db frontend caddy

This starts:

  • app-db — PostgreSQL 16. Migrations run automatically on first start.
  • backend — Go HTTP API on :8080.
  • frontend — nginx serving the built React app.
  • caddy — reverse proxy (you usually don't need it in dev; skip it if you're going to use the Vite dev server below).
  • steam-auth-public — the Steam login sidecar (skipped if SKIP_PUBLIC_CONNECTION=true).

Check it's alive:

docker compose ps
curl http://localhost:8080/api/auth/me   # → 401 unauthorized (correct)

3. Run the frontend with hot reload

cd frontend
npm install
npm run dev

Vite serves at http://localhost:5174. It proxies /api/* to the backend (see frontend/vite.config.ts). Open the URL, click Sign in with Discord, complete the OAuth flow.

4. Useful day-to-day commands

# Backend logs
docker compose logs -f backend

# Restart just the backend after a code change
go build ./... && docker compose up -d --build backend

# Reset the database
docker compose down -v app-db && docker compose up -d app-db

# Open a psql shell
docker compose exec app-db psql -U quinfall

# Build the frontend the way Docker does
cd frontend && npm run build

5. Optional: run the scraper

The scraper is off by default (SCRAPER_ENABLED=false). To enable:

  1. Provision a separate Steam account from the one in STEAM_USER — sharing the same account causes the game server to kick one of the sessions with LogonSessionReplaced.

  2. Fill in the scraper-specific env vars in .env:

    SCRAPER_ENABLED=true
    SCRAPER_STEAM_USER=...
    SCRAPER_STEAM_PASS=...
    SCRAPER_GAME_TOKEN=...      # optional, falls back to GAME_TOKEN
    SCRAPER_HW_FINGERPRINT=...  # optional, falls back to HW_FINGERPRINT
    # SCRAPER_SOCKS_PROXY=socks5://host:port    # optional
  3. Start the scraper profile:

    docker compose --profile scraper up -d steam-auth-scraper backend

The scraper writes to the listing_snapshots table, which powers price history, market movers, deals, and alert matching.

6. Optional: enable Web Push notifications

npx web-push generate-vapid-keys --json
# Paste the keys into .env:
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
ADMIN_CONTACT_EMAIL=you@example.com

The frontend will then prompt premium users to enable push for alerts.

7. Optional: enable Cloudflare Turnstile

Free CAPTCHA-like challenge for auction search. Get a site key + secret from https://dash.cloudflare.com/?to=/:account/turnstile:

TURNSTILE_SECRET=...

The frontend's site key is configured in frontend/src/hooks/useTurnstile.ts.

Next steps