mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 18:57:32 +00:00
fix(login): improve webauthn error handling (#9474)
This PR improves error handling around webauthn functions in the login.
This commit is contained in:
@@ -15,7 +15,17 @@ function checkWebauthnSupported(button, func) {
|
|||||||
|
|
||||||
function webauthnError(error) {
|
function webauthnError(error) {
|
||||||
let err = document.getElementById("wa-error");
|
let err = document.getElementById("wa-error");
|
||||||
err.getElementsByClassName("cause")[0].innerText = error.message;
|
let causeElement = err.getElementsByClassName("cause")[0];
|
||||||
|
|
||||||
|
if (error.message) {
|
||||||
|
causeElement.innerText = error.message;
|
||||||
|
} else if (error.value) {
|
||||||
|
causeElement.innerText = error.value;
|
||||||
|
} else {
|
||||||
|
console.error("Unknown error:", error);
|
||||||
|
causeElement.innerText = "An unknown error occurred.";
|
||||||
|
}
|
||||||
|
|
||||||
err.classList.remove("hidden");
|
err.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,29 +3,36 @@ document.addEventListener(
|
|||||||
checkWebauthnSupported("btn-login", login)
|
checkWebauthnSupported("btn-login", login)
|
||||||
);
|
);
|
||||||
|
|
||||||
function login() {
|
async function login() {
|
||||||
document.getElementById("wa-error").classList.add("hidden");
|
document.getElementById("wa-error").classList.add("hidden");
|
||||||
|
|
||||||
let makeAssertionOptions = JSON.parse(
|
let makeAssertionOptions;
|
||||||
atob(document.getElementsByName("credentialAssertionData")[0].value)
|
try {
|
||||||
);
|
makeAssertionOptions = JSON.parse(atob(document.getElementsByName("credentialAssertionData")[0].value));
|
||||||
makeAssertionOptions.publicKey.challenge = bufferDecode(
|
} catch (e) {
|
||||||
makeAssertionOptions.publicKey.challenge,
|
webauthnError({ message: "Failed to parse credential assertion data." });
|
||||||
"publicKey.challenge"
|
return;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
makeAssertionOptions.publicKey.challenge = bufferDecode(makeAssertionOptions.publicKey.challenge, "publicKey.challenge");
|
||||||
makeAssertionOptions.publicKey.allowCredentials.forEach(function (listItem) {
|
makeAssertionOptions.publicKey.allowCredentials.forEach(function (listItem) {
|
||||||
listItem.id = bufferDecode(listItem.id, "publicKey.allowCredentials.id");
|
listItem.id = bufferDecode(listItem.id, "publicKey.allowCredentials.id");
|
||||||
});
|
});
|
||||||
navigator.credentials
|
} catch (e) {
|
||||||
.get({
|
webauthnError({ message: "Failed to decode buffer data." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await navigator.credentials.get({
|
||||||
publicKey: makeAssertionOptions.publicKey,
|
publicKey: makeAssertionOptions.publicKey,
|
||||||
})
|
|
||||||
.then(function (credential) {
|
|
||||||
verifyAssertion(credential);
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
webauthnError(err);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
verifyAssertion(credential);
|
||||||
|
} catch (err) {
|
||||||
|
webauthnError(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyAssertion(assertedCredential) {
|
function verifyAssertion(assertedCredential) {
|
||||||
@@ -49,6 +56,6 @@ function verifyAssertion(assertedCredential) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementsByName("credentialData")[0].value = btoa(data);
|
document.getElementsByName("credentialData")[0].value = window.btoa(data);
|
||||||
document.getElementsByTagName("form")[0].submit();
|
document.getElementsByTagName("form")[0].submit();
|
||||||
}
|
}
|
||||||
|
@@ -3,40 +3,41 @@ document.addEventListener(
|
|||||||
checkWebauthnSupported("btn-register", registerCredential)
|
checkWebauthnSupported("btn-register", registerCredential)
|
||||||
);
|
);
|
||||||
|
|
||||||
function registerCredential() {
|
async function registerCredential() {
|
||||||
document.getElementById("wa-error").classList.add("hidden");
|
document.getElementById("wa-error").classList.add("hidden");
|
||||||
|
|
||||||
let opt = JSON.parse(
|
let opt;
|
||||||
atob(document.getElementsByName("credentialCreationData")[0].value)
|
try {
|
||||||
);
|
opt = JSON.parse(atob(document.getElementsByName("credentialCreationData")[0].value));
|
||||||
opt.publicKey.challenge = bufferDecode(
|
} catch (e) {
|
||||||
opt.publicKey.challenge,
|
webauthnError({ message: "Failed to parse credential creation data." });
|
||||||
"publicKey.challenge"
|
return;
|
||||||
);
|
}
|
||||||
opt.publicKey.user.id = bufferDecode(
|
|
||||||
opt.publicKey.user.id,
|
try {
|
||||||
"publicKey.user.id"
|
opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge, "publicKey.challenge");
|
||||||
);
|
opt.publicKey.user.id = bufferDecode(opt.publicKey.user.id, "publicKey.user.id");
|
||||||
if (opt.publicKey.excludeCredentials) {
|
if (opt.publicKey.excludeCredentials) {
|
||||||
for (let i = 0; i < opt.publicKey.excludeCredentials.length; i++) {
|
for (let i = 0; i < opt.publicKey.excludeCredentials.length; i++) {
|
||||||
if (opt.publicKey.excludeCredentials[i].id !== null) {
|
if (opt.publicKey.excludeCredentials[i].id !== null) {
|
||||||
opt.publicKey.excludeCredentials[i].id = bufferDecode(
|
opt.publicKey.excludeCredentials[i].id = bufferDecode(opt.publicKey.excludeCredentials[i].id, "publicKey.excludeCredentials");
|
||||||
opt.publicKey.excludeCredentials[i].id,
|
|
||||||
"publicKey.excludeCredentials"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
navigator.credentials
|
} catch (e) {
|
||||||
.create({
|
webauthnError({ message: "Failed to decode buffer data." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await navigator.credentials.create({
|
||||||
publicKey: opt.publicKey,
|
publicKey: opt.publicKey,
|
||||||
})
|
|
||||||
.then(function (credential) {
|
|
||||||
createCredential(credential);
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
webauthnError(err);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
createCredential(credential);
|
||||||
|
} catch (err) {
|
||||||
|
webauthnError(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCredential(newCredential) {
|
function createCredential(newCredential) {
|
||||||
@@ -56,6 +57,6 @@ function createCredential(newCredential) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementsByName("credentialData")[0].value = btoa(data);
|
document.getElementsByName("credentialData")[0].value = window.btoa(data);
|
||||||
document.getElementsByTagName("form")[0].submit();
|
document.getElementsByTagName("form")[0].submit();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user