Parcourir la source

Merge remote-tracking branch 'origin/master' into directory

# Conflicts:
#	email_handler.py
Son NK il y a 5 ans
Parent
commit
851ddce5a5

+ 2 - 0
app/config.py

@@ -30,6 +30,8 @@ COLOR_LOG = "COLOR_LOG" in os.environ
 # Allow user to have 1 year of premium: set the expiration_date to 1 year more
 PROMO_CODE = "SIMPLEISBETTER"
 
+# Debug mode
+DEBUG = os.environ["DEBUG"] if "DEBUG" in os.environ else False
 # Server url
 URL = os.environ["URL"]
 print(">>> URL:", URL)

+ 92 - 1
app/dashboard/templates/dashboard/alias_log.html

@@ -1,7 +1,68 @@
 {% extends 'default.html' %}
 
 {% set active_page = "dashboard" %}
+{% block head %}
+  <style>
+{#  https://bootsnipp.com/snippets/rljEW#}
+.card-counter{
+    box-shadow: 2px 2px 10px #DADADA;
+    margin: 5px;
+    padding: 20px 10px;
+    background-color: #fff;
+    height: 100px;
+    border-radius: 5px;
+    transition: .3s linear all;
+  }
 
+  .card-counter:hover{
+    box-shadow: 4px 4px 20px #DADADA;
+    transition: .3s linear all;
+  }
+
+  .card-counter.primary{
+    background-color: #007bff;
+    color: #FFF;
+  }
+
+  .card-counter.danger{
+    background-color: #ef5350;
+    color: #FFF;
+  }
+
+  .card-counter.success{
+    background-color: #66bb6a;
+    color: #FFF;
+  }
+
+  .card-counter.info{
+    background-color: #26c6da;
+    color: #FFF;
+  }
+
+  .card-counter i{
+    font-size: 5em;
+    opacity: 0.2;
+  }
+
+  .card-counter .count-numbers{
+    position: absolute;
+    right: 35px;
+    top: 20px;
+    font-size: 32px;
+    display: block;
+  }
+
+  .card-counter .count-name{
+    position: absolute;
+    right: 35px;
+    top: 65px;
+    text-transform: capitalize;
+    opacity: 0.5;
+    display: block;
+    font-size: 18px;
+  }
+  </style>
+{% endblock %}
 {% block title %}
   Alias Activity
 {% endblock %}
@@ -12,7 +73,37 @@
       {{ alias }}
     </h3>
   </div>
-
+    <div class="row">
+        <div class="col-3">
+            <div class="card-counter primary">
+                <i class="fa fa-at"></i>
+                <span class="count-numbers">{{ total }}</span>
+                <span class="count-name">Email Handled</span>
+            </div>
+        </div>
+        <div class="col-3">
+            <div class="card-counter primary">
+                <i class="fa fa-paper-plane"></i>
+                <span class="count-numbers">{{ email_forwarded }}</span>
+                <span class="count-name">Email Forwarded</span>
+            </div>
+        </div>
+        <div class="col-3">
+            <div class="card-counter primary">
+                <i class="fa fa-reply"></i>
+                <span class="count-numbers">{{ email_replied }}</span>
+                <span class="count-name">Email Replied</span>
+            </div>
+        </div>
+        <div class="col-3">
+             <div class="card-counter danger">
+                <i class="fa fa-ban"></i>
+                <span class="count-numbers">{{ email_blocked }}</span>
+            <span class="count-name">Email Blocked</span>
+            </div>
+        </div>
+    </div>
+    <h2 class="pt-4">Activities</h2>
   <div class="row">
     {% for log in logs %}
       <div class="col-12">

+ 7 - 7
app/dashboard/templates/dashboard/index.html

@@ -19,7 +19,7 @@
   <div class="page-header row">
     <div class="col-lg-3 col-sm-12 p-0 mt-1">
       <form method="get">
-        <input type="search" name="query" autofocus placeholder="Enter to search for alias" class="form-control"
+        <input type="search" name="query" autofocus placeholder="Enter to search for alias" class="form-control shadow"
                value="{{ query }}">
       </form>
     </div>
@@ -30,7 +30,7 @@
           <input type="hidden" name="form-name" value="create-custom-email">
           <button data-toggle="tooltip"
                   title="Create a custom alias"
-                  class="btn btn-primary mr-2">New Email Alias
+                  class="btn btn-primary mr-2"><i class="fa fa-plus"></i> New Email Alias
           </button>
         </form>
         <div class="btn-group" role="group">
@@ -38,7 +38,7 @@
             <input type="hidden" name="form-name" value="create-random-email">
             <button data-toggle="tooltip"
                     title="Create a totally random alias"
-                    class="btn btn-success">Random Alias
+                    class="btn btn-success"><i class="fa fa-random"></i> Random Alias
             </button>
           </form>
           <button id="btnGroupDrop1" type="button" class="btn btn-success dropdown-toggle"
@@ -49,7 +49,7 @@
               <form method="post">
                 <input type="hidden" name="form-name" value="create-random-email">
                 <input type="hidden" name="generator_scheme" value="{{ AliasGeneratorEnum.word.value }}">
-                <button class="dropdown-item">By random words</button>
+                <button class="dropdown-item">By Random Words</button>
               </form>
             </div>
             <div class="">
@@ -71,7 +71,7 @@
       {% set gen_email = alias_info.gen_email %}
 
       <div class="col-md-6">
-        <div class="card p-3 {% if alias_info.highlight %} highlight-row {% endif %}">
+        <div class="card p-3 shadow-sm border-0 {% if alias_info.highlight %} highlight-row {% endif %}">
           <div>
             <span class="clipboard cursor mb-0"
                 {% if loop.index ==1 %}
@@ -171,8 +171,8 @@
                 <input type="hidden" name="gen-email-id" value="{{ gen_email.id }}">
                 <input type="hidden" name="alias" class="alias" value="{{ gen_email.email }}">
 
-                <span class="delete-email  btn btn-link btn-sm float-right">
-                  Delete&nbsp; &nbsp;<i class="dropdown-icon fe fe-trash-2"></i>
+                <span class="delete-email btn btn-link btn-sm float-right text-danger">
+                  Delete&nbsp; &nbsp;<i class="dropdown-icon fe fe-trash-2 text-danger"></i>
                 </span>
               </form>
             </div>

+ 13 - 0
app/dashboard/views/alias_log.py

@@ -38,6 +38,19 @@ def alias_log(alias, page_id):
         return redirect(url_for("dashboard.index"))
 
     logs = get_alias_log(gen_email, page_id)
+    base = (
+        db.session.query(ForwardEmail, ForwardEmailLog)
+        .filter(ForwardEmail.id == ForwardEmailLog.forward_id)
+        .filter(ForwardEmail.gen_email_id == gen_email.id)
+    )
+    total = base.count()
+    email_forwarded = (
+        base.filter(ForwardEmailLog.is_reply == False)
+        .filter(ForwardEmailLog.blocked == False)
+        .count()
+    )
+    email_replied = base.filter(ForwardEmailLog.is_reply == True).count()
+    email_blocked = base.filter(ForwardEmailLog.blocked == True).count()
     last_page = (
         len(logs) < _LIMIT
     )  # lightweight pagination without counting all objects

+ 4 - 2
app/email_utils.py

@@ -208,5 +208,7 @@ def add_or_replace_header(msg: Message, header: str, value: str):
 
 
 def delete_header(msg: Message, header: str):
-    if msg[header]:
-        del msg[header]
+    """a header can appear several times in message."""
+    for h in msg._headers:
+        if h[0].lower() == header.lower():
+            msg._headers.remove(h)

+ 3 - 0
email_handler.py

@@ -288,6 +288,9 @@ class MailHandler:
             msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
         )
 
+        # Received-SPF is injected by postfix-policyd-spf-python can reveal user original email
+        delete_header(msg, "Received-SPF")
+
         LOG.d(
             "send email from %s to %s, mail_options:%s,rcpt_options:%s",
             alias,

+ 1 - 2
server.py

@@ -18,6 +18,7 @@ from app.admin_model import SLModelView, SLAdminIndexView
 from app.api.base import api_bp
 from app.auth.base import auth_bp
 from app.config import (
+    DEBUG,
     DB_URI,
     FLASK_SECRET,
     SENTRY_DSN,
@@ -422,8 +423,6 @@ window.location.href = "/";
 if __name__ == "__main__":
     app = create_app()
 
-    app.debug = True
-
     # enable flask toolbar
     # app.config["DEBUG_TB_PROFILER_ENABLED"] = True
     # app.config["DEBUG_TB_INTERCEPT_REDIRECTS"] = False