Initial commit: webmail client (M0/M1)

Three-pane webmail client.
- Backend: FastAPI + async SQLAlchemy + arq worker (Postgres/Redis), IMAP/SMTP
  sync, threading, search, drafts/outbox with undo, attachments, 2FA.
- Frontend: React 18 + Vite + TypeScript + TanStack Query + Tailwind; three-pane
  UI with rich-text composer, light/dark themes, resizable panels.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 23:20:34 +02:00
co-authored by Claude Opus 4.8
commit a5ec0d21cb
174 changed files with 22239 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
"""Argon2id password hashing (SPEC §6.1, §10.1).
Params are fixed: ``time_cost=3``, ``memory_cost=64 MiB``, ``parallelism=4``.
No other password hashing is permitted anywhere (SPEC §10.1).
"""
from __future__ import annotations
from argon2 import PasswordHasher
from argon2.exceptions import VerificationError, VerifyMismatchError
_hasher = PasswordHasher(
time_cost=3,
memory_cost=64 * 1024, # KiB -> 64 MiB
parallelism=4,
)
def hash_password(password: str) -> str:
"""Return an argon2id hash for ``password``."""
return _hasher.hash(password)
def verify_password(password_hash: str, password: str) -> bool:
"""Constant-time verify ``password`` against ``password_hash``."""
try:
return _hasher.verify(password_hash, password)
except (VerifyMismatchError, VerificationError):
return False
def needs_rehash(password_hash: str) -> bool:
"""Return True if ``password_hash`` was made with outdated parameters."""
return _hasher.check_needs_rehash(password_hash)