README: вход по логину и паролю
В таблицах методов входа (раздел «Аутентификация» и сводка окружений) пароль теперь основной способ во всех окружениях, Telegram — второй, stub остаётся только в dev. Описаны правила пароля, защита от перебора, обязательное окно для аккаунтов без пароля, привязка Telegram и восстановление пароля через админку. Поправлены места, где test-клон описывался как «только Telegram». #24 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XfTsytzT6TojfmprRDKiV6
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Forbidden Stars — учёт партий
|
# Forbidden Stars — учёт партий
|
||||||
|
|
||||||
Мобильное веб-приложение для учёта партий настольной игры **Forbidden Stars**:
|
Мобильное веб-приложение для учёта партий настольной игры **Forbidden Stars**:
|
||||||
профили игроков (вход через Telegram, пока — dev-заглушка), группы, создание партий
|
профили игроков (вход по логину и паролю или через Telegram), группы, создание партий
|
||||||
с рандомом фракций и фильтром по дополнениям группы, статистика и общий топ, админ-панель.
|
с рандомом фракций и фильтром по дополнениям группы, статистика и общий топ, админ-панель.
|
||||||
|
|
||||||
- **Бэкенд / ядро + API:** Python · FastAPI · SQLModel · SQLite
|
- **Бэкенд / ядро + API:** Python · FastAPI · SQLModel · SQLite
|
||||||
@@ -91,8 +91,8 @@ npm run gen:api # сгенерирует типы из живог
|
|||||||
npm run dev # http://127.0.0.1:5173 или http://localhost:5173 (оба стека)
|
npm run dev # http://127.0.0.1:5173 или http://localhost:5173 (оба стека)
|
||||||
```
|
```
|
||||||
|
|
||||||
Вход в dev-режиме — экран `/login`: в деве доступны оба метода (Telegram + вход по нику),
|
Вход в dev-режиме — экран `/login`: логин/пароль, Telegram и вход по нику без пароля (stub);
|
||||||
в проде — только Telegram (см. раздел «Аутентификация»).
|
в проде stub нет (см. раздел «Аутентификация»).
|
||||||
|
|
||||||
## Production (Docker на Pi)
|
## Production (Docker на Pi)
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ FastAPI отдаёт собранный SPA и API с одного origin. Ми
|
|||||||
## Test — локальный прод-клон в контейнере
|
## Test — локальный прод-клон в контейнере
|
||||||
|
|
||||||
Тот же образ и поведение, что и прод (FastAPI отдаёт SPA, БД на томе, вход игроков
|
Тот же образ и поведение, что и прод (FastAPI отдаёт SPA, БД на томе, вход игроков
|
||||||
только через Telegram), но на своей машине — для проверки прод-сборки до выката на Pi.
|
по логину/паролю или через Telegram), но на своей машине — для проверки прод-сборки до выката на Pi.
|
||||||
Изолированные тома и порт **8080** (не конфликтует с dev-uvicorn на :8000).
|
Изолированные тома и порт **8080** (не конфликтует с dev-uvicorn на :8000).
|
||||||
|
|
||||||
Проще всего — через лаунчер: поставить `APP_ENV=test` в `.env` и запустить `.\run.ps1`.
|
Проще всего — через лаунчер: поставить `APP_ENV=test` в `.env` и запустить `.\run.ps1`.
|
||||||
@@ -123,8 +123,8 @@ docker compose -f docker-compose.test.yml down -v # остановить и с
|
|||||||
- Читает **тот же `.env`**, что dev/prod (отдельного `.env.test` больше нет); внутри
|
- Читает **тот же `.env`**, что dev/prod (отдельного `.env.test` больше нет); внутри
|
||||||
контейнера `APP_ENV` форсится в `test` (см. `docker-compose.test.yml`).
|
контейнера `APP_ENV` форсится в `test` (см. `docker-compose.test.yml`).
|
||||||
- Данные — на отдельных томах `db-data-test` / `uploads-data-test` (не пересекаются с dev и Pi).
|
- Данные — на отдельных томах `db-data-test` / `uploads-data-test` (не пересекаются с dev и Pi).
|
||||||
- Вход: **админ-панель** (`/admin/login`) работает сразу по логину/паролю; вход **игроков** —
|
- Вход: **админ-панель** (`/admin/login`) работает сразу по логину/паролю; **игроки** —
|
||||||
только через Telegram (нужен бот + публичный HTTPS/туннель на `localhost:8080`).
|
по логину/паролю сразу, через Telegram — при боте и публичном HTTPS/туннеле на `localhost:8080`.
|
||||||
- **Не используйте `$` в секретах.** Единый `.env` читают и pydantic (dev — `$` дословно),
|
- **Не используйте `$` в секретах.** Единый `.env` читают и pydantic (dev — `$` дословно),
|
||||||
и docker compose (test/prod — `$` = подстановка переменной). Чтобы значение совпадало
|
и docker compose (test/prod — `$` = подстановка переменной). Чтобы значение совпадало
|
||||||
везде, в `SECRET_KEY`/`ADMIN_PASSWORD` не должно быть `$`. Удобно генерировать так:
|
везде, в `SECRET_KEY`/`ADMIN_PASSWORD` не должно быть `$`. Удобно генерировать так:
|
||||||
@@ -136,9 +136,17 @@ docker compose -f docker-compose.test.yml down -v # остановить и с
|
|||||||
|
|
||||||
| | dev | test / prod |
|
| | dev | test / prod |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Telegram Login Widget | ✓ | ✓ (единственный) |
|
| Логин (= ник) и пароль | ✓ | ✓ (основной) |
|
||||||
| Вход по нику (stub) | ✓ | ✗ (физически отсутствует) |
|
| Telegram Login Widget | ✓ | ✓ |
|
||||||
|
| Вход по нику без пароля (stub) | ✓ | ✗ (физически отсутствует) |
|
||||||
|
|
||||||
|
- **Логин и пароль** (`app/auth/password.py`) — основной вход. Логин — это ник игрока
|
||||||
|
(смена ника меняет логин). Пароль: от 8 символов, не длиннее 72 байт, хранится bcrypt.
|
||||||
|
От перебора — окно 15 минут в памяти процесса: 5 неудач на пару «IP + логин» и 20 на IP,
|
||||||
|
дальше `429 TOO_MANY_ATTEMPTS`. Игрок без пароля (из Telegram или созданный до паролей)
|
||||||
|
после входа видит обязательное окно «Задайте пароль». В профиле пароль меняется (нужен
|
||||||
|
текущий) и привязывается Telegram (ник не меняется). Забытый пароль задаёт админ
|
||||||
|
на вкладке аккаунтов — почту приложение не хранит.
|
||||||
- **Stub-вход (по нику)** — только для разработки. Его код **физически не попадает в прод:**
|
- **Stub-вход (по нику)** — только для разработки. Его код **физически не попадает в прод:**
|
||||||
файлы `backend/app/auth/dev_stub.py` и `backend/app/routers/dev_auth.py` исключены из
|
файлы `backend/app/auth/dev_stub.py` и `backend/app/routers/dev_auth.py` исключены из
|
||||||
Docker-образа (`.dockerignore`), роутер подключается лишь при `APP_ENV=development`
|
Docker-образа (`.dockerignore`), роутер подключается лишь при `APP_ENV=development`
|
||||||
@@ -165,7 +173,7 @@ docker compose -f docker-compose.test.yml down -v # остановить и с
|
|||||||
| Env-файл | единый `.env` | единый `.env` | единый `.env` (на Pi) |
|
| Env-файл | единый `.env` | единый `.env` | единый `.env` (на Pi) |
|
||||||
| Раздача SPA | Vite (HMR), :5173 | FastAPI, :8080 | FastAPI, :8000 |
|
| Раздача SPA | Vite (HMR), :5173 | FastAPI, :8080 | FastAPI, :8000 |
|
||||||
| База данных | `backend/data/dev/…` | том `db-data-test` (`/data`) | том `db-data` (`/data`) |
|
| База данных | `backend/data/dev/…` | том `db-data-test` (`/data`) | том `db-data` (`/data`) |
|
||||||
| Вход игроков | Telegram + ник (stub) | только Telegram | только Telegram |
|
| Вход игроков | пароль + Telegram + ник (stub) | пароль + Telegram | пароль + Telegram |
|
||||||
|
|
||||||
- **Один `.env` на машину** в корне (рядом с `.env.example`). `APP_ENV` в нём решает, что
|
- **Один `.env` на машину** в корне (рядом с `.env.example`). `APP_ENV` в нём решает, что
|
||||||
запустит лаунчер (`development`/`test`); прод-контейнер это значение **игнорирует** и всегда
|
запустит лаунчер (`development`/`test`); прод-контейнер это значение **игнорирует** и всегда
|
||||||
|
|||||||
Reference in New Issue
Block a user