def create_mailbox(): """ Create a new mailbox. User needs to verify the mailbox via an activation email. Input: email: in body Output: the new mailbox dict """ user = g.user mailbox_email = request.get_json().get("email").lower().strip().replace( " ", "") if mailbox_already_used(mailbox_email, user): return jsonify(error=f"{mailbox_email} already used"), 400 elif not email_can_be_used_as_mailbox(mailbox_email): return ( jsonify( error= f"{mailbox_email} cannot be used. Please note a mailbox cannot " f"be a disposable email address"), 400, ) else: new_mailbox = Mailbox.create(email=mailbox_email, user_id=user.id) db.session.commit() send_verification_email(user, new_mailbox) return ( jsonify(mailbox_to_dict(new_mailbox)), 201, )
def update_mailbox(mailbox_id): """ Update mailbox Input: mailbox_id: in url (optional) default: in body. Set a mailbox as the default mailbox. (optional) email: in body. Change a mailbox email. (optional) cancel_email_change: in body. Cancel mailbox email change. Output: 200 if updated successfully """ user = g.user mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != user.id: return jsonify(error="Forbidden"), 403 data = request.get_json() or {} changed = False if "default" in data: is_default = data.get("default") if is_default: user.default_mailbox_id = mailbox.id changed = True if "email" in data: new_email = data.get("email").lower().strip() if mailbox_already_used(new_email, user): return jsonify(error=f"{new_email} already used"), 400 elif not email_domain_can_be_used_as_mailbox(new_email): return ( jsonify( error= f"{new_email} cannot be used. Please note a mailbox cannot " f"be a disposable email address"), 400, ) try: verify_mailbox_change(user, mailbox, new_email) except SMTPRecipientsRefused: return jsonify( error=f"Incorrect mailbox, please recheck {new_email}"), 400 else: mailbox.new_email = new_email changed = True if "cancel_email_change" in data: cancel_email_change = data.get("cancel_email_change") if cancel_email_change: mailbox.new_email = None changed = True if changed: db.session.commit() return jsonify(updated=True), 200
def create_mailbox(): """ Create a new mailbox. User needs to verify the mailbox via an activation email. Input: email: in body Output: the new mailbox dict """ user = g.user mailbox_email = sanitize_email(request.get_json().get("email")) if not user.is_premium(): return jsonify( error=f"Only premium plan can add additional mailbox"), 400 if not is_valid_email(mailbox_email): return jsonify(error=f"{mailbox_email} invalid"), 400 elif mailbox_already_used(mailbox_email, user): return jsonify(error=f"{mailbox_email} already used"), 400 elif not email_can_be_used_as_mailbox(mailbox_email): return ( jsonify( error= f"{mailbox_email} cannot be used. Please note a mailbox cannot " f"be a disposable email address"), 400, ) else: new_mailbox = Mailbox.create(email=mailbox_email, user_id=user.id) Session.commit() send_verification_email(user, new_mailbox) return ( jsonify(mailbox_to_dict(new_mailbox)), 201, )
def mailbox_route(): mailboxes = ( Mailbox.query.filter_by(user_id=current_user.id) .order_by(Mailbox.created_at.desc()) .all() ) new_mailbox_form = NewMailboxForm() if request.method == "POST": if request.form.get("form-name") == "delete": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("You cannot delete default mailbox", "error") return redirect(url_for("dashboard.mailbox_route")) email = mailbox.email Mailbox.delete(mailbox_id) db.session.commit() flash(f"Mailbox {email} has been deleted", "success") return redirect(url_for("dashboard.mailbox_route")) if request.form.get("form-name") == "set-default": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("This mailbox is already default one", "error") return redirect(url_for("dashboard.mailbox_route")) if not mailbox.verified: flash("Cannot set unverified mailbox as default", "error") return redirect(url_for("dashboard.mailbox_route")) current_user.default_mailbox_id = mailbox.id db.session.commit() flash(f"Mailbox {mailbox.email} is set as Default Mailbox", "success") return redirect(url_for("dashboard.mailbox_route")) elif request.form.get("form-name") == "create": if not current_user.is_premium(): flash("Only premium plan can add additional mailbox", "warning") return redirect(url_for("dashboard.mailbox_route")) if new_mailbox_form.validate(): mailbox_email = ( new_mailbox_form.email.data.lower().strip().replace(" ", "") ) if not is_valid_email(mailbox_email): flash(f"{mailbox_email} invalid", "error") elif mailbox_already_used(mailbox_email, current_user): flash(f"{mailbox_email} already used", "error") elif not email_can_be_used_as_mailbox(mailbox_email): flash(f"You cannot use {mailbox_email}.", "error") else: new_mailbox = Mailbox.create( email=mailbox_email, user_id=current_user.id ) db.session.commit() send_verification_email(current_user, new_mailbox) flash( f"You are going to receive an email to confirm {mailbox_email}.", "success", ) return redirect( url_for( "dashboard.mailbox_detail_route", mailbox_id=new_mailbox.id ) ) return render_template( "dashboard/mailbox.html", mailboxes=mailboxes, new_mailbox_form=new_mailbox_form, )
def mailbox_detail_route(mailbox_id): mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("You cannot see this page", "warning") return redirect(url_for("dashboard.index")) change_email_form = ChangeEmailForm() if mailbox.new_email: pending_email = mailbox.new_email else: pending_email = None if request.method == "POST": if ( request.form.get("form-name") == "update-email" and change_email_form.validate_on_submit() ): new_email = change_email_form.email.data.lower().strip() if new_email != mailbox.email and not pending_email: # check if this email is not already used if mailbox_already_used(new_email, current_user) or Alias.get_by( email=new_email ): flash(f"Email {new_email} already used", "error") elif not email_domain_can_be_used_as_mailbox(new_email): flash("You cannot use this email address as your mailbox", "error") else: mailbox.new_email = new_email db.session.commit() try: verify_mailbox_change(current_user, mailbox, new_email) except SMTPRecipientsRefused: flash( f"Incorrect mailbox, please recheck {mailbox.email}", "error", ) else: flash( f"You are going to receive an email to confirm {new_email}.", "success", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id) ) elif request.form.get("form-name") == "force-spf": if not ENFORCE_SPF: flash("SPF enforcement globally not enabled", "error") return redirect(url_for("dashboard.index")) mailbox.force_spf = ( True if request.form.get("spf-status") == "on" else False ) db.session.commit() flash( "SPF enforcement was " + "enabled" if request.form.get("spf-status") else "disabled" + " successfully", "success", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id) ) elif request.form.get("form-name") == "pgp": if request.form.get("action") == "save": if not current_user.is_premium(): flash("Only premium plan can add PGP Key", "warning") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id) ) mailbox.pgp_public_key = request.form.get("pgp") try: mailbox.pgp_finger_print = load_public_key(mailbox.pgp_public_key) except PGPException: flash("Cannot add the public key, please verify it", "error") else: db.session.commit() flash("Your PGP public key is saved successfully", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id) ) elif request.form.get("action") == "remove": # Free user can decide to remove their added PGP key mailbox.pgp_public_key = None mailbox.pgp_finger_print = None db.session.commit() flash("Your PGP public key is removed successfully", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id) ) spf_available = ENFORCE_SPF return render_template("dashboard/mailbox_detail.html", **locals())
def mailbox_detail_route(mailbox_id): mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("You cannot see this page", "warning") return redirect(url_for("dashboard.index")) change_email_form = ChangeEmailForm() if mailbox.new_email: pending_email = mailbox.new_email else: pending_email = None if request.method == "POST": if (request.form.get("form-name") == "update-email" and change_email_form.validate_on_submit()): new_email = change_email_form.email.data.lower().strip() if new_email != mailbox.email and not pending_email: # check if this email is not already used if mailbox_already_used( new_email, current_user) or Alias.get_by(email=new_email): flash(f"Email {new_email} already used", "error") elif not email_can_be_used_as_mailbox(new_email): flash("You cannot use this email address as your mailbox", "error") else: mailbox.new_email = new_email db.session.commit() try: verify_mailbox_change(current_user, mailbox, new_email) except SMTPRecipientsRefused: flash( f"Incorrect mailbox, please recheck {mailbox.email}", "error", ) else: flash( f"You are going to receive an email to confirm {new_email}.", "success", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "force-spf": if not ENFORCE_SPF: flash("SPF enforcement globally not enabled", "error") return redirect(url_for("dashboard.index")) mailbox.force_spf = (True if request.form.get("spf-status") == "on" else False) db.session.commit() flash( "SPF enforcement was " + "enabled" if request.form.get("spf-status") else "disabled" + " successfully", "success", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "add-authorized-address": address = request.form.get("email").lower().strip().replace( " ", "") if AuthorizedAddress.get_by(mailbox_id=mailbox.id, email=address): flash(f"{address} already added", "error") else: AuthorizedAddress.create( user_id=current_user.id, mailbox_id=mailbox.id, email=address, commit=True, ) flash(f"{address} added as authorized address", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "delete-authorized-address": authorized_address_id = request.form.get("authorized-address-id") authorized_address: AuthorizedAddress = AuthorizedAddress.get( authorized_address_id) if not authorized_address or authorized_address.mailbox_id != mailbox.id: flash("Unknown error. Refresh the page", "warning") else: address = authorized_address.email AuthorizedAddress.delete(authorized_address_id) db.session.commit() flash(f"{address} has been deleted", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "pgp": if request.form.get("action") == "save": if not current_user.is_premium(): flash("Only premium plan can add PGP Key", "warning") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) mailbox.pgp_public_key = request.form.get("pgp") try: mailbox.pgp_finger_print = load_public_key_and_check( mailbox.pgp_public_key) except PGPException: flash("Cannot add the public key, please verify it", "error") else: db.session.commit() flash("Your PGP public key is saved successfully", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("action") == "remove": # Free user can decide to remove their added PGP key mailbox.pgp_public_key = None mailbox.pgp_finger_print = None mailbox.disable_pgp = False db.session.commit() flash("Your PGP public key is removed successfully", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "toggle-pgp": if request.form.get("pgp-enabled") == "on": mailbox.disable_pgp = False flash(f"PGP is enabled on {mailbox.email}", "success") else: mailbox.disable_pgp = True flash(f"PGP is disabled on {mailbox.email}", "info") db.session.commit() return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("form-name") == "generic-subject": if request.form.get("action") == "save": if not mailbox.pgp_enabled(): flash( "Generic subject can only be used on PGP-enabled mailbox", "error", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) mailbox.generic_subject = request.form.get("generic-subject") db.session.commit() flash("Generic subject for PGP-encrypted email is enabled", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) elif request.form.get("action") == "remove": mailbox.generic_subject = None db.session.commit() flash("Generic subject for PGP-encrypted email is disabled", "success") return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=mailbox_id)) spf_available = ENFORCE_SPF return render_template("dashboard/mailbox_detail.html", **locals())
def mailbox_route(): mailboxes = (Mailbox.query.filter_by(user_id=current_user.id).order_by( Mailbox.created_at.desc()).all()) new_mailbox_form = NewMailboxForm() if request.method == "POST": if request.form.get("form-name") == "delete": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("You cannot delete default mailbox", "error") return redirect(url_for("dashboard.mailbox_route")) email = mailbox.email Mailbox.delete(mailbox_id) db.session.commit() flash(f"Mailbox {email} has been deleted", "success") return redirect(url_for("dashboard.mailbox_route")) if request.form.get("form-name") == "set-default": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("This mailbox is already default one", "error") return redirect(url_for("dashboard.mailbox_route")) if not mailbox.verified: flash("Cannot set unverified mailbox as default", "error") return redirect(url_for("dashboard.mailbox_route")) current_user.default_mailbox_id = mailbox.id db.session.commit() flash(f"Mailbox {mailbox.email} is set as Default Mailbox", "success") return redirect(url_for("dashboard.mailbox_route")) elif request.form.get("form-name") == "create": if not current_user.is_premium(): flash("Only premium plan can add additional mailbox", "warning") return redirect(url_for("dashboard.mailbox_route")) if new_mailbox_form.validate(): mailbox_email = new_mailbox_form.email.data.lower() if mailbox_already_used(mailbox_email, current_user): flash(f"{mailbox_email} already used", "error") elif not email_domain_can_be_used_as_mailbox(mailbox_email): flash(f"You cannot use {mailbox_email}.", "error") else: new_mailbox = Mailbox.create(email=mailbox_email, user_id=current_user.id) db.session.commit() s = Signer(MAILBOX_SECRET) mailbox_id_signed = s.sign(str(new_mailbox.id)).decode() verification_url = (URL + "/dashboard/mailbox_verify" + f"?mailbox_id={mailbox_id_signed}") send_email( mailbox_email, f"Please confirm your email {mailbox_email}", render( "transactional/verify-mailbox.txt", user=current_user, link=verification_url, mailbox_email=mailbox_email, ), render( "transactional/verify-mailbox.html", user=current_user, link=verification_url, mailbox_email=mailbox_email, ), ) flash( f"You are going to receive an email to confirm {mailbox_email}.", "success", ) return redirect( url_for("dashboard.mailbox_detail_route", mailbox_id=new_mailbox.id)) return render_template( "dashboard/mailbox.html", mailboxes=mailboxes, new_mailbox_form=new_mailbox_form, EMAIL_DOMAIN=EMAIL_DOMAIN, ALIAS_DOMAINS=ALIAS_DOMAINS, )
def mailbox_route(): mailboxes = ( Mailbox.filter_by(user_id=current_user.id) .order_by(Mailbox.created_at.desc()) .all() ) new_mailbox_form = NewMailboxForm() if request.method == "POST": if request.form.get("form-name") == "delete": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("You cannot delete default mailbox", "error") return redirect(url_for("dashboard.mailbox_route")) # Schedule delete account job LOG.w("schedule delete mailbox job for %s", mailbox) Job.create( name=JOB_DELETE_MAILBOX, payload={"mailbox_id": mailbox.id}, run_at=arrow.now(), commit=True, ) flash( f"Mailbox {mailbox.email} scheduled for deletion." f"You will receive a confirmation email when the deletion is finished", "success", ) return redirect(url_for("dashboard.mailbox_route")) if request.form.get("form-name") == "set-default": mailbox_id = request.form.get("mailbox-id") mailbox = Mailbox.get(mailbox_id) if not mailbox or mailbox.user_id != current_user.id: flash("Unknown error. Refresh the page", "warning") return redirect(url_for("dashboard.mailbox_route")) if mailbox.id == current_user.default_mailbox_id: flash("This mailbox is already default one", "error") return redirect(url_for("dashboard.mailbox_route")) if not mailbox.verified: flash("Cannot set unverified mailbox as default", "error") return redirect(url_for("dashboard.mailbox_route")) current_user.default_mailbox_id = mailbox.id Session.commit() flash(f"Mailbox {mailbox.email} is set as Default Mailbox", "success") return redirect(url_for("dashboard.mailbox_route")) elif request.form.get("form-name") == "create": if not current_user.is_premium(): flash("Only premium plan can add additional mailbox", "warning") return redirect(url_for("dashboard.mailbox_route")) if new_mailbox_form.validate(): mailbox_email = ( new_mailbox_form.email.data.lower().strip().replace(" ", "") ) if not is_valid_email(mailbox_email): flash(f"{mailbox_email} invalid", "error") elif mailbox_already_used(mailbox_email, current_user): flash(f"{mailbox_email} already used", "error") elif not email_can_be_used_as_mailbox(mailbox_email): flash(f"You cannot use {mailbox_email}.", "error") else: new_mailbox = Mailbox.create( email=mailbox_email, user_id=current_user.id ) Session.commit() send_verification_email(current_user, new_mailbox) flash( f"You are going to receive an email to confirm {mailbox_email}.", "success", ) return redirect( url_for( "dashboard.mailbox_detail_route", mailbox_id=new_mailbox.id ) ) return render_template( "dashboard/mailbox.html", mailboxes=mailboxes, new_mailbox_form=new_mailbox_form, )