@haus-tech/bankid-auth-plugin 1.0.7 → 1.1.6
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/CHANGELOG.md +30 -0
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/api/api-extensions.js +4 -0
- package/src/api/api-extensions.js.map +1 -1
- package/src/bankid-auth.resolver.d.ts +13 -5
- package/src/bankid-auth.resolver.js +19 -7
- package/src/bankid-auth.resolver.js.map +1 -1
- package/src/services/bankid-auth.service.js +30 -0
- package/src/services/bankid-auth.service.js.map +1 -1
- package/src/services/bankid-session.service.d.ts +2 -1
- package/src/services/bankid-session.service.js +35 -3
- package/src/services/bankid-session.service.js.map +1 -1
- package/src/types.d.ts +3 -0
- package/src/utils.d.ts +8 -1
- package/src/utils.js +12 -2
- package/src/utils.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
## 1.1.5
|
|
2
|
+
|
|
3
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
4
|
+
|
|
5
|
+
## 1.1.4
|
|
6
|
+
|
|
7
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
8
|
+
|
|
9
|
+
## 1.1.3
|
|
10
|
+
|
|
11
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
12
|
+
|
|
13
|
+
## 1.1.2
|
|
14
|
+
|
|
15
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
16
|
+
|
|
17
|
+
## 1.1.1
|
|
18
|
+
|
|
19
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
20
|
+
|
|
21
|
+
## 1.1.0
|
|
22
|
+
|
|
23
|
+
### 🚀 Features
|
|
24
|
+
|
|
25
|
+
- automatically renew bankid order if startfailed error for max 5 min ([d6b08c3](https://github.com/WeAreHausTech/haus-tech-vendure-plugins/commit/d6b08c3))
|
|
26
|
+
|
|
27
|
+
## 1.0.7
|
|
28
|
+
|
|
29
|
+
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
|
30
|
+
|
|
1
31
|
## 1.0.6
|
|
2
32
|
|
|
3
33
|
This was a version bump only for bankid-auth-plugin to align it with other projects, there were no code changes.
|
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
name: bankid-auth-plugin
|
|
3
3
|
title: BankID Auth Plugin
|
|
4
4
|
description: Vendure plugin that integrates BankID authentication into your e-commerce platform.
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.1.5
|
|
6
|
+
tags: [vendure, plugin, bankid, authentication]
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# BankID Auth Plugin
|
package/package.json
CHANGED
|
@@ -9,6 +9,8 @@ exports.shopSchema = (0, graphql_tag_1.gql) `
|
|
|
9
9
|
|
|
10
10
|
type InitiateBankidAuthResponse {
|
|
11
11
|
autoStartToken: String!
|
|
12
|
+
expiresAt: String!
|
|
13
|
+
remainingSeconds: Int!
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
extend type Mutation {
|
|
@@ -24,6 +26,8 @@ exports.shopSchema = (0, graphql_tag_1.gql) `
|
|
|
24
26
|
hintCode: String
|
|
25
27
|
autoStartToken: String
|
|
26
28
|
qrData: String
|
|
29
|
+
expiresAt: String
|
|
30
|
+
remainingSeconds: Int
|
|
27
31
|
}
|
|
28
32
|
extend type Mutation {
|
|
29
33
|
cancelBankidAuth: Boolean!
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-extensions.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/api/api-extensions.ts"],"names":[],"mappings":";;;AAAA,6CAAiC;AAEpB,QAAA,UAAU,GAAG,IAAA,iBAAG,EAAA
|
|
1
|
+
{"version":3,"file":"api-extensions.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/api/api-extensions.ts"],"names":[],"mappings":";;;AAAA,6CAAiC;AAEpB,QAAA,UAAU,GAAG,IAAA,iBAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B5B,CAAA"}
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
import { BankIdAuthService } from './services/bankid-auth.service';
|
|
2
2
|
import { BankIdSessionService } from './services/bankid-session.service';
|
|
3
3
|
import { RequestContext } from '@vendure/core';
|
|
4
|
-
import { GetBankidAuthStatusInput } from './types';
|
|
4
|
+
import { BankIdOrderStatus, GetBankidAuthStatusInput } from './types';
|
|
5
5
|
import { Request } from 'express';
|
|
6
6
|
export declare class BankIdAuthResolver {
|
|
7
7
|
private bankIdAuthService;
|
|
8
8
|
private bankIdSessionService;
|
|
9
9
|
constructor(bankIdAuthService: BankIdAuthService, bankIdSessionService: BankIdSessionService);
|
|
10
|
-
initiateBankidAuth(ctx: RequestContext, req: Request): Promise<
|
|
10
|
+
initiateBankidAuth(ctx: RequestContext, req: Request): Promise<{
|
|
11
|
+
autoStartToken: string;
|
|
12
|
+
expiresAt: string;
|
|
13
|
+
remainingSeconds: number;
|
|
14
|
+
}>;
|
|
11
15
|
getBankidAuthStatus(ctx: RequestContext, args: {
|
|
12
16
|
input: GetBankidAuthStatusInput;
|
|
13
17
|
}): Promise<{
|
|
14
|
-
status:
|
|
15
|
-
hintCode:
|
|
18
|
+
status: BankIdOrderStatus;
|
|
19
|
+
hintCode: string;
|
|
16
20
|
autoStartToken: null;
|
|
17
21
|
qrData: null;
|
|
22
|
+
expiresAt: null;
|
|
23
|
+
remainingSeconds: null;
|
|
18
24
|
} | {
|
|
19
|
-
status:
|
|
25
|
+
status: BankIdOrderStatus;
|
|
20
26
|
hintCode: string;
|
|
21
27
|
autoStartToken: string;
|
|
22
28
|
qrData: string | undefined;
|
|
29
|
+
expiresAt: string;
|
|
30
|
+
remainingSeconds: number;
|
|
23
31
|
}>;
|
|
24
32
|
cancelBankidAuth(ctx: RequestContext): Promise<boolean>;
|
|
25
33
|
}
|
|
@@ -19,9 +19,10 @@ const bankid_session_service_1 = require("./services/bankid-session.service");
|
|
|
19
19
|
const core_1 = require("@vendure/core");
|
|
20
20
|
const utils_1 = require("./utils");
|
|
21
21
|
const utils_2 = require("./utils");
|
|
22
|
+
const utils_3 = require("./utils");
|
|
22
23
|
const graphql_1 = require("@nestjs/graphql");
|
|
24
|
+
const types_1 = require("./types");
|
|
23
25
|
const graphql_2 = require("@nestjs/graphql");
|
|
24
|
-
const lodash_1 = require("lodash");
|
|
25
26
|
const constants_1 = require("./constants");
|
|
26
27
|
let BankIdAuthResolver = class BankIdAuthResolver {
|
|
27
28
|
bankIdAuthService;
|
|
@@ -34,8 +35,13 @@ let BankIdAuthResolver = class BankIdAuthResolver {
|
|
|
34
35
|
try {
|
|
35
36
|
const endUserIp = (0, utils_1.getClientIp)(req);
|
|
36
37
|
const result = await this.bankIdAuthService.initiate(ctx, endUserIp);
|
|
37
|
-
await this.bankIdSessionService.save(ctx, result, endUserIp);
|
|
38
|
-
|
|
38
|
+
const sessionData = await this.bankIdSessionService.save(ctx, result, endUserIp);
|
|
39
|
+
const { expiresAt, remainingSeconds } = (0, utils_2.getBankidSessionTiming)(sessionData.expiresAt);
|
|
40
|
+
return {
|
|
41
|
+
autoStartToken: result.autoStartToken,
|
|
42
|
+
expiresAt,
|
|
43
|
+
remainingSeconds,
|
|
44
|
+
};
|
|
39
45
|
}
|
|
40
46
|
catch (error) {
|
|
41
47
|
const err = error;
|
|
@@ -47,23 +53,29 @@ let BankIdAuthResolver = class BankIdAuthResolver {
|
|
|
47
53
|
const data = await this.bankIdSessionService.get(ctx);
|
|
48
54
|
if (!data || !data.orderRef) {
|
|
49
55
|
return {
|
|
50
|
-
status:
|
|
51
|
-
hintCode:
|
|
56
|
+
status: types_1.BankIdOrderStatus.Failed,
|
|
57
|
+
hintCode: 'sessionExpired',
|
|
52
58
|
autoStartToken: null,
|
|
53
59
|
qrData: null,
|
|
60
|
+
expiresAt: null,
|
|
61
|
+
remainingSeconds: null,
|
|
54
62
|
};
|
|
55
63
|
}
|
|
56
64
|
try {
|
|
57
65
|
const statusResponse = await this.bankIdAuthService.getBankidAuthStatus(ctx, data, args.input.isSameDevice);
|
|
66
|
+
const sessionData = (await this.bankIdSessionService.get(ctx)) ?? data;
|
|
67
|
+
const { expiresAt, remainingSeconds } = (0, utils_2.getBankidSessionTiming)(data.expiresAt);
|
|
58
68
|
return {
|
|
59
69
|
status: statusResponse.status,
|
|
60
70
|
hintCode: statusResponse.hintCode,
|
|
61
|
-
autoStartToken:
|
|
71
|
+
autoStartToken: sessionData.autoStartToken,
|
|
62
72
|
qrData: statusResponse.qrData,
|
|
73
|
+
expiresAt,
|
|
74
|
+
remainingSeconds,
|
|
63
75
|
};
|
|
64
76
|
}
|
|
65
77
|
catch (error) {
|
|
66
|
-
if (error instanceof
|
|
78
|
+
if (error instanceof utils_3.IpMismatchError) {
|
|
67
79
|
throw new common_1.UnauthorizedException(error);
|
|
68
80
|
}
|
|
69
81
|
throw (0, utils_1.handleBankIdError)(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bankid-auth.resolver.js","sourceRoot":"","sources":["../../../../packages/bankid-auth-plugin/src/bankid-auth.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAiF;AACjF,wEAAkE;AAClE,8EAAwE;AACxE,wCAA2D;AAC3D,mCAAwD;AACxD,mCAAyC;AACzC,6CAA0D;
|
|
1
|
+
{"version":3,"file":"bankid-auth.resolver.js","sourceRoot":"","sources":["../../../../packages/bankid-auth-plugin/src/bankid-auth.resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,11 +29,41 @@ let BankIdAuthService = class BankIdAuthService {
|
|
|
29
29
|
return this.apiService.initiate(ctx, endUserIp);
|
|
30
30
|
}
|
|
31
31
|
async getBankidAuthStatus(ctx, data, isSameDevice) {
|
|
32
|
+
// Never renew/create new orders after the 5-minute session has expired.
|
|
33
|
+
if ((0, utils_1.isBankidSessionExpired)(data.expiresAt)) {
|
|
34
|
+
await this.bankIdSessionService.clear(ctx);
|
|
35
|
+
return {
|
|
36
|
+
orderRef: data.orderRef,
|
|
37
|
+
status: types_1.BankIdOrderStatus.Failed,
|
|
38
|
+
hintCode: 'sessionExpired',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
32
41
|
try {
|
|
33
42
|
const response = await this.apiService.collect(ctx, data.orderRef);
|
|
34
43
|
if (response.status === types_1.BankIdOrderStatus.Complete && response.completionData != null) {
|
|
35
44
|
return await this.handleComplete(ctx, response, isSameDevice, data.endUserIp);
|
|
36
45
|
}
|
|
46
|
+
// If BankID reports startFailed, create a new order within the existing session window.
|
|
47
|
+
if (response.status === types_1.BankIdOrderStatus.Failed && response.hintCode === 'startFailed') {
|
|
48
|
+
const newOrder = await this.apiService.initiate(ctx, data.endUserIp);
|
|
49
|
+
const updated = await this.bankIdSessionService.updateActiveOrder(ctx, newOrder);
|
|
50
|
+
if (updated) {
|
|
51
|
+
return {
|
|
52
|
+
orderRef: updated.orderRef,
|
|
53
|
+
status: types_1.BankIdOrderStatus.Pending,
|
|
54
|
+
hintCode: 'orderRenewed',
|
|
55
|
+
qrData: (0, utils_1.generateQrData)(updated),
|
|
56
|
+
autoStartToken: updated.autoStartToken,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// If updateActiveOrder() returned undefined, the session has expired (or was cleared),
|
|
60
|
+
// so do not attempt any further renewal.
|
|
61
|
+
return {
|
|
62
|
+
orderRef: data.orderRef,
|
|
63
|
+
status: types_1.BankIdOrderStatus.Failed,
|
|
64
|
+
hintCode: 'sessionExpired',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
37
67
|
const qrData = (0, utils_1.generateQrData)(data);
|
|
38
68
|
const result = {
|
|
39
69
|
...response,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bankid-auth.service.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/services/bankid-auth.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA2C;AAC3C,wCAAsD;AACtD,4CAAwC;AACxC,oCAAoG;AACpG,
|
|
1
|
+
{"version":3,"file":"bankid-auth.service.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/services/bankid-auth.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,8 @@ import { BankIdSessionData } from '../types';
|
|
|
4
4
|
export declare class BankIdSessionService {
|
|
5
5
|
private cacheService;
|
|
6
6
|
constructor(cacheService: CacheService);
|
|
7
|
-
save(ctx: RequestContext, bankIdData: InitiateResponse, endUserIp: string): Promise<
|
|
7
|
+
save(ctx: RequestContext, bankIdData: InitiateResponse, endUserIp: string): Promise<BankIdSessionData>;
|
|
8
|
+
updateActiveOrder(ctx: RequestContext, bankIdData: InitiateResponse): Promise<BankIdSessionData | undefined>;
|
|
8
9
|
get(ctx: RequestContext): Promise<BankIdSessionData | undefined>;
|
|
9
10
|
clear(ctx: RequestContext): Promise<void>;
|
|
10
11
|
getSessionToken(ctx: RequestContext): Promise<string | undefined>;
|
|
@@ -17,7 +17,9 @@ const common_1 = require("@nestjs/common");
|
|
|
17
17
|
const core_1 = require("@vendure/core");
|
|
18
18
|
const lodash_1 = require("lodash");
|
|
19
19
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
20
|
-
const
|
|
20
|
+
const utils_1 = require("../utils");
|
|
21
|
+
const BANKID_AUTH_SESSION_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
22
|
+
const AUTH_USER_TTL_MS = 1800000; // 30 minutes
|
|
21
23
|
const ENCRYPTION_KEY = process.env.BANKID_ENCRYPTION_KEY;
|
|
22
24
|
let BankIdSessionService = class BankIdSessionService {
|
|
23
25
|
cacheService;
|
|
@@ -26,12 +28,42 @@ let BankIdSessionService = class BankIdSessionService {
|
|
|
26
28
|
}
|
|
27
29
|
async save(ctx, bankIdData, endUserIp) {
|
|
28
30
|
const sessionToken = await this.getSessionToken(ctx);
|
|
31
|
+
const createdAt = Date.now();
|
|
32
|
+
const expiresAt = createdAt + BANKID_AUTH_SESSION_TTL_MS;
|
|
29
33
|
const data = {
|
|
30
34
|
...(0, lodash_1.pick)(bankIdData, ['orderRef', 'autoStartToken', 'qrStartToken', 'qrStartSecret']),
|
|
31
35
|
endUserIp,
|
|
36
|
+
createdAt,
|
|
37
|
+
expiresAt,
|
|
38
|
+
orderCreatedAt: createdAt,
|
|
32
39
|
};
|
|
33
40
|
const cacheKey = `bankid:${sessionToken}:authExtra`;
|
|
34
|
-
await this.cacheService.set(cacheKey, data, { ttl:
|
|
41
|
+
await this.cacheService.set(cacheKey, data, { ttl: BANKID_AUTH_SESSION_TTL_MS });
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
async updateActiveOrder(ctx, bankIdData) {
|
|
45
|
+
const activeSession = await this.get(ctx);
|
|
46
|
+
if (!activeSession) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const sessionToken = await this.getSessionToken(ctx);
|
|
50
|
+
if (!sessionToken) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
if ((0, utils_1.isBankidSessionExpired)(activeSession.expiresAt)) {
|
|
54
|
+
await this.clear(ctx);
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
const ttlMs = Math.max(0, activeSession.expiresAt - now);
|
|
59
|
+
const updatedSession = {
|
|
60
|
+
...activeSession,
|
|
61
|
+
...(0, lodash_1.pick)(bankIdData, ['orderRef', 'autoStartToken', 'qrStartToken', 'qrStartSecret']),
|
|
62
|
+
orderCreatedAt: now,
|
|
63
|
+
};
|
|
64
|
+
const cacheKey = `bankid:${sessionToken}:authExtra`;
|
|
65
|
+
await this.cacheService.set(cacheKey, updatedSession, { ttl: ttlMs });
|
|
66
|
+
return updatedSession;
|
|
35
67
|
}
|
|
36
68
|
async get(ctx) {
|
|
37
69
|
const sessionToken = await this.getSessionToken(ctx);
|
|
@@ -56,7 +88,7 @@ let BankIdSessionService = class BankIdSessionService {
|
|
|
56
88
|
}
|
|
57
89
|
const encrypted = crypto_js_1.default.AES.encrypt(ssn, ENCRYPTION_KEY).toString();
|
|
58
90
|
const cacheKey = `bankid:${sessionToken}:authUser`;
|
|
59
|
-
await this.cacheService.set(cacheKey, encrypted, { ttl:
|
|
91
|
+
await this.cacheService.set(cacheKey, encrypted, { ttl: AUTH_USER_TTL_MS });
|
|
60
92
|
}
|
|
61
93
|
async getAuthenticatedUser(ctx) {
|
|
62
94
|
const sessionToken = await this.getSessionToken(ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bankid-session.service.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/services/bankid-session.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA2C;AAC3C,wCAA4D;AAE5D,mCAA6B;AAC7B,0DAAgC;
|
|
1
|
+
{"version":3,"file":"bankid-session.service.js","sourceRoot":"","sources":["../../../../../packages/bankid-auth-plugin/src/services/bankid-session.service.ts"],"names":[],"mappings":"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"}
|
package/src/types.d.ts
CHANGED
package/src/utils.d.ts
CHANGED
|
@@ -4,7 +4,14 @@ import { Request } from 'express';
|
|
|
4
4
|
import { InitiateResponse } from './types';
|
|
5
5
|
export declare function handleBankIdError(error: AxiosError | Error): HttpException;
|
|
6
6
|
export declare function getClientIp(req: Request): string;
|
|
7
|
-
export declare function generateQrData(data: InitiateResponse
|
|
7
|
+
export declare function generateQrData(data: (InitiateResponse & {
|
|
8
|
+
orderCreatedAt?: number;
|
|
9
|
+
}) | null): string;
|
|
10
|
+
export declare function getBankidSessionTiming(expiresAtMs: number): {
|
|
11
|
+
expiresAt: string;
|
|
12
|
+
remainingSeconds: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function isBankidSessionExpired(expiresAtMs?: number): boolean;
|
|
8
15
|
export declare class IpMismatchError extends Error {
|
|
9
16
|
expected: string;
|
|
10
17
|
actual: string;
|
package/src/utils.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.IpMismatchError = void 0;
|
|
|
4
4
|
exports.handleBankIdError = handleBankIdError;
|
|
5
5
|
exports.getClientIp = getClientIp;
|
|
6
6
|
exports.generateQrData = generateQrData;
|
|
7
|
+
exports.getBankidSessionTiming = getBankidSessionTiming;
|
|
8
|
+
exports.isBankidSessionExpired = isBankidSessionExpired;
|
|
7
9
|
const common_1 = require("@nestjs/common");
|
|
8
10
|
const core_1 = require("@vendure/core");
|
|
9
11
|
const constants_1 = require("./constants");
|
|
@@ -54,13 +56,21 @@ function generateQrData(data) {
|
|
|
54
56
|
if (!data || !data.qrStartToken || !data.qrStartSecret) {
|
|
55
57
|
throw new Error('BankID data not found');
|
|
56
58
|
}
|
|
57
|
-
const
|
|
58
|
-
const qrTime = Math.floor(Date.now() / 1000
|
|
59
|
+
const orderCreatedAt = data.orderCreatedAt ?? Date.now();
|
|
60
|
+
const qrTime = Math.max(0, Math.floor((Date.now() - orderCreatedAt) / 1000));
|
|
59
61
|
const qrTimeString = qrTime.toString();
|
|
60
62
|
const qrAuthCode = (0, crypto_1.createHmac)('sha256', data.qrStartSecret).update(qrTimeString).digest('hex');
|
|
61
63
|
const qrData = `bankid.${data.qrStartToken}.${qrTimeString}.${qrAuthCode}`;
|
|
62
64
|
return qrData;
|
|
63
65
|
}
|
|
66
|
+
function getBankidSessionTiming(expiresAtMs) {
|
|
67
|
+
const expiresAt = new Date(expiresAtMs).toISOString();
|
|
68
|
+
const remainingSeconds = Math.max(0, Math.ceil((expiresAtMs - Date.now()) / 1000));
|
|
69
|
+
return { expiresAt, remainingSeconds };
|
|
70
|
+
}
|
|
71
|
+
function isBankidSessionExpired(expiresAtMs) {
|
|
72
|
+
return !expiresAtMs || Date.now() >= expiresAtMs;
|
|
73
|
+
}
|
|
64
74
|
class IpMismatchError extends Error {
|
|
65
75
|
expected;
|
|
66
76
|
actual;
|
package/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../packages/bankid-auth-plugin/src/utils.ts"],"names":[],"mappings":";;;AAQA,8CAgCC;AAED,kCAyBC;AAED,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../packages/bankid-auth-plugin/src/utils.ts"],"names":[],"mappings":";;;AAQA,8CAgCC;AAED,kCAyBC;AAED,wCAgBC;AAED,wDAQC;AAED,wDAEC;AAnGD,2CAA0D;AAC1D,wCAAsC;AAEtC,2CAAuC;AAEvC,mCAAmC;AAGnC,SAAgB,iBAAiB,CAAC,KAAyB;IACzD,IAAK,KAAoB,EAAE,YAAY,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,KAAmB,CAAA;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,CAAA;QAEjD,aAAM,CAAC,KAAK,CAAC,iBAAiB,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,qBAAS,CAAC,CAAA;QAE1E,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,OAAO,IAAI,sBAAa,CACtB;gBACE,OAAO,EAAE,4BAA4B;gBACrC,OAAO,EAAE,UAAU,CAAC,QAAQ,EAAE,IAAI;aACnC,EACD,MAAM,KAAK,mBAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,mBAAU,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAC9E,CAAA;QACH,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,sBAAa,CACtB;gBACE,OAAO,EAAE,2BAA2B;aACrC,EACD,MAAM,CACP,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,sBAAa,CACtB;QACE,OAAO,EAAE,kBAAkB;KAC5B,EACD,mBAAU,CAAC,qBAAqB,CACjC,CAAA;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,GAAY;IACtC,+CAA+C;IAC/C,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAW,CAAA;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAW,CAAA;IAClD,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAW,CAAA,CAAC,aAAa;IAE9E,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACpC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACnC,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAA;IAC/C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;AAC1D,CAAC;AAED,SAAgB,cAAc,CAC5B,IAA6D;IAE7D,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAC5E,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;IAEtC,MAAM,UAAU,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE9F,MAAM,MAAM,GAAG,UAAU,IAAI,CAAC,YAAY,IAAI,YAAY,IAAI,UAAU,EAAE,CAAA;IAE1E,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAgB,sBAAsB,CAAC,WAAmB;IAIxD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAA;IACrD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAElF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAA;AACxC,CAAC;AAED,SAAgB,sBAAsB,CAAC,WAAoB;IACzD,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,WAAW,CAAA;AAClD,CAAC;AAED,MAAa,eAAgB,SAAQ,KAAK;IAE/B;IACA;IAFT,YACS,QAAgB,EAChB,MAAc;QAErB,KAAK,CAAC,yBAAyB,QAAQ,SAAS,MAAM,EAAE,CAAC,CAAA;QAHlD,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAQ;QAGrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAA;IACxD,CAAC;CACF;AAXD,0CAWC"}
|