diff --git a/src/app/requirements.txt b/src/app/requirements.txt
index 86478ce..9b130fc 100755
--- a/src/app/requirements.txt
+++ b/src/app/requirements.txt
@@ -2,3 +2,4 @@ web.py==0.40
mysql-connector-python==8.0.5
python-dotenv
bcrypt
+qrcode[pil]
diff --git a/src/app/templates/verify.html b/src/app/templates/verify.html
index ff776f5..b11b32c 100644
--- a/src/app/templates/verify.html
+++ b/src/app/templates/verify.html
@@ -1,4 +1,4 @@
-$def with (nav, success, secret, message)
+$def with (nav, success, secret, qr, message)
Beelance2
@@ -16,8 +16,9 @@ $def with (nav, success, secret, message)
$if success:
We require two-factor authentication on this site.
- Please enter the following code into your authenticator: $secret
+ Please scan the QR code, or enter the following code into your authenticator: $secret
This code will only be displayed once.
+
diff --git a/src/app/views/register.py b/src/app/views/register.py
index 0303c4b..7d15669 100755
--- a/src/app/views/register.py
+++ b/src/app/views/register.py
@@ -1,10 +1,13 @@
import web
+import io
+import base64
from views.forms import register_form
from views.utils import (get_nav_bar, csrf_protected, password_weakness, get_render,
sendmail, hash_password, generate_authenticator_secret)
from uuid import uuid4
import models.register
import models.user
+import qrcode
import logging
import re
@@ -100,8 +103,18 @@ class Verify:
if token and userid is not None:
models.user.verify_user(userid)
+ models.user.set_token(userid, "")
+ username = models.user.get_user_name_by_id(userid)
secret = generate_authenticator_secret()
+
+ # Generate a base64 QR image
+ qr_url = "otpauth://totp/beelance.com:{}?secret={}&issuer=beelance.com".format(username, secret)
+ qr_img = qrcode.make(qr_url)
+ with io.BytesIO() as stream:
+ qr_img.save(stream)
+ img = base64.b64encode(stream.getvalue()).decode('UTF-8')
+
models.user.set_authenticator_secret(userid, secret)
- return render.verify(nav, True, secret, "Your email has been verified.")
+ return render.verify(nav, True, secret, img, "Your email has been verified.")
else:
- return render.verify(nav, True, secret, "Invalid token. Please try again.")
+ return render.verify(nav, False, "", "", "Invalid token. Please try again.")