diff --git a/python-django-mfa-example/mfa/static/css/login.css b/python-django-mfa-example/mfa/static/css/login.css index c24833f..2d9a3bf 100644 --- a/python-django-mfa-example/mfa/static/css/login.css +++ b/python-django-mfa-example/mfa/static/css/login.css @@ -122,7 +122,6 @@ h1 { align-items: center; position: relative; bottom: 10%; - /* background-color: #f9f9fb; */ } .logged_in_div_left { @@ -204,8 +203,7 @@ div.text_box { background-color: #f9f9fb; height: 60px; padding: 15px 30px 15px 30px; - - z-index: 1000; + z-index: 998; } .logged_in_nav p { @@ -216,12 +214,6 @@ div.text_box { .logged_in_nav img { height: 50px; - border-radius: 50%; - border: 2px solid #2f2e2e; -} - -.logged_in_nav img:hover { - border: 2px solid #555555; } .nav-item { @@ -274,15 +266,6 @@ pre.prettyprint { margin-bottom: 20px; } -.qr_div { - align-self: center; - padding-top: 15px; -} - -.qr_code { - width: 7vw; - max-width: 100px; -} ul { list-style-type: none; @@ -320,4 +303,44 @@ li.even { .mt-20 { margin-top: 20px; +} + +.overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0.5); + z-index: 999; +} + +.modal { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; + padding: 25px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.5); + z-index: 1000; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.qr_code_instructions { + width: 300px; +} + +.qr_code { + width: 300px; + margin: 25px; +} + +button:disabled { + opacity: 0.5; + pointer-events: none; } \ No newline at end of file diff --git a/python-django-mfa-example/mfa/templates/mfa/challenge_factor.html b/python-django-mfa-example/mfa/templates/mfa/challenge_factor.html index 2a8b8d2..24e3100 100644 --- a/python-django-mfa-example/mfa/templates/mfa/challenge_factor.html +++ b/python-django-mfa-example/mfa/templates/mfa/challenge_factor.html @@ -10,11 +10,9 @@
- workos logo -
-
-

WorkOS

+ workos logo
+
diff --git a/python-django-mfa-example/mfa/templates/mfa/enroll_factor_details.html b/python-django-mfa-example/mfa/templates/mfa/enroll_factor_details.html index 39ad1f0..dfa554d 100644 --- a/python-django-mfa-example/mfa/templates/mfa/enroll_factor_details.html +++ b/python-django-mfa-example/mfa/templates/mfa/enroll_factor_details.html @@ -10,10 +10,7 @@
- workos logo -
-
-

WorkOS

+ workos logo
@@ -47,15 +44,15 @@

Enterprise Ready

Enroll SMS Factor

-
+
+ placeholder="Phone Number">
-
@@ -64,23 +61,22 @@

Enroll SMS Factor

Enroll TOTP Factor

- - {% csrf_token %} +
+ placeholder="TOTP Issuer">
+ placeholder="User Email">
- +
- +
@@ -88,7 +84,65 @@

Enroll TOTP Factor

- + + + \ No newline at end of file diff --git a/python-django-mfa-example/mfa/templates/mfa/factor_detail.html b/python-django-mfa-example/mfa/templates/mfa/factor_detail.html index 92e2277..b4641db 100644 --- a/python-django-mfa-example/mfa/templates/mfa/factor_detail.html +++ b/python-django-mfa-example/mfa/templates/mfa/factor_detail.html @@ -11,10 +11,7 @@
- workos logo -
-
-

WorkOS

+ workos logo
@@ -64,13 +61,6 @@

Factor Details

  • Created At: {{factor.created_at}}
  • Updated At: {{factor.updated_at}}
  • - - - {% if factor.type == 'totp' %} -
    - qr_code -
    - {% endif %}
    diff --git a/python-django-mfa-example/mfa/templates/mfa/list_factors.html b/python-django-mfa-example/mfa/templates/mfa/list_factors.html index 1ae9b3c..a91cb90 100644 --- a/python-django-mfa-example/mfa/templates/mfa/list_factors.html +++ b/python-django-mfa-example/mfa/templates/mfa/list_factors.html @@ -11,7 +11,7 @@
    - workos logo + workos logo
    diff --git a/python-django-mfa-example/mfa/templates/mfa/verify_factor.html b/python-django-mfa-example/mfa/templates/mfa/verify_factor.html index 76b7c10..c4004bf 100644 --- a/python-django-mfa-example/mfa/templates/mfa/verify_factor.html +++ b/python-django-mfa-example/mfa/templates/mfa/verify_factor.html @@ -10,10 +10,7 @@
    - workos logo -
    -
    -

    WorkOS

    + workos logo
    diff --git a/python-django-mfa-example/mfa/urls.py b/python-django-mfa-example/mfa/urls.py index 34608d9..a0eccd8 100644 --- a/python-django-mfa-example/mfa/urls.py +++ b/python-django-mfa-example/mfa/urls.py @@ -9,7 +9,8 @@ views.enroll_factor_details, name="enroll_factor_details", ), - path("enroll_factor", views.enroll_factor, name="enroll_factor"), + path("enroll_sms_factor", views.enroll_sms_factor, name="enroll_sms_factor"), + path("enroll_totp_factor", views.enroll_totp_factor, name="enroll_totp_factor"), path("factor_detail", views.factor_detail, name="factor_detail"), path("challenge_factor", views.challenge_factor, name="challenge_factor"), path("verify_factor", views.verify_factor, name="verify_factor"), diff --git a/python-django-mfa-example/mfa/views.py b/python-django-mfa-example/mfa/views.py index 8faf91c..a4b2985 100644 --- a/python-django-mfa-example/mfa/views.py +++ b/python-django-mfa-example/mfa/views.py @@ -3,6 +3,8 @@ from django.conf import settings from django.shortcuts import redirect, render from django.views.decorators.csrf import csrf_exempt +import json +from django.http import HttpResponse workos.api_key = os.getenv("WORKOS_API_KEY") @@ -39,37 +41,49 @@ def enroll_factor_details(request): @csrf_exempt -def enroll_factor(request): +def enroll_sms_factor(request): factor_type = request.POST["type"] + phone_number = request.POST["phone_number"] - if factor_type == "sms": - factor_type = "sms" - phone_number = request.POST["phone_number"] - new_factor = workos.client.mfa.enroll_factor( - type=factor_type, phone_number=phone_number - ) - if request.session.get("factor_list"): + new_factor = workos.client.mfa.enroll_factor( + type=factor_type, + phone_number=phone_number + ) + + if request.session.get("factor_list"): request.session["factor_list"].append(new_factor) - else: - request.session["factor_list"] = [new_factor] - - if factor_type == "totp": - factor_type = "totp" - totp_issuer = request.POST["totp_issuer"] - totp_user = request.POST["totp_user"] - new_factor = workos.client.mfa.enroll_factor( - type=factor_type, totp_issuer=totp_issuer, totp_user=totp_user - ) - if request.session.get("factor_list") != None: - new_session_list = request.session["factor_list"] - new_session_list.append(new_factor) - request.session["factor_list"] = new_session_list - else: - request.session["factor_list"] = [new_factor] + else: + request.session["factor_list"] = [new_factor] + + request.session.save() return redirect("list_factors") +@csrf_exempt +def enroll_totp_factor(request): + data = json.loads(request.body.decode("utf-8")) + + type = data["type"] + issuer = data["issuer"] + user = data["user"] + + new_factor = workos.client.mfa.enroll_factor( + type=type, + totp_issuer=issuer, + totp_user=user + ) + + if request.session.get("factor_list"): + request.session["factor_list"].append(new_factor) + else: + request.session["factor_list"] = [new_factor] + + request.session.save() + + return HttpResponse(new_factor["totp"]["qr_code"]) + + def factor_detail(request): factorId = request.GET["id"] for factor in request.session["factor_list"]: @@ -80,9 +94,6 @@ def factor_detail(request): if factor["type"] == "sms": phone_number = factor["sms"]["phone_number"] - if factor["type"] == "totp": - request.session["current_factor_qr"] = factor["totp"]["qr_code"] - request.session["current_factor"] = fullFactor["id"] request.session["current_factor_type"] = fullFactor["type"] @@ -92,7 +103,6 @@ def factor_detail(request): { "factor": fullFactor, "phone_number": phone_number, - "qr_code": request.session["current_factor_qr"], }, )