For the complete documentation index, see llms.txt. This page is also available as Markdown.

47 - SMTP Configuration

Storage

SMTP settings are columns on the single Settings row (__tablename__ = "settings") in database/settings_db.py; there is no separate SMTP database or email service module.

Column
Type
Notes

smtp_server

String(255)

Hostname

smtp_port

Integer

Route default is 587 when the form omits it

smtp_username

String(255)

smtp_password_encrypted

Text

Fernet ciphertext, never plaintext

smtp_use_tls

Boolean

Defaults to True

smtp_from_email

String(255)

smtp_helo_hostname

String(255)

Optional EHLO/HELO override

New password writes use _get_smtp_fernet(): PBKDF2-HMAC-SHA256, 100,000 iterations, keyed on the validated API_KEY_PEPPER with the salt from SMTP_KEY_SALT (env var, default smtp-openalgo-salt). _decrypt_password() falls back to _legacy_smtp_fernet() (the raw pepper padded to 32 bytes, no KDF) for values written before that upgrade, and re-saving the settings migrates them forward. Decrypted passwords must never be returned by profile/admin APIs or logged.

Authenticated Routes

blueprints/auth.py exposes:

Method/path
Purpose

POST /auth/smtp-config

Update settings from form fields; a blank password preserves the existing secret

POST /auth/test-smtp

Validate recipient and send a test message

POST /auth/debug-smtp

Run connection/auth diagnostics

GET /auth/profile-data

Return non-secret config and password-present state

The React configuration UI is the SMTP tab in frontend/src/pages/Profile.tsx.

Delivery

utils/email_utils.py exposes send_test_email(), send_password_reset_email(), send_email(), and validate_smtp_settings(). Port 465 uses smtplib.SMTP_SSL from the start; any other port opens a plain SMTP connection and upgrades with starttls() when smtp_use_tls is set. smtp_helo_hostname is passed to ehlo(), falling back to smtp_server when it is blank. utils/email_debug.py performs staged diagnostics behind POST /auth/debug-smtp.

Security Rules

  • Require a valid app session and CSRF token for changes.

  • Preserve the existing password when the form leaves it blank.

  • Return password presence only, never ciphertext or plaintext.

  • Do not include credentials in SMTP errors or logs.

  • Prefer provider app passwords and TLS/SSL.

  • Treat debug output as authenticated operational data.

Key Files

File
Purpose

database/settings_db.py

Settings and SMTP encryption

utils/email_utils.py

Test/reset/general delivery

utils/email_debug.py

Connection diagnostics

blueprints/auth.py

Configuration routes

frontend/src/pages/Profile.tsx

SMTP form

Last updated

Was this helpful?