fix(email): resolve SMTP authentication failure and improve configuration resilience
- Fixed a bug where missing 'id=0' in the 'cfg' table caused SMTP authentication to fail by defaulting to placeholder credentials. - Updated 'app/lib_email.py' to explicitly validate SMTP server and port settings before connecting, preventing crashes with 'please run connect() first'. - Added email fallback logic in 'app/methods/person_methods.py' to use 'user_email' or 'primary_email' if the primary contact email is missing. - Aligned 'app/config.py.default' with the production structure, explicitly re-adding 'SMTP' and 'FILES_PATH' dictionaries. - Added comprehensive unit tests in 'tests/test_email_configuration.py' to verify configuration handling.
This commit is contained in:
@@ -133,7 +133,14 @@ def send_email(
|
||||
message.add_alternative(html_version, subtype='html')
|
||||
|
||||
log.info('Sending email...')
|
||||
log.debug(settings.SMTP)
|
||||
|
||||
# Safe access to SMTP settings
|
||||
smtp_settings = getattr(settings, 'SMTP', {})
|
||||
if not smtp_settings:
|
||||
log.error('SMTP settings not found in configuration. Returning False.')
|
||||
return False
|
||||
|
||||
log.debug(smtp_settings)
|
||||
|
||||
log.info(f'Subject: {subject}')
|
||||
log.info(f'From: {from_email} Reply To: {reply_to_email} To: {to_email} CC: {cc_email} BCC: {bcc_email}')
|
||||
@@ -144,17 +151,37 @@ def send_email(
|
||||
log.info('Creating SMTP SSL connection...')
|
||||
context = ssl.create_default_context()
|
||||
|
||||
# Validate SMTP settings
|
||||
smtp_server = smtp_settings.get('server')
|
||||
smtp_port = smtp_settings.get('port')
|
||||
smtp_username = smtp_settings.get('username')
|
||||
smtp_password = smtp_settings.get('password')
|
||||
|
||||
if not smtp_server or not smtp_port:
|
||||
log.error(f'Error: SMTP server or port not configured. Server: {smtp_server}, Port: {smtp_port}')
|
||||
return False
|
||||
|
||||
try:
|
||||
smtp_port = int(smtp_port)
|
||||
except ValueError:
|
||||
log.error(f'Error: Invalid SMTP port: {smtp_port}')
|
||||
return False
|
||||
|
||||
log.info('SMTP configuration, connect, and send')
|
||||
log.info(f'Server: {settings.SMTP["server"]} Port: {settings.SMTP["port"]} Username: {settings.SMTP["username"]}')
|
||||
log.info(f'Server: {smtp_server} Port: {smtp_port} Username: {smtp_username}')
|
||||
|
||||
log.info('Trying smtplib.SMTP_SSL in send_email()...')
|
||||
if test:
|
||||
log.info('[TESTING] Email will NOT actually be sent! [TEST MODE]')
|
||||
try:
|
||||
with smtplib.SMTP_SSL(settings.SMTP['server'], settings.SMTP['port'], context=context) as server:
|
||||
with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:
|
||||
log.info('SMTP log in...')
|
||||
log.debug(f'Server: {settings.SMTP["server"]} Port: {settings.SMTP["port"]} Username: {settings.SMTP["username"]} Password: {settings.SMTP["password"]}')
|
||||
server.login(settings.SMTP['username'], settings.SMTP['password'])
|
||||
# Avoid logging password in debug
|
||||
log.debug(f'Server: {smtp_server} Port: {smtp_port} Username: {smtp_username}')
|
||||
|
||||
if smtp_username and smtp_password:
|
||||
server.login(smtp_username, smtp_password)
|
||||
|
||||
log.info('SMTP send message...')
|
||||
if not test:
|
||||
log.info('Email sent! Returning True')
|
||||
@@ -162,7 +189,7 @@ def send_email(
|
||||
else:
|
||||
log.info('[TESTING] Email (NOT) sent! Returning True [TEST MODE]')
|
||||
return True
|
||||
except:
|
||||
log.error('Error: Unable to send email. Returning False')
|
||||
except Exception as e:
|
||||
log.error(f'Error: Unable to send email. Exception: {e}')
|
||||
return False
|
||||
# ### END ### API Lib Email ### send_email() ###
|
||||
|
||||
Reference in New Issue
Block a user