Serve bot_username at runtime instead of baking it into the SPA build

Auth.tsx and Profile.tsx read import.meta.env.VITE_BOT_USERNAME — a Vite
build-time constant. This ЛК frontend is a single static bundle built
once in CI and served identically by both prod and dev (no
server-rendering to re-inject a value per environment, unlike the
Next.js landing fix from earlier). So the Telegram Login Widget on the
dev stand was rendering with whatever bot the CI build happened to be
compiled with — in practice the fallback default, the prod bot's
username — and Telegram correctly refused it with "Bot domain invalid"
since that bot's registered domain is the prod domain, not
dev.netrunner-vpn.com.

Added GET /api/v1/config (unauthenticated, reads BOT_USERNAME from the
server's actual environment on every request) and switched both files to
fetch it at runtime instead of reading the baked-in env var. Verified
locally: the dev container's /api/v1/config correctly returns its own
dev bot's username, and a real headless Chrome run confirms the Login
Widget script tag gets that value, not the hardcoded fallback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-05 14:21:55 +07:00
parent 4f1efc6ff9
commit 818d4fa384
5 changed files with 59 additions and 4 deletions
+6
View File
@@ -163,6 +163,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"КРИТИЧЕСКАЯ ОШИБКА: BOT_ENABLED=true, но TELOXIDE_TOKEN не задан в .env!".into(),
);
}
// Тот же бот, что читает bot.rs при старте — но здесь ещё и отдаётся фронту
// через GET /api/v1/config (см. ApiState::bot_username), не как VITE_-переменная,
// зашиваемая в SPA-бандл на этапе сборки в CI.
let bot_username =
std::env::var("BOT_USERNAME").unwrap_or_else(|_| "ntrnr_vpn_bot".to_string());
let jwt_secret =
std::env::var("JWT_SECRET").expect("КРИТИЧЕСКАЯ ОШИБКА: JWT_SECRET не задан в .env!");
let frontend_dir =
@@ -244,6 +249,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
jwt_secret,
bot_token: bot_token.clone(),
admin_tg_id,
bot_username,
cookie_domain,
cookie_secure,
csrf_allowed_origins,