Files
webmail-client/backend/migrations/versions/0020_system_mail.py
T

49 lines
1.6 KiB
Python
Raw Normal View History

"""outgoing system mail (password reset) configured in the admin panel
The server sends its own mail — today only password-reset links — through an
SMTP account the administrator sets up in the admin panel. The password is
envelope-encrypted with MASTER_KEY like every mail-account secret. ``public_url``
is where users reach the app; reset links are built from it, never from the
request's Host header, which an attacker controls.
Revision ID: 0020
Revises: 0019
Create Date: 2026-09-30
"""
from __future__ import annotations
from collections.abc import Sequence
from alembic import op
revision: str = "0020"
down_revision: str | None = "0019"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
_COLUMNS = (
("smtp_host", "text NOT NULL DEFAULT ''"),
("smtp_port", "integer NOT NULL DEFAULT 587"),
("smtp_security", "text NOT NULL DEFAULT 'starttls'"),
("smtp_username", "text NOT NULL DEFAULT ''"),
("smtp_secret_ct", "bytea"),
("smtp_from", "text NOT NULL DEFAULT ''"),
("public_url", "text NOT NULL DEFAULT ''"),
)
def upgrade() -> None:
for name, ddl in _COLUMNS:
op.execute(f"ALTER TABLE app_settings ADD COLUMN {name} {ddl}")
op.execute(
"ALTER TABLE app_settings ADD CONSTRAINT ck_app_settings_smtp_security "
"CHECK (smtp_security IN ('starttls', 'ssl', 'none'))"
)
def downgrade() -> None:
op.execute("ALTER TABLE app_settings DROP CONSTRAINT IF EXISTS ck_app_settings_smtp_security")
for name, _ in reversed(_COLUMNS):
op.execute(f"ALTER TABLE app_settings DROP COLUMN IF EXISTS {name}")