diff --git a/app/dashboard/views/fido_setup.py b/app/dashboard/views/fido_setup.py
index e9432e6c..eec252e1 100644
--- a/app/dashboard/views/fido_setup.py
+++ b/app/dashboard/views/fido_setup.py
@@ -25,6 +25,13 @@ def fido_setup():
flash("You have already registered your security key", "warning")
return redirect(url_for("dashboard.index"))
+ if not current_user.can_use_fido:
+ flash(
+ "This feature is currently in invitation-only beta. Please send us an email if you want to try",
+ "warning",
+ )
+ return redirect(url_for("dashboard.index"))
+
fido_token_form = FidoTokenForm()
# Handling POST requests
From ef2a385563db5123940d7e055d534016f25adf3d Mon Sep 17 00:00:00 2001
From: Son NK <>
Date: Thu, 7 May 2020 17:58:36 +0200
Subject: [PATCH 3/6] redirect user to TOTP in welcome email
---
templates/emails/com/welcome.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/templates/emails/com/welcome.html b/templates/emails/com/welcome.html
index 26410f25..f28dd4a8 100644
--- a/templates/emails/com/welcome.html
+++ b/templates/emails/com/welcome.html
@@ -13,7 +13,7 @@
{% block content %}
{{ render_text("My name is Son. I’m the founder of SimpleLogin and I wanted to be the first to welcome you on board.") }}
- {{ render_text('To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your
Setting page.') }}
+ {{ render_text('To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your
Setting page.') }}
{{ render_text('If you have any feedback or improvement ideas please let me know by simply replying to this email. Yes, this email is not sent from a no-reply address.
') }}
From 0a497c9f67648009ef6a080b5c83c6b7080188df Mon Sep 17 00:00:00 2001
From: Son NK <>
Date: Thu, 7 May 2020 17:59:21 +0200
Subject: [PATCH 4/6] put migration generation into a script
---
README.md | 13 +------------
new_migration.sh | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 12 deletions(-)
create mode 100644 new_migration.sh
diff --git a/README.md b/README.md
index 509c0685..af6d761e 100644
--- a/README.md
+++ b/README.md
@@ -1160,18 +1160,7 @@ Whenever the model changes, a new migration has to be created.
If you have Docker installed, you can create the migration by the following script:
```bash
-# create a postgres database for SimpleLogin
-docker rm -f sl-db
-docker run -p 5432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres
-
-# run run `flask db upgrade` to upgrade the DB to the latest stage and
-env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db upgrade
-
-# finally `flask db migrate` to generate the migration script.
-env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db migrate
-
-# remove the db
-docker rm -f sl-db
+sh new_migration.sh
```
Make sure to review the migration script before committing it.
diff --git a/new_migration.sh b/new_migration.sh
new file mode 100644
index 00000000..6c786097
--- /dev/null
+++ b/new_migration.sh
@@ -0,0 +1,16 @@
+# Generate a new migration script using Docker
+# To run it:
+# sh new_migration.sh
+
+# create a postgres database for SimpleLogin
+docker rm -f sl-db
+docker run -p 5432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres
+
+# run run `flask db upgrade` to upgrade the DB to the latest stage and
+env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db upgrade
+
+# finally `flask db migrate` to generate the migration script.
+env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db migrate
+
+# remove the db
+docker rm -f sl-db
\ No newline at end of file
From 985e4ee2f8387bcc0a6fa00ce4ff8dc8cbd9d61d Mon Sep 17 00:00:00 2001
From: Son NK <>
Date: Thu, 7 May 2020 17:59:29 +0200
Subject: [PATCH 5/6] sql migration for fido
---
.../versions/2020_050717_026e7a782ed6_.py | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 migrations/versions/2020_050717_026e7a782ed6_.py
diff --git a/migrations/versions/2020_050717_026e7a782ed6_.py b/migrations/versions/2020_050717_026e7a782ed6_.py
new file mode 100644
index 00000000..7292a0ce
--- /dev/null
+++ b/migrations/versions/2020_050717_026e7a782ed6_.py
@@ -0,0 +1,43 @@
+"""empty message
+
+Revision ID: 026e7a782ed6
+Revises: ae94fe5c4e9f
+Create Date: 2020-05-07 17:51:48.440962
+
+"""
+import sqlalchemy_utils
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '026e7a782ed6'
+down_revision = 'ae94fe5c4e9f'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column('users', sa.Column('can_use_fido', sa.Boolean(), server_default='0', nullable=False))
+ op.add_column('users', sa.Column('fido_credential_id', sa.String(), nullable=True))
+ op.add_column('users', sa.Column('fido_pk', sa.String(), nullable=True))
+ op.add_column('users', sa.Column('fido_sign_count', sa.Integer(), nullable=True))
+ op.add_column('users', sa.Column('fido_uuid', sa.String(), nullable=True))
+ op.create_unique_constraint(None, 'users', ['fido_credential_id'])
+ op.create_unique_constraint(None, 'users', ['fido_pk'])
+ op.create_unique_constraint(None, 'users', ['fido_uuid'])
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.drop_constraint(None, 'users', type_='unique')
+ op.drop_constraint(None, 'users', type_='unique')
+ op.drop_constraint(None, 'users', type_='unique')
+ op.drop_column('users', 'fido_uuid')
+ op.drop_column('users', 'fido_sign_count')
+ op.drop_column('users', 'fido_pk')
+ op.drop_column('users', 'fido_credential_id')
+ op.drop_column('users', 'can_use_fido')
+ # ### end Alembic commands ###
From 101ab408b2c3bd49e569b495504b6f42e03e9f80 Mon Sep 17 00:00:00 2001
From: Son NK <>
Date: Thu, 7 May 2020 18:01:12 +0200
Subject: [PATCH 6/6] black format
---
app/paddle_utils.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/paddle_utils.py b/app/paddle_utils.py
index a7a35155..cb782e90 100644
--- a/app/paddle_utils.py
+++ b/app/paddle_utils.py
@@ -10,11 +10,13 @@ import collections
import phpserialize
import requests
from Crypto.Hash import SHA1
+
# Crypto can be found at https://pypi.org/project/pycryptodome/
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from app.config import PADDLE_PUBLIC_KEY_PATH, PADDLE_VENDOR_ID, PADDLE_AUTH_CODE
+
# Your Paddle public key.
from app.log import LOG