kanidm/server/core/static/external/cred_update.js

128 lines
5 KiB
JavaScript
Raw Normal View History

// Makes the password form interactive (e.g. shows when passwords don't match)
function setupInteractivePwdFormListeners() {
const new_pwd = document.getElementById("new-password");
const new_pwd_check = document.getElementById("new-password-check");
const pwd_submit = document.getElementById("password-submit");
function markPwdCheckValid() {
new_pwd_check.classList.remove("is-invalid");
new_pwd_check.classList.add("is-valid");
pwd_submit.disabled = false;
}
function markPwdCheckInvalid() {
new_pwd_check.classList.add("is-invalid");
new_pwd_check.classList.remove("is-valid");
pwd_submit.disabled = true;
}
new_pwd.addEventListener("input", (_) => {
// Don't mark invalid if user didn't fill in the confirmation box yet
// Also my password manager (keepassxc with autocomplete)
// likes to fire off input events when both inputs were empty.
if (new_pwd_check.value !== "") {
if (new_pwd.value === new_pwd_check.value) {
markPwdCheckValid();
} else {
markPwdCheckInvalid();
}
}
new_pwd.classList.remove("is-invalid");
});
new_pwd_check.addEventListener("input", (_) => {
// No point in updating the status if confirmation box is empty
if (new_pwd_check.value === "") return;
if (new_pwd_check.value === new_pwd.value) {
markPwdCheckValid();
} else {
markPwdCheckInvalid();
}
});
}
function stillSwapFailureResponse(event) {
if (event.detail.xhr.status === 422 || event.detail.xhr.status === 500) {
console.log("Still swapping failure response")
event.detail.shouldSwap = true;
event.detail.isError = false;
}
}
function onPasskeyCreated(assertion) {
try {
console.log(assertion)
let creationData = {};
creationData.id = assertion.id;
creationData.rawId = Base64.fromUint8Array(new Uint8Array(assertion.rawId))
creationData.response = {};
creationData.response.attestationObject = Base64.fromUint8Array(new Uint8Array(assertion.response.attestationObject))
creationData.response.clientDataJSON = Base64.fromUint8Array(new Uint8Array(assertion.response.clientDataJSON))
creationData.type = assertion.type
creationData.extensions = assertion.getClientExtensionResults()
creationData.extensions.uvm = undefined
// Put the passkey creation data into the form for submission
document.getElementById("passkey-create-data").value = JSON.stringify(creationData)
// Make the name input visible and hide the "Begin Passkey Enrollment" button
document.getElementById("passkeyNamingSafariBtn").classList.add("d-none")
document.getElementById("passkeyNamingForm").classList.remove("d-none")
document.getElementById("passkeyNamingSubmitBtn").classList.remove("d-none")
} catch (e) {
console.log(e)
if (confirm("Failed to encode your new passkey's data for transmission, confirm to reload this page.\nReport this issue if it keeps occurring.")) {
window.location.reload();
}
}
}
function startPasskeyEnrollment() {
try {
const data_elem = document.getElementById('data');
const credentialRequestOptions = JSON.parse(data_elem.textContent);
credentialRequestOptions.publicKey.challenge = Base64.toUint8Array(credentialRequestOptions.publicKey.challenge);
credentialRequestOptions.publicKey.user.id = Base64.toUint8Array(credentialRequestOptions.publicKey.user.id);
console.log(credentialRequestOptions)
navigator.credentials
.create({publicKey: credentialRequestOptions.publicKey})
.then((assertion) => {
onPasskeyCreated(assertion);
}, (reason) => {
alert("Passkey creation failed " + reason.toString())
console.log("Passkey creation failed: " + reason.toString())
});
} catch (e) {
console.log(e)
if (confirm("Failed to initialize passkey creation, confirm to reload this page.\nReport this issue if it keeps occurring.")) {
window.location.reload();
}
}
}
function setupPasskeyNamingSafariButton() {
document.getElementById("passkeyNamingSafariBtn")
.addEventListener("click", startPasskeyEnrollment)
}
function setupSubmitBtnVisibility() {
document.getElementById("passkey-label")
?.addEventListener("input", updateSubmitButtonVisibility)
}
function updateSubmitButtonVisibility(event) {
const submitButton = document.getElementById("passkeyNamingSubmitBtn");
submitButton.disabled = event.value === "";
}
window.onload = function () {
document.body.addEventListener("addPasswordSwapped", () => { setupInteractivePwdFormListeners() });
document.body.addEventListener("addPasskeySwapped", () => {
setupPasskeyNamingSafariButton();
startPasskeyEnrollment();
setupSubmitBtnVisibility();
});
}