|
| 1 | +# SteamGuard Web |
| 2 | + |
| 3 | +Open-source web implementation of Steam Desktop Authenticator (SDA) with multi-user and multi-account support. |
| 4 | + |
| 5 | +- Backend: Fastify + TypeScript (API-first REST + WebSocket notifications) |
| 6 | +- Frontend: React + Vite + Tailwind + PWA |
| 7 | +- DB: MySQL 8 in Docker with encrypted MA files |
| 8 | +- Bot: Aiogram (single Telegram bot for all users) |
| 9 | +- License: MIT |
| 10 | + |
| 11 | +## Why this stack |
| 12 | + |
| 13 | +- **Fastify (instead of Express)**: lower overhead and better throughput for polling/real-time workloads. |
| 14 | +- **TypeScript on backend/frontend**: safer refactoring and better API contracts. |
| 15 | +- **MySQL 8 + Docker internal network**: relational consistency, easy VPS deploy, DB isolated from public access. |
| 16 | +- **React + Vite + Tailwind**: fast DX + responsive UI + simple theming. |
| 17 | +- **Vite PWA plugin**: installable app + service worker caching. |
| 18 | +- **Aiogram bot**: mature async Telegram framework for command and deep-link flows. |
| 19 | + |
| 20 | +## Key features |
| 21 | + |
| 22 | +- MA file import/export (`.maFile`) with AES-256 encryption in DB. |
| 23 | +- Multi-user + unlimited Steam accounts per user. |
| 24 | +- Steam code generation from `shared_secret`. |
| 25 | +- Trade/login confirmations API + queue + manual confirm/reject. |
| 26 | +- Auto-confirm toggle with per-account delay (0-60s). |
| 27 | +- Telegram OAuth-like login flow via bot deep-link. |
| 28 | +- Telegram account linking with `/add=<code>` (15 min TTL). |
| 29 | +- Telegram commands: `/accounts`, `/codes`, `/confirm <trade_id>`, `/status`. |
| 30 | +- JWT cookie sessions, CSRF protection, Helmet, bcrypt, brute-force guard via `rate-limiter-flexible`. |
| 31 | +- i18n EN/RU + light/dark theme. |
| 32 | +- Admin panel with global registration toggle. |
| 33 | +- Swagger docs at `/api-docs`. |
| 34 | + |
| 35 | +## Default admin |
| 36 | + |
| 37 | +- Email: `admin@admin.com` |
| 38 | +- Password: `admin123` |
| 39 | + |
| 40 | +(Override with `.env`: `ADMIN_EMAIL`, `ADMIN_PASSWORD`) |
| 41 | + |
| 42 | +## Architecture |
| 43 | + |
| 44 | +- Monolith API-first backend (`/api/...`) + WS (`/ws`) on port `3001`. |
| 45 | +- Frontend SPA on port `3000`. |
| 46 | +- Frontend server (Vite/Nginx) proxies `/api` and `/ws` to backend. |
| 47 | +- MySQL is isolated in internal Docker network and not exposed externally. |
| 48 | +- Optional reverse proxy service (`nginx`) in compose profile `proxy`. |
| 49 | + |
| 50 | +## Project structure |
| 51 | + |
| 52 | +```text |
| 53 | +. |
| 54 | +├── backend/ # Fastify API (TypeScript) |
| 55 | +├── frontend/ # React + Vite + Tailwind + PWA |
| 56 | +├── bot/ # Aiogram Telegram bot |
| 57 | +├── docker/ |
| 58 | +│ ├── mysql/init.sql # Schema bootstrap |
| 59 | +│ └── nginx/nginx.conf # Reverse proxy example |
| 60 | +├── docker-compose.yml |
| 61 | +├── docker-compose.dev.yml |
| 62 | +├── Makefile |
| 63 | +├── .env.example |
| 64 | +└── README.md |
| 65 | +``` |
| 66 | + |
| 67 | +## Quick start |
| 68 | + |
| 69 | +```bash |
| 70 | +cp .env.example .env |
| 71 | +make dev |
| 72 | +``` |
| 73 | + |
| 74 | +Open: |
| 75 | +- Frontend: `http://localhost:3000` |
| 76 | +- Backend API: `http://localhost:3001` |
| 77 | +- Swagger: `http://localhost:3001/api-docs` |
| 78 | + |
| 79 | +## Make targets |
| 80 | + |
| 81 | +- `make dev` - Docker dev stack with hot reload. |
| 82 | +- `make build` - build production images. |
| 83 | +- `make up` - run production stack detached. |
| 84 | +- `make deploy` - alias for `make up`. |
| 85 | +- `make down` - stop and remove containers. |
| 86 | +- `make lint` - backend + frontend lint. |
| 87 | +- `make test` - backend Jest + frontend Cypress (via docker service). |
| 88 | +- `make logs` - follow container logs. |
| 89 | + |
| 90 | +## Environment variables |
| 91 | + |
| 92 | +See `.env.example`. |
| 93 | + |
| 94 | +Core variables: |
| 95 | +- `DB_*` MySQL connection and bootstrap user credentials. |
| 96 | +- `JWT_SECRET`, `COOKIE_SECRET`, `ENCRYPTION_KEY` security secrets. |
| 97 | +- `APP_URL`, `API_URL` frontend/backend origins. |
| 98 | +- `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_USERNAME` bot settings. |
| 99 | +- `STEAM_POLL_INTERVAL_SEC` auto-confirm polling interval. |
| 100 | + |
| 101 | +If `TELEGRAM_BOT_TOKEN` is empty or starts with `change_me`, bot service stays in disabled idle mode (no crash, API stays up). |
| 102 | + |
| 103 | +## Security model |
| 104 | + |
| 105 | +- **MA encryption**: AES-256-GCM per user. |
| 106 | +- **Key derivation**: per-user key derived from bcrypt password hash + global `ENCRYPTION_KEY`. |
| 107 | +- **Auth**: JWT in HTTP-only cookie. |
| 108 | +- **CSRF**: double-submit protection for mutating endpoints. |
| 109 | +- **Brute-force/DoS**: `rate-limiter-flexible` in auth/write paths. |
| 110 | +- **Hardening**: `helmet`, CORS with credentials. |
| 111 | +- **DB isolation**: MySQL only on internal Docker network (`db_internal`). |
| 112 | + |
| 113 | +## Telegram flows |
| 114 | + |
| 115 | +### Link Telegram account |
| 116 | +1. In Settings click "Generate /add code". |
| 117 | +2. Send `/add=<code>` to bot within 15 min. |
| 118 | +3. Bot binds `telegram_user_id` to your web user. |
| 119 | + |
| 120 | +### Login via Telegram |
| 121 | +1. On login page click "Login via Telegram". |
| 122 | +2. Open bot deep-link (`/start login_<code>`). |
| 123 | +3. Bot confirms code. |
| 124 | +4. Web page polls and creates session automatically. |
| 125 | + |
| 126 | +## Steam confirmations notes |
| 127 | + |
| 128 | +Steam mobile confirmations require valid session tokens (`steamLoginSecure`, `sessionid`, optional `oauthToken`). |
| 129 | +You can set/update them in account detail page (`/accounts/:id`) or they are imported if present in `.maFile` session payload. |
| 130 | + |
| 131 | +## Bot API integration |
| 132 | + |
| 133 | +Internal bot endpoints are under `/api/telegram/bot/*` and protected by header: |
| 134 | + |
| 135 | +- `x-telegram-bot-token: $TELEGRAM_BOT_TOKEN` |
| 136 | + |
| 137 | +## Screenshots (descriptive) |
| 138 | + |
| 139 | +Planned screenshot set (see `docs/screenshots/README.md`): |
| 140 | + |
| 141 | +1. `login.png`: login/register card with Telegram and Passkey actions. |
| 142 | +2. `dashboard.png`: account/notification/live cards + real-time events list. |
| 143 | +3. `accounts.png`: multi-account table with import/code/export/details actions. |
| 144 | +4. `account-detail.png`: confirmation queue with confirm/reject and session fields. |
| 145 | +5. `settings.png`: language/theme/twofa/telegram/api-key controls. |
| 146 | +6. `admin.png`: registration toggle and user overview. |
| 147 | +7. `logs.png`: activity feed for trade/login/code/system events. |
| 148 | + |
| 149 | +## Deployment on VPS |
| 150 | + |
| 151 | +1. Install Docker + Docker Compose. |
| 152 | +2. Clone repository. |
| 153 | +3. `cp .env.example .env` and set production secrets. |
| 154 | +4. Optionally set external reverse proxy to forward: |
| 155 | + - `/` -> frontend `:3000` |
| 156 | + - `/api` and `/ws` -> backend `:3001` |
| 157 | +5. Run `make deploy`. |
| 158 | + |
| 159 | +Optional bundled Nginx proxy: |
| 160 | + |
| 161 | +```bash |
| 162 | +docker compose --profile proxy up -d |
| 163 | +``` |
| 164 | + |
| 165 | +## Testing |
| 166 | + |
| 167 | +- Backend unit/API tests: Jest (`backend/tests/*`). |
| 168 | +- Frontend unit tests: Vitest (`frontend/src/utils/format.test.ts`). |
| 169 | +- E2E smoke: Cypress (`frontend/cypress/e2e/smoke.cy.ts`). |
| 170 | + |
| 171 | +For local host runs Cypress may require system dependencies (`Xvfb`). `make test` uses `cypress/included` Docker image to avoid host setup issues. |
| 172 | + |
| 173 | +## License |
| 174 | + |
| 175 | +MIT (`LICENSE`). |
0 commit comments