fds-vue-core 8.11.0 → 8.11.1

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.
@@ -13,6 +13,8 @@ export interface UseBankIdSessionOptions extends Pick<UseBankIdSameDeviceOptions
13
13
  onNonceMismatch?: () => void;
14
14
  mapPollError?: (error: unknown) => string | null | undefined;
15
15
  pollIntervalMs?: number;
16
+ /** How often an unscanned QR order is replaced. */
17
+ qrRefreshMs?: number;
16
18
  maxPolls?: number;
17
19
  }
18
20
  export declare const useBankIdSession: (options: UseBankIdSessionOptions) => {
@@ -32908,6 +32908,11 @@ function useRouteScrollPositions(currentRoute) {
32908
32908
  var bankIdConstants = {
32909
32909
  deviceIdentifierStorageKey: "bankid_device_identifier",
32910
32910
  pollIntervalMs: 2e3,
32911
+ /**
32912
+ * A QR order that nobody has scanned fails after about 30 seconds, so it is
32913
+ * replaced with a new order shortly before that.
32914
+ */
32915
+ qrRefreshMs: 28e3,
32911
32916
  maxPolls: 300,
32912
32917
  /**
32913
32918
  * BankID's own limit: an auth or sign order expires after 3 minutes
@@ -33298,7 +33303,7 @@ var createInitialBankIdState = () => ({
33298
33303
  messageCode: null
33299
33304
  });
33300
33305
  var useBankIdSession = (options) => {
33301
- const { storageKey, getCurrentPath, navigateTo, deviceIdentifierStorageKey, createOrder, poll, cancel, onSuccess, onActivation, onPoll, onNonceMismatch, mapPollError, pollIntervalMs = bankIdConstants.pollIntervalMs, maxPolls = bankIdConstants.maxPolls, titles, bodies } = options;
33306
+ const { storageKey, getCurrentPath, navigateTo, deviceIdentifierStorageKey, createOrder, poll, cancel, onSuccess, onActivation, onPoll, onNonceMismatch, mapPollError, pollIntervalMs = bankIdConstants.pollIntervalMs, qrRefreshMs = bankIdConstants.qrRefreshMs, maxPolls = bankIdConstants.maxPolls, titles, bodies } = options;
33302
33307
  const { getBankIdDeviceIdentifier } = useBankIdDeviceIdentifier({ storageKey: deviceIdentifierStorageKey });
33303
33308
  const sameDevice = useBankIdSameDevice({
33304
33309
  storageKey,
@@ -33316,6 +33321,7 @@ var useBankIdSession = (options) => {
33316
33321
  let disposed = false;
33317
33322
  let attemptId = 0;
33318
33323
  let pollTimer = null;
33324
+ let qrRefreshTimer = null;
33319
33325
  let pollInFlight = false;
33320
33326
  let currentOrderRef = null;
33321
33327
  /** Flow captured when the order was created. Later UI changes must not apply to it. */
@@ -33325,12 +33331,22 @@ var useBankIdSession = (options) => {
33325
33331
  let returnedNonce = null;
33326
33332
  /** Return landed on another route. Unmount must leave the stored order alone. */
33327
33333
  let handingOff = false;
33328
- const stopTimers = () => {
33334
+ const stopPollTimer = () => {
33329
33335
  if (pollTimer) {
33330
33336
  clearTimeout(pollTimer);
33331
33337
  pollTimer = null;
33332
33338
  }
33333
33339
  };
33340
+ const stopQrRefreshTimer = () => {
33341
+ if (qrRefreshTimer) {
33342
+ clearTimeout(qrRefreshTimer);
33343
+ qrRefreshTimer = null;
33344
+ }
33345
+ };
33346
+ const stopTimers = () => {
33347
+ stopPollTimer();
33348
+ stopQrRefreshTimer();
33349
+ };
33334
33350
  const isCurrentAttempt = (attempt) => !disposed && attempt === attemptId;
33335
33351
  const isCurrentOrder = (orderRef) => !disposed && currentOrderRef === orderRef;
33336
33352
  const invalidateAttempt = () => {
@@ -33421,13 +33437,16 @@ var useBankIdSession = (options) => {
33421
33437
  device: device.value,
33422
33438
  sameDevice: orderSameDevice
33423
33439
  });
33424
- if (hintCode === "userSign") bankId.ongoingLogin = true;
33440
+ if (hintCode === "userSign") {
33441
+ bankId.ongoingLogin = true;
33442
+ stopQrRefreshTimer();
33443
+ }
33425
33444
  }
33426
33445
  if (response.orderRef) bankId.transactionToken = { orderRef: response.orderRef };
33427
33446
  return true;
33428
33447
  };
33429
33448
  const schedulePoll = (orderRef) => {
33430
- stopTimers();
33449
+ stopPollTimer();
33431
33450
  if (!isCurrentOrder(orderRef)) return;
33432
33451
  pollTimer = setTimeout(() => {
33433
33452
  pollTimer = null;
@@ -33470,16 +33489,7 @@ var useBankIdSession = (options) => {
33470
33489
  if (orderRef) cancel(orderRef).catch(() => void 0);
33471
33490
  return true;
33472
33491
  };
33473
- const initiateBankId = async () => {
33474
- const previousOrderRef = currentOrderRef;
33475
- if (previousOrderRef) cancel(previousOrderRef).catch(() => void 0);
33476
- clearError();
33477
- const attempt = attemptId;
33478
- const sameDeviceOrder = bankId.sameDevice;
33479
- orderSameDevice = sameDeviceOrder;
33480
- getDevice();
33481
- bankId.activePolling = true;
33482
- loading.value = true;
33492
+ const createBankIdOrder = async (attempt, sameDeviceOrder) => {
33483
33493
  let deviceIdentifier;
33484
33494
  try {
33485
33495
  deviceIdentifier = await getBankIdDeviceIdentifier();
@@ -33515,12 +33525,43 @@ var useBankIdSession = (options) => {
33515
33525
  if (sameDeviceOrder && nonce && response.orderRef) sameDevice.persistNonceMetadata(nonce, response.orderRef);
33516
33526
  loading.value = false;
33517
33527
  schedulePoll(response.orderRef);
33528
+ if (!sameDeviceOrder) scheduleQrRefresh(response.orderRef);
33518
33529
  return response;
33519
33530
  } catch {
33520
33531
  if (isCurrentAttempt(attempt)) clearBankid("RFA6");
33521
33532
  return;
33522
33533
  }
33523
33534
  };
33535
+ /**
33536
+ * Replaces an unscanned QR order before it fails. The QR on screen stays
33537
+ * until the new one arrives, and the poll count carries over so maxPolls
33538
+ * still limits the whole session.
33539
+ */
33540
+ const refreshQrOrder = (orderRef) => {
33541
+ if (!isCurrentOrder(orderRef) || orderSameDevice || bankId.ongoingLogin) return;
33542
+ cancel(orderRef).catch(() => void 0);
33543
+ invalidateAttempt();
33544
+ createBankIdOrder(attemptId, false);
33545
+ };
33546
+ const scheduleQrRefresh = (orderRef) => {
33547
+ stopQrRefreshTimer();
33548
+ qrRefreshTimer = setTimeout(() => {
33549
+ qrRefreshTimer = null;
33550
+ refreshQrOrder(orderRef);
33551
+ }, qrRefreshMs);
33552
+ };
33553
+ const initiateBankId = async () => {
33554
+ const previousOrderRef = currentOrderRef;
33555
+ if (previousOrderRef) cancel(previousOrderRef).catch(() => void 0);
33556
+ clearError();
33557
+ const attempt = attemptId;
33558
+ const sameDeviceOrder = bankId.sameDevice;
33559
+ orderSameDevice = sameDeviceOrder;
33560
+ getDevice();
33561
+ bankId.activePolling = true;
33562
+ loading.value = true;
33563
+ return createBankIdOrder(attempt, sameDeviceOrder);
33564
+ };
33524
33565
  const openBankId = async () => {
33525
33566
  bankId.sameDevice = true;
33526
33567
  const response = await initiateBankId();