fds-vue-core 8.11.0 → 8.11.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.
- package/dist/composables/useBankIdSession.d.ts +2 -0
- package/dist/fds-vue-core.cjs.js +60 -16
- package/dist/fds-vue-core.cjs.js.map +1 -1
- package/dist/fds-vue-core.es.js +60 -16
- package/dist/fds-vue-core.es.js.map +1 -1
- package/dist/helpers/bankId/constants.d.ts +5 -0
- package/dist/helpers/bankId/index.d.ts +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/components/BankId/FdsBankIdStatusAlert/FdsBankIdStatusAlert.vue +1 -1
- package/src/composables/useBankIdSession.spec.ts +73 -4
- package/src/composables/useBankIdSession.ts +60 -15
- package/src/helpers/bankId/constants.ts +5 -0
|
@@ -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) => {
|
package/dist/fds-vue-core.cjs.js
CHANGED
|
@@ -19928,7 +19928,7 @@ var FdsBankIdSameDevice_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
19928
19928
|
});
|
|
19929
19929
|
//#endregion
|
|
19930
19930
|
//#region src/components/BankId/FdsBankIdStatusAlert/FdsBankIdStatusAlert.vue?vue&type=script&setup=true&lang.ts
|
|
19931
|
-
var _hoisted_1$7 =
|
|
19931
|
+
var _hoisted_1$7 = ["innerHTML"];
|
|
19932
19932
|
//#endregion
|
|
19933
19933
|
//#region src/components/BankId/FdsBankIdStatusAlert/FdsBankIdStatusAlert.vue
|
|
19934
19934
|
var FdsBankIdStatusAlert_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
@@ -19955,7 +19955,10 @@ var FdsBankIdStatusAlert_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
19955
19955
|
dataTestid: __props.dataTestid,
|
|
19956
19956
|
onClose: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
19957
19957
|
}, {
|
|
19958
|
-
default: (0, vue.withCtx)(() => [__props.body ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("
|
|
19958
|
+
default: (0, vue.withCtx)(() => [__props.body ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
19959
|
+
key: 0,
|
|
19960
|
+
innerHTML: __props.body
|
|
19961
|
+
}, null, 8, _hoisted_1$7)) : (0, vue.createCommentVNode)("", true)]),
|
|
19959
19962
|
_: 1
|
|
19960
19963
|
}, 8, [
|
|
19961
19964
|
"heading",
|
|
@@ -32908,6 +32911,11 @@ function useRouteScrollPositions(currentRoute) {
|
|
|
32908
32911
|
var bankIdConstants = {
|
|
32909
32912
|
deviceIdentifierStorageKey: "bankid_device_identifier",
|
|
32910
32913
|
pollIntervalMs: 2e3,
|
|
32914
|
+
/**
|
|
32915
|
+
* A QR order that nobody has scanned fails after about 30 seconds, so it is
|
|
32916
|
+
* replaced with a new order shortly before that.
|
|
32917
|
+
*/
|
|
32918
|
+
qrRefreshMs: 28e3,
|
|
32911
32919
|
maxPolls: 300,
|
|
32912
32920
|
/**
|
|
32913
32921
|
* BankID's own limit: an auth or sign order expires after 3 minutes
|
|
@@ -33298,7 +33306,7 @@ var createInitialBankIdState = () => ({
|
|
|
33298
33306
|
messageCode: null
|
|
33299
33307
|
});
|
|
33300
33308
|
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;
|
|
33309
|
+
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
33310
|
const { getBankIdDeviceIdentifier } = useBankIdDeviceIdentifier({ storageKey: deviceIdentifierStorageKey });
|
|
33303
33311
|
const sameDevice = useBankIdSameDevice({
|
|
33304
33312
|
storageKey,
|
|
@@ -33316,6 +33324,7 @@ var useBankIdSession = (options) => {
|
|
|
33316
33324
|
let disposed = false;
|
|
33317
33325
|
let attemptId = 0;
|
|
33318
33326
|
let pollTimer = null;
|
|
33327
|
+
let qrRefreshTimer = null;
|
|
33319
33328
|
let pollInFlight = false;
|
|
33320
33329
|
let currentOrderRef = null;
|
|
33321
33330
|
/** Flow captured when the order was created. Later UI changes must not apply to it. */
|
|
@@ -33325,12 +33334,22 @@ var useBankIdSession = (options) => {
|
|
|
33325
33334
|
let returnedNonce = null;
|
|
33326
33335
|
/** Return landed on another route. Unmount must leave the stored order alone. */
|
|
33327
33336
|
let handingOff = false;
|
|
33328
|
-
const
|
|
33337
|
+
const stopPollTimer = () => {
|
|
33329
33338
|
if (pollTimer) {
|
|
33330
33339
|
clearTimeout(pollTimer);
|
|
33331
33340
|
pollTimer = null;
|
|
33332
33341
|
}
|
|
33333
33342
|
};
|
|
33343
|
+
const stopQrRefreshTimer = () => {
|
|
33344
|
+
if (qrRefreshTimer) {
|
|
33345
|
+
clearTimeout(qrRefreshTimer);
|
|
33346
|
+
qrRefreshTimer = null;
|
|
33347
|
+
}
|
|
33348
|
+
};
|
|
33349
|
+
const stopTimers = () => {
|
|
33350
|
+
stopPollTimer();
|
|
33351
|
+
stopQrRefreshTimer();
|
|
33352
|
+
};
|
|
33334
33353
|
const isCurrentAttempt = (attempt) => !disposed && attempt === attemptId;
|
|
33335
33354
|
const isCurrentOrder = (orderRef) => !disposed && currentOrderRef === orderRef;
|
|
33336
33355
|
const invalidateAttempt = () => {
|
|
@@ -33421,13 +33440,16 @@ var useBankIdSession = (options) => {
|
|
|
33421
33440
|
device: device.value,
|
|
33422
33441
|
sameDevice: orderSameDevice
|
|
33423
33442
|
});
|
|
33424
|
-
if (hintCode === "userSign")
|
|
33443
|
+
if (hintCode === "userSign") {
|
|
33444
|
+
bankId.ongoingLogin = true;
|
|
33445
|
+
stopQrRefreshTimer();
|
|
33446
|
+
}
|
|
33425
33447
|
}
|
|
33426
33448
|
if (response.orderRef) bankId.transactionToken = { orderRef: response.orderRef };
|
|
33427
33449
|
return true;
|
|
33428
33450
|
};
|
|
33429
33451
|
const schedulePoll = (orderRef) => {
|
|
33430
|
-
|
|
33452
|
+
stopPollTimer();
|
|
33431
33453
|
if (!isCurrentOrder(orderRef)) return;
|
|
33432
33454
|
pollTimer = setTimeout(() => {
|
|
33433
33455
|
pollTimer = null;
|
|
@@ -33470,16 +33492,7 @@ var useBankIdSession = (options) => {
|
|
|
33470
33492
|
if (orderRef) cancel(orderRef).catch(() => void 0);
|
|
33471
33493
|
return true;
|
|
33472
33494
|
};
|
|
33473
|
-
const
|
|
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;
|
|
33495
|
+
const createBankIdOrder = async (attempt, sameDeviceOrder) => {
|
|
33483
33496
|
let deviceIdentifier;
|
|
33484
33497
|
try {
|
|
33485
33498
|
deviceIdentifier = await getBankIdDeviceIdentifier();
|
|
@@ -33515,12 +33528,43 @@ var useBankIdSession = (options) => {
|
|
|
33515
33528
|
if (sameDeviceOrder && nonce && response.orderRef) sameDevice.persistNonceMetadata(nonce, response.orderRef);
|
|
33516
33529
|
loading.value = false;
|
|
33517
33530
|
schedulePoll(response.orderRef);
|
|
33531
|
+
if (!sameDeviceOrder) scheduleQrRefresh(response.orderRef);
|
|
33518
33532
|
return response;
|
|
33519
33533
|
} catch {
|
|
33520
33534
|
if (isCurrentAttempt(attempt)) clearBankid("RFA6");
|
|
33521
33535
|
return;
|
|
33522
33536
|
}
|
|
33523
33537
|
};
|
|
33538
|
+
/**
|
|
33539
|
+
* Replaces an unscanned QR order before it fails. The QR on screen stays
|
|
33540
|
+
* until the new one arrives, and the poll count carries over so maxPolls
|
|
33541
|
+
* still limits the whole session.
|
|
33542
|
+
*/
|
|
33543
|
+
const refreshQrOrder = (orderRef) => {
|
|
33544
|
+
if (!isCurrentOrder(orderRef) || orderSameDevice || bankId.ongoingLogin) return;
|
|
33545
|
+
cancel(orderRef).catch(() => void 0);
|
|
33546
|
+
invalidateAttempt();
|
|
33547
|
+
createBankIdOrder(attemptId, false);
|
|
33548
|
+
};
|
|
33549
|
+
const scheduleQrRefresh = (orderRef) => {
|
|
33550
|
+
stopQrRefreshTimer();
|
|
33551
|
+
qrRefreshTimer = setTimeout(() => {
|
|
33552
|
+
qrRefreshTimer = null;
|
|
33553
|
+
refreshQrOrder(orderRef);
|
|
33554
|
+
}, qrRefreshMs);
|
|
33555
|
+
};
|
|
33556
|
+
const initiateBankId = async () => {
|
|
33557
|
+
const previousOrderRef = currentOrderRef;
|
|
33558
|
+
if (previousOrderRef) cancel(previousOrderRef).catch(() => void 0);
|
|
33559
|
+
clearError();
|
|
33560
|
+
const attempt = attemptId;
|
|
33561
|
+
const sameDeviceOrder = bankId.sameDevice;
|
|
33562
|
+
orderSameDevice = sameDeviceOrder;
|
|
33563
|
+
getDevice();
|
|
33564
|
+
bankId.activePolling = true;
|
|
33565
|
+
loading.value = true;
|
|
33566
|
+
return createBankIdOrder(attempt, sameDeviceOrder);
|
|
33567
|
+
};
|
|
33524
33568
|
const openBankId = async () => {
|
|
33525
33569
|
bankId.sameDevice = true;
|
|
33526
33570
|
const response = await initiateBankId();
|