with the credential management API
James Allardice
<form method="post" action="/login" id="login-form">
<div>
<label for="username">Username:</label>
<input
type="text"
id="username"
name="username"
>
</div>
<div>
<label for="password">Password:</label>
<input
type="password"
id="password"
name="password"
>
</div>
<input type="submit" value="Login">
</form>
const form = document.getElementById('login-form');
form.addEventListener('submit', (e) => {
e.preventDefault();
sendLoginRequest(new FormData(form));
});
function sendLoginRequest(formData)
const fetchOpts = {
method: 'POST',
headers: {
Accept: 'application/json',
},
};
if (navigator.credentials) {
const credentials = new PasswordCredential({
id: formData.get('username'),
password: formData.get('password'),
});
credentials.additionalData = formData;
fetchOpts.credentials = credentials;
} else {
fetchOpts.body = formData;
}
return fetch('/api/login', fetchOpts)
.then((res) => res.json())
.then((json) => validateResponse(json, formData))
.then((redirectUrl) => {
window.location = redirectUrl;
});
}
// Validate the response from the auth service. Returns a URL to redirect
// the user to.
function validateResponse(res, credentials)
if (res.valid) {
// Logged in successfully. If the browser supports the Credential
// Management API we can attempt to save the provided login details.
if (navigator.credentials) {
return navigator.credentials.store(credentials)
.then(() => res.redirectUrl);
}
return res.redirectUrl;
}
throw new Error('Login failed.');
}
// If the browser supports the Credential Management API we can attempt to
// get a stored password credential. If no credential is stored, of if the
// call fails for any reason, the user can still log in like normal.
if (navigator.credentials) {
navigator.credentials.get({
password: true,
})
.then((credentials) => {
if (credentials) {
return sendLoginRequest(credentials);
}
return null;
});
}
if (navigator.credentials) {
navigator.credentials.requireUserMediation()
.then(() => {
// Redirect to login page.
});
}