|
145 | 145 | } |
146 | 146 | }; |
147 | 147 |
|
| 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 | + |
148 | 178 | // Throws errors to a correct exceptions |
149 | 179 | const throwError = function(errorCode, errorMessage) { |
150 | 180 | if ((!errorCode && !errorMessage) || errorCode === PASSKEYS_REQUEST_CANCELED) { |
|
205 | 235 | throwError(response?.errorCode, response?.errorMessage); |
206 | 236 | return null; |
207 | 237 | } |
208 | | - return originalCredentials.create(options); |
| 238 | + return callOnFocus(() => originalCredentials.create(options)); |
209 | 239 | } |
210 | 240 |
|
211 | 241 | return createPublicKeyCredential(response.publicKey); |
|
231 | 261 | throwError(response?.errorCode, response?.errorMessage); |
232 | 262 | return null; |
233 | 263 | } |
234 | | - return originalCredentials.get(options); |
| 264 | + return callOnFocus(() => originalCredentials.get(options)); |
235 | 265 | } |
236 | 266 |
|
237 | 267 | return createPublicKeyCredential(response.publicKey); |
|
0 commit comments