From 1384ccc4594c45b80d857b7b5b4da9082a813584 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:32:33 +0200 Subject: [PATCH 001/144] remove RESET_DB config --- app/config.py | 1 - example.env | 3 --- server.py | 10 ---------- tests/test.env | 2 -- 4 files changed, 16 deletions(-) diff --git a/app/config.py b/app/config.py index 432fa075..c49109e8 100644 --- a/app/config.py +++ b/app/config.py @@ -45,7 +45,6 @@ if config_file: else: load_dotenv() -RESET_DB = "RESET_DB" in os.environ COLOR_LOG = "COLOR_LOG" in os.environ # Allow user to have 1 year of premium: set the expiration_date to 1 year more diff --git a/example.env b/example.env index 2e7e859f..5b00468e 100644 --- a/example.env +++ b/example.env @@ -74,9 +74,6 @@ EMAIL_SERVERS_WITH_PRIORITY=[(10, "email.hostname.")] # the DKIM private key used to compute DKIM-Signature # DKIM_PRIVATE_KEY_PATH=local_data/dkim.key -# delete and recreate the sqlite database, for local development -RESET_DB=true - # DB Connection # Local SQLite database DB_URI=sqlite:///db.sqlite diff --git a/server.py b/server.py index 15bda4b9..d0c60f51 100644 --- a/server.py +++ b/server.py @@ -49,7 +49,6 @@ from app.config import ( URL, SHA1, PADDLE_MONTHLY_PRODUCT_ID, - RESET_DB, FLASK_PROFILER_PATH, FLASK_PROFILER_PASSWORD, SENTRY_FRONT_END_DSN, @@ -951,15 +950,6 @@ def local_main(): app.debug = True DebugToolbarExtension(app) - # warning: only used in local - if RESET_DB: - from init_app import add_sl_domains - - LOG.warning("reset db, add fake data") - with app.app_context(): - fake_data() - add_sl_domains() - app.run(debug=True, port=7777) # uncomment to run https locally diff --git a/tests/test.env b/tests/test.env index 8b5669fd..3c5b3ff9 100644 --- a/tests/test.env +++ b/tests/test.env @@ -14,8 +14,6 @@ MAX_NB_EMAIL_FREE_PLAN=3 EMAIL_SERVERS_WITH_PRIORITY=[(10, "email.hostname.")] DKIM_PRIVATE_KEY_PATH=local_data/dkim.key -# Database -RESET_DB=true DB_URI=postgresql://test:test@localhost:5432/test # Flask From 4cbbf260d489e564fb729f7955d748fa384e82f0 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:32:54 +0200 Subject: [PATCH 002/144] add dummy-data flask command --- server.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/server.py b/server.py index d0c60f51..36a44b9a 100644 --- a/server.py +++ b/server.py @@ -204,13 +204,7 @@ def create_app() -> Flask: def fake_data(): LOG.d("create fake data") - # Remove db if exist - if os.path.exists("db.sqlite"): - LOG.d("remove existing db file") - os.remove("db.sqlite") - # Create all tables - db.create_all() # Create a user user = User.create( @@ -918,6 +912,15 @@ def register_custom_commands(app): LOG.d("finish trunk %s, update %s email logs", trunk, nb_update) db.session.commit() + @app.cli.command("dummy-data") + def dummy_data(): + from init_app import add_sl_domains + + LOG.warning("reset db, add fake data") + with app.app_context(): + fake_data() + add_sl_domains() + def setup_do_not_track(app): @app.route("/dnt") From d9c682a23e1d78243889091a23992acd14f82ca7 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:41:16 +0200 Subject: [PATCH 003/144] remove sqlite everywhere, only use postgres. Do not use 5432 port to avoid conflict --- .github/workflows/main.yml | 5 ++-- CONTRIBUTING.md | 50 ++++++++++++++++---------------------- example.env | 5 +--- new_migration.sh | 6 ++--- tests/test.env | 2 +- 5 files changed, 28 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 58ccb1bb..5256b69e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,12 +25,11 @@ jobs: # required POSTGRES_PASSWORD: test # optional (defaults to `5432`) - POSTGRES_PORT: 5432 + POSTGRES_PORT: 15432 # optional (defaults to `postgres`) POSTGRES_USER: test ports: - # maps tcp port 5432 on service container to the host - - 5432:5432 + - 15432:15432 # set health checks to wait until postgres has started options: >- --health-cmd pg_isready diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8e8243ff..ace9b5ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,6 @@ Thanks for taking the time to contribute! 🎉👍 -The project uses Flask and requires Python3.7+. - -## Quick start - -If you have Docker installed, run the following command to start SimpleLogin local server: - - -```bash -docker run --name sl -it --rm \ - -e RESET_DB=true \ - -e CONFIG=/code/example.env \ - -p 7777:7777 \ - simplelogin/app:3.4.0 python server.py -``` - -Then open http://localhost:7777, you should be able to login with `john@wick.com/password` account. +The project uses Flask, Python3.7+ and requires Postgres 12+ as dependency. ## General Architecture @@ -25,15 +10,16 @@ Then open http://localhost:7777, you should be able to login with `john@wick.com SimpleLogin backend consists of 2 main components: -- the `webapp` used by several clients: web UI (the dashboard), browser extension (Chrome & Firefox for now), OAuth clients (apps that integrate "Login with SimpleLogin" button) and mobile app (work in progress). +- the `webapp` used by several clients: the web app, the browser extensions (Chrome & Firefox for now), OAuth clients (apps that integrate "Sign in with SimpleLogin" button) and mobile apps. - the `email handler`: implements the email forwarding (i.e. alias receiving email) and email sending (i.e. alias sending email). -## Run code locally +## Install dependencies -The project uses +The project requires: - Python 3.7+ and [poetry](https://python-poetry.org/) to manage dependencies - Node v10 for front-end. +- Postgres 12+ First, install all dependencies by running the following command. Feel free to use `virtualenv` or similar tools to isolate development environment. @@ -42,22 +28,24 @@ Feel free to use `virtualenv` or similar tools to isolate development environmen poetry install ``` -On Mac, sometimes you might need to install some other packages like +On Mac, sometimes you might need to install some other packages via `brew`: ```bash brew install pkg-config libffi openssl postgresql ``` -You also need to install `gpg`, on Mac it can be done with: +You also need to install `gpg` tool, on Mac it can be done with: ```bash brew install gnupg ``` -Then make sure all tests pass. You need to run a local postgres database to run tests, it can be run with docker with: +## Run tests + +Running test requires a Postgres database. You can run one with docker: ```bash -docker run -e POSTGRES_PASSWORD=test -e POSTGRES_USER=test -e POSTGRES_DB=test -p 5432:5432 postgres:13 +docker run -e POSTGRES_PASSWORD=test -e POSTGRES_USER=test -e POSTGRES_DB=test -p 15432:5432 postgres:13 ``` then run all tests @@ -66,6 +54,8 @@ then run all tests pytest ``` +## Run the code locally + Install npm packages ```bash @@ -78,17 +68,19 @@ To run the code locally, please create a local setting file based on `example.en cp example.env .env ``` +Run the postgres database: + +```bash +docker run -e POSTGRES_PASSWORD=mypassword -e POSTGRES_USER=myuser -e POSTGRES_DB=simplelogin -p 35432:5432 postgres:13 +``` + To run the server: ``` -python3 server.py +flask db upgrade && flask dummy-data && python3 server.py ``` -then open http://localhost:7777, you should be able to login with the following account - -``` -john@wick.com / password -``` +then open http://localhost:7777, you should be able to login with `john@wick.com / password` account. You might need to change the `.env` file for developing certain features. This file is ignored by git. diff --git a/example.env b/example.env index 5b00468e..9dfac231 100644 --- a/example.env +++ b/example.env @@ -75,10 +75,7 @@ EMAIL_SERVERS_WITH_PRIORITY=[(10, "email.hostname.")] # DKIM_PRIVATE_KEY_PATH=local_data/dkim.key # DB Connection -# Local SQLite database -DB_URI=sqlite:///db.sqlite -# Postgres -# DB_URI=postgresql://myuser:mypassword@sl-db:5432/simplelogin +DB_URI=postgresql://myuser:mypassword@localhost:35432/simplelogin FLASK_SECRET=secret diff --git a/new_migration.sh b/new_migration.sh index 660ccd17..476a7d87 100644 --- a/new_migration.sh +++ b/new_migration.sh @@ -4,13 +4,13 @@ # create a postgres database for SimpleLogin docker rm -f sl-db -docker run -p 15432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres +docker run -p 25432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres:13 # run run `flask db upgrade` to upgrade the DB to the latest stage and -env DB_URI=postgresql://postgres:postgres@127.0.0.1:15432/sl flask db upgrade +env DB_URI=postgresql://postgres:postgres@127.0.0.1:25432/sl flask db upgrade # finally `flask db migrate` to generate the migration script. -env DB_URI=postgresql://postgres:postgres@127.0.0.1:15432/sl flask db migrate +env DB_URI=postgresql://postgres:postgres@127.0.0.1:25432/sl flask db migrate # remove the db docker rm -f sl-db \ No newline at end of file diff --git a/tests/test.env b/tests/test.env index 3c5b3ff9..d1fbe886 100644 --- a/tests/test.env +++ b/tests/test.env @@ -14,7 +14,7 @@ MAX_NB_EMAIL_FREE_PLAN=3 EMAIL_SERVERS_WITH_PRIORITY=[(10, "email.hostname.")] DKIM_PRIVATE_KEY_PATH=local_data/dkim.key -DB_URI=postgresql://test:test@localhost:5432/test +DB_URI=postgresql://test:test@localhost:15432/test # Flask FLASK_SECRET=secret From 66bafe7439b277a2cab61db2a05a1e0bf7b8f727 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:42:15 +0200 Subject: [PATCH 004/144] flake8 --- server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server.py b/server.py index 36a44b9a..cb99cd57 100644 --- a/server.py +++ b/server.py @@ -205,7 +205,6 @@ def create_app() -> Flask: def fake_data(): LOG.d("create fake data") - # Create a user user = User.create( email="john@wick.com", From e5308932a2d013485553b5b7e87eb07cf3ad28a0 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:50:47 +0200 Subject: [PATCH 005/144] make mailbox deletion async --- app/dashboard/views/domain_detail.py | 2 +- app/dashboard/views/mailbox.py | 39 +++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/app/dashboard/views/domain_detail.py b/app/dashboard/views/domain_detail.py index 6d65bea6..9f6eb746 100644 --- a/app/dashboard/views/domain_detail.py +++ b/app/dashboard/views/domain_detail.py @@ -208,7 +208,7 @@ def domain_detail(custom_domain_id): return render_template("dashboard/domain_detail/info.html", **locals()) -def delete_domain(custom_domain_id: CustomDomain): +def delete_domain(custom_domain_id: int): from server import create_light_app with create_light_app().app_context(): diff --git a/app/dashboard/views/mailbox.py b/app/dashboard/views/mailbox.py index c3ee81ac..42774014 100644 --- a/app/dashboard/views/mailbox.py +++ b/app/dashboard/views/mailbox.py @@ -1,3 +1,5 @@ +from threading import Thread + from flask import render_template, request, redirect, url_for, flash from flask_login import login_required, current_user from flask_wtf import FlaskForm @@ -49,10 +51,13 @@ def mailbox_route(): flash("You cannot delete default mailbox", "error") return redirect(url_for("dashboard.mailbox_route")) - email = mailbox.email - Mailbox.delete(mailbox_id) - db.session.commit() - flash(f"Mailbox {email} has been deleted", "success") + LOG.d("Schedule deleting %s", mailbox) + Thread(target=delete_mailbox, args=(mailbox.id,)).start() + flash( + f"Mailbox {mailbox.email} scheduled for deletion." + f"You will receive a confirmation email when the deletion is finished", + "success", + ) return redirect(url_for("dashboard.mailbox_route")) if request.form.get("form-name") == "set-default": @@ -119,6 +124,32 @@ def mailbox_route(): ) +def delete_mailbox(mailbox_id: int): + from server import create_light_app + + with create_light_app().app_context(): + mailbox = Mailbox.get(mailbox_id) + if not mailbox: + return + + mailbox_email = mailbox.email + user = mailbox.user + + Mailbox.delete(mailbox_id) + db.session.commit() + LOG.d("Mailbox %s %s deleted", mailbox_id,mailbox_email) + + send_email( + user.email, + f"Your mailbox {mailbox_email} has been deleted", + f"""Mailbox {mailbox_email} along with its aliases are deleted successfully. + +Regards, +SimpleLogin team. + """, + ) + + def send_verification_email(user, mailbox): s = Signer(MAILBOX_SECRET) mailbox_id_signed = s.sign(str(mailbox.id)).decode() From 0f4ad1a0d453ecdd266c0e4605db508c471dc065 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:56:31 +0200 Subject: [PATCH 006/144] black --- app/dashboard/views/mailbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/views/mailbox.py b/app/dashboard/views/mailbox.py index 42774014..2f6fd867 100644 --- a/app/dashboard/views/mailbox.py +++ b/app/dashboard/views/mailbox.py @@ -137,7 +137,7 @@ def delete_mailbox(mailbox_id: int): Mailbox.delete(mailbox_id) db.session.commit() - LOG.d("Mailbox %s %s deleted", mailbox_id,mailbox_email) + LOG.d("Mailbox %s %s deleted", mailbox_id, mailbox_email) send_email( user.email, From 1678945d5a7212465169231b837b2adead8cb910 Mon Sep 17 00:00:00 2001 From: Son Date: Sun, 15 Aug 2021 17:58:49 +0200 Subject: [PATCH 007/144] improve wording --- app/dashboard/templates/dashboard/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/dashboard/templates/dashboard/index.html b/app/dashboard/templates/dashboard/index.html index 731c2a79..de8510ea 100644 --- a/app/dashboard/templates/dashboard/index.html +++ b/app/dashboard/templates/dashboard/index.html @@ -384,7 +384,7 @@ {% endif %} -
Alias Note
+
Note
+
+ + +
+
@@ -390,25 +409,6 @@
{% endif %} -
Note
-
-
- -
- - -
-
Display name diff --git a/static/js/index.js b/static/js/index.js index 4e8a8e53..dab6b406 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -172,7 +172,7 @@ $(".save-note").on("click", async function () { }); if (res.ok) { - toastr.success(`Note Saved`); + toastr.success(`Saved`); } else { toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error"); // reset to the original value From 40915ad74140b7f42f18af6f4bec69fffd86a510 Mon Sep 17 00:00:00 2001 From: Son Nguyen Kim Date: Sat, 21 Aug 2021 16:18:01 +0200 Subject: [PATCH 029/144] make alias description font smaller --- app/dashboard/templates/dashboard/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/app/dashboard/templates/dashboard/index.html b/app/dashboard/templates/dashboard/index.html index 2d3c0ac4..6cc04271 100644 --- a/app/dashboard/templates/dashboard/index.html +++ b/app/dashboard/templates/dashboard/index.html @@ -320,6 +320,7 @@ id="note-{{ alias.id }}" name="note" class="form-control" + style="font-size: 12px" rows="2" placeholder="e.g. where the alias is used or why is it created">{{ alias.note or "" }}
From ef6388887f110d54f943f518aa674136299010f0 Mon Sep 17 00:00:00 2001 From: Son Nguyen Kim Date: Sat, 21 Aug 2021 17:56:09 +0200 Subject: [PATCH 030/144] better filter app --- app/dashboard/templates/dashboard/index.html | 200 ++++++++++--------- 1 file changed, 105 insertions(+), 95 deletions(-) diff --git a/app/dashboard/templates/dashboard/index.html b/app/dashboard/templates/dashboard/index.html index 6cc04271..1c878d84 100644 --- a/app/dashboard/templates/dashboard/index.html +++ b/app/dashboard/templates/dashboard/index.html @@ -92,124 +92,133 @@
- -
- -
-
-
- - -
-
-
- - -
- -