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" '