Prevent registration if WebAuthn is not supported

This hides the "Register" button and shows an error that's specific
to one of two ways a browser may not support WebAuthn:

- JavaScript is disabled (there's no possible fallback for this).
- WebAuthn API is not supported (e.g. on Internet Explorer).

We could add a similar check for the API in the JS code to handle
the button click, but hiding it seems like enough protection.

In order to avoid elements flashing when the page loads, this uses
a view macro to embed a script at the start of the body element,
which is the same approach used for the "js-enabled" class flag [1].

Tested with Chrome and IE 11.

[1]: https://github.com/alphagov/govuk-frontend/blob/main/src/govuk/template.njk#L31
This commit is contained in:
Ben Thorner
2021-05-13 14:52:32 +01:00
parent a7d7cb3421
commit 2039d3aa45
5 changed files with 50 additions and 1 deletions

View File

@@ -83,6 +83,7 @@ $path: '/static/images/';
@import 'views/get_started';
@import 'views/history';
@import 'views/cookies';
@import 'views/webauthn';
// TODO: break this up
@import 'app';

View File

@@ -0,0 +1,25 @@
.webauthn__no-js {
.js-enabled & {
display: none;
}
}
.webauthn__api-missing {
display: none;
.js-enabled & {
display: block;
}
.js-enabled.webauthn-api-enabled & {
display: none;
}
}
.webauthn__api-required {
display: none;
.webauthn-api-enabled & {
display: block;
}
}

View File

@@ -1,6 +1,7 @@
{% extends "template.njk" %}
{% from "components/banner.html" import banner %}
{% from "components/cookie-banner.html" import cookie_banner %}
{% from "components/webauthn-api-check.html" import webauthn_api_check %}
{% block headIcons %}
<link rel="shortcut icon" sizes="16x16 32x32 48x48" href="{{ asset_url('images/favicon.ico') }}" type="image/x-icon" />
@@ -38,6 +39,10 @@
{% endblock %}
{% block bodyStart %}
{% block webauthn_api %}
{{ webauthn_api_check() }}
{% endblock %}
{% block cookie_message %}
{{ cookie_banner() }}
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% macro webauthn_api_check() %}
<script>
if ('credentials' in window.navigator) {
document.body.className = ((document.body.className) ? document.body.className + ' webauthn-api-enabled' : 'webauthn-api-enabled');
}
</script>
{% endmacro %}

View File

@@ -3,6 +3,7 @@
{% from "components/button/macro.njk" import govukButton %}
{% from "components/back-link/macro.njk" import govukBackLink %}
{% from "components/table.html" import mapping_table, row, field, row_heading %}
{% from "vendor/govuk-frontend/components/error-message/macro.njk" import govukErrorMessage %}
{% set page_title = 'Security keys' %}
{% set credentials = current_user.webauthn_credentials %}
@@ -45,10 +46,20 @@
{% endif %}
{{ govukErrorMessage({
"classes": "webauthn__api-missing",
"text": "Your browser does not support security keys. Try signing in to Notify using a different browser."
}) }}
{{ govukErrorMessage({
"classes": "webauthn__no-js",
"text": "JavaScript is not available for this page. Security keys need JavaScript to work."
}) }}
{{ govukButton({
"element": "button",
"text": "Register a key",
"classes": "govuk-button--secondary",
"classes": "govuk-button--secondary webauthn__api-required",
"attributes": {
"data-module": "register-security-key",
"data-csrf-token": csrf_token(),