Skip to content

Commit 800d831

Browse files
committed
Waiting for the focus to return from KeePassXC-desktop back to the page
1 parent 1a0e218 commit 800d831

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

keepassxc-browser/content/passkeys.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,36 @@
145145
}
146146
};
147147

148+
/**
149+
* @template T
150+
* @param {() => T} action
151+
* @returns {Promise<T>}
152+
*/
153+
const callOnFocus = function (action) {
154+
/*
155+
Some browsers (like Firefox) reject requests to original `navigator.credentials.create/get` if the page
156+
is out of focus (when the user selects a passkey in KeePassXC-desktop).
157+
158+
`document.visibilityState` is not suitable: if the page is visible, but the focus is on another application
159+
(or DevTools), the request will be rejected.
160+
*/
161+
return new Promise((resolve) => {
162+
if (document.hasFocus()) {
163+
return resolve(action());
164+
}
165+
166+
/** @param {FocusEvent} e */
167+
const listener = function (e) {
168+
if (!e.isTrusted) {
169+
return;
170+
}
171+
resolve(action());
172+
};
173+
174+
document.addEventListener('focus', listener, { capture: true, passive: true, once: true });
175+
});
176+
};
177+
148178
// Throws errors to a correct exceptions
149179
const throwError = function(errorCode, errorMessage) {
150180
if ((!errorCode && !errorMessage) || errorCode === PASSKEYS_REQUEST_CANCELED) {
@@ -205,7 +235,7 @@
205235
throwError(response?.errorCode, response?.errorMessage);
206236
return null;
207237
}
208-
return originalCredentials.create(options);
238+
return callOnFocus(() => originalCredentials.create(options));
209239
}
210240

211241
return createPublicKeyCredential(response.publicKey);
@@ -231,7 +261,7 @@
231261
throwError(response?.errorCode, response?.errorMessage);
232262
return null;
233263
}
234-
return originalCredentials.get(options);
264+
return callOnFocus(() => originalCredentials.get(options));
235265
}
236266

237267
return createPublicKeyCredential(response.publicKey);

0 commit comments

Comments
 (0)