commit
5c48f82f41
|
@ -870,6 +870,7 @@ If success, 200 with the list of aliases. Each alias has the following fields:
|
|||
|
||||
- id
|
||||
- email
|
||||
- name
|
||||
- enabled
|
||||
- creation_timestamp
|
||||
- note
|
||||
|
@ -896,6 +897,7 @@ Here's an example:
|
|||
"creation_date": "2020-04-06 17:57:14+00:00",
|
||||
"creation_timestamp": 1586195834,
|
||||
"email": "prefix1.cat@sl.local",
|
||||
"name": "A Name",
|
||||
"enabled": true,
|
||||
"id": 3,
|
||||
"mailbox": {
|
||||
|
@ -920,6 +922,7 @@ Here's an example:
|
|||
"creation_date": "2020-04-06 17:57:14+00:00",
|
||||
"creation_timestamp": 1586195834,
|
||||
"email": "prefix0.hey@sl.local",
|
||||
"name": null,
|
||||
"enabled": true,
|
||||
"id": 2,
|
||||
"mailbox": {
|
||||
|
@ -1046,6 +1049,7 @@ Input:
|
|||
- `alias_id` in url.
|
||||
- (optional) `note` in request body
|
||||
- (optional) `mailbox_id` in request body
|
||||
- (optional) `name` in request body
|
||||
|
||||
Output:
|
||||
If success, return 200
|
||||
|
|
|
@ -47,6 +47,7 @@ def serialize_alias_info_v2(alias_info: AliasInfo) -> dict:
|
|||
"creation_timestamp": alias_info.alias.created_at.timestamp,
|
||||
"enabled": alias_info.alias.enabled,
|
||||
"note": alias_info.alias.note,
|
||||
"name": alias_info.alias.name,
|
||||
# activity
|
||||
"nb_forward": alias_info.nb_forward,
|
||||
"nb_block": alias_info.nb_blocked,
|
||||
|
|
|
@ -253,6 +253,7 @@ def update_alias(alias_id):
|
|||
Input:
|
||||
alias_id: in url
|
||||
note: in body
|
||||
name: in body
|
||||
Output:
|
||||
200
|
||||
"""
|
||||
|
@ -281,6 +282,11 @@ def update_alias(alias_id):
|
|||
alias.mailbox_id = mailbox_id
|
||||
changed = True
|
||||
|
||||
if "name" in data:
|
||||
new_name = data.get("name")
|
||||
alias.name = new_name
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
db.session.commit()
|
||||
|
||||
|
|
|
@ -212,10 +212,16 @@
|
|||
<!-- END Send Email && More button -->
|
||||
|
||||
<!-- Collapse section -->
|
||||
<div class="collapse" id="alias-{{ alias.id }}">
|
||||
<div class="collapse mt-2" id="alias-{{ alias.id }}">
|
||||
|
||||
{% if alias_info.latest_email_log != None %}
|
||||
<div style="font-size: 12px">
|
||||
Alias created {{ alias.created_at | dt }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if mailboxes|length > 1 %}
|
||||
<div class="small-text mt-2">Current mailbox</div>
|
||||
<div class="small-text">Current mailbox</div>
|
||||
<div class="d-flex">
|
||||
<div class="flex-grow-1 mr-2">
|
||||
<select id="mailbox-{{ alias.id }}"
|
||||
|
@ -243,14 +249,15 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="d-flex mt-2">
|
||||
<div class="small-text mt-2">Alias Note</div>
|
||||
<div class="d-flex">
|
||||
<div class="flex-grow-1 mr-2">
|
||||
<textarea
|
||||
id="note-{{ alias.id }}"
|
||||
name="note"
|
||||
class="form-control"
|
||||
rows="2"
|
||||
placeholder="Alias Note.">{{ alias.note or "" }}</textarea>
|
||||
placeholder="e.g. where the alias is used or why is it created">{{ alias.note or "" }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
|
@ -261,6 +268,29 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-text mt-2" data-toogle="tooltip"
|
||||
title="Alias name is used when you send or reply from alias">
|
||||
Alias name
|
||||
<i class="fe fe-help-circle"></i>
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
<div class="flex-grow-1 mr-2">
|
||||
<input id="alias-name-{{ alias.id }}"
|
||||
value="{{ alias.name or '' }}" class="form-control" placeholder="Alias name">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="">
|
||||
<a data-alias="{{ alias.id }}"
|
||||
class="save-alias-name btn btn-sm btn-outline-primary w-100">
|
||||
save
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
<form method="post">
|
||||
|
@ -495,5 +525,31 @@
|
|||
}
|
||||
|
||||
})
|
||||
|
||||
$(".save-alias-name").on("click", async function () {
|
||||
let aliasId = $(this).data("alias");
|
||||
let name = $(`#alias-name-${aliasId}`).val();
|
||||
|
||||
try {
|
||||
let res = await fetch(`/api/aliases/${aliasId}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
toastr.success(`Alias Name Saved`);
|
||||
} else {
|
||||
toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error");
|
||||
}
|
||||
} catch (e) {
|
||||
toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error");
|
||||
}
|
||||
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -579,6 +579,9 @@ class Alias(db.Model, ModelMixin):
|
|||
user_id = db.Column(db.ForeignKey(User.id, ondelete="cascade"), nullable=False)
|
||||
email = db.Column(db.String(128), unique=True, nullable=False)
|
||||
|
||||
# the name to use when user replies/sends from alias
|
||||
name = db.Column(db.String(128), nullable=True, default=None)
|
||||
|
||||
enabled = db.Column(db.Boolean(), default=True, nullable=False)
|
||||
|
||||
custom_domain_id = db.Column(
|
||||
|
|
|
@ -513,7 +513,12 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str
|
|||
delete_header(msg, "Received")
|
||||
|
||||
# make the email comes from alias
|
||||
add_or_replace_header(msg, "From", alias.email)
|
||||
if alias.name:
|
||||
LOG.d("Put alias name in from header")
|
||||
from_header = formataddr((alias.name, alias.email))
|
||||
else:
|
||||
from_header = alias.email
|
||||
add_or_replace_header(msg, "From", from_header)
|
||||
|
||||
# some email providers like ProtonMail adds automatically the Reply-To field
|
||||
# make sure to delete it
|
||||
|
|
29
migrations/versions/2020_042610_b4146f7d5277_.py
Normal file
29
migrations/versions/2020_042610_b4146f7d5277_.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: b4146f7d5277
|
||||
Revises: bd05eac83f5f
|
||||
Create Date: 2020-04-26 10:26:18.625088
|
||||
|
||||
"""
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'b4146f7d5277'
|
||||
down_revision = 'bd05eac83f5f'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('alias', sa.Column('name', sa.String(length=128), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('alias', 'name')
|
||||
# ### end Alembic commands ###
|
|
@ -155,6 +155,7 @@ def test_get_aliases_v2(flask_client):
|
|||
# "email": "prefix1.yeah@sl.local",
|
||||
# "enabled": true,
|
||||
# "id": 3,
|
||||
# "name": "Hey hey",
|
||||
# "latest_activity": {
|
||||
# "action": "forward",
|
||||
# "contact": {
|
||||
|
@ -173,6 +174,7 @@ def test_get_aliases_v2(flask_client):
|
|||
# "nb_reply": 0,
|
||||
# "note": null
|
||||
# }
|
||||
assert "name" in r0
|
||||
assert r0["email"].startswith("prefix1")
|
||||
assert r0["latest_activity"]["action"] == "forward"
|
||||
assert "timestamp" in r0["latest_activity"]
|
||||
|
@ -333,6 +335,30 @@ def test_update_alias_mailbox(flask_client):
|
|||
assert r.status_code == 400
|
||||
|
||||
|
||||
def test_update_alias_name(flask_client):
|
||||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
# create api_key
|
||||
api_key = ApiKey.create(user.id, "for test")
|
||||
db.session.commit()
|
||||
|
||||
alias = Alias.create_new_random(user)
|
||||
db.session.commit()
|
||||
|
||||
r = flask_client.put(
|
||||
url_for("api.update_alias", alias_id=alias.id),
|
||||
headers={"Authentication": api_key.code},
|
||||
json={"name": "Test Name"},
|
||||
)
|
||||
|
||||
assert r.status_code == 200
|
||||
alias = Alias.get(alias.id)
|
||||
assert alias.name == "Test Name"
|
||||
|
||||
|
||||
def test_alias_contacts(flask_client):
|
||||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
|
|
Loading…
Reference in a new issue