Browse Source

Add auth method selection step

This has dual purpose:

* if user has both WebAuthn and TOTP set up, they can choose
  between the two as equal options.
* we initiate WebAuthn flow only after an explicit user action
  (button press). This may help with authentication failures
  on recent MacOS, iOS and iPadOS versions [1]

[1] https://support.yubico.com/hc/en-us/articles/360022004600-No-reaction-when-using-WebAuthn-on-macOS-iOS-and-iPadOS
pull/551/head
Pēteris Caune 3 years ago
parent
commit
ca3afa33f9
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
4 changed files with 27 additions and 15 deletions
  1. +2
    -2
      hc/accounts/tests/test_login_webauthn.py
  2. +2
    -3
      static/js/login_tfa.js
  3. +2
    -2
      templates/accounts/login_totp.html
  4. +21
    -8
      templates/accounts/login_webauthn.html

+ 2
- 2
hc/accounts/tests/test_login_webauthn.py View File

@ -21,7 +21,7 @@ class LoginWebAuthnTestCase(BaseTestCase):
def test_it_shows_form(self):
r = self.client.get(self.url)
self.assertContains(r, "Waiting for security key")
self.assertNotContains(r, "Use the authenticator app instead?")
self.assertNotContains(r, "Use authenticator app")
# It should put a "state" key in the session:
self.assertIn("state", self.client.session)
@ -31,7 +31,7 @@ class LoginWebAuthnTestCase(BaseTestCase):
self.profile.save()
r = self.client.get(self.url)
self.assertContains(r, "Use the authenticator app instead?")
self.assertContains(r, "Use authenticator app")
def test_it_requires_unauthenticated_user(self):
self.client.login(username="[email protected]", password="password")


+ 2
- 3
static/js/login_tfa.js View File

@ -9,6 +9,7 @@ $(function() {
}
function authenticate() {
$("#pick-method").addClass("hide");
$("#waiting").removeClass("hide");
$("#error").addClass("hide");
@ -30,8 +31,6 @@ $(function() {
});
}
$("#use-key-btn").click(authenticate);
$("#retry").click(authenticate);
authenticate();
});

+ 2
- 2
templates/accounts/login_totp.html View File

@ -17,8 +17,8 @@
type="text"
name="code"
pattern="[0-9]{6}"
title="six-digit code"
placeholder="123456"
title="6-digit code"
placeholder="6-digit code"
class="form-control input-lg" />
{% if form.code.errors %}
<div class="help-block">


+ 21
- 8
templates/accounts/login_webauthn.html View File

@ -12,6 +12,27 @@
encrypt="multipart/form-data">
<h1>Two-factor Authentication</h1>
<div id="pick-method">
{% if offer_totp %}
<p>Please select how you want to authenticate.</p>
{% else %}
<p>
Please authenticate using your security key.<br />
When you are ready, press the button below.
</p>
{% endif %}
<button
id="use-key-btn"
type="button"
class="btn btn-primary">Use security key</button>
{% if offer_totp %}
<a href="{% url 'hc-login-totp' %}" class="btn btn-default">
Use authenticator app
</a>
{% endif %}
</div>
{% csrf_token %}
<input id="credential_id" type="hidden" name="credential_id">
<input id="authenticator_data" type="hidden" name="authenticator_data">
@ -44,14 +65,6 @@
</div>
</div>
{% if offer_totp %}
<p>
<a href="{% url 'hc-login-totp' %}">
Use the authenticator app instead?
</a>
</p>
{% endif %}
<div id="success" class="hide">
<div class="alert alert-success">
<strong>Success!</strong>


Loading…
Cancel
Save