@decaf-ts/integrations 0.3.12 → 0.4.1-0
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/README.md +11 -3
- package/dist/integrations.cjs +445 -7
- package/dist/integrations.js +479 -8
- package/jest.config.cjs +1 -1
- package/lib/cjs/feature-flags/constants.cjs +16 -0
- package/lib/cjs/feature-flags/decorators.cjs +65 -0
- package/lib/cjs/feature-flags/environment.cjs +26 -0
- package/lib/cjs/feature-flags/index.cjs +31 -0
- package/lib/cjs/feature-flags/models/FeatureFlag.model.cjs +81 -0
- package/lib/cjs/feature-flags/models/FeatureFlagAccess.model.cjs +78 -0
- package/lib/cjs/feature-flags/readers/FeatureFlagReader.cjs +25 -0
- package/lib/cjs/feature-flags/readers/index.cjs +19 -0
- package/lib/cjs/feature-flags/services/FeatureFlag.service.cjs +259 -0
- package/lib/cjs/feature-flags/types.cjs +4 -0
- package/lib/cjs/feature-flags/utils.cjs +141 -0
- package/lib/cjs/graph/engine/execution/SwitchGraphNodeExecutor.cjs +9 -9
- package/lib/cjs/graph/shared/nodes/flow-control.cjs +4 -3
- package/lib/cjs/graph/shared/types.cjs +2 -2
- package/lib/cjs/index.cjs +6 -5
- package/lib/cjs/kibana/builders/KibanaIndexBuilder.cjs +329 -0
- package/lib/cjs/kibana/builders/KibanaIndexBuilderCollection.cjs +37 -0
- package/lib/cjs/kibana/builders/index.cjs +20 -0
- package/lib/cjs/kibana/helpers.cjs +20 -16
- package/lib/cjs/kibana/index.cjs +3 -2
- package/lib/cjs/kibana/types.cjs +11 -2
- package/lib/cjs/loader/ObjectLoader.cjs +154 -0
- package/lib/cjs/loader/families.cjs +78 -0
- package/lib/cjs/loader/index.cjs +28 -0
- package/lib/cjs/loader/types.cjs +4 -0
- package/lib/cjs/nest/decorators.cjs +17 -0
- package/lib/cjs/nest/index.cjs +3 -3
- package/lib/cjs/nest/keycloakAuthHandler.cjs +74 -35
- package/lib/cjs/nest/keycloakModule.cjs +7 -10
- package/lib/cjs/nest/types.cjs +2 -2
- package/lib/cjs/nest/utils.cjs +58 -50
- package/lib/cjs/plugins/contract.cjs +76 -0
- package/lib/cjs/plugins/index.cjs +35 -0
- package/lib/cjs/plugins/kibana/host.cjs +24 -0
- package/lib/cjs/plugins/kibana/index.cjs +38 -0
- package/lib/cjs/plugins/kibana/installer.cjs +180 -0
- package/lib/cjs/plugins/kibana/manifest.cjs +33 -0
- package/lib/cjs/plugins/kibana/templates.cjs +503 -0
- package/lib/cjs/plugins/kibana/types.cjs +33 -0
- package/lib/cjs/plugins/superset/host.cjs +26 -0
- package/lib/cjs/plugins/superset/index.cjs +40 -0
- package/lib/cjs/plugins/superset/installer.cjs +232 -0
- package/lib/cjs/plugins/superset/manifest.cjs +35 -0
- package/lib/cjs/plugins/superset/templates.cjs +844 -0
- package/lib/cjs/plugins/superset/types.cjs +39 -0
- package/lib/esm/feature-flags/constants.js +12 -0
- package/lib/esm/feature-flags/decorators.js +49 -0
- package/lib/esm/feature-flags/environment.js +18 -0
- package/lib/esm/feature-flags/index.js +14 -0
- package/lib/esm/feature-flags/models/FeatureFlag.model.js +72 -0
- package/lib/esm/feature-flags/models/FeatureFlagAccess.model.js +69 -0
- package/lib/esm/feature-flags/readers/FeatureFlagReader.js +19 -0
- package/lib/esm/feature-flags/readers/index.js +2 -0
- package/lib/esm/feature-flags/services/FeatureFlag.service.js +250 -0
- package/lib/esm/feature-flags/types.js +2 -0
- package/lib/esm/feature-flags/utils.js +126 -0
- package/lib/esm/graph/engine/execution/SwitchGraphNodeExecutor.js +8 -8
- package/lib/esm/graph/shared/nodes/flow-control.js +3 -2
- package/lib/esm/graph/shared/types.js +1 -1
- package/lib/esm/index.js +5 -4
- package/lib/esm/kibana/builders/KibanaIndexBuilder.js +319 -0
- package/lib/esm/kibana/builders/KibanaIndexBuilderCollection.js +32 -0
- package/lib/esm/kibana/builders/index.js +3 -0
- package/lib/esm/kibana/helpers.js +19 -15
- package/lib/esm/kibana/index.js +2 -1
- package/lib/esm/kibana/types.js +13 -2
- package/lib/esm/loader/ObjectLoader.js +115 -0
- package/lib/esm/loader/families.js +66 -0
- package/lib/esm/loader/index.js +11 -0
- package/lib/esm/loader/types.js +2 -0
- package/lib/esm/nest/decorators.js +12 -0
- package/lib/esm/nest/index.js +2 -2
- package/lib/esm/nest/keycloakAuthHandler.js +67 -35
- package/lib/esm/nest/keycloakModule.js +7 -10
- package/lib/esm/nest/types.js +1 -1
- package/lib/esm/nest/utils.js +55 -46
- package/lib/esm/plugins/contract.js +68 -0
- package/lib/esm/plugins/index.js +18 -0
- package/lib/esm/plugins/kibana/host.js +19 -0
- package/lib/esm/plugins/kibana/index.js +14 -0
- package/lib/esm/plugins/kibana/installer.js +140 -0
- package/lib/esm/plugins/kibana/manifest.js +32 -0
- package/lib/esm/plugins/kibana/templates.js +499 -0
- package/lib/esm/plugins/kibana/types.js +10 -0
- package/lib/esm/plugins/superset/host.js +21 -0
- package/lib/esm/plugins/superset/index.js +16 -0
- package/lib/esm/plugins/superset/installer.js +192 -0
- package/lib/esm/plugins/superset/manifest.js +30 -0
- package/lib/esm/plugins/superset/templates.js +840 -0
- package/lib/esm/plugins/superset/types.js +11 -0
- package/lib/types/feature-flags/constants.d.cts +11 -0
- package/lib/types/feature-flags/constants.d.mts +11 -0
- package/lib/types/feature-flags/decorators.d.cts +11 -0
- package/lib/types/feature-flags/decorators.d.mts +11 -0
- package/lib/types/feature-flags/environment.d.cts +11 -0
- package/lib/types/feature-flags/environment.d.mts +11 -0
- package/lib/types/feature-flags/index.d.cts +13 -0
- package/lib/types/feature-flags/index.d.mts +13 -0
- package/lib/types/feature-flags/models/FeatureFlag.model.d.cts +16 -0
- package/lib/types/feature-flags/models/FeatureFlag.model.d.mts +16 -0
- package/lib/types/feature-flags/models/FeatureFlagAccess.model.d.cts +15 -0
- package/lib/types/feature-flags/models/FeatureFlagAccess.model.d.mts +15 -0
- package/lib/types/feature-flags/readers/FeatureFlagReader.d.cts +10 -0
- package/lib/types/feature-flags/readers/FeatureFlagReader.d.mts +10 -0
- package/lib/types/feature-flags/readers/index.d.cts +1 -0
- package/lib/types/feature-flags/readers/index.d.mts +1 -0
- package/lib/types/feature-flags/services/FeatureFlag.service.d.cts +43 -0
- package/lib/types/feature-flags/services/FeatureFlag.service.d.mts +43 -0
- package/lib/types/feature-flags/types.d.cts +39 -0
- package/lib/types/feature-flags/types.d.mts +39 -0
- package/lib/types/feature-flags/utils.d.cts +13 -0
- package/lib/types/feature-flags/utils.d.mts +13 -0
- package/lib/types/graph/engine/execution/SwitchGraphNodeExecutor.d.cts +2 -2
- package/lib/types/graph/engine/execution/SwitchGraphNodeExecutor.d.mts +2 -2
- package/lib/types/graph/shared/types.d.cts +3 -3
- package/lib/types/graph/shared/types.d.mts +3 -3
- package/lib/types/index.d.cts +3 -2
- package/lib/types/index.d.mts +3 -2
- package/lib/types/kibana/builders/KibanaIndexBuilder.d.cts +67 -0
- package/lib/types/kibana/builders/KibanaIndexBuilder.d.mts +67 -0
- package/lib/types/kibana/builders/KibanaIndexBuilderCollection.d.cts +17 -0
- package/lib/types/kibana/builders/KibanaIndexBuilderCollection.d.mts +17 -0
- package/lib/types/kibana/builders/index.d.cts +2 -0
- package/lib/types/kibana/builders/index.d.mts +2 -0
- package/lib/types/kibana/index.d.cts +1 -0
- package/lib/types/kibana/index.d.mts +1 -0
- package/lib/types/kibana/types.d.cts +11 -0
- package/lib/types/kibana/types.d.mts +11 -0
- package/lib/types/loader/ObjectLoader.d.cts +27 -0
- package/lib/types/loader/ObjectLoader.d.mts +27 -0
- package/lib/types/loader/families.d.cts +34 -0
- package/lib/types/loader/families.d.mts +34 -0
- package/lib/types/loader/index.d.cts +10 -0
- package/lib/types/loader/index.d.mts +10 -0
- package/lib/types/loader/types.d.cts +24 -0
- package/lib/types/loader/types.d.mts +24 -0
- package/lib/types/nest/decorators.d.cts +8 -0
- package/lib/types/nest/decorators.d.mts +8 -0
- package/lib/types/nest/index.d.cts +1 -1
- package/lib/types/nest/index.d.mts +1 -1
- package/lib/types/nest/keycloakAuthHandler.d.cts +19 -42
- package/lib/types/nest/keycloakAuthHandler.d.mts +19 -42
- package/lib/types/nest/keycloakModule.d.cts +3 -5
- package/lib/types/nest/keycloakModule.d.mts +3 -5
- package/lib/types/nest/types.d.cts +2 -0
- package/lib/types/nest/types.d.mts +2 -0
- package/lib/types/nest/utils.d.cts +3 -4
- package/lib/types/nest/utils.d.mts +3 -4
- package/lib/types/plugins/contract.d.cts +180 -0
- package/lib/types/plugins/contract.d.mts +180 -0
- package/lib/types/plugins/index.d.cts +17 -0
- package/lib/types/plugins/index.d.mts +17 -0
- package/lib/types/plugins/kibana/host.d.cts +18 -0
- package/lib/types/plugins/kibana/host.d.mts +18 -0
- package/lib/types/plugins/kibana/index.d.cts +13 -0
- package/lib/types/plugins/kibana/index.d.mts +13 -0
- package/lib/types/plugins/kibana/installer.d.cts +45 -0
- package/lib/types/plugins/kibana/installer.d.mts +45 -0
- package/lib/types/plugins/kibana/manifest.d.cts +31 -0
- package/lib/types/plugins/kibana/manifest.d.mts +31 -0
- package/lib/types/plugins/kibana/templates.d.cts +12 -0
- package/lib/types/plugins/kibana/templates.d.mts +12 -0
- package/lib/types/plugins/kibana/types.d.cts +9 -0
- package/lib/types/plugins/kibana/types.d.mts +9 -0
- package/lib/types/plugins/superset/host.d.cts +20 -0
- package/lib/types/plugins/superset/host.d.mts +20 -0
- package/lib/types/plugins/superset/index.d.cts +15 -0
- package/lib/types/plugins/superset/index.d.mts +15 -0
- package/lib/types/plugins/superset/installer.d.cts +70 -0
- package/lib/types/plugins/superset/installer.d.mts +70 -0
- package/lib/types/plugins/superset/manifest.d.cts +28 -0
- package/lib/types/plugins/superset/manifest.d.mts +28 -0
- package/lib/types/plugins/superset/templates.d.cts +12 -0
- package/lib/types/plugins/superset/templates.d.mts +12 -0
- package/lib/types/plugins/superset/types.d.cts +10 -0
- package/lib/types/plugins/superset/types.d.mts +10 -0
- package/package.json +62 -3
- package/plugins/kibana/.gitignore +16 -0
- package/plugins/kibana/Dockerfile +19 -0
- package/plugins/kibana/docker-compose.yml +50 -0
- package/plugins/kibana/host/index.html +101 -0
- package/plugins/kibana/setup-dashboards.sh +84 -0
- package/plugins/superset/.gitignore +17 -0
- package/plugins/superset/Dockerfile +79 -0
- package/plugins/superset/docker-compose.yml +62 -0
- package/plugins/superset/host/index.html +168 -0
- package/plugins/superset/setup-dashboards.sh +106 -0
- package/plugins/superset/superset_config.py +49 -0
- package/lib/cjs/nest/authService.cjs +0 -91
- package/lib/esm/nest/authService.js +0 -86
- package/lib/types/nest/authService.d.cts +0 -63
- package/lib/types/nest/authService.d.mts +0 -63
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AuthService = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* @module integrations/nest/authService
|
|
6
|
-
* @summary Nest-compatible authentication service helpers.
|
|
7
|
-
* @description Request-context-aware auth helpers for Nest applications using Decaf integration patterns.
|
|
8
|
-
*
|
|
9
|
-
* Supports two modes:
|
|
10
|
-
* - **Verify mode** (default when `verifyUrl` is set): validates the JWT signature
|
|
11
|
-
* against the Keycloak JWKS endpoint using `jose.jwtVerify`.
|
|
12
|
-
* - **Decode-only mode** (when `verifyToken` is false / `verifyUrl` is empty):
|
|
13
|
-
* decodes the JWT without signature verification (dev/local mode).
|
|
14
|
-
*/
|
|
15
|
-
const core_1 = require("@decaf-ts/core");
|
|
16
|
-
const jose_1 = require("jose");
|
|
17
|
-
const utils_js_1 = require("./utils.cjs");
|
|
18
|
-
class AuthService {
|
|
19
|
-
constructor(options = {}) {
|
|
20
|
-
this.verifyToken = !!options.verifyToken && !!options.verifyUrl;
|
|
21
|
-
this.verifyUrl = options.verifyUrl ?? "";
|
|
22
|
-
this.clockToleranceSeconds = options.clockToleranceSeconds ?? 5;
|
|
23
|
-
this.excludedClients = options.excludedClients ?? ["account"];
|
|
24
|
-
}
|
|
25
|
-
isTokenVerificationEnabled() {
|
|
26
|
-
return this.verifyToken;
|
|
27
|
-
}
|
|
28
|
-
getTokenPayload(jwt) {
|
|
29
|
-
return (0, utils_js_1.getTokenPayload)(jwt);
|
|
30
|
-
}
|
|
31
|
-
getRoles(jwt) {
|
|
32
|
-
return this.extractKeycloakRoles(this.getTokenPayload(jwt));
|
|
33
|
-
}
|
|
34
|
-
getUser(jwt) {
|
|
35
|
-
return (0, utils_js_1.getUser)(jwt);
|
|
36
|
-
}
|
|
37
|
-
extractKeycloakRoles(payload) {
|
|
38
|
-
return (0, utils_js_1.extractKeycloakRoles)(payload);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Extracts client roles from the `resource_access` claim, excluding
|
|
42
|
-
* the configured `excludedClients` (default: `["account"]`).
|
|
43
|
-
*/
|
|
44
|
-
extractClientRoles(payload) {
|
|
45
|
-
return (0, utils_js_1.getClientRoles)(payload, this.excludedClients);
|
|
46
|
-
}
|
|
47
|
-
getRealmFromIssuer(jwt) {
|
|
48
|
-
return (0, utils_js_1.getRealmFromIssuer)(jwt);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Validates a JWT:
|
|
52
|
-
* - In **verify mode**: verifies the signature against the Keycloak JWKS
|
|
53
|
-
* endpoint using `jose.jwtVerify`, then returns the verified payload.
|
|
54
|
-
* - In **decode-only mode**: decodes the JWT without verification and
|
|
55
|
-
* returns the payload (or throws if unparseable).
|
|
56
|
-
*
|
|
57
|
-
* @throws {AuthorizationError} when the token is invalid, expired, or
|
|
58
|
-
* signature verification fails.
|
|
59
|
-
*/
|
|
60
|
-
async assertValidToken(jwt) {
|
|
61
|
-
if (this.verifyToken) {
|
|
62
|
-
return this.verifyAgainstJwks(jwt);
|
|
63
|
-
}
|
|
64
|
-
const payload = this.getTokenPayload(jwt);
|
|
65
|
-
if (!payload) {
|
|
66
|
-
throw new core_1.AuthorizationError("Invalid token");
|
|
67
|
-
}
|
|
68
|
-
return payload;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Verifies the JWT signature against the Keycloak JWKS endpoint.
|
|
72
|
-
* Lazily creates the JWKS keystore on first call.
|
|
73
|
-
*/
|
|
74
|
-
async verifyAgainstJwks(jwt) {
|
|
75
|
-
if (!this.jwks) {
|
|
76
|
-
this.jwks = (0, jose_1.createRemoteJWKSet)(new URL(this.verifyUrl));
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
const { payload } = await (0, jose_1.jwtVerify)(jwt, this.jwks, {
|
|
80
|
-
clockTolerance: `${this.clockToleranceSeconds}s`,
|
|
81
|
-
});
|
|
82
|
-
return payload;
|
|
83
|
-
}
|
|
84
|
-
catch (e) {
|
|
85
|
-
throw new core_1.AuthorizationError("Invalid token: " + (e?.message ?? e));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
exports.AuthService = AuthService;
|
|
90
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aFNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbmVzdC9hdXRoU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBQ0gsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsT0FBTyxFQUNQLGNBQWMsR0FDZixtQkFBZ0I7QUErQmpCLE1BQU0sT0FBTyxXQUFXO0lBT3RCLFlBQVksVUFBOEIsRUFBRTtRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELDBCQUEwQjtRQUN4QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVELGVBQWUsQ0FBQyxHQUFXO1FBQ3pCLE9BQU8sZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxRQUFRLENBQUMsR0FBVztRQUNsQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFXO1FBQ2pCLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxPQUEwQztRQUM3RCxPQUFPLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0IsQ0FDaEIsT0FBMEM7UUFFMUMsT0FBTyxjQUFjLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsR0FBVztRQUM1QixPQUFPLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLEdBQVc7UUFFWCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksa0JBQWtCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7O09BR0c7SUFDSyxLQUFLLENBQUMsaUJBQWlCLENBQzdCLEdBQVc7UUFFWCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNsRCxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMscUJBQXFCLEdBQUc7YUFDakQsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxPQUFnRCxDQUFDO1FBQzFELENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUMsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIGludGVncmF0aW9ucy9uZXN0L2F1dGhTZXJ2aWNlXG4gKiBAc3VtbWFyeSBOZXN0LWNvbXBhdGlibGUgYXV0aGVudGljYXRpb24gc2VydmljZSBoZWxwZXJzLlxuICogQGRlc2NyaXB0aW9uIFJlcXVlc3QtY29udGV4dC1hd2FyZSBhdXRoIGhlbHBlcnMgZm9yIE5lc3QgYXBwbGljYXRpb25zIHVzaW5nIERlY2FmIGludGVncmF0aW9uIHBhdHRlcm5zLlxuICpcbiAqIFN1cHBvcnRzIHR3byBtb2RlczpcbiAqIC0gKipWZXJpZnkgbW9kZSoqIChkZWZhdWx0IHdoZW4gYHZlcmlmeVVybGAgaXMgc2V0KTogdmFsaWRhdGVzIHRoZSBKV1Qgc2lnbmF0dXJlXG4gKiAgIGFnYWluc3QgdGhlIEtleWNsb2FrIEpXS1MgZW5kcG9pbnQgdXNpbmcgYGpvc2Uuand0VmVyaWZ5YC5cbiAqIC0gKipEZWNvZGUtb25seSBtb2RlKiogKHdoZW4gYHZlcmlmeVRva2VuYCBpcyBmYWxzZSAvIGB2ZXJpZnlVcmxgIGlzIGVtcHR5KTpcbiAqICAgZGVjb2RlcyB0aGUgSldUIHdpdGhvdXQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiAoZGV2L2xvY2FsIG1vZGUpLlxuICovXG5pbXBvcnQgeyBBdXRob3JpemF0aW9uRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IGNyZWF0ZVJlbW90ZUpXS1NldCwgand0VmVyaWZ5IH0gZnJvbSBcImpvc2VcIjtcbmltcG9ydCB7XG4gIGV4dHJhY3RLZXljbG9ha1JvbGVzLFxuICBnZXRSZWFsbUZyb21Jc3N1ZXIsXG4gIGdldFRva2VuUGF5bG9hZCxcbiAgZ2V0VXNlcixcbiAgZ2V0Q2xpZW50Um9sZXMsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgdHlwZSB7IEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkLCBLZXljbG9ha1VzZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSB7QGxpbmsgQXV0aFNlcnZpY2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhTZXJ2aWNlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHZlcmlmeSB0aGUgSldUIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBLZXljbG9hayBKV0tTIGVuZHBvaW50LlxuICAgKiBXaGVuIGBmYWxzZWAgKG9yIGB2ZXJpZnlVcmxgIGlzIGVtcHR5KSwgdG9rZW5zIGFyZSBkZWNvZGVkIHdpdGhvdXRcbiAgICogc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiAoZGV2L2xvY2FsIG1vZGUgb25seSkuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICB2ZXJpZnlUb2tlbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUaGUgS2V5Y2xvYWsgSldLUyBVUkwgKGUuZy4gYGh0dHBzOi8va2V5Y2xvYWsvcmVhbG1zL215cmVhbG0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvY2VydHNgKS5cbiAgICogUmVxdWlyZWQgd2hlbiBgdmVyaWZ5VG9rZW5gIGlzIGB0cnVlYC5cbiAgICovXG4gIHZlcmlmeVVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIENsb2NrIHRvbGVyYW5jZSBmb3IgSldUIGV4cGlyeSB2ZXJpZmljYXRpb24gKGluIHNlY29uZHMpLlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICBjbG9ja1RvbGVyYW5jZVNlY29uZHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBLZXljbG9hayBjbGllbnQgSURzIHRvIGV4Y2x1ZGUgd2hlbiBleHRyYWN0aW5nIHJvbGVzIGZyb20gYHJlc291cmNlX2FjY2Vzc2AuXG4gICAqIEBkZWZhdWx0IFtcImFjY291bnRcIl1cbiAgICovXG4gIGV4Y2x1ZGVkQ2xpZW50cz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcmlmeVRva2VuOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcmlmeVVybDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsb2NrVG9sZXJhbmNlU2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGV4Y2x1ZGVkQ2xpZW50czogc3RyaW5nW107XG4gIHByaXZhdGUgandrczogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlUmVtb3RlSldLU2V0PiB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBBdXRoU2VydmljZU9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMudmVyaWZ5VG9rZW4gPSAhIW9wdGlvbnMudmVyaWZ5VG9rZW4gJiYgISFvcHRpb25zLnZlcmlmeVVybDtcbiAgICB0aGlzLnZlcmlmeVVybCA9IG9wdGlvbnMudmVyaWZ5VXJsID8/IFwiXCI7XG4gICAgdGhpcy5jbG9ja1RvbGVyYW5jZVNlY29uZHMgPSBvcHRpb25zLmNsb2NrVG9sZXJhbmNlU2Vjb25kcyA/PyA1O1xuICAgIHRoaXMuZXhjbHVkZWRDbGllbnRzID0gb3B0aW9ucy5leGNsdWRlZENsaWVudHMgPz8gW1wiYWNjb3VudFwiXTtcbiAgfVxuXG4gIGlzVG9rZW5WZXJpZmljYXRpb25FbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZlcmlmeVRva2VuO1xuICB9XG5cbiAgZ2V0VG9rZW5QYXlsb2FkKGp3dDogc3RyaW5nKTogS2V5Y2xvYWtBY2Nlc3NUb2tlblBheWxvYWQgfCBudWxsIHtcbiAgICByZXR1cm4gZ2V0VG9rZW5QYXlsb2FkKGp3dCk7XG4gIH1cblxuICBnZXRSb2xlcyhqd3Q6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5leHRyYWN0S2V5Y2xvYWtSb2xlcyh0aGlzLmdldFRva2VuUGF5bG9hZChqd3QpKTtcbiAgfVxuXG4gIGdldFVzZXIoand0OiBzdHJpbmcpOiBLZXljbG9ha1VzZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBnZXRVc2VyKGp3dCk7XG4gIH1cblxuICBleHRyYWN0S2V5Y2xvYWtSb2xlcyhwYXlsb2FkOiBLZXljbG9ha0FjY2Vzc1Rva2VuUGF5bG9hZCB8IG51bGwpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIGV4dHJhY3RLZXljbG9ha1JvbGVzKHBheWxvYWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIGNsaWVudCByb2xlcyBmcm9tIHRoZSBgcmVzb3VyY2VfYWNjZXNzYCBjbGFpbSwgZXhjbHVkaW5nXG4gICAqIHRoZSBjb25maWd1cmVkIGBleGNsdWRlZENsaWVudHNgIChkZWZhdWx0OiBgW1wiYWNjb3VudFwiXWApLlxuICAgKi9cbiAgZXh0cmFjdENsaWVudFJvbGVzKFxuICAgIHBheWxvYWQ6IEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkIHwgbnVsbFxuICApOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIGdldENsaWVudFJvbGVzKHBheWxvYWQsIHRoaXMuZXhjbHVkZWRDbGllbnRzKTtcbiAgfVxuXG4gIGdldFJlYWxtRnJvbUlzc3Vlcihqd3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdldFJlYWxtRnJvbUlzc3Vlcihqd3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIEpXVDpcbiAgICogLSBJbiAqKnZlcmlmeSBtb2RlKio6IHZlcmlmaWVzIHRoZSBzaWduYXR1cmUgYWdhaW5zdCB0aGUgS2V5Y2xvYWsgSldLU1xuICAgKiAgIGVuZHBvaW50IHVzaW5nIGBqb3NlLmp3dFZlcmlmeWAsIHRoZW4gcmV0dXJucyB0aGUgdmVyaWZpZWQgcGF5bG9hZC5cbiAgICogLSBJbiAqKmRlY29kZS1vbmx5IG1vZGUqKjogZGVjb2RlcyB0aGUgSldUIHdpdGhvdXQgdmVyaWZpY2F0aW9uIGFuZFxuICAgKiAgIHJldHVybnMgdGhlIHBheWxvYWQgKG9yIHRocm93cyBpZiB1bnBhcnNlYWJsZSkuXG4gICAqXG4gICAqIEB0aHJvd3Mge0F1dGhvcml6YXRpb25FcnJvcn0gd2hlbiB0aGUgdG9rZW4gaXMgaW52YWxpZCwgZXhwaXJlZCwgb3JcbiAgICogICBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxzLlxuICAgKi9cbiAgYXN5bmMgYXNzZXJ0VmFsaWRUb2tlbihcbiAgICBqd3Q6IHN0cmluZ1xuICApOiBQcm9taXNlPEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkPiB7XG4gICAgaWYgKHRoaXMudmVyaWZ5VG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLnZlcmlmeUFnYWluc3RKd2tzKGp3dCk7XG4gICAgfVxuICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmdldFRva2VuUGF5bG9hZChqd3QpO1xuICAgIGlmICghcGF5bG9hZCkge1xuICAgICAgdGhyb3cgbmV3IEF1dGhvcml6YXRpb25FcnJvcihcIkludmFsaWQgdG9rZW5cIik7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoZSBKV1Qgc2lnbmF0dXJlIGFnYWluc3QgdGhlIEtleWNsb2FrIEpXS1MgZW5kcG9pbnQuXG4gICAqIExhemlseSBjcmVhdGVzIHRoZSBKV0tTIGtleXN0b3JlIG9uIGZpcnN0IGNhbGwuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHZlcmlmeUFnYWluc3RKd2tzKFxuICAgIGp3dDogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2xvYWtBY2Nlc3NUb2tlblBheWxvYWQ+IHtcbiAgICBpZiAoIXRoaXMuandrcykge1xuICAgICAgdGhpcy5qd2tzID0gY3JlYXRlUmVtb3RlSldLU2V0KG5ldyBVUkwodGhpcy52ZXJpZnlVcmwpKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgand0VmVyaWZ5KGp3dCwgdGhpcy5qd2tzLCB7XG4gICAgICAgIGNsb2NrVG9sZXJhbmNlOiBgJHt0aGlzLmNsb2NrVG9sZXJhbmNlU2Vjb25kc31zYCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHBheWxvYWQgYXMgdW5rbm93biBhcyBLZXljbG9ha0FjY2Vzc1Rva2VuUGF5bG9hZDtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoXCJJbnZhbGlkIHRva2VuOiBcIiArIChlPy5tZXNzYWdlID8/IGUpKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
91
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aFNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhdXRoU2VydmljZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7OztHQVVHO0FBQ0gseUNBQW9EO0FBQ3BELCtCQUFxRDtBQUNyRCx5Q0FBaUg7QUFDakgsTUFBYSxXQUFXO0lBQ3BCLFlBQVksT0FBTyxHQUFHLEVBQUU7UUFDcEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztRQUNoRSxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLENBQUMscUJBQXFCLElBQUksQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFDRCwwQkFBMEI7UUFDdEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzVCLENBQUM7SUFDRCxlQUFlLENBQUMsR0FBRztRQUNmLE9BQU8sSUFBQSwwQkFBZSxFQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFDRCxRQUFRLENBQUMsR0FBRztRQUNSLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUc7UUFDUCxPQUFPLElBQUEsa0JBQU8sRUFBQyxHQUFHLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBQ0Qsb0JBQW9CLENBQUMsT0FBTztRQUN4QixPQUFPLElBQUEsK0JBQW9CLEVBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUNEOzs7T0FHRztJQUNILGtCQUFrQixDQUFDLE9BQU87UUFDdEIsT0FBTyxJQUFBLHlCQUFjLEVBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0Qsa0JBQWtCLENBQUMsR0FBRztRQUNsQixPQUFPLElBQUEsNkJBQWtCLEVBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUNEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHO1FBQ3RCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ25CLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSx5QkFBa0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQztJQUNEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUEseUJBQWtCLEVBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDNUQsQ0FBQztRQUNELElBQUksQ0FBQztZQUNELE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxNQUFNLElBQUEsZ0JBQVMsRUFBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDaEQsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixHQUFHO2FBQ25ELENBQUMsQ0FBQztZQUNILE9BQU8sT0FBTyxDQUFDO1FBQ25CLENBQUM7UUFDRCxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1AsTUFBTSxJQUFJLHlCQUFrQixDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUF0RUQsa0NBc0VDO0FBQ0QsMHNSQUEwc1IiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgaW50ZWdyYXRpb25zL25lc3QvYXV0aFNlcnZpY2VcbiAqIEBzdW1tYXJ5IE5lc3QtY29tcGF0aWJsZSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlIGhlbHBlcnMuXG4gKiBAZGVzY3JpcHRpb24gUmVxdWVzdC1jb250ZXh0LWF3YXJlIGF1dGggaGVscGVycyBmb3IgTmVzdCBhcHBsaWNhdGlvbnMgdXNpbmcgRGVjYWYgaW50ZWdyYXRpb24gcGF0dGVybnMuXG4gKlxuICogU3VwcG9ydHMgdHdvIG1vZGVzOlxuICogLSAqKlZlcmlmeSBtb2RlKiogKGRlZmF1bHQgd2hlbiBgdmVyaWZ5VXJsYCBpcyBzZXQpOiB2YWxpZGF0ZXMgdGhlIEpXVCBzaWduYXR1cmVcbiAqICAgYWdhaW5zdCB0aGUgS2V5Y2xvYWsgSldLUyBlbmRwb2ludCB1c2luZyBgam9zZS5qd3RWZXJpZnlgLlxuICogLSAqKkRlY29kZS1vbmx5IG1vZGUqKiAod2hlbiBgdmVyaWZ5VG9rZW5gIGlzIGZhbHNlIC8gYHZlcmlmeVVybGAgaXMgZW1wdHkpOlxuICogICBkZWNvZGVzIHRoZSBKV1Qgd2l0aG91dCBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIChkZXYvbG9jYWwgbW9kZSkuXG4gKi9cbmltcG9ydCB7IEF1dGhvcml6YXRpb25FcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgY3JlYXRlUmVtb3RlSldLU2V0LCBqd3RWZXJpZnkgfSBmcm9tIFwiam9zZVwiO1xuaW1wb3J0IHsgZXh0cmFjdEtleWNsb2FrUm9sZXMsIGdldFJlYWxtRnJvbUlzc3VlciwgZ2V0VG9rZW5QYXlsb2FkLCBnZXRVc2VyLCBnZXRDbGllbnRSb2xlcywgfSBmcm9tIFwiLi91dGlscy5qc1wiO1xuZXhwb3J0IGNsYXNzIEF1dGhTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgdGhpcy52ZXJpZnlUb2tlbiA9ICEhb3B0aW9ucy52ZXJpZnlUb2tlbiAmJiAhIW9wdGlvbnMudmVyaWZ5VXJsO1xuICAgICAgICB0aGlzLnZlcmlmeVVybCA9IG9wdGlvbnMudmVyaWZ5VXJsID8/IFwiXCI7XG4gICAgICAgIHRoaXMuY2xvY2tUb2xlcmFuY2VTZWNvbmRzID0gb3B0aW9ucy5jbG9ja1RvbGVyYW5jZVNlY29uZHMgPz8gNTtcbiAgICAgICAgdGhpcy5leGNsdWRlZENsaWVudHMgPSBvcHRpb25zLmV4Y2x1ZGVkQ2xpZW50cyA/PyBbXCJhY2NvdW50XCJdO1xuICAgIH1cbiAgICBpc1Rva2VuVmVyaWZpY2F0aW9uRW5hYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5VG9rZW47XG4gICAgfVxuICAgIGdldFRva2VuUGF5bG9hZChqd3QpIHtcbiAgICAgICAgcmV0dXJuIGdldFRva2VuUGF5bG9hZChqd3QpO1xuICAgIH1cbiAgICBnZXRSb2xlcyhqd3QpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXh0cmFjdEtleWNsb2FrUm9sZXModGhpcy5nZXRUb2tlblBheWxvYWQoand0KSk7XG4gICAgfVxuICAgIGdldFVzZXIoand0KSB7XG4gICAgICAgIHJldHVybiBnZXRVc2VyKGp3dCk7XG4gICAgfVxuICAgIGV4dHJhY3RLZXljbG9ha1JvbGVzKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIGV4dHJhY3RLZXljbG9ha1JvbGVzKHBheWxvYWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyBjbGllbnQgcm9sZXMgZnJvbSB0aGUgYHJlc291cmNlX2FjY2Vzc2AgY2xhaW0sIGV4Y2x1ZGluZ1xuICAgICAqIHRoZSBjb25maWd1cmVkIGBleGNsdWRlZENsaWVudHNgIChkZWZhdWx0OiBgW1wiYWNjb3VudFwiXWApLlxuICAgICAqL1xuICAgIGV4dHJhY3RDbGllbnRSb2xlcyhwYXlsb2FkKSB7XG4gICAgICAgIHJldHVybiBnZXRDbGllbnRSb2xlcyhwYXlsb2FkLCB0aGlzLmV4Y2x1ZGVkQ2xpZW50cyk7XG4gICAgfVxuICAgIGdldFJlYWxtRnJvbUlzc3Vlcihqd3QpIHtcbiAgICAgICAgcmV0dXJuIGdldFJlYWxtRnJvbUlzc3Vlcihqd3QpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZXMgYSBKV1Q6XG4gICAgICogLSBJbiAqKnZlcmlmeSBtb2RlKio6IHZlcmlmaWVzIHRoZSBzaWduYXR1cmUgYWdhaW5zdCB0aGUgS2V5Y2xvYWsgSldLU1xuICAgICAqICAgZW5kcG9pbnQgdXNpbmcgYGpvc2Uuand0VmVyaWZ5YCwgdGhlbiByZXR1cm5zIHRoZSB2ZXJpZmllZCBwYXlsb2FkLlxuICAgICAqIC0gSW4gKipkZWNvZGUtb25seSBtb2RlKio6IGRlY29kZXMgdGhlIEpXVCB3aXRob3V0IHZlcmlmaWNhdGlvbiBhbmRcbiAgICAgKiAgIHJldHVybnMgdGhlIHBheWxvYWQgKG9yIHRocm93cyBpZiB1bnBhcnNlYWJsZSkuXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtBdXRob3JpemF0aW9uRXJyb3J9IHdoZW4gdGhlIHRva2VuIGlzIGludmFsaWQsIGV4cGlyZWQsIG9yXG4gICAgICogICBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxzLlxuICAgICAqL1xuICAgIGFzeW5jIGFzc2VydFZhbGlkVG9rZW4oand0KSB7XG4gICAgICAgIGlmICh0aGlzLnZlcmlmeVRva2VuKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52ZXJpZnlBZ2FpbnN0Sndrcyhqd3QpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmdldFRva2VuUGF5bG9hZChqd3QpO1xuICAgICAgICBpZiAoIXBheWxvYWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoXCJJbnZhbGlkIHRva2VuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyB0aGUgSldUIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBLZXljbG9hayBKV0tTIGVuZHBvaW50LlxuICAgICAqIExhemlseSBjcmVhdGVzIHRoZSBKV0tTIGtleXN0b3JlIG9uIGZpcnN0IGNhbGwuXG4gICAgICovXG4gICAgYXN5bmMgdmVyaWZ5QWdhaW5zdEp3a3Moand0KSB7XG4gICAgICAgIGlmICghdGhpcy5qd2tzKSB7XG4gICAgICAgICAgICB0aGlzLmp3a3MgPSBjcmVhdGVSZW1vdGVKV0tTZXQobmV3IFVSTCh0aGlzLnZlcmlmeVVybCkpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IGp3dFZlcmlmeShqd3QsIHRoaXMuandrcywge1xuICAgICAgICAgICAgICAgIGNsb2NrVG9sZXJhbmNlOiBgJHt0aGlzLmNsb2NrVG9sZXJhbmNlU2Vjb25kc31zYCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoXCJJbnZhbGlkIHRva2VuOiBcIiArIChlPy5tZXNzYWdlID8/IGUpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSm1hV3hsSWpvaVlYVjBhRk5sY25acFkyVXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjeUk2V3lJdUxpOHVMaTh1TGk5emNtTXZibVZ6ZEM5aGRYUm9VMlZ5ZG1salpTNTBjeUpkTENKdVlXMWxjeUk2VzEwc0ltMWhjSEJwYm1keklqb2lRVUZCUVRzN096czdPenM3T3p0SFFWVkhPMEZCUTBnc1QwRkJUeXhGUVVGRkxHdENRVUZyUWl4RlFVRkZMRTFCUVUwc1owSkJRV2RDTEVOQlFVTTdRVUZEY0VRc1QwRkJUeXhGUVVGRkxHdENRVUZyUWl4RlFVRkZMRk5CUVZNc1JVRkJSU3hOUVVGTkxFMUJRVTBzUTBGQlF6dEJRVU55UkN4UFFVRlBMRVZCUTB3c2IwSkJRVzlDTEVWQlEzQkNMR3RDUVVGclFpeEZRVU5zUWl4bFFVRmxMRVZCUTJZc1QwRkJUeXhGUVVOUUxHTkJRV01zUjBGRFppeHRRa0ZCWjBJN1FVRXJRbXBDTEUxQlFVMHNUMEZCVHl4WFFVRlhPMGxCVDNSQ0xGbEJRVmtzVlVGQk9FSXNSVUZCUlR0UlFVTXhReXhKUVVGSkxFTkJRVU1zVjBGQlZ5eEhRVUZITEVOQlFVTXNRMEZCUXl4UFFVRlBMRU5CUVVNc1YwRkJWeXhKUVVGSkxFTkJRVU1zUTBGQlF5eFBRVUZQTEVOQlFVTXNVMEZCVXl4RFFVRkRPMUZCUTJoRkxFbEJRVWtzUTBGQlF5eFRRVUZUTEVkQlFVY3NUMEZCVHl4RFFVRkRMRk5CUVZNc1NVRkJTU3hGUVVGRkxFTkJRVU03VVVGRGVrTXNTVUZCU1N4RFFVRkRMSEZDUVVGeFFpeEhRVUZITEU5QlFVOHNRMEZCUXl4eFFrRkJjVUlzU1VGQlNTeERRVUZETEVOQlFVTTdVVUZEYUVVc1NVRkJTU3hEUVVGRExHVkJRV1VzUjBGQlJ5eFBRVUZQTEVOQlFVTXNaVUZCWlN4SlFVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFTkJRVU03U1VGRGFFVXNRMEZCUXp0SlFVVkVMREJDUVVFd1FqdFJRVU40UWl4UFFVRlBMRWxCUVVrc1EwRkJReXhYUVVGWExFTkJRVU03U1VGRE1VSXNRMEZCUXp0SlFVVkVMR1ZCUVdVc1EwRkJReXhIUVVGWE8xRkJRM3BDTEU5QlFVOHNaVUZCWlN4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wbEJRemxDTEVOQlFVTTdTVUZGUkN4UlFVRlJMRU5CUVVNc1IwRkJWenRSUVVOc1FpeFBRVUZQTEVsQlFVa3NRMEZCUXl4dlFrRkJiMElzUTBGQlF5eEpRVUZKTEVOQlFVTXNaVUZCWlN4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRExFTkJRVU03U1VGRE9VUXNRMEZCUXp0SlFVVkVMRTlCUVU4c1EwRkJReXhIUVVGWE8xRkJRMnBDTEU5QlFVOHNUMEZCVHl4RFFVRkRMRWRCUVVjc1EwRkJReXhEUVVGRE8wbEJRM1JDTEVOQlFVTTdTVUZGUkN4dlFrRkJiMElzUTBGQlF5eFBRVUV3UXp0UlFVTTNSQ3hQUVVGUExHOUNRVUZ2UWl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRE8wbEJRM1pETEVOQlFVTTdTVUZGUkRzN08wOUJSMGM3U1VGRFNDeHJRa0ZCYTBJc1EwRkRhRUlzVDBGQk1FTTdVVUZGTVVNc1QwRkJUeXhqUVVGakxFTkJRVU1zVDBGQlR5eEZRVUZGTEVsQlFVa3NRMEZCUXl4bFFVRmxMRU5CUVVNc1EwRkJRenRKUVVOMlJDeERRVUZETzBsQlJVUXNhMEpCUVd0Q0xFTkJRVU1zUjBGQlZ6dFJRVU0xUWl4UFFVRlBMR3RDUVVGclFpeERRVUZETEVkQlFVY3NRMEZCUXl4RFFVRkRPMGxCUTJwRExFTkJRVU03U1VGRlJEczdPenM3T3pzN08wOUJVMGM3U1VGRFNDeExRVUZMTEVOQlFVTXNaMEpCUVdkQ0xFTkJRM0JDTEVkQlFWYzdVVUZGV0N4SlFVRkpMRWxCUVVrc1EwRkJReXhYUVVGWExFVkJRVVVzUTBGQlF6dFpRVU55UWl4UFFVRlBMRWxCUVVrc1EwRkJReXhwUWtGQmFVSXNRMEZCUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRSUVVOeVF5eERRVUZETzFGQlEwUXNUVUZCVFN4UFFVRlBMRWRCUVVjc1NVRkJTU3hEUVVGRExHVkJRV1VzUTBGQlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0UlFVTXhReXhKUVVGSkxFTkJRVU1zVDBGQlR5eEZRVUZGTEVOQlFVTTdXVUZEWWl4TlFVRk5MRWxCUVVrc2EwSkJRV3RDTEVOQlFVTXNaVUZCWlN4RFFVRkRMRU5CUVVNN1VVRkRhRVFzUTBGQlF6dFJRVU5FTEU5QlFVOHNUMEZCVHl4RFFVRkRPMGxCUTJwQ0xFTkJRVU03U1VGRlJEczdPMDlCUjBjN1NVRkRTeXhMUVVGTExFTkJRVU1zYVVKQlFXbENMRU5CUXpkQ0xFZEJRVmM3VVVGRldDeEpRVUZKTEVOQlFVTXNTVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8xbEJRMllzU1VGQlNTeERRVUZETEVsQlFVa3NSMEZCUnl4clFrRkJhMElzUTBGQlF5eEpRVUZKTEVkQlFVY3NRMEZCUXl4SlFVRkpMRU5CUVVNc1UwRkJVeXhEUVVGRExFTkJRVU1zUTBGQlF6dFJRVU14UkN4RFFVRkRPMUZCUTBRc1NVRkJTU3hEUVVGRE8xbEJRMGdzVFVGQlRTeEZRVUZGTEU5QlFVOHNSVUZCUlN4SFFVRkhMRTFCUVUwc1UwRkJVeXhEUVVGRExFZEJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTXNTVUZCU1N4RlFVRkZPMmRDUVVOc1JDeGpRVUZqTEVWQlFVVXNSMEZCUnl4SlFVRkpMRU5CUVVNc2NVSkJRWEZDTEVkQlFVYzdZVUZEYWtRc1EwRkJReXhEUVVGRE8xbEJRMGdzVDBGQlR5eFBRVUZuUkN4RFFVRkRPMUZCUXpGRUxFTkJRVU03VVVGQlF5eFBRVUZQTEVOQlFVMHNSVUZCUlN4RFFVRkRPMWxCUTJoQ0xFMUJRVTBzU1VGQlNTeHJRa0ZCYTBJc1EwRkJReXhwUWtGQmFVSXNSMEZCUnl4RFFVRkRMRU5CUVVNc1JVRkJSU3hQUVVGUExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXp0UlFVTjBSU3hEUVVGRE8wbEJRMGdzUTBGQlF6dERRVU5HSWl3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2xzaUx5b3FYRzRnS2lCQWJXOWtkV3hsSUdsdWRHVm5jbUYwYVc5dWN5OXVaWE4wTDJGMWRHaFRaWEoyYVdObFhHNGdLaUJBYzNWdGJXRnllU0JPWlhOMExXTnZiWEJoZEdsaWJHVWdZWFYwYUdWdWRHbGpZWFJwYjI0Z2MyVnlkbWxqWlNCb1pXeHdaWEp6TGx4dUlDb2dRR1JsYzJOeWFYQjBhVzl1SUZKbGNYVmxjM1F0WTI5dWRHVjRkQzFoZDJGeVpTQmhkWFJvSUdobGJIQmxjbk1nWm05eUlFNWxjM1FnWVhCd2JHbGpZWFJwYjI1eklIVnphVzVuSUVSbFkyRm1JR2x1ZEdWbmNtRjBhVzl1SUhCaGRIUmxjbTV6TGx4dUlDcGNiaUFxSUZOMWNIQnZjblJ6SUhSM2J5QnRiMlJsY3pwY2JpQXFJQzBnS2lwV1pYSnBabmtnYlc5a1pTb3FJQ2hrWldaaGRXeDBJSGRvWlc0Z1lIWmxjbWxtZVZWeWJHQWdhWE1nYzJWMEtUb2dkbUZzYVdSaGRHVnpJSFJvWlNCS1YxUWdjMmxuYm1GMGRYSmxYRzRnS2lBZ0lHRm5ZV2x1YzNRZ2RHaGxJRXRsZVdOc2IyRnJJRXBYUzFNZ1pXNWtjRzlwYm5RZ2RYTnBibWNnWUdwdmMyVXVhbmQwVm1WeWFXWjVZQzVjYmlBcUlDMGdLaXBFWldOdlpHVXRiMjVzZVNCdGIyUmxLaW9nS0hkb1pXNGdZSFpsY21sbWVWUnZhMlZ1WUNCcGN5Qm1ZV3h6WlNBdklHQjJaWEpwWm5sVmNteGdJR2x6SUdWdGNIUjVLVHBjYmlBcUlDQWdaR1ZqYjJSbGN5QjBhR1VnU2xkVUlIZHBkR2h2ZFhRZ2MybG5ibUYwZFhKbElIWmxjbWxtYVdOaGRHbHZiaUFvWkdWMkwyeHZZMkZzSUcxdlpHVXBMbHh1SUNvdlhHNXBiWEJ2Y25RZ2V5QkJkWFJvYjNKcGVtRjBhVzl1UlhKeWIzSWdmU0JtY205dElGd2lRR1JsWTJGbUxYUnpMMk52Y21WY0lqdGNibWx0Y0c5eWRDQjdJR055WldGMFpWSmxiVzkwWlVwWFMxTmxkQ3dnYW5kMFZtVnlhV1o1SUgwZ1puSnZiU0JjSW1wdmMyVmNJanRjYm1sdGNHOXlkQ0I3WEc0Z0lHVjRkSEpoWTNSTFpYbGpiRzloYTFKdmJHVnpMRnh1SUNCblpYUlNaV0ZzYlVaeWIyMUpjM04xWlhJc1hHNGdJR2RsZEZSdmEyVnVVR0Y1Ykc5aFpDeGNiaUFnWjJWMFZYTmxjaXhjYmlBZ1oyVjBRMnhwWlc1MFVtOXNaWE1zWEc1OUlHWnliMjBnWENJdUwzVjBhV3h6WENJN1hHNXBiWEJ2Y25RZ2RIbHdaU0I3SUV0bGVXTnNiMkZyUVdOalpYTnpWRzlyWlc1UVlYbHNiMkZrTENCTFpYbGpiRzloYTFWelpYSWdmU0JtY205dElGd2lMaTkwZVhCbGMxd2lPMXh1WEc0dktpcGNiaUFxSUVOdmJtWnBaM1Z5WVhScGIyNGdabTl5SUhSb1pTQjdRR3hwYm1zZ1FYVjBhRk5sY25acFkyVjlMbHh1SUNvdlhHNWxlSEJ2Y25RZ2FXNTBaWEptWVdObElFRjFkR2hUWlhKMmFXTmxUM0IwYVc5dWN5QjdYRzRnSUM4cUtseHVJQ0FnS2lCWGFHVjBhR1Z5SUhSdklIWmxjbWxtZVNCMGFHVWdTbGRVSUhOcFoyNWhkSFZ5WlNCaFoyRnBibk4wSUhSb1pTQkxaWGxqYkc5aGF5QktWMHRUSUdWdVpIQnZhVzUwTGx4dUlDQWdLaUJYYUdWdUlHQm1ZV3h6WldBZ0tHOXlJR0IyWlhKcFpubFZjbXhnSUdseklHVnRjSFI1S1N3Z2RHOXJaVzV6SUdGeVpTQmtaV052WkdWa0lIZHBkR2h2ZFhSY2JpQWdJQ29nYzJsbmJtRjBkWEpsSUhabGNtbG1hV05oZEdsdmJpQW9aR1YyTDJ4dlkyRnNJRzF2WkdVZ2IyNXNlU2t1WEc0Z0lDQXFJRUJrWldaaGRXeDBJR1poYkhObFhHNGdJQ0FxTDF4dUlDQjJaWEpwWm5sVWIydGxiajg2SUdKdmIyeGxZVzQ3WEc0Z0lDOHFLbHh1SUNBZ0tpQlVhR1VnUzJWNVkyeHZZV3NnU2xkTFV5QlZVa3dnS0dVdVp5NGdZR2gwZEhCek9pOHZhMlY1WTJ4dllXc3ZjbVZoYkcxekwyMTVjbVZoYkcwdmNISnZkRzlqYjJ3dmIzQmxibWxrTFdOdmJtNWxZM1F2WTJWeWRITmdLUzVjYmlBZ0lDb2dVbVZ4ZFdseVpXUWdkMmhsYmlCZ2RtVnlhV1o1Vkc5clpXNWdJR2x6SUdCMGNuVmxZQzVjYmlBZ0lDb3ZYRzRnSUhabGNtbG1lVlZ5YkQ4NklITjBjbWx1Wnp0Y2JpQWdMeW9xWEc0Z0lDQXFJRU5zYjJOcklIUnZiR1Z5WVc1alpTQm1iM0lnU2xkVUlHVjRjR2x5ZVNCMlpYSnBabWxqWVhScGIyNGdLR2x1SUhObFkyOXVaSE1wTGx4dUlDQWdLaUJBWkdWbVlYVnNkQ0ExWEc0Z0lDQXFMMXh1SUNCamJHOWphMVJ2YkdWeVlXNWpaVk5sWTI5dVpITS9PaUJ1ZFcxaVpYSTdYRzRnSUM4cUtseHVJQ0FnS2lCTFpYbGpiRzloYXlCamJHbGxiblFnU1VSeklIUnZJR1Y0WTJ4MVpHVWdkMmhsYmlCbGVIUnlZV04wYVc1bklISnZiR1Z6SUdaeWIyMGdZSEpsYzI5MWNtTmxYMkZqWTJWemMyQXVYRzRnSUNBcUlFQmtaV1poZFd4MElGdGNJbUZqWTI5MWJuUmNJbDFjYmlBZ0lDb3ZYRzRnSUdWNFkyeDFaR1ZrUTJ4cFpXNTBjejg2SUhOMGNtbHVaMXRkTzF4dWZWeHVYRzVsZUhCdmNuUWdZMnhoYzNNZ1FYVjBhRk5sY25acFkyVWdlMXh1SUNCd2NtbDJZWFJsSUhKbFlXUnZibXg1SUhabGNtbG1lVlJ2YTJWdU9pQmliMjlzWldGdU8xeHVJQ0J3Y21sMllYUmxJSEpsWVdSdmJteDVJSFpsY21sbWVWVnliRG9nYzNSeWFXNW5PMXh1SUNCd2NtbDJZWFJsSUhKbFlXUnZibXg1SUdOc2IyTnJWRzlzWlhKaGJtTmxVMlZqYjI1a2N6b2diblZ0WW1WeU8xeHVJQ0J3Y21sMllYUmxJSEpsWVdSdmJteDVJR1Y0WTJ4MVpHVmtRMnhwWlc1MGN6b2djM1J5YVc1blcxMDdYRzRnSUhCeWFYWmhkR1VnYW5kcmN6b2dVbVYwZFhKdVZIbHdaVHgwZVhCbGIyWWdZM0psWVhSbFVtVnRiM1JsU2xkTFUyVjBQaUI4SUhWdVpHVm1hVzVsWkR0Y2JseHVJQ0JqYjI1emRISjFZM1J2Y2lodmNIUnBiMjV6T2lCQmRYUm9VMlZ5ZG1salpVOXdkR2x2Ym5NZ1BTQjdmU2tnZTF4dUlDQWdJSFJvYVhNdWRtVnlhV1o1Vkc5clpXNGdQU0FoSVc5d2RHbHZibk11ZG1WeWFXWjVWRzlyWlc0Z0ppWWdJU0Z2Y0hScGIyNXpMblpsY21sbWVWVnliRHRjYmlBZ0lDQjBhR2x6TG5abGNtbG1lVlZ5YkNBOUlHOXdkR2x2Ym5NdWRtVnlhV1o1VlhKc0lEOC9JRndpWENJN1hHNGdJQ0FnZEdocGN5NWpiRzlqYTFSdmJHVnlZVzVqWlZObFkyOXVaSE1nUFNCdmNIUnBiMjV6TG1Oc2IyTnJWRzlzWlhKaGJtTmxVMlZqYjI1a2N5QS9QeUExTzF4dUlDQWdJSFJvYVhNdVpYaGpiSFZrWldSRGJHbGxiblJ6SUQwZ2IzQjBhVzl1Y3k1bGVHTnNkV1JsWkVOc2FXVnVkSE1nUHo4Z1cxd2lZV05qYjNWdWRGd2lYVHRjYmlBZ2ZWeHVYRzRnSUdselZHOXJaVzVXWlhKcFptbGpZWFJwYjI1RmJtRmliR1ZrS0NrNklHSnZiMnhsWVc0Z2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxuWmxjbWxtZVZSdmEyVnVPMXh1SUNCOVhHNWNiaUFnWjJWMFZHOXJaVzVRWVhsc2IyRmtLR3AzZERvZ2MzUnlhVzVuS1RvZ1MyVjVZMnh2WVd0QlkyTmxjM05VYjJ0bGJsQmhlV3h2WVdRZ2ZDQnVkV3hzSUh0Y2JpQWdJQ0J5WlhSMWNtNGdaMlYwVkc5clpXNVFZWGxzYjJGa0tHcDNkQ2s3WEc0Z0lIMWNibHh1SUNCblpYUlNiMnhsY3locWQzUTZJSE4wY21sdVp5azZJSE4wY21sdVoxdGRJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVsZUhSeVlXTjBTMlY1WTJ4dllXdFNiMnhsY3loMGFHbHpMbWRsZEZSdmEyVnVVR0Y1Ykc5aFpDaHFkM1FwS1R0Y2JpQWdmVnh1WEc0Z0lHZGxkRlZ6WlhJb2FuZDBPaUJ6ZEhKcGJtY3BPaUJMWlhsamJHOWhhMVZ6WlhJZ2ZDQjFibVJsWm1sdVpXUWdlMXh1SUNBZ0lISmxkSFZ5YmlCblpYUlZjMlZ5S0dwM2RDazdYRzRnSUgxY2JseHVJQ0JsZUhSeVlXTjBTMlY1WTJ4dllXdFNiMnhsY3lod1lYbHNiMkZrT2lCTFpYbGpiRzloYTBGalkyVnpjMVJ2YTJWdVVHRjViRzloWkNCOElHNTFiR3dwT2lCemRISnBibWRiWFNCN1hHNGdJQ0FnY21WMGRYSnVJR1Y0ZEhKaFkzUkxaWGxqYkc5aGExSnZiR1Z6S0hCaGVXeHZZV1FwTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUNBcUlFVjRkSEpoWTNSeklHTnNhV1Z1ZENCeWIyeGxjeUJtY205dElIUm9aU0JnY21WemIzVnlZMlZmWVdOalpYTnpZQ0JqYkdGcGJTd2daWGhqYkhWa2FXNW5YRzRnSUNBcUlIUm9aU0JqYjI1bWFXZDFjbVZrSUdCbGVHTnNkV1JsWkVOc2FXVnVkSE5nSUNoa1pXWmhkV3gwT2lCZ1cxd2lZV05qYjNWdWRGd2lYV0FwTGx4dUlDQWdLaTljYmlBZ1pYaDBjbUZqZEVOc2FXVnVkRkp2YkdWektGeHVJQ0FnSUhCaGVXeHZZV1E2SUV0bGVXTnNiMkZyUVdOalpYTnpWRzlyWlc1UVlYbHNiMkZrSUh3Z2JuVnNiRnh1SUNBcE9pQnpkSEpwYm1kYlhTQjdYRzRnSUNBZ2NtVjBkWEp1SUdkbGRFTnNhV1Z1ZEZKdmJHVnpLSEJoZVd4dllXUXNJSFJvYVhNdVpYaGpiSFZrWldSRGJHbGxiblJ6S1R0Y2JpQWdmVnh1WEc0Z0lHZGxkRkpsWVd4dFJuSnZiVWx6YzNWbGNpaHFkM1E2SUhOMGNtbHVaeWs2SUhOMGNtbHVaeUI3WEc0Z0lDQWdjbVYwZFhKdUlHZGxkRkpsWVd4dFJuSnZiVWx6YzNWbGNpaHFkM1FwTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUNBcUlGWmhiR2xrWVhSbGN5QmhJRXBYVkRwY2JpQWdJQ29nTFNCSmJpQXFLblpsY21sbWVTQnRiMlJsS2lvNklIWmxjbWxtYVdWeklIUm9aU0J6YVdkdVlYUjFjbVVnWVdkaGFXNXpkQ0IwYUdVZ1MyVjVZMnh2WVdzZ1NsZExVMXh1SUNBZ0tpQWdJR1Z1WkhCdmFXNTBJSFZ6YVc1bklHQnFiM05sTG1wM2RGWmxjbWxtZVdBc0lIUm9aVzRnY21WMGRYSnVjeUIwYUdVZ2RtVnlhV1pwWldRZ2NHRjViRzloWkM1Y2JpQWdJQ29nTFNCSmJpQXFLbVJsWTI5a1pTMXZibXg1SUcxdlpHVXFLam9nWkdWamIyUmxjeUIwYUdVZ1NsZFVJSGRwZEdodmRYUWdkbVZ5YVdacFkyRjBhVzl1SUdGdVpGeHVJQ0FnS2lBZ0lISmxkSFZ5Ym5NZ2RHaGxJSEJoZVd4dllXUWdLRzl5SUhSb2NtOTNjeUJwWmlCMWJuQmhjbk5sWVdKc1pTa3VYRzRnSUNBcVhHNGdJQ0FxSUVCMGFISnZkM01nZTBGMWRHaHZjbWw2WVhScGIyNUZjbkp2Y24wZ2QyaGxiaUIwYUdVZ2RHOXJaVzRnYVhNZ2FXNTJZV3hwWkN3Z1pYaHdhWEpsWkN3Z2IzSmNiaUFnSUNvZ0lDQnphV2R1WVhSMWNtVWdkbVZ5YVdacFkyRjBhVzl1SUdaaGFXeHpMbHh1SUNBZ0tpOWNiaUFnWVhONWJtTWdZWE56WlhKMFZtRnNhV1JVYjJ0bGJpaGNiaUFnSUNCcWQzUTZJSE4wY21sdVoxeHVJQ0FwT2lCUWNtOXRhWE5sUEV0bGVXTnNiMkZyUVdOalpYTnpWRzlyWlc1UVlYbHNiMkZrUGlCN1hHNGdJQ0FnYVdZZ0tIUm9hWE11ZG1WeWFXWjVWRzlyWlc0cElIdGNiaUFnSUNBZ0lISmxkSFZ5YmlCMGFHbHpMblpsY21sbWVVRm5ZV2x1YzNSS2QydHpLR3AzZENrN1hHNGdJQ0FnZlZ4dUlDQWdJR052Ym5OMElIQmhlV3h2WVdRZ1BTQjBhR2x6TG1kbGRGUnZhMlZ1VUdGNWJHOWhaQ2hxZDNRcE8xeHVJQ0FnSUdsbUlDZ2hjR0Y1Ykc5aFpDa2dlMXh1SUNBZ0lDQWdkR2h5YjNjZ2JtVjNJRUYxZEdodmNtbDZZWFJwYjI1RmNuSnZjaWhjSWtsdWRtRnNhV1FnZEc5clpXNWNJaWs3WEc0Z0lDQWdmVnh1SUNBZ0lISmxkSFZ5YmlCd1lYbHNiMkZrTzF4dUlDQjlYRzVjYmlBZ0x5b3FYRzRnSUNBcUlGWmxjbWxtYVdWeklIUm9aU0JLVjFRZ2MybG5ibUYwZFhKbElHRm5ZV2x1YzNRZ2RHaGxJRXRsZVdOc2IyRnJJRXBYUzFNZ1pXNWtjRzlwYm5RdVhHNGdJQ0FxSUV4aGVtbHNlU0JqY21WaGRHVnpJSFJvWlNCS1YwdFRJR3RsZVhOMGIzSmxJRzl1SUdacGNuTjBJR05oYkd3dVhHNGdJQ0FxTDF4dUlDQndjbWwyWVhSbElHRnplVzVqSUhabGNtbG1lVUZuWVdsdWMzUktkMnR6S0Z4dUlDQWdJR3AzZERvZ2MzUnlhVzVuWEc0Z0lDazZJRkJ5YjIxcGMyVThTMlY1WTJ4dllXdEJZMk5sYzNOVWIydGxibEJoZVd4dllXUStJSHRjYmlBZ0lDQnBaaUFvSVhSb2FYTXVhbmRyY3lrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVxZDJ0eklEMGdZM0psWVhSbFVtVnRiM1JsU2xkTFUyVjBLRzVsZHlCVlVrd29kR2hwY3k1MlpYSnBabmxWY213cEtUdGNiaUFnSUNCOVhHNGdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lHTnZibk4wSUhzZ2NHRjViRzloWkNCOUlEMGdZWGRoYVhRZ2FuZDBWbVZ5YVdaNUtHcDNkQ3dnZEdocGN5NXFkMnR6TENCN1hHNGdJQ0FnSUNBZ0lHTnNiMk5yVkc5c1pYSmhibU5sT2lCZ0pIdDBhR2x6TG1Oc2IyTnJWRzlzWlhKaGJtTmxVMlZqYjI1a2MzMXpZQ3hjYmlBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnY21WMGRYSnVJSEJoZVd4dllXUWdZWE1nZFc1cmJtOTNiaUJoY3lCTFpYbGpiRzloYTBGalkyVnpjMVJ2YTJWdVVHRjViRzloWkR0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsT2lCaGJua3BJSHRjYmlBZ0lDQWdJSFJvY205M0lHNWxkeUJCZFhSb2IzSnBlbUYwYVc5dVJYSnliM0lvWENKSmJuWmhiR2xrSUhSdmEyVnVPaUJjSWlBcklDaGxQeTV0WlhOellXZGxJRDgvSUdVcEtUdGNiaUFnSUNCOVhHNGdJSDFjYm4xY2JpSmRmUT09Il19
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module integrations/nest/authService
|
|
3
|
-
* @summary Nest-compatible authentication service helpers.
|
|
4
|
-
* @description Request-context-aware auth helpers for Nest applications using Decaf integration patterns.
|
|
5
|
-
*
|
|
6
|
-
* Supports two modes:
|
|
7
|
-
* - **Verify mode** (default when `verifyUrl` is set): validates the JWT signature
|
|
8
|
-
* against the Keycloak JWKS endpoint using `jose.jwtVerify`.
|
|
9
|
-
* - **Decode-only mode** (when `verifyToken` is false / `verifyUrl` is empty):
|
|
10
|
-
* decodes the JWT without signature verification (dev/local mode).
|
|
11
|
-
*/
|
|
12
|
-
import { AuthorizationError } from "@decaf-ts/core";
|
|
13
|
-
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
14
|
-
import { extractKeycloakRoles, getRealmFromIssuer, getTokenPayload, getUser, getClientRoles, } from "./utils.js";
|
|
15
|
-
export class AuthService {
|
|
16
|
-
constructor(options = {}) {
|
|
17
|
-
this.verifyToken = !!options.verifyToken && !!options.verifyUrl;
|
|
18
|
-
this.verifyUrl = options.verifyUrl ?? "";
|
|
19
|
-
this.clockToleranceSeconds = options.clockToleranceSeconds ?? 5;
|
|
20
|
-
this.excludedClients = options.excludedClients ?? ["account"];
|
|
21
|
-
}
|
|
22
|
-
isTokenVerificationEnabled() {
|
|
23
|
-
return this.verifyToken;
|
|
24
|
-
}
|
|
25
|
-
getTokenPayload(jwt) {
|
|
26
|
-
return getTokenPayload(jwt);
|
|
27
|
-
}
|
|
28
|
-
getRoles(jwt) {
|
|
29
|
-
return this.extractKeycloakRoles(this.getTokenPayload(jwt));
|
|
30
|
-
}
|
|
31
|
-
getUser(jwt) {
|
|
32
|
-
return getUser(jwt);
|
|
33
|
-
}
|
|
34
|
-
extractKeycloakRoles(payload) {
|
|
35
|
-
return extractKeycloakRoles(payload);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Extracts client roles from the `resource_access` claim, excluding
|
|
39
|
-
* the configured `excludedClients` (default: `["account"]`).
|
|
40
|
-
*/
|
|
41
|
-
extractClientRoles(payload) {
|
|
42
|
-
return getClientRoles(payload, this.excludedClients);
|
|
43
|
-
}
|
|
44
|
-
getRealmFromIssuer(jwt) {
|
|
45
|
-
return getRealmFromIssuer(jwt);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Validates a JWT:
|
|
49
|
-
* - In **verify mode**: verifies the signature against the Keycloak JWKS
|
|
50
|
-
* endpoint using `jose.jwtVerify`, then returns the verified payload.
|
|
51
|
-
* - In **decode-only mode**: decodes the JWT without verification and
|
|
52
|
-
* returns the payload (or throws if unparseable).
|
|
53
|
-
*
|
|
54
|
-
* @throws {AuthorizationError} when the token is invalid, expired, or
|
|
55
|
-
* signature verification fails.
|
|
56
|
-
*/
|
|
57
|
-
async assertValidToken(jwt) {
|
|
58
|
-
if (this.verifyToken) {
|
|
59
|
-
return this.verifyAgainstJwks(jwt);
|
|
60
|
-
}
|
|
61
|
-
const payload = this.getTokenPayload(jwt);
|
|
62
|
-
if (!payload) {
|
|
63
|
-
throw new AuthorizationError("Invalid token");
|
|
64
|
-
}
|
|
65
|
-
return payload;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Verifies the JWT signature against the Keycloak JWKS endpoint.
|
|
69
|
-
* Lazily creates the JWKS keystore on first call.
|
|
70
|
-
*/
|
|
71
|
-
async verifyAgainstJwks(jwt) {
|
|
72
|
-
if (!this.jwks) {
|
|
73
|
-
this.jwks = createRemoteJWKSet(new URL(this.verifyUrl));
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
const { payload } = await jwtVerify(jwt, this.jwks, {
|
|
77
|
-
clockTolerance: `${this.clockToleranceSeconds}s`,
|
|
78
|
-
});
|
|
79
|
-
return payload;
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
throw new AuthorizationError("Invalid token: " + (e?.message ?? e));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aFNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbmVzdC9hdXRoU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBQ0gsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsT0FBTyxFQUNQLGNBQWMsR0FDZixtQkFBZ0I7QUErQmpCLE1BQU0sT0FBTyxXQUFXO0lBT3RCLFlBQVksVUFBOEIsRUFBRTtRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELDBCQUEwQjtRQUN4QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVELGVBQWUsQ0FBQyxHQUFXO1FBQ3pCLE9BQU8sZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxRQUFRLENBQUMsR0FBVztRQUNsQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFXO1FBQ2pCLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxPQUEwQztRQUM3RCxPQUFPLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0IsQ0FDaEIsT0FBMEM7UUFFMUMsT0FBTyxjQUFjLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsR0FBVztRQUM1QixPQUFPLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLEdBQVc7UUFFWCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksa0JBQWtCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7O09BR0c7SUFDSyxLQUFLLENBQUMsaUJBQWlCLENBQzdCLEdBQVc7UUFFWCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNsRCxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMscUJBQXFCLEdBQUc7YUFDakQsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxPQUFnRCxDQUFDO1FBQzFELENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUMsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIGludGVncmF0aW9ucy9uZXN0L2F1dGhTZXJ2aWNlXG4gKiBAc3VtbWFyeSBOZXN0LWNvbXBhdGlibGUgYXV0aGVudGljYXRpb24gc2VydmljZSBoZWxwZXJzLlxuICogQGRlc2NyaXB0aW9uIFJlcXVlc3QtY29udGV4dC1hd2FyZSBhdXRoIGhlbHBlcnMgZm9yIE5lc3QgYXBwbGljYXRpb25zIHVzaW5nIERlY2FmIGludGVncmF0aW9uIHBhdHRlcm5zLlxuICpcbiAqIFN1cHBvcnRzIHR3byBtb2RlczpcbiAqIC0gKipWZXJpZnkgbW9kZSoqIChkZWZhdWx0IHdoZW4gYHZlcmlmeVVybGAgaXMgc2V0KTogdmFsaWRhdGVzIHRoZSBKV1Qgc2lnbmF0dXJlXG4gKiAgIGFnYWluc3QgdGhlIEtleWNsb2FrIEpXS1MgZW5kcG9pbnQgdXNpbmcgYGpvc2Uuand0VmVyaWZ5YC5cbiAqIC0gKipEZWNvZGUtb25seSBtb2RlKiogKHdoZW4gYHZlcmlmeVRva2VuYCBpcyBmYWxzZSAvIGB2ZXJpZnlVcmxgIGlzIGVtcHR5KTpcbiAqICAgZGVjb2RlcyB0aGUgSldUIHdpdGhvdXQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiAoZGV2L2xvY2FsIG1vZGUpLlxuICovXG5pbXBvcnQgeyBBdXRob3JpemF0aW9uRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IGNyZWF0ZVJlbW90ZUpXS1NldCwgand0VmVyaWZ5IH0gZnJvbSBcImpvc2VcIjtcbmltcG9ydCB7XG4gIGV4dHJhY3RLZXljbG9ha1JvbGVzLFxuICBnZXRSZWFsbUZyb21Jc3N1ZXIsXG4gIGdldFRva2VuUGF5bG9hZCxcbiAgZ2V0VXNlcixcbiAgZ2V0Q2xpZW50Um9sZXMsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgdHlwZSB7IEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkLCBLZXljbG9ha1VzZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSB7QGxpbmsgQXV0aFNlcnZpY2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhTZXJ2aWNlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHZlcmlmeSB0aGUgSldUIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBLZXljbG9hayBKV0tTIGVuZHBvaW50LlxuICAgKiBXaGVuIGBmYWxzZWAgKG9yIGB2ZXJpZnlVcmxgIGlzIGVtcHR5KSwgdG9rZW5zIGFyZSBkZWNvZGVkIHdpdGhvdXRcbiAgICogc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiAoZGV2L2xvY2FsIG1vZGUgb25seSkuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICB2ZXJpZnlUb2tlbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUaGUgS2V5Y2xvYWsgSldLUyBVUkwgKGUuZy4gYGh0dHBzOi8va2V5Y2xvYWsvcmVhbG1zL215cmVhbG0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvY2VydHNgKS5cbiAgICogUmVxdWlyZWQgd2hlbiBgdmVyaWZ5VG9rZW5gIGlzIGB0cnVlYC5cbiAgICovXG4gIHZlcmlmeVVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIENsb2NrIHRvbGVyYW5jZSBmb3IgSldUIGV4cGlyeSB2ZXJpZmljYXRpb24gKGluIHNlY29uZHMpLlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICBjbG9ja1RvbGVyYW5jZVNlY29uZHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBLZXljbG9hayBjbGllbnQgSURzIHRvIGV4Y2x1ZGUgd2hlbiBleHRyYWN0aW5nIHJvbGVzIGZyb20gYHJlc291cmNlX2FjY2Vzc2AuXG4gICAqIEBkZWZhdWx0IFtcImFjY291bnRcIl1cbiAgICovXG4gIGV4Y2x1ZGVkQ2xpZW50cz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcmlmeVRva2VuOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcmlmeVVybDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsb2NrVG9sZXJhbmNlU2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGV4Y2x1ZGVkQ2xpZW50czogc3RyaW5nW107XG4gIHByaXZhdGUgandrczogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlUmVtb3RlSldLU2V0PiB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBBdXRoU2VydmljZU9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMudmVyaWZ5VG9rZW4gPSAhIW9wdGlvbnMudmVyaWZ5VG9rZW4gJiYgISFvcHRpb25zLnZlcmlmeVVybDtcbiAgICB0aGlzLnZlcmlmeVVybCA9IG9wdGlvbnMudmVyaWZ5VXJsID8/IFwiXCI7XG4gICAgdGhpcy5jbG9ja1RvbGVyYW5jZVNlY29uZHMgPSBvcHRpb25zLmNsb2NrVG9sZXJhbmNlU2Vjb25kcyA/PyA1O1xuICAgIHRoaXMuZXhjbHVkZWRDbGllbnRzID0gb3B0aW9ucy5leGNsdWRlZENsaWVudHMgPz8gW1wiYWNjb3VudFwiXTtcbiAgfVxuXG4gIGlzVG9rZW5WZXJpZmljYXRpb25FbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZlcmlmeVRva2VuO1xuICB9XG5cbiAgZ2V0VG9rZW5QYXlsb2FkKGp3dDogc3RyaW5nKTogS2V5Y2xvYWtBY2Nlc3NUb2tlblBheWxvYWQgfCBudWxsIHtcbiAgICByZXR1cm4gZ2V0VG9rZW5QYXlsb2FkKGp3dCk7XG4gIH1cblxuICBnZXRSb2xlcyhqd3Q6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5leHRyYWN0S2V5Y2xvYWtSb2xlcyh0aGlzLmdldFRva2VuUGF5bG9hZChqd3QpKTtcbiAgfVxuXG4gIGdldFVzZXIoand0OiBzdHJpbmcpOiBLZXljbG9ha1VzZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBnZXRVc2VyKGp3dCk7XG4gIH1cblxuICBleHRyYWN0S2V5Y2xvYWtSb2xlcyhwYXlsb2FkOiBLZXljbG9ha0FjY2Vzc1Rva2VuUGF5bG9hZCB8IG51bGwpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIGV4dHJhY3RLZXljbG9ha1JvbGVzKHBheWxvYWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIGNsaWVudCByb2xlcyBmcm9tIHRoZSBgcmVzb3VyY2VfYWNjZXNzYCBjbGFpbSwgZXhjbHVkaW5nXG4gICAqIHRoZSBjb25maWd1cmVkIGBleGNsdWRlZENsaWVudHNgIChkZWZhdWx0OiBgW1wiYWNjb3VudFwiXWApLlxuICAgKi9cbiAgZXh0cmFjdENsaWVudFJvbGVzKFxuICAgIHBheWxvYWQ6IEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkIHwgbnVsbFxuICApOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIGdldENsaWVudFJvbGVzKHBheWxvYWQsIHRoaXMuZXhjbHVkZWRDbGllbnRzKTtcbiAgfVxuXG4gIGdldFJlYWxtRnJvbUlzc3Vlcihqd3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdldFJlYWxtRnJvbUlzc3Vlcihqd3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIEpXVDpcbiAgICogLSBJbiAqKnZlcmlmeSBtb2RlKio6IHZlcmlmaWVzIHRoZSBzaWduYXR1cmUgYWdhaW5zdCB0aGUgS2V5Y2xvYWsgSldLU1xuICAgKiAgIGVuZHBvaW50IHVzaW5nIGBqb3NlLmp3dFZlcmlmeWAsIHRoZW4gcmV0dXJucyB0aGUgdmVyaWZpZWQgcGF5bG9hZC5cbiAgICogLSBJbiAqKmRlY29kZS1vbmx5IG1vZGUqKjogZGVjb2RlcyB0aGUgSldUIHdpdGhvdXQgdmVyaWZpY2F0aW9uIGFuZFxuICAgKiAgIHJldHVybnMgdGhlIHBheWxvYWQgKG9yIHRocm93cyBpZiB1bnBhcnNlYWJsZSkuXG4gICAqXG4gICAqIEB0aHJvd3Mge0F1dGhvcml6YXRpb25FcnJvcn0gd2hlbiB0aGUgdG9rZW4gaXMgaW52YWxpZCwgZXhwaXJlZCwgb3JcbiAgICogICBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxzLlxuICAgKi9cbiAgYXN5bmMgYXNzZXJ0VmFsaWRUb2tlbihcbiAgICBqd3Q6IHN0cmluZ1xuICApOiBQcm9taXNlPEtleWNsb2FrQWNjZXNzVG9rZW5QYXlsb2FkPiB7XG4gICAgaWYgKHRoaXMudmVyaWZ5VG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLnZlcmlmeUFnYWluc3RKd2tzKGp3dCk7XG4gICAgfVxuICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmdldFRva2VuUGF5bG9hZChqd3QpO1xuICAgIGlmICghcGF5bG9hZCkge1xuICAgICAgdGhyb3cgbmV3IEF1dGhvcml6YXRpb25FcnJvcihcIkludmFsaWQgdG9rZW5cIik7XG4gICAgfVxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoZSBKV1Qgc2lnbmF0dXJlIGFnYWluc3QgdGhlIEtleWNsb2FrIEpXS1MgZW5kcG9pbnQuXG4gICAqIExhemlseSBjcmVhdGVzIHRoZSBKV0tTIGtleXN0b3JlIG9uIGZpcnN0IGNhbGwuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHZlcmlmeUFnYWluc3RKd2tzKFxuICAgIGp3dDogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2xvYWtBY2Nlc3NUb2tlblBheWxvYWQ+IHtcbiAgICBpZiAoIXRoaXMuandrcykge1xuICAgICAgdGhpcy5qd2tzID0gY3JlYXRlUmVtb3RlSldLU2V0KG5ldyBVUkwodGhpcy52ZXJpZnlVcmwpKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgand0VmVyaWZ5KGp3dCwgdGhpcy5qd2tzLCB7XG4gICAgICAgIGNsb2NrVG9sZXJhbmNlOiBgJHt0aGlzLmNsb2NrVG9sZXJhbmNlU2Vjb25kc31zYCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHBheWxvYWQgYXMgdW5rbm93biBhcyBLZXljbG9ha0FjY2Vzc1Rva2VuUGF5bG9hZDtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoXCJJbnZhbGlkIHRva2VuOiBcIiArIChlPy5tZXNzYWdlID8/IGUpKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { KeycloakAccessTokenPayload, KeycloakUser } from "./types.d.cts";
|
|
2
|
-
/**
|
|
3
|
-
* Configuration for the {@link AuthService}.
|
|
4
|
-
*/
|
|
5
|
-
export interface AuthServiceOptions {
|
|
6
|
-
/**
|
|
7
|
-
* Whether to verify the JWT signature against the Keycloak JWKS endpoint.
|
|
8
|
-
* When `false` (or `verifyUrl` is empty), tokens are decoded without
|
|
9
|
-
* signature verification (dev/local mode only).
|
|
10
|
-
* @default false
|
|
11
|
-
*/
|
|
12
|
-
verifyToken?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* The Keycloak JWKS URL (e.g. `https://keycloak/realms/myrealm/protocol/openid-connect/certs`).
|
|
15
|
-
* Required when `verifyToken` is `true`.
|
|
16
|
-
*/
|
|
17
|
-
verifyUrl?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Clock tolerance for JWT expiry verification (in seconds).
|
|
20
|
-
* @default 5
|
|
21
|
-
*/
|
|
22
|
-
clockToleranceSeconds?: number;
|
|
23
|
-
/**
|
|
24
|
-
* Keycloak client IDs to exclude when extracting roles from `resource_access`.
|
|
25
|
-
* @default ["account"]
|
|
26
|
-
*/
|
|
27
|
-
excludedClients?: string[];
|
|
28
|
-
}
|
|
29
|
-
export declare class AuthService {
|
|
30
|
-
private readonly verifyToken;
|
|
31
|
-
private readonly verifyUrl;
|
|
32
|
-
private readonly clockToleranceSeconds;
|
|
33
|
-
private readonly excludedClients;
|
|
34
|
-
private jwks;
|
|
35
|
-
constructor(options?: AuthServiceOptions);
|
|
36
|
-
isTokenVerificationEnabled(): boolean;
|
|
37
|
-
getTokenPayload(jwt: string): KeycloakAccessTokenPayload | null;
|
|
38
|
-
getRoles(jwt: string): string[];
|
|
39
|
-
getUser(jwt: string): KeycloakUser | undefined;
|
|
40
|
-
extractKeycloakRoles(payload: KeycloakAccessTokenPayload | null): string[];
|
|
41
|
-
/**
|
|
42
|
-
* Extracts client roles from the `resource_access` claim, excluding
|
|
43
|
-
* the configured `excludedClients` (default: `["account"]`).
|
|
44
|
-
*/
|
|
45
|
-
extractClientRoles(payload: KeycloakAccessTokenPayload | null): string[];
|
|
46
|
-
getRealmFromIssuer(jwt: string): string;
|
|
47
|
-
/**
|
|
48
|
-
* Validates a JWT:
|
|
49
|
-
* - In **verify mode**: verifies the signature against the Keycloak JWKS
|
|
50
|
-
* endpoint using `jose.jwtVerify`, then returns the verified payload.
|
|
51
|
-
* - In **decode-only mode**: decodes the JWT without verification and
|
|
52
|
-
* returns the payload (or throws if unparseable).
|
|
53
|
-
*
|
|
54
|
-
* @throws {AuthorizationError} when the token is invalid, expired, or
|
|
55
|
-
* signature verification fails.
|
|
56
|
-
*/
|
|
57
|
-
assertValidToken(jwt: string): Promise<KeycloakAccessTokenPayload>;
|
|
58
|
-
/**
|
|
59
|
-
* Verifies the JWT signature against the Keycloak JWKS endpoint.
|
|
60
|
-
* Lazily creates the JWKS keystore on first call.
|
|
61
|
-
*/
|
|
62
|
-
private verifyAgainstJwks;
|
|
63
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { KeycloakAccessTokenPayload, KeycloakUser } from "./types.d.mts";
|
|
2
|
-
/**
|
|
3
|
-
* Configuration for the {@link AuthService}.
|
|
4
|
-
*/
|
|
5
|
-
export interface AuthServiceOptions {
|
|
6
|
-
/**
|
|
7
|
-
* Whether to verify the JWT signature against the Keycloak JWKS endpoint.
|
|
8
|
-
* When `false` (or `verifyUrl` is empty), tokens are decoded without
|
|
9
|
-
* signature verification (dev/local mode only).
|
|
10
|
-
* @default false
|
|
11
|
-
*/
|
|
12
|
-
verifyToken?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* The Keycloak JWKS URL (e.g. `https://keycloak/realms/myrealm/protocol/openid-connect/certs`).
|
|
15
|
-
* Required when `verifyToken` is `true`.
|
|
16
|
-
*/
|
|
17
|
-
verifyUrl?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Clock tolerance for JWT expiry verification (in seconds).
|
|
20
|
-
* @default 5
|
|
21
|
-
*/
|
|
22
|
-
clockToleranceSeconds?: number;
|
|
23
|
-
/**
|
|
24
|
-
* Keycloak client IDs to exclude when extracting roles from `resource_access`.
|
|
25
|
-
* @default ["account"]
|
|
26
|
-
*/
|
|
27
|
-
excludedClients?: string[];
|
|
28
|
-
}
|
|
29
|
-
export declare class AuthService {
|
|
30
|
-
private readonly verifyToken;
|
|
31
|
-
private readonly verifyUrl;
|
|
32
|
-
private readonly clockToleranceSeconds;
|
|
33
|
-
private readonly excludedClients;
|
|
34
|
-
private jwks;
|
|
35
|
-
constructor(options?: AuthServiceOptions);
|
|
36
|
-
isTokenVerificationEnabled(): boolean;
|
|
37
|
-
getTokenPayload(jwt: string): KeycloakAccessTokenPayload | null;
|
|
38
|
-
getRoles(jwt: string): string[];
|
|
39
|
-
getUser(jwt: string): KeycloakUser | undefined;
|
|
40
|
-
extractKeycloakRoles(payload: KeycloakAccessTokenPayload | null): string[];
|
|
41
|
-
/**
|
|
42
|
-
* Extracts client roles from the `resource_access` claim, excluding
|
|
43
|
-
* the configured `excludedClients` (default: `["account"]`).
|
|
44
|
-
*/
|
|
45
|
-
extractClientRoles(payload: KeycloakAccessTokenPayload | null): string[];
|
|
46
|
-
getRealmFromIssuer(jwt: string): string;
|
|
47
|
-
/**
|
|
48
|
-
* Validates a JWT:
|
|
49
|
-
* - In **verify mode**: verifies the signature against the Keycloak JWKS
|
|
50
|
-
* endpoint using `jose.jwtVerify`, then returns the verified payload.
|
|
51
|
-
* - In **decode-only mode**: decodes the JWT without verification and
|
|
52
|
-
* returns the payload (or throws if unparseable).
|
|
53
|
-
*
|
|
54
|
-
* @throws {AuthorizationError} when the token is invalid, expired, or
|
|
55
|
-
* signature verification fails.
|
|
56
|
-
*/
|
|
57
|
-
assertValidToken(jwt: string): Promise<KeycloakAccessTokenPayload>;
|
|
58
|
-
/**
|
|
59
|
-
* Verifies the JWT signature against the Keycloak JWKS endpoint.
|
|
60
|
-
* Lazily creates the JWKS keystore on first call.
|
|
61
|
-
*/
|
|
62
|
-
private verifyAgainstJwks;
|
|
63
|
-
}
|