Add login lockout and encrypt Player.totp_secret/auth_token at rest
Per-username lockout (5 failed TOTP attempts / 5 min) stops account-targeted brute force regardless of source IP. Player.totp_secret is now Fernet- encrypted (ENCRYPTION_KEY env, db/crypto.py) instead of stored in plaintext, and auth_token is stored as a SHA-256 hash rather than the raw session token. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,8 +51,9 @@ Serialization: `Card.JSONEncoder` flattens a `Card` to `{color, value}` name str
|
||||
Async SQLAlchemy 2.0, independent of Socket.IO (mirrors how the engine is kept clean).
|
||||
|
||||
- **`db/db.py`** — async `engine` + `async_sessionmaker`, declarative `Base`, and `init_db()` (`create_all`). Connection string from env **`DATABASE_URL`** (default `sqlite+aiosqlite:///bridzik.db`; Docker sets PostgreSQL via `asyncpg`). There are **no migrations** — `create_all` only adds new tables, so a changed column needs a fresh DB.
|
||||
- **`db/crypto.py`** — encryption/hashing for sensitive `Player` columns. `encrypt`/`decrypt` (Fernet, key from env **`ENCRYPTION_KEY`** — must stay stable, losing it locks out every account) for `totp_secret`; `hash_token` (SHA-256, one-way) for `auth_token`.
|
||||
- **`db/models.py`** — 3 tables:
|
||||
- **`Player`** — account + auth: `username` (unique login), `totp_secret`, `totp_last_step` (TOTP replay guard), `auth_token` (session token for reconnect).
|
||||
- **`Player`** — account + auth: `username` (unique login), `totp_secret` (Fernet-encrypted at rest via `db/crypto.py`), `totp_last_step` (TOTP replay guard), `auth_token` (session token for reconnect, stored as a SHA-256 hash, not plaintext).
|
||||
- **`Game`** — one match: `id` (gid), 4 `playerN_id` seats, `name`, `series`/`round` (current position, used for restore), `created_at`, `ended_at`.
|
||||
- **`Guess`** — one player's bid+result in a round: `series_number`, `round_number`, `guess`, `points`. `won` is derived (`points > 0`). Unique on (game, series, round, player) → idempotent writes.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user