Skip to content

Commit 7f36b38

Browse files
committed
fix(webauthn): address PR #55 code review feedback
- escapeHtml: encode " and ' after DOM-based escape to prevent attribute breakout in data-* attributes - webauthn-manage: use JSON-with-text-fallback for rename and delete error responses to avoid throwing on non-JSON bodies (500/403) - login: add passkeyBtn null check to prevent TypeError if element is missing from template - login: add #passkeyError alert div and wire showMessage to it so passkey auth failures are visible to the user instead of silently swallowed
1 parent 57d6d85 commit 7f36b38

4 files changed

Lines changed: 24 additions & 7 deletions

File tree

src/main/resources/static/js/user/login.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ document.addEventListener("DOMContentLoaded", () => {
1515
const passkeySection = document.getElementById("passkey-login-section");
1616
const passkeyBtn = document.getElementById("passkeyLoginBtn");
1717

18-
if (passkeySection && isWebAuthnSupported()) {
18+
if (passkeySection && passkeyBtn && isWebAuthnSupported()) {
1919
passkeySection.style.display = "block";
20+
const passkeyError = document.getElementById("passkeyError");
2021

2122
passkeyBtn.addEventListener("click", async () => {
2223
passkeyBtn.disabled = true;
@@ -27,7 +28,7 @@ document.addEventListener("DOMContentLoaded", () => {
2728
window.location.href = redirectUrl;
2829
} catch (error) {
2930
console.error("Passkey authentication failed:", error);
30-
showMessage(null, "Passkey authentication failed. Please try again.", "alert-danger");
31+
showMessage(passkeyError, "Passkey authentication failed. Please try again.", "alert-danger");
3132
passkeyBtn.disabled = false;
3233
passkeyBtn.innerHTML = '<i class="bi bi-key me-2"></i> Sign in with Passkey';
3334
}

src/main/resources/static/js/user/webauthn-manage.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,15 @@ function renamePasskey(credentialId, currentLabel) {
153153
});
154154

155155
if (!response.ok) {
156-
const data = await response.json();
157-
throw new Error(data.message || 'Failed to rename passkey');
156+
let msg = 'Failed to rename passkey';
157+
try {
158+
const data = await response.json();
159+
msg = data.message || msg;
160+
} catch {
161+
const text = await response.text();
162+
if (text) msg = text;
163+
}
164+
throw new Error(msg);
158165
}
159166

160167
renameModalInstance.hide();
@@ -199,8 +206,15 @@ async function deletePasskey(credentialId) {
199206
});
200207

201208
if (!response.ok) {
202-
const data = await response.json();
203-
throw new Error(data.message || 'Failed to delete passkey');
209+
let msg = 'Failed to delete passkey';
210+
try {
211+
const data = await response.json();
212+
msg = data.message || msg;
213+
} catch {
214+
const text = await response.text();
215+
if (text) msg = text;
216+
}
217+
throw new Error(msg);
204218
}
205219

206220
if (globalMessage) {

src/main/resources/static/js/user/webauthn-utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,5 @@ export function escapeHtml(text) {
7171
if (!text) return '';
7272
const div = document.createElement('div');
7373
div.textContent = text;
74-
return div.innerHTML;
74+
return div.innerHTML.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
7575
}

src/main/resources/templates/user/login.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<div th:if="${param.error != null and errormessage == null}" class="alert alert-danger text-center" role="alert" id="loginError">
2121
<span th:text="${session.SPRING_SECURITY_LAST_EXCEPTION?.message} ?: 'Invalid email or password'">Invalid email or password</span>
2222
</div>
23+
<!-- Passkey error message (shown by JS) -->
24+
<div id="passkeyError" class="alert alert-danger text-center d-none" role="alert"></div>
2325

2426
<!-- Card Header -->
2527
<div class="card-header text-center">

0 commit comments

Comments
 (0)