feat: аккаунты по почте с подтверждением, сбросом пароля и синхронизацией прогресса
API аккаунтов на чистой стандартной библиотеке Python (server/splitapi): - регистрация по почте: пароль задаётся по ссылке из письма, аккаунт создаётся только после подтверждения - вход, выход, сброс пароля по почте (токены одноразовые, в базе только SHA-256), удаление аккаунта - пароли scrypt, лимиты попыток по паре «адрес + IP», IP и аккаунту, защита от CSRF - хранение прогресса пользователя с оптимистичной блокировкой версии - SMTP через переменные окружения; без SMTP на публичном адресе API не стартует Клиент: public/auth.js (вход, регистрация, сброс, синхронизация), public/sync.js (чистое слияние прогресса). Без API сайт работает как раньше. Развёртывание: Dockerfile.api, сервис splitapi в docker-compose, проксирование /api/ в nginx с ограничением частоты, deploy/install-api-debian.sh (systemd), .env.example. Тесты: 216 для бэкенда (unittest, покрытие около 97%), 16 для клиентского слияния. Документация: раздел «Аккаунты и почта» в docs/DEPLOY.md, раздел 9 в docs/ИНСТРУКЦИЯ.md.
This commit is contained in:
+45
-2
@@ -1,6 +1,6 @@
|
||||
# Запуск: docker compose up -d --build
|
||||
# По умолчанию порт открыт только на localhost: сайт предназначен для работы за обратным прокси.
|
||||
# BIND=0.0.0.0 откроет его наружу, PORT=9000 сменит порт (переменные можно положить в файл .env рядом).
|
||||
# Сайт по умолчанию открыт только на localhost: он предназначен для работы за обратным прокси.
|
||||
# BIND=0.0.0.0 откроет его наружу, PORT=9000 сменит порт. Все переменные можно положить в файл .env рядом (образец: .env.example).
|
||||
services:
|
||||
split-trainer:
|
||||
build: .
|
||||
@@ -23,3 +23,46 @@ services:
|
||||
options:
|
||||
max-size: "5m"
|
||||
max-file: "3"
|
||||
|
||||
# API аккаунтов. Порт наружу не публикуется: к нему ходит только nginx из контейнера выше по имени splitapi.
|
||||
# Если API не нужен, сайт работает и без него (просто без входа): уберите этот сервис.
|
||||
splitapi:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.api
|
||||
image: split-trainer-api:latest
|
||||
container_name: splitapi
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# Должен совпадать с адресом, по которому открывают сайт (схема, домен, порт): из него строятся ссылки в письмах и проверяется Origin
|
||||
PUBLIC_URL: ${PUBLIC_URL:-http://127.0.0.1:${PORT:-8080}}
|
||||
# Верим X-Real-IP, потому что порт API не публикуется и до него доходит только nginx. Не публикуйте порт 8000.
|
||||
TRUST_PROXY: "1"
|
||||
MAIL_BACKEND: ${MAIL_BACKEND:-}
|
||||
MAIL_FROM: ${MAIL_FROM:-}
|
||||
SMTP_HOST: ${SMTP_HOST:-}
|
||||
SMTP_PORT: ${SMTP_PORT:-}
|
||||
SMTP_SECURITY: ${SMTP_SECURITY:-}
|
||||
SMTP_USER: ${SMTP_USER:-}
|
||||
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
|
||||
ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-true}
|
||||
SESSION_DAYS: ${SESSION_DAYS:-}
|
||||
volumes:
|
||||
- splitapi-data:/data
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp
|
||||
cap_drop:
|
||||
- ALL
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
mem_limit: 384m # scrypt занимает десятки МБ на каждый одновременный вход
|
||||
pids_limit: 64
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "5m"
|
||||
max-file: "3"
|
||||
|
||||
volumes:
|
||||
splitapi-data:
|
||||
|
||||
Reference in New Issue
Block a user