diff --git a/hc/accounts/tests/test_login_webauthn.py b/hc/accounts/tests/test_login_webauthn.py index f74e55d6..26d27669 100644 --- a/hc/accounts/tests/test_login_webauthn.py +++ b/hc/accounts/tests/test_login_webauthn.py @@ -33,6 +33,14 @@ class LoginWebAuthnTestCase(BaseTestCase): r = self.client.get(self.url) self.assertContains(r, "Use authenticator app") + def test_it_preserves_next_parameter_in_totp_url(self): + self.profile.totp = "0" * 32 + self.profile.save() + + url = self.url + "?next=" + self.channels_url + r = self.client.get(url) + self.assertContains(r, "/login/two_factor/totp/?next=" + self.channels_url) + def test_it_requires_unauthenticated_user(self): self.client.login(username="alice@example.org", password="password") diff --git a/hc/accounts/views.py b/hc/accounts/views.py index eb165f82..8e21f8a6 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -827,9 +827,17 @@ def login_webauthn(request): options, state = FIDO2_SERVER.authenticate_begin(credentials) request.session["state"] = state + totp_url = None + if user.profile.totp: + totp_url = reverse("hc-login-totp") + + redirect_url = request.GET.get("next") + if _allow_redirect(redirect_url): + totp_url += "?next=%s" % redirect_url + ctx = { "options": base64.b64encode(cbor.encode(options)).decode(), - "offer_totp": True if user.profile.totp else False, + "totp_url": totp_url, } return render(request, "accounts/login_webauthn.html", ctx) diff --git a/templates/accounts/login_webauthn.html b/templates/accounts/login_webauthn.html index 37e6007d..9046d4cd 100644 --- a/templates/accounts/login_webauthn.html +++ b/templates/accounts/login_webauthn.html @@ -13,7 +13,7 @@

Two-factor Authentication

- {% if offer_totp %} + {% if totp_url %}

Please select how you want to authenticate.

{% else %}

@@ -26,8 +26,8 @@ id="use-key-btn" type="button" class="btn btn-primary">Use security key - {% if offer_totp %} - + {% if totp_url %} + Use authenticator app {% endif %}