do not forward cycle email: email sent to alias from its mailbox
This commit is contained in:
parent
ce791567f1
commit
ab911fd55e
|
@ -289,6 +289,9 @@ ALERT_BOUNCE_EMAIL = "bounce"
|
|||
# When a forwarding email is detected as spam
|
||||
ALERT_SPAM_EMAIL = "spam"
|
||||
|
||||
# When an email is sent from a mailbox to an alias - a cycle
|
||||
ALERT_SEND_EMAIL_CYCLE = "cycle"
|
||||
|
||||
ALERT_SPF = "spf"
|
||||
|
||||
# <<<<< END ALERT EMAIL >>>>
|
||||
|
|
|
@ -71,6 +71,7 @@ from app.config import (
|
|||
SPAMASSASSIN_HOST,
|
||||
MAX_SPAM_SCORE,
|
||||
MAX_REPLY_PHASE_SPAM_SCORE,
|
||||
ALERT_SEND_EMAIL_CYCLE,
|
||||
)
|
||||
from app.email_utils import (
|
||||
send_email,
|
||||
|
@ -116,6 +117,7 @@ _MAILBOX_ID_HEADER = "X-SimpleLogin-Mailbox-ID"
|
|||
_EMAIL_LOG_ID_HEADER = "X-SimpleLogin-EmailLog-ID"
|
||||
_MESSAGE_ID = "Message-ID"
|
||||
|
||||
|
||||
# fix the database connection leak issue
|
||||
# use this method instead of create_app
|
||||
def new_app():
|
||||
|
@ -374,6 +376,41 @@ def prepare_pgp_message(orig_msg: Message, pgp_fingerprint: str):
|
|||
return msg
|
||||
|
||||
|
||||
def handle_email_sent_to_ourself(alias, mailbox, msg: Message, user):
|
||||
# store the refused email
|
||||
random_name = str(uuid.uuid4())
|
||||
full_report_path = f"refused-emails/cycle-{random_name}.eml"
|
||||
s3.upload_email_from_bytesio(full_report_path, BytesIO(msg.as_bytes()), random_name)
|
||||
refused_email = RefusedEmail.create(
|
||||
path=None, full_report_path=full_report_path, user_id=alias.user_id
|
||||
)
|
||||
db.session.commit()
|
||||
LOG.d("Create refused email %s", refused_email)
|
||||
# link available for 6 days as it gets deleted in 7 days
|
||||
refused_email_url = refused_email.get_url(expires_in=518400)
|
||||
|
||||
send_email_with_rate_control(
|
||||
user,
|
||||
ALERT_SEND_EMAIL_CYCLE,
|
||||
mailbox.email,
|
||||
f"Warning: email sent from {mailbox.email} to {alias.email} forms a cycle",
|
||||
render(
|
||||
"transactional/cycle-email.txt",
|
||||
name=user.name or "",
|
||||
alias=alias,
|
||||
mailbox=mailbox,
|
||||
refused_email_url=refused_email_url,
|
||||
),
|
||||
render(
|
||||
"transactional/cycle-email.html",
|
||||
name=user.name or "",
|
||||
alias=alias,
|
||||
mailbox=mailbox,
|
||||
refused_email_url=refused_email_url,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def handle_forward(
|
||||
envelope, smtp: SMTP, msg: Message, rcpt_to: str
|
||||
) -> List[Tuple[bool, str]]:
|
||||
|
@ -390,6 +427,14 @@ async def handle_forward(
|
|||
LOG.d("alias %s cannot be created on-the-fly, return 550", address)
|
||||
return [(False, "550 SL E3 Email not exist")]
|
||||
|
||||
mail_from = envelope.mail_from.lower().strip()
|
||||
for mb in alias.mailboxes:
|
||||
# email send from a mailbox to alias
|
||||
if mb.email.lower().strip() == mail_from:
|
||||
LOG.exception("cycle email sent from %s to %s", mb, alias)
|
||||
handle_email_sent_to_ourself(alias, mb, msg, alias.user)
|
||||
return [(True, "250 Message accepted for delivery")]
|
||||
|
||||
contact = get_or_create_contact(msg["From"], envelope.mail_from, alias)
|
||||
email_log = EmailLog.create(contact_id=contact.id, user_id=contact.user_id)
|
||||
db.session.commit()
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% call text() %}
|
||||
Hi {{ name }}
|
||||
{% endcall %}
|
||||
|
||||
{% call text() %}
|
||||
SimpleLogin has blocked an email that was sent to your alias <b>{{ alias.email }}</b> from its mailbox
|
||||
<b>{{ mailbox.email }}</b>:
|
||||
the email would be forwarded to the same mailbox <b>{{ mailbox.email }}</b>.
|
||||
|
||||
{% endcall %}
|
||||
|
||||
{% call text() %}
|
||||
This creates a <b>cycle</b> and the email will probably be refused or hidden by your email service anyway.
|
||||
{% endcall %}
|
||||
|
||||
{{ render_button("View the refused email", refused_email_url) }}
|
||||
|
||||
{% call text() %}
|
||||
The email is automatically deleted in 7 days.
|
||||
{% endcall %}
|
||||
|
||||
{% call text() %}
|
||||
Please let us know if you have any question.
|
||||
{% endcall %}
|
||||
|
||||
{{ render_text('Thanks, <br />SimpleLogin Team.') }}
|
||||
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
|||
Hi {{name}}
|
||||
|
||||
SimpleLogin has blocked an email that was sent to your alias {{alias.email}} from its mailbox {{ mailbox.email }}:
|
||||
the email would be forwarded to the same mailbox {{ mailbox.email }}.
|
||||
|
||||
This creates a *cycle* and the email will probably be refused or hidden by your email service anyway.
|
||||
|
||||
You can view this email here:
|
||||
{{ refused_email_url }}
|
||||
|
||||
The email is automatically deleted in 7 days.
|
||||
|
||||
Please let us know if you have any question.
|
||||
|
||||
Best,
|
||||
SimpleLogin team.
|
Loading…
Reference in New Issue