mirror of
https://github.com/simple-login/app.git
synced 2024-11-13 23:51:13 +01:00
148 lines
5.2 KiB
Python
148 lines
5.2 KiB
Python
import re
|
|
|
|
from flask import render_template, request, redirect, url_for, flash
|
|
from flask_login import login_required, current_user
|
|
from flask_wtf import FlaskForm
|
|
from wtforms import StringField, validators, ValidationError
|
|
|
|
from app.config import EMAIL_DOMAIN
|
|
from app.dashboard.base import dashboard_bp
|
|
from app.email_utils import get_email_part
|
|
from app.extensions import db
|
|
from app.log import LOG
|
|
from app.models import GenEmail, ForwardEmail
|
|
from app.utils import random_string
|
|
|
|
|
|
def email_validator():
|
|
"""validate email address. Handle both only email and email with name:
|
|
- ab@cd.com
|
|
- AB CD <ab@cd.com>
|
|
|
|
"""
|
|
message = "Invalid email format. Email must be either email@example.com or *First Last <email@example.com>*"
|
|
|
|
def _check(form, field):
|
|
email = field.data
|
|
email = email.strip()
|
|
email_part = email
|
|
|
|
if "<" in email and ">" in email:
|
|
if email.find("<") + 1 < email.find(">"):
|
|
email_part = email[email.find("<") + 1 : email.find(">")].strip()
|
|
|
|
if re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", email_part):
|
|
return
|
|
|
|
raise ValidationError(message)
|
|
|
|
return _check
|
|
|
|
|
|
class NewContactForm(FlaskForm):
|
|
email = StringField(
|
|
"Email", validators=[validators.DataRequired(), email_validator()]
|
|
)
|
|
|
|
|
|
@dashboard_bp.route("/alias_contact_manager/<alias_id>/", methods=["GET", "POST"])
|
|
@dashboard_bp.route(
|
|
"/alias_contact_manager/<alias_id>/<int:forward_email_id>", methods=["GET", "POST"]
|
|
)
|
|
@login_required
|
|
def alias_contact_manager(alias_id, forward_email_id=None):
|
|
gen_email = GenEmail.get(alias_id)
|
|
|
|
# sanity check
|
|
if not gen_email:
|
|
flash("You do not have access to this page", "warning")
|
|
return redirect(url_for("dashboard.index"))
|
|
|
|
if gen_email.user_id != current_user.id:
|
|
flash("You do not have access to this page", "warning")
|
|
return redirect(url_for("dashboard.index"))
|
|
|
|
new_contact_form = NewContactForm()
|
|
|
|
if request.method == "POST":
|
|
if request.form.get("form-name") == "create":
|
|
if new_contact_form.validate():
|
|
contact_email = new_contact_form.email.data.strip()
|
|
|
|
# generate a reply_email, make sure it is unique
|
|
# not use while to avoid infinite loop
|
|
for _ in range(1000):
|
|
reply_email = f"ra+{random_string(25)}@{EMAIL_DOMAIN}"
|
|
if not ForwardEmail.get_by(reply_email=reply_email):
|
|
break
|
|
|
|
website_email = get_email_part(contact_email)
|
|
|
|
# already been added
|
|
if ForwardEmail.get_by(
|
|
gen_email_id=gen_email.id, website_email=website_email
|
|
):
|
|
flash(f"{website_email} is already added", "error")
|
|
return redirect(
|
|
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
|
|
)
|
|
|
|
forward_email = ForwardEmail.create(
|
|
gen_email_id=gen_email.id,
|
|
website_email=website_email,
|
|
website_from=contact_email,
|
|
reply_email=reply_email,
|
|
)
|
|
|
|
LOG.d("create reverse-alias for %s", contact_email)
|
|
db.session.commit()
|
|
flash(f"Reverse alias for {contact_email} is created", "success")
|
|
|
|
return redirect(
|
|
url_for(
|
|
"dashboard.alias_contact_manager",
|
|
alias_id=alias_id,
|
|
forward_email_id=forward_email.id,
|
|
)
|
|
)
|
|
elif request.form.get("form-name") == "delete":
|
|
forward_email_id = request.form.get("forward-email-id")
|
|
forward_email = ForwardEmail.get(forward_email_id)
|
|
|
|
if not forward_email:
|
|
flash("Unknown error. Refresh the page", "warning")
|
|
return redirect(
|
|
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
|
|
)
|
|
elif forward_email.gen_email_id != gen_email.id:
|
|
flash("You cannot delete reverse-alias", "warning")
|
|
return redirect(
|
|
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
|
|
)
|
|
|
|
contact_name = forward_email.website_from
|
|
ForwardEmail.delete(forward_email_id)
|
|
db.session.commit()
|
|
|
|
flash(f"Reverse-alias for {contact_name} has been deleted", "success")
|
|
|
|
return redirect(
|
|
url_for("dashboard.alias_contact_manager", alias_id=alias_id)
|
|
)
|
|
|
|
# make sure highlighted forward_email is at array start
|
|
forward_emails = gen_email.forward_emails
|
|
|
|
if forward_email_id:
|
|
forward_emails = sorted(
|
|
forward_emails, key=lambda fe: fe.id == forward_email_id, reverse=True
|
|
)
|
|
|
|
return render_template(
|
|
"dashboard/alias_contact_manager.html",
|
|
forward_emails=forward_emails,
|
|
alias=gen_email.email,
|
|
gen_email=gen_email,
|
|
new_contact_form=new_contact_form,
|
|
forward_email_id=forward_email_id,
|
|
)
|