diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index b62be20b..2ccbb6bb 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -206,31 +206,30 @@
Sender address format
- When your alias receives an email, says from John Wick <john@wick.com>, + When your alias receives an email, it says from: John Wick <john@wick.com>, SimpleLogin forwards it to your mailbox.
Due to some email constraints, SimpleLogin cannot keep the sender email address - in the original form and needs to transform it to one of the 2 below formats. + in the original form and needs to transform it to one of the formats below.
-
- - -
- -
- - -
+
diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index 0a935667..478d9314 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -30,6 +30,7 @@ from app.models import ( Client, AliasGeneratorEnum, ManualSubscription, + SenderFormatEnum, ) from app.utils import random_string @@ -161,12 +162,11 @@ def setting(): return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "change-sender-format": sender_format = int(request.form.get("sender-format")) - if sender_format == 0: - current_user.use_via_format_for_sender = False - else: - current_user.use_via_format_for_sender = True + if SenderFormatEnum.has_value(sender_format): + current_user.sender_format = sender_format + db.session.commit() + flash("Your sender format preference has been updated", "success") db.session.commit() - flash("Your sender format preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "export-data": @@ -200,6 +200,7 @@ def setting(): "dashboard/setting.html", form=form, PlanEnum=PlanEnum, + SenderFormatEnum=SenderFormatEnum, promo_form=promo_form, change_email_form=change_email_form, pending_email=pending_email, diff --git a/app/models.py b/app/models.py index ba353c74..b54b1d2c 100644 --- a/app/models.py +++ b/app/models.py @@ -96,19 +96,29 @@ class File(db.Model, ModelMixin): return s3.get_url(self.path, expires_in) -class PlanEnum(enum.Enum): +class EnumE(enum.Enum): + @classmethod + def has_value(cls, value: int) -> bool: + return value in set(item.value for item in cls) + + +class PlanEnum(EnumE): monthly = 2 yearly = 3 -class AliasGeneratorEnum(enum.Enum): +# Specify the format for sender address +class SenderFormatEnum(EnumE): + AT = 0 # John Wick - john at wick.com + VIA = 1 # john@wick.com via SimpleLogin + A = 2 # John Wick - john(a)wick.com + FULL = 3 # John Wick - john@wick.com + + +class AliasGeneratorEnum(EnumE): word = 1 # aliases are generated based on random words uuid = 2 # aliases are generated based on uuid - @classmethod - def has_value(cls, value: int) -> bool: - return value in set(item.value for item in cls) - class User(db.Model, ModelMixin, UserMixin): __tablename__ = "users" @@ -172,10 +182,13 @@ class User(db.Model, ModelMixin, UserMixin): profile_picture = db.relationship(File, foreign_keys=[profile_picture_id]) - # Use the "via" format for sender address, i.e. "name@example.com via SimpleLogin" - # If False, use the format "Name - name at example.com" - use_via_format_for_sender = db.Column( - db.Boolean, default=True, nullable=False, server_default="1" + # Specify the format for sender address + # John Wick - john at wick.com -> 0 + # john@wick.com via SimpleLogin -> 1 + # John Wick - john@wick.com -> 2 + # John Wick - john@wick.com -> 3 + sender_format = db.Column( + db.Integer, default="1", nullable=False, server_default="1" ) referral_id = db.Column( @@ -868,21 +881,35 @@ class Contact(db.Model, ModelMixin): def new_addr(self): """ - Replace original email by reply_email. 2 possible formats: - - first@example.com by SimpleLogin OR - - First Last - first at example.com + Replace original email by reply_email. Possible formats: + - first@example.com via SimpleLogin OR + - First Last - first at example.com OR + - First Last - first(a)example.com OR + - First Last - first@example.com OR And return new address with RFC 2047 format `new_email` is a special reply address """ user = self.user - if user and user.use_via_format_for_sender: + if ( + not user + or not SenderFormatEnum.has_value(user.sender_format) + or user.sender_format == SenderFormatEnum.VIA.value + ): new_name = f"{self.website_email} via SimpleLogin" - else: + elif user.sender_format == SenderFormatEnum.AT.value: name = self.name or "" new_name = ( name + (" - " if name else "") + self.website_email.replace("@", " at ") ).strip() + elif user.sender_format == SenderFormatEnum.A.value: + name = self.name or "" + new_name = ( + name + (" - " if name else "") + self.website_email.replace("@", "(a)") + ).strip() + elif user.sender_format == SenderFormatEnum.FULL.value: + name = self.name or "" + new_name = (name + (" - " if name else "") + self.website_email).strip() new_addr = formataddr((new_name, self.reply_email)).strip() return new_addr.strip() diff --git a/migrations/versions/2020_051515_5cad8fa84386_.py b/migrations/versions/2020_051515_5cad8fa84386_.py new file mode 100644 index 00000000..dc42d004 --- /dev/null +++ b/migrations/versions/2020_051515_5cad8fa84386_.py @@ -0,0 +1,45 @@ +"""empty message + +Revision ID: 5cad8fa84386 +Revises: a5e3c6693dc6 +Create Date: 2020-05-15 15:10:00.096349 + +""" +import sqlalchemy_utils +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "5cad8fa84386" +down_revision = "a5e3c6693dc6" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column("users", "use_via_format_for_sender", server_default=None) + op.alter_column( + "users", + "use_via_format_for_sender", + new_column_name="sender_format", + type_=sa.Integer(), + postgresql_using="use_via_format_for_sender::integer", + ) + op.alter_column("users", "sender_format", server_default="1") + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column("users", "sender_format", server_default=None) + op.alter_column( + "users", + "sender_format", + new_column_name="use_via_format_for_sender", + type_=sa.Boolean(), + postgresql_using="sender_format::boolean", + ) + op.alter_column("users", "use_via_format_for_sender", server_default="1") + # ### end Alembic commands ### diff --git a/tests/test_models.py b/tests/test_models.py index be796f75..e6938431 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,11 +1,18 @@ -from uuid import UUID - import pytest +from uuid import UUID from app.config import EMAIL_DOMAIN, MAX_NB_EMAIL_FREE_PLAN from app.email_utils import parseaddr_unicode from app.extensions import db -from app.models import generate_email, User, Alias, Contact, Mailbox, AliasMailbox +from app.models import ( + generate_email, + User, + Alias, + Contact, + Mailbox, + AliasMailbox, + SenderFormatEnum, +) def test_generate_email(flask_client): @@ -104,7 +111,7 @@ def test_new_addr(flask_client): alias = Alias.create_new_random(user) db.session.commit() - # use_via_format_for_sender is by default + # default sender_format is 'via' c1 = Contact.create( user_id=user.id, alias_id=alias.id, @@ -115,8 +122,8 @@ def test_new_addr(flask_client): db.session.commit() assert c1.new_addr() == '"abcd@example.com via SimpleLogin" ' - # use_via_format_for_sender = False - user.use_via_format_for_sender = False + # set sender_format = AT + user.sender_format = SenderFormatEnum.AT.value db.session.commit() assert c1.new_addr() == '"First Last - abcd at example.com" '