1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-11 17:51:01 +00:00

refactor(js): enable touch handlers only on touch devices and fix various issues in WebAuthnHandler

This commit is contained in:
Frédéric Guillot 2025-08-02 15:34:54 -07:00
parent 4910f1f0f4
commit 52c1386450
2 changed files with 43 additions and 16 deletions

View file

@ -47,7 +47,7 @@ class TouchHandler {
}
onItemTouchMove(event) {
if (event.touches === undefined || event.touches.length !== 1 || this.element === null) {
if (event.touches === undefined || event.touches.length !== 1 || this.touch.element === null) {
return;
}
@ -151,7 +151,15 @@ class TouchHandler {
}
}
static isTouchSupported() {
return "ontouchstart" in window || navigator.maxTouchPoints > 0;
}
listen() {
if (!TouchHandler.isTouchSupported()) {
return;
}
const eventListenerOptions = { passive: true };
document.querySelectorAll(".entry-swipe").forEach((element) => {

View file

@ -1,16 +1,15 @@
class WebAuthnHandler {
static isWebAuthnSupported() {
return window.PublicKeyCredential;
return typeof PublicKeyCredential !== "undefined";
}
static showErrorMessage(errorMessage) {
console.log("webauthn error: " + errorMessage);
console.error("WebAuthn error:", errorMessage);
const alertElement = document.getElementById("webauthn-error-alert");
if (!alertElement) {
return;
if (alertElement) {
alertElement.remove();
}
alertElement.remove();
const alertTemplateElement = document.getElementById("webauthn-error");
if (alertTemplateElement) {
@ -23,15 +22,15 @@ class WebAuthnHandler {
}
}
async isConditionalLoginSupported() {
static async isConditionalLoginSupported() {
return WebAuthnHandler.isWebAuthnSupported() &&
window.PublicKeyCredential.isConditionalMediationAvailable &&
window.PublicKeyCredential.isConditionalMediationAvailable();
await window.PublicKeyCredential.isConditionalMediationAvailable();
}
async conditionalLogin(abortController) {
if (await this.isConditionalLoginSupported()) {
this.login("", abortController);
if (await WebAuthnHandler.isConditionalLoginSupported()) {
return this.login("", abortController);
}
}
@ -49,7 +48,7 @@ class WebAuthnHandler {
async post(urlKey, username, data) {
let url = document.body.dataset[urlKey];
if (username) {
url += "?username=" + username;
url += "?username=" + encodeURIComponent(username);
}
return sendPOSTRequest(url, data);
@ -58,7 +57,7 @@ class WebAuthnHandler {
async get(urlKey, username) {
let url = document.body.dataset[urlKey];
if (username) {
url += "?username=" + username;
url += "?username=" + encodeURIComponent(username);
}
return fetch(url);
}
@ -83,14 +82,27 @@ class WebAuthnHandler {
return;
}
const credentialCreationOptions = await registerBeginResponse.json();
let credentialCreationOptions;
try {
credentialCreationOptions = await registerBeginResponse.json();
} catch (err) {
WebAuthnHandler.showErrorMessage("Failed to parse registration options");
return;
}
credentialCreationOptions.publicKey.challenge = this.decodeBuffer(credentialCreationOptions.publicKey.challenge);
credentialCreationOptions.publicKey.user.id = this.decodeBuffer(credentialCreationOptions.publicKey.user.id);
if (Object.hasOwn(credentialCreationOptions.publicKey, 'excludeCredentials')) {
credentialCreationOptions.publicKey.excludeCredentials.forEach((credential) => credential.id = this.decodeBuffer(credential.id));
}
const attestation = await navigator.credentials.create(credentialCreationOptions);
let attestation;
try {
attestation = await navigator.credentials.create(credentialCreationOptions);
} catch (err) {
WebAuthnHandler.showErrorMessage(err);
return;
}
let registrationFinishResponse;
try {
@ -109,7 +121,7 @@ class WebAuthnHandler {
}
if (!registrationFinishResponse.ok) {
throw new Error("Login failed with HTTP status code " + response.status);
throw new Error("Registration failed with HTTP status code " + registrationFinishResponse.status);
}
const jsonData = await registrationFinishResponse.json();
@ -125,7 +137,14 @@ class WebAuthnHandler {
return;
}
const credentialRequestOptions = await loginBeginResponse.json();
let credentialRequestOptions;
try {
credentialRequestOptions = await loginBeginResponse.json();
} catch (err) {
WebAuthnHandler.showErrorMessage("Failed to parse login options");
return;
}
credentialRequestOptions.publicKey.challenge = this.decodeBuffer(credentialRequestOptions.publicKey.challenge);
if (Object.hasOwn(credentialRequestOptions.publicKey, 'allowCredentials')) {