fix: add sender_email to UserSmtpConfig to fix SMTP From header (501 bad sender address)

Agent-Logs-Url: https://github.com/christianlouis/InboxConverge/sessions/dc853384-976a-46e5-945b-60c9a9cce638

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-03 21:46:47 +00:00
committed by GitHub
parent edb4e8b0cc
commit a21e2f7df6
9 changed files with 72 additions and 3 deletions
@@ -0,0 +1,36 @@
"""Add sender_email column to user_smtp_configs
Revision ID: 0003
Revises: 0002
Create Date: 2026-05-03
Adds a ``sender_email`` column to ``user_smtp_configs``.
SMTP providers such as Postmark use an API token (UUID) as the SMTP username
for authentication, but require a real email address as the ``From:`` header.
This column stores the address that should appear as the sender; when blank,
the existing ``username`` value is used as a fallback so existing rows remain
fully functional.
Using IF NOT EXISTS makes the migration idempotent against fresh installs
where create_all() already created the column.
"""
from alembic import op
# revision identifiers, used by Alembic.
revision = "0003"
down_revision = "0002"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.execute(
"ALTER TABLE user_smtp_configs "
"ADD COLUMN IF NOT EXISTS sender_email VARCHAR(255) NOT NULL DEFAULT ''"
)
def downgrade() -> None:
op.execute("ALTER TABLE user_smtp_configs DROP COLUMN IF EXISTS sender_email")
+5 -1
View File
@@ -72,6 +72,7 @@ async def get_smtp_config(
host=config.host, # type: ignore[arg-type]
port=config.port, # type: ignore[arg-type]
username=config.username, # type: ignore[arg-type]
sender_email=config.sender_email, # type: ignore[arg-type]
use_tls=config.use_tls, # type: ignore[arg-type]
has_password=bool(config.encrypted_password),
created_at=config.created_at, # type: ignore[arg-type]
@@ -95,6 +96,7 @@ async def upsert_smtp_config(
config.host = config_in.host # type: ignore[assignment]
config.port = config_in.port # type: ignore[assignment]
config.username = config_in.username # type: ignore[assignment]
config.sender_email = config_in.sender_email # type: ignore[assignment]
config.use_tls = config_in.use_tls # type: ignore[assignment]
if config_in.password is not None:
config.encrypted_password = encrypt_credential(config_in.password) # type: ignore[assignment]
@@ -104,6 +106,7 @@ async def upsert_smtp_config(
host=config_in.host,
port=config_in.port,
username=config_in.username,
sender_email=config_in.sender_email,
encrypted_password=(
encrypt_credential(config_in.password) if config_in.password else ""
),
@@ -120,6 +123,7 @@ async def upsert_smtp_config(
host=config.host, # type: ignore[arg-type]
port=config.port, # type: ignore[arg-type]
username=config.username, # type: ignore[arg-type]
sender_email=config.sender_email, # type: ignore[arg-type]
use_tls=config.use_tls, # type: ignore[arg-type]
has_password=bool(config.encrypted_password),
created_at=config.created_at, # type: ignore[arg-type]
@@ -174,7 +178,7 @@ async def test_smtp_config(
"plain",
"utf-8",
)
msg["From"] = config.username # type: ignore[index]
msg["From"] = config.sender_email or config.username # type: ignore[index]
msg["To"] = recipient
msg["Date"] = formatdate(localtime=True)
msg["Message-ID"] = make_msgid()
+1
View File
@@ -475,6 +475,7 @@ class UserSmtpConfig(Base):
username = Column(String(255), nullable=False, default="")
encrypted_password = Column(Text, nullable=False, default="")
use_tls = Column(Boolean, default=True)
sender_email = Column(String(255), nullable=False, default="")
created_at = Column(
DateTime(timezone=True),
+1
View File
@@ -481,6 +481,7 @@ class UserSmtpConfigBase(BaseModel):
host: str = "smtp.gmail.com"
port: int = Field(587, gt=0, lt=65536)
username: str = ""
sender_email: str = ""
use_tls: bool = True
+3 -1
View File
@@ -1256,7 +1256,9 @@ class MailProcessor:
# Create forwarding message
forward_msg = MIMEMultipart("mixed")
forward_msg["From"] = smtp_config["username"]
forward_msg["From"] = (
smtp_config.get("sender_email") or smtp_config["username"]
)
forward_msg["To"] = destination
forward_msg["Date"] = formatdate(localtime=True)
forward_msg["Message-ID"] = make_msgid()
+1
View File
@@ -210,6 +210,7 @@ async def process_mail_account(account_id: int):
"host": user_smtp.host,
"port": user_smtp.port,
"username": user_smtp.username,
"sender_email": user_smtp.sender_email or "",
"password": decrypt_credential(user_smtp.encrypted_password), # type: ignore[arg-type]
"use_tls": user_smtp.use_tls,
}