Files
netrunner-backend/frontend/README.md
T
2026-07-05 14:23:31 +07:00

4.3 KiB
Raw Blame History

Netrunner — фронтенд

SPA-клиент (React 19 + TypeScript + Vite) для Netrunner Control Plane. Собирается в статику и раздаётся самим бэкендом (../src/api.rsServeDir с SPA-фолбэком на index.html), поэтому в проде отдельного веб-сервера для фронта нет.

Экраны (src/*.tsx)

Файл Роут Что делает
Auth.tsx / Вход: Telegram Login Widget, генерация/логин Ghost-seed (с обязательным скачиванием + подтверждением сохранения seed перед переходом дальше). Хранит терминальный лог событий для киберпанк-эстетики.
Profile.tsx /profile Личный кабинет: баланс, статус подписки, покупка тарифа через TON Connect, реферальная ссылка. Также цель WebApp-ссылок из бота («Личный Кабинет»/«Тарифы»/«Синдикат»).
HackGame.tsx /hack Обёртка над npm-пакетом cyberhack (мини-игра). Server-authoritative: сначала POST /users/hack/start за доской, сгенерированной сервером, по завершении партии шлёт путь кликов на POST /users/hack/result — сервер сам считает очки.
AdminDashboard.tsx /admin Список всех VPN-нод (GET /admin/nodes, любой статус) + форма добавления ноды + force-restart/удаление. Доступ ограничен admin_guard на бэкенде; сам роут на фронте не проверяет роль (полагается на то, что API откажет не-админу 401/403).

App.tsx — роутинг (react-router-dom), провайдер TonConnectUIProvider и мост useBootstrapTokenExchange: если в URL есть #token= (пришли из бота), сразу меняет его на cookie-сессию через POST /auth/exchange и чистит URL. api.ts — единая обёртка apiFetch над /api/v1/*: всегда с cookie (credentials: "same-origin"), при первом 401 тихо пробует POST /auth/refresh и повторяет запрос один раз, при провале — редирект на /.

Аутентификация на фронте

Сессия — только HttpOnly-cookie (nrxp_token/nrxp_refresh), которую полностью контролирует сервер; фронт её не читает и не хранит нигде сам (ни localStorage, ни JS-видимая cookie). Раньше api.ts пытался читать nrxp_token через document.cookie для простановки в Authorization: Bearer, но сервер ставил её HttpOnly — то есть JS физически не мог её увидеть, и все "авторизованные" запросы уходили без токена вообще. Подробности серверной части — в ../src/modules/auth/README.md.

Разработка

pnpm install
pnpm dev       # dev-сервер Vite; бэкенд отдельно на :8080 (см. VITE_API_BASE)
pnpm build     # tsc -b && vite build -> dist/
pnpm lint

Переменные окружения (.env.production / Vite import.meta.env): VITE_API_BASE (по умолчанию /api/v1).

Юзернейм бота (для Telegram Login Widget и реферальной ссылки) не build-time переменная — этот SPA собирается один раз в CI и раздаётся одинаково и прод-, и dev-стендом, так что зашитое в бандл значение не различалось бы между ними. Вместо VITE_BOT_USERNAME Auth.tsx/Profile.tsx берут его рантаймом через GET /api/v1/config (api.ts::getPublicConfig), который читает BOT_USERNAME из окружения сервера заново на каждый запрос.