2021-05-14 11:20:56 +01:00
|
|
|
(function (window) {
|
2021-05-14 17:37:57 +01:00
|
|
|
"use strict";
|
2021-05-14 11:20:56 +01:00
|
|
|
|
2021-05-14 17:37:57 +01:00
|
|
|
window.GOVUK.Modules.AuthenticateSecurityKey = function () {
|
|
|
|
|
this.start = function (component) {
|
|
|
|
|
$(component)
|
|
|
|
|
.on('click', function (event) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
2021-08-11 18:02:50 +01:00
|
|
|
// hide any existing error prompt
|
|
|
|
|
window.GOVUK.ErrorBanner.hideBanner();
|
|
|
|
|
|
2021-05-14 17:37:57 +01:00
|
|
|
fetch('/webauthn/authenticate')
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw Error(response.statusText);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.arrayBuffer();
|
|
|
|
|
})
|
|
|
|
|
.then(data => {
|
|
|
|
|
var options = window.CBOR.decode(data);
|
|
|
|
|
// triggers browser dialogue to login with authenticator
|
|
|
|
|
return window.navigator.credentials.get(options);
|
|
|
|
|
})
|
|
|
|
|
.then(credential => {
|
2021-05-27 12:07:11 +01:00
|
|
|
const currentURL = new URL(window.location.href);
|
|
|
|
|
|
|
|
|
|
// create authenticateURL from admin hostname plus /webauthn/authenticate path
|
|
|
|
|
const authenticateURL = new URL('/webauthn/authenticate', window.location.href);
|
|
|
|
|
|
|
|
|
|
const nextUrl = currentURL.searchParams.get('next');
|
|
|
|
|
if (nextUrl) {
|
|
|
|
|
// takes nextUrl from the query string on the current browser URL
|
|
|
|
|
// (which should be /two-factor-webauthn) and pass it through to
|
|
|
|
|
// the POST. put it in a query string so it's consistent with how
|
|
|
|
|
// the other login flows manage it
|
|
|
|
|
authenticateURL.searchParams.set('next', nextUrl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fetch(authenticateURL, {
|
2021-05-14 17:37:57 +01:00
|
|
|
method: 'POST',
|
|
|
|
|
headers: { 'X-CSRFToken': component.data('csrfToken') },
|
|
|
|
|
body: window.CBOR.encode({
|
|
|
|
|
credentialId: new Uint8Array(credential.rawId),
|
|
|
|
|
authenticatorData: new Uint8Array(credential.response.authenticatorData),
|
|
|
|
|
signature: new Uint8Array(credential.response.signature),
|
|
|
|
|
clientDataJSON: new Uint8Array(credential.response.clientDataJSON),
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
2021-09-14 14:31:45 +01:00
|
|
|
if (!response.ok) {
|
|
|
|
|
throw Error(response.statusText);
|
2021-05-17 15:56:15 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-14 14:31:45 +01:00
|
|
|
return response.arrayBuffer();
|
|
|
|
|
})
|
|
|
|
|
.then(cbor => {
|
|
|
|
|
return Promise.resolve(window.CBOR.decode(cbor));
|
|
|
|
|
})
|
|
|
|
|
.then(data => {
|
|
|
|
|
window.location.assign(data.redirect_url);
|
2021-05-14 17:37:57 +01:00
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error(error);
|
|
|
|
|
// some browsers will show an error dialogue for some
|
2021-08-11 18:02:50 +01:00
|
|
|
// errors; to be safe we always display an error message on the page.
|
2021-09-13 16:31:58 +01:00
|
|
|
window.GOVUK.ErrorBanner.showBanner();
|
2021-05-14 17:37:57 +01:00
|
|
|
});
|
|
|
|
|
});
|
2021-05-14 11:20:56 +01:00
|
|
|
};
|
2021-05-14 17:37:57 +01:00
|
|
|
};
|
|
|
|
|
}) (window);
|