Browse Source

add Directory page to add/delete directory

Son NK 5 years ago
parent
commit
cdae3c5309

+ 1 - 0
app/dashboard/__init__.py

@@ -13,4 +13,5 @@ from .views import (
     mfa_cancel,
     domain_detail,
     lifetime_licence,
+    directory,
 )

+ 94 - 0
app/dashboard/templates/dashboard/directory.html

@@ -0,0 +1,94 @@
+{% extends 'default.html' %}
+{% set active_page = "directory" %}
+
+{% block title %}
+  Directory
+{% endblock %}
+
+{% block default_content %}
+  <div class="row">
+    <div class="col-md-8 offset-md-2">
+      <h1 class="h3"> Directories </h1>
+
+      <div class="alert alert-primary" role="alert">
+        Directory allows you to create aliases <b>on the fly</b>. <br>
+        Simply use <em>directory/<b>anything</b>@{{ EMAIL_DOMAIN }}</em>
+        or <em>directory+<b>anything</b>@{{ EMAIL_DOMAIN }}</em>
+        next time you need an email address. <br>
+        The alias will be created the first time it receives an email.
+      </div>
+
+      {% for dir in dirs %}
+        <div class="card" style="max-width: 50rem">
+          <div class="card-body">
+            <h5 class="card-title">
+              {{ dir.name }}
+            </h5>
+            <h6 class="card-subtitle mb-2 text-muted">
+              Created {{ dir.created_at | dt }} <br>
+              <span class="font-weight-bold">{{ dir.nb_alias() }}</span> aliases.
+            </h6>
+          </div>
+
+          <div class="card-footer p-0">
+            <div class="row">
+              <div class="col">
+                <form method="post">
+                  <input type="hidden" name="form-name" value="delete">
+                  <input type="hidden" class="dir-name" value="{{ dir.name }}">
+                  <input type="hidden" name="dir-id" value="{{ dir.id }}">
+                  <span class="card-link btn btn-link float-right delete-dir">
+                    Delete
+                  </span>
+                </form>
+              </div>
+            </div>
+
+          </div>
+
+        </div>
+      {% endfor %}
+
+      {% if dirs|length > 0 %}
+        <hr>
+      {% endif %}
+
+      <form method="post" class="mt-6">
+        {{ new_dir_form.csrf_token }}
+        <input type="hidden" name="form-name" value="create">
+
+        <div class="font-weight-bold">Directory Name</div>
+        <div class="small-text">
+          Directory name must be at least 3 characters.
+          Only letter, number, dash (-), underscore (_) can be used.
+        </div>
+
+        {{ new_dir_form.name(class="form-control", placeholder="my-directory", pattern="[0-9A-Za-z-_]{3,}",
+            title="Only letter, number, dash (-), underscore (_) can be used. Directory name must be at least 3 characters.",
+            autofocus="1") }}
+        {{ render_field_errors(new_dir_form.name) }}
+        <button class="btn btn-lg btn-success mt-2">Create</button>
+      </form>
+
+    </div>
+
+  </div>
+{% endblock %}
+
+{% block script %}
+  <script>
+    $(".delete-dir").on("click", function (e) {
+      let directory = $(this).parent().find(".dir-name").val();
+      notie.confirm({
+        text: `All aliases associated with <b>${directory}</b> directory will be also deleted, ` +
+          " please confirm.",
+        cancelCallback: () => {
+          // nothing to do
+        },
+        submitCallback: () => {
+          $(this).closest("form").submit();
+        }
+      });
+    });
+  </script>
+{% endblock %}

+ 76 - 0
app/dashboard/views/directory.py

@@ -0,0 +1,76 @@
+from flask import render_template, request, redirect, url_for, flash
+from flask_login import login_required, current_user
+from flask_wtf import FlaskForm
+from wtforms import StringField, validators
+
+from app.config import EMAIL_DOMAIN
+from app.dashboard.base import dashboard_bp
+from app.extensions import db
+from app.models import Directory
+
+
+class NewDirForm(FlaskForm):
+    name = StringField(
+        "name", validators=[validators.DataRequired(), validators.Length(min=3)]
+    )
+
+
+@dashboard_bp.route("/directory", methods=["GET", "POST"])
+@login_required
+def directory():
+    # only premium user can add directory
+    if not current_user.is_premium():
+        flash("Only premium user can add directories", "warning")
+        return redirect(url_for("dashboard.index"))
+
+    dirs = Directory.query.filter_by(user_id=current_user.id).all()
+
+    new_dir_form = NewDirForm()
+
+    if request.method == "POST":
+        if request.form.get("form-name") == "delete":
+            dir_id = request.form.get("dir-id")
+            dir = Directory.get(dir_id)
+
+            if not dir:
+                flash("Unknown error. Refresh the page", "warning")
+                return redirect(url_for("dashboard.directory"))
+            elif dir.user_id != current_user.id:
+                flash("You cannot delete this directory", "warning")
+                return redirect(url_for("dashboard.directory"))
+
+            name = dir.name
+            Directory.delete(dir_id)
+            db.session.commit()
+            flash(f"Directory {name} has been deleted", "success")
+
+            return redirect(url_for("dashboard.directory"))
+
+        elif request.form.get("form-name") == "create":
+            if new_dir_form.validate():
+                new_dir_name = new_dir_form.name.data
+
+                if Directory.get_by(name=new_dir_name):
+                    flash(f"{new_dir_name} already added", "warning")
+                # ra+ and reply+ are reserved for reply-email and reverse-alias
+                elif new_dir_name in ("ra", "reply"):
+                    flash(
+                        f"{new_dir_name} cannot be *ra* and *reply*, please use another name!",
+                        "warning",
+                    )
+                else:
+                    new_dir = Directory.create(
+                        name=new_dir_name, user_id=current_user.id
+                    )
+                    db.session.commit()
+
+                    flash(f"Directory {new_dir.name} is created", "success")
+
+                    return redirect(url_for("dashboard.directory",))
+
+    return render_template(
+        "dashboard/directory.html",
+        dirs=dirs,
+        new_dir_form=new_dir_form,
+        EMAIL_DOMAIN=EMAIL_DOMAIN,
+    )

+ 8 - 0
templates/menu.html

@@ -30,6 +30,14 @@
     </a>
   </li>
 
+  <li class="nav-item">
+    <a href="{{ url_for('dashboard.directory') }}"
+       class="nav-link {{ 'active' if active_page == 'directory' }}">
+      <i class="fe fe-folder"></i> Alias Directory
+      <span class="badge badge-success" style="font-size: .5rem; top: 5px">Premium</span>
+    </a>
+  </li>
+
   <!--
   <li class="nav-item">
     <a href="{{ url_for('discover.index') }}"