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:
@@ -0,0 +1,30 @@
|
||||
"""Build a MailProvider from an account row (SPEC §10.2 decryption boundary).
|
||||
|
||||
This module runs only inside the worker/sync context; ``decrypt_secret`` (the
|
||||
credential vault) is invoked here to obtain the plaintext mailbox password. It
|
||||
must never be imported by API request code.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from app.models import Account
|
||||
from app.providers.imap_smtp import ImapSmtpProvider, ProviderConfig
|
||||
from app.security.crypto import decrypt_secret
|
||||
|
||||
|
||||
def build_provider(account: Account) -> ImapSmtpProvider:
|
||||
"""Construct an :class:`ImapSmtpProvider` for ``account`` (password auth, M0)."""
|
||||
imap = account.imap_config
|
||||
smtp = account.smtp_config
|
||||
password = decrypt_secret(account.secret_ct).decode("utf-8")
|
||||
config = ProviderConfig(
|
||||
imap_host=str(imap["host"]),
|
||||
imap_port=int(str(imap["port"])),
|
||||
imap_tls=str(imap.get("tls", "ssl")),
|
||||
smtp_host=str(smtp["host"]),
|
||||
smtp_port=int(str(smtp["port"])),
|
||||
smtp_tls=str(smtp.get("tls", "ssl")),
|
||||
username=account.email,
|
||||
password=password,
|
||||
)
|
||||
return ImapSmtpProvider(config)
|
||||
Reference in New Issue
Block a user