@franzzemen/brokenstock-shell 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -850,7 +850,9 @@ class AuthenticationService {
850
850
  if (err instanceof PasskeyCancelledError)
851
851
  throw new AuthenticatorError(undefined, 'Cancelled — no passkey was added.', 0);
852
852
  if (err instanceof DOMException && err.name === 'InvalidStateError') {
853
- throw new AuthenticatorError(undefined, 'This device already has a passkey for this account.', 0);
853
+ // The browser found one of this account's passkeys already usable here — often synced from
854
+ // another computer through a Google or Apple account. No second one is needed.
855
+ throw new AuthenticatorError(undefined, 'A passkey for this account is already on this device — it may be synced from another computer through your Google or Apple account. Use "Sign in with a passkey".', 0);
854
856
  }
855
857
  throw new AuthenticatorError(undefined, 'The browser could not make a passkey.', 0);
856
858
  }
@@ -4402,6 +4404,8 @@ class Login {
4402
4404
  #activatedRoute;
4403
4405
  /** The quiet wait for a passkey picked from the username box's suggestions (passkey D9). */
4404
4406
  #autofill;
4407
+ /** Settles when the quiet wait has fully ended — the button's prompt waits for it. */
4408
+ #autofillSettled;
4405
4409
  constructor(authenticationService, router) {
4406
4410
  this.authenticationService = authenticationService;
4407
4411
  this.router = router;
@@ -4451,12 +4455,18 @@ class Login {
4451
4455
  this.#autofill?.abort();
4452
4456
  }
4453
4457
  /** "Sign in with a passkey". The quiet wait must stop first: a browser runs one passkey prompt at a time. */
4454
- onPasskey() {
4458
+ async onPasskey() {
4455
4459
  this.errors = [];
4456
4460
  this.passkeyHint.set(false);
4461
+ this.submitted = true;
4457
4462
  this.#autofill?.abort();
4458
4463
  this.#autofill = undefined;
4459
- this.submitted = true;
4464
+ // ⚠ Wait for the browser to finish cancelling the quiet request before opening the prompt.
4465
+ // Starting a second passkey request while the first is still being torn down is the overlap
4466
+ // Windows is least tolerant of. Bounded, so a request that never settles cannot block the button.
4467
+ const settled = this.#autofillSettled;
4468
+ if (settled)
4469
+ await Promise.race([settled, new Promise(r => setTimeout(r, 1500))]);
4460
4470
  this.#passkeySignIn(false);
4461
4471
  }
4462
4472
  /**
@@ -4472,10 +4482,10 @@ class Login {
4472
4482
  this.#autofill?.abort();
4473
4483
  const controller = new AbortController();
4474
4484
  this.#autofill = controller;
4475
- this.#passkeySignIn(true, controller.signal);
4485
+ this.#autofillSettled = this.#passkeySignIn(true, controller.signal);
4476
4486
  }
4477
4487
  #passkeySignIn(conditional, signal) {
4478
- this.authenticationService
4488
+ return this.authenticationService
4479
4489
  .loginWithPasskey({ conditional, ...(signal ? { signal } : {}) })
4480
4490
  .then(() => this.#afterSignIn(undefined))
4481
4491
  .catch((err) => {