diff --git a/app/api/views/auth_mfa.py b/app/api/views/auth_mfa.py index ebefc992..5bf3b24b 100644 --- a/app/api/views/auth_mfa.py +++ b/app/api/views/auth_mfa.py @@ -6,6 +6,7 @@ from itsdangerous import Signer from app.api.base import api_bp from app.config import FLASK_SECRET from app.db import Session +from app.email_utils import send_invalid_totp_login_email from app.log import LOG from app.models import User, ApiKey @@ -53,6 +54,7 @@ def auth_mfa(): totp = pyotp.TOTP(user.otp_secret) if not totp.verify(mfa_token): + send_invalid_totp_login_email(user, "TOTP") return jsonify(error="Wrong TOTP Token"), 400 ret = {"name": user.name or "", "email": user.email} diff --git a/app/auth/views/mfa.py b/app/auth/views/mfa.py index 14414f1c..b9f0214a 100644 --- a/app/auth/views/mfa.py +++ b/app/auth/views/mfa.py @@ -14,9 +14,9 @@ from flask_wtf import FlaskForm from wtforms import BooleanField, StringField, validators from app.auth.base import auth_bp -from app.config import MFA_USER_ID, URL, ALERT_INVALID_TOTP_LOGIN +from app.config import MFA_USER_ID, URL from app.db import Session -from app.email_utils import send_email_with_rate_control, render +from app.email_utils import send_invalid_totp_login_email from app.extensions import limiter from app.models import User, MfaBrowser @@ -96,21 +96,7 @@ def mfa(): # Trigger rate limiter g.deduct_limit = True otp_token_form.token.data = None - send_email_with_rate_control( - user, - ALERT_INVALID_TOTP_LOGIN, - user.email, - "There was an unsuccessful login on your SimpleLogin account", - render( - "transactional/invalid-totp-login.txt", - type="TOTP", - ), - render( - "transactional/invalid-totp-login.html", - type="TOTP", - ), - 1, - ) + send_invalid_totp_login_email(user, "TOTP") return render_template( "auth/mfa.html", diff --git a/app/auth/views/recovery.py b/app/auth/views/recovery.py index 371a3ebf..31a9ebcd 100644 --- a/app/auth/views/recovery.py +++ b/app/auth/views/recovery.py @@ -5,9 +5,9 @@ from flask_wtf import FlaskForm from wtforms import StringField, validators from app.auth.base import auth_bp -from app.config import MFA_USER_ID, ALERT_INVALID_TOTP_LOGIN +from app.config import MFA_USER_ID from app.db import Session -from app.email_utils import send_email_with_rate_control, render +from app.email_utils import send_invalid_totp_login_email from app.extensions import limiter from app.log import LOG from app.models import User, RecoveryCode @@ -69,20 +69,6 @@ def recovery_route(): # Trigger rate limiter g.deduct_limit = True flash("Incorrect code", "error") - send_email_with_rate_control( - user, - ALERT_INVALID_TOTP_LOGIN, - user.email, - "There was an unsuccessful login on your SimpleLogin account", - render( - "transactional/invalid-totp-login.txt", - type="recovery", - ), - render( - "transactional/invalid-totp-login.html", - type="recovery", - ), - 1, - ) + send_invalid_totp_login_email(user, "recovery") return render_template("auth/recovery.html", recovery_form=recovery_form) diff --git a/app/email_utils.py b/app/email_utils.py index 88e511c6..71a2ca00 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -50,6 +50,7 @@ from app.config import ( ALERT_DIRECTORY_DISABLED_ALIAS_CREATION, TRANSACTIONAL_BOUNCE_EMAIL, ALERT_SPF, + ALERT_INVALID_TOTP_LOGIN, TEMP_DIR, ALIAS_AUTOMATIC_DISABLE, RSPAMD_SIGN_DKIM, @@ -173,6 +174,24 @@ def send_change_email(new_email, current_email, link): ) +def send_invalid_totp_login_email(user, totp_type): + send_email_with_rate_control( + user, + ALERT_INVALID_TOTP_LOGIN, + user.email, + "There was an unsuccessful login on your SimpleLogin account", + render( + "transactional/invalid-totp-login.txt", + type=totp_type, + ), + render( + "transactional/invalid-totp-login.html", + type=totp_type, + ), + 1, + ) + + def send_test_email_alias(email, name): send_email( email,