@pipeline-builder/api-core 5.2.3 → 5.2.4
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/lib/constants/ai-providers.d.ts +3 -22
- package/lib/constants/ai-providers.js +6 -56
- package/lib/errors/app-errors.d.ts +14 -0
- package/lib/errors/app-errors.js +21 -1
- package/lib/helpers/sse-helpers.d.ts +33 -3
- package/lib/helpers/sse-helpers.js +91 -19
- package/lib/middleware/auth.js +6 -3
- package/lib/middleware/deferred-quota-check.d.ts +5 -0
- package/lib/middleware/deferred-quota-check.js +33 -0
- package/lib/middleware/ecosystem-guard.d.ts +3 -3
- package/lib/middleware/ecosystem-guard.js +5 -5
- package/lib/middleware/index.d.ts +5 -2
- package/lib/middleware/index.js +6 -3
- package/lib/middleware/on-behalf.d.ts +37 -0
- package/lib/middleware/on-behalf.js +143 -0
- package/lib/middleware/permission-gates.d.ts +11 -0
- package/lib/middleware/permission-gates.js +7 -1
- package/lib/middleware/quota-exempt-routes.d.ts +36 -0
- package/lib/middleware/quota-exempt-routes.js +47 -0
- package/lib/middleware/route-table.d.ts +104 -0
- package/lib/middleware/route-table.js +72 -2
- package/lib/middleware/service-tokens.d.ts +8 -0
- package/lib/middleware/service-tokens.js +2 -1
- package/lib/middleware/step-up.js +11 -1
- package/lib/services/ai-call-weight.d.ts +24 -0
- package/lib/services/ai-call-weight.js +77 -0
- package/lib/services/audit-context.d.ts +105 -0
- package/lib/services/audit-context.js +134 -0
- package/lib/services/index.d.ts +7 -2
- package/lib/services/index.js +7 -2
- package/lib/services/org-ai-client.d.ts +61 -0
- package/lib/services/org-ai-client.js +112 -0
- package/lib/services/quota-increment-batcher.d.ts +81 -0
- package/lib/services/quota-increment-batcher.js +166 -0
- package/lib/services/quota.d.ts +158 -14
- package/lib/services/quota.js +252 -22
- package/lib/services/remote-audit-client.d.ts +44 -1
- package/lib/services/remote-audit-client.js +106 -20
- package/lib/services/version-vuln-policy.d.ts +174 -0
- package/lib/services/version-vuln-policy.js +242 -0
- package/lib/types/ai-catalog.d.ts +63 -0
- package/lib/types/ai-catalog.js +82 -0
- package/lib/types/ask-proposals.js +6 -6
- package/lib/types/build-catalog.d.ts +154 -0
- package/lib/types/build-catalog.js +158 -0
- package/lib/types/common.d.ts +37 -3
- package/lib/types/common.js +20 -2
- package/lib/types/ecosystem-notifications.d.ts +5 -5
- package/lib/types/ecosystem-notifications.js +9 -3
- package/lib/types/error-codes.d.ts +13 -6
- package/lib/types/error-codes.js +18 -8
- package/lib/types/feature-flags.d.ts +6 -4
- package/lib/types/feature-flags.js +11 -6
- package/lib/types/index.d.ts +6 -4
- package/lib/types/index.js +12 -5
- package/lib/types/metadata-keys.d.ts +6 -0
- package/lib/types/metadata-keys.js +4 -1
- package/lib/types/permissions.d.ts +344 -3
- package/lib/types/permissions.js +596 -21
- package/lib/types/pipeline.d.ts +39 -0
- package/lib/types/pipeline.js +57 -1
- package/lib/types/plugin-health.d.ts +0 -2
- package/lib/types/plugin-health.js +1 -11
- package/lib/types/plugin-scan.d.ts +192 -42
- package/lib/types/plugin-scan.js +159 -43
- package/lib/types/quota-catalog.d.ts +247 -0
- package/lib/types/quota-catalog.js +122 -0
- package/lib/types/quota-tiers.d.ts +118 -0
- package/lib/types/quota-tiers.js +153 -2
- package/lib/types/remote-audit-actions.d.ts +1 -1
- package/lib/types/remote-audit-actions.js +131 -1
- package/lib/types/wire-vocabulary.js +8 -1
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +2 -2
- package/lib/utils/response.d.ts +35 -2
- package/lib/utils/response.js +42 -3
- package/lib/validation/ai-schemas.d.ts +27 -0
- package/lib/validation/ai-schemas.js +31 -5
- package/lib/validation/plugin-schemas.d.ts +15 -0
- package/lib/validation/plugin-schemas.js +28 -1
- package/package.json +31 -2
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
2
|
+
/** Arm `check` to run after this request authenticates. */
|
|
3
|
+
export declare function armDeferredQuotaCheck(res: Response, check: RequestHandler): void;
|
|
4
|
+
/** `requireAuth`'s `next()`: run the armed quota check, if any, then continue. */
|
|
5
|
+
export declare function runDeferredQuotaCheck(req: Request, res: Response, next: NextFunction): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* A quota check armed at MOUNT time and run by `requireAuth` once the caller is
|
|
5
|
+
* verified.
|
|
6
|
+
*
|
|
7
|
+
* Why deferred: the apiCalls meter + check mount ONCE per service, ahead of its
|
|
8
|
+
* whole user surface (api-server `apiCallsQuota`), but authentication is per
|
|
9
|
+
* route — routers mix public, user and machine routes under one prefix. At mount
|
|
10
|
+
* time there is no verified org to check yet, and checking a header-derived or
|
|
11
|
+
* peeked one would hand a forged token a victim org's usage in the 429 body. So
|
|
12
|
+
* the mount only ARMS the check here, and `requireAuth` (api-core's, and
|
|
13
|
+
* platform's own) runs it at its single post-verification choke point, after
|
|
14
|
+
* the request identity has been re-derived from the JWT. A route that never
|
|
15
|
+
* authenticates never runs it — there is no org to bill.
|
|
16
|
+
*
|
|
17
|
+
* At most once per request: running it empties the slot, so a second
|
|
18
|
+
* `requireAuth` in the same chain is a plain `next()`.
|
|
19
|
+
*/
|
|
20
|
+
const SLOT = 'deferredQuotaCheck';
|
|
21
|
+
/** Arm `check` to run after this request authenticates. */
|
|
22
|
+
export function armDeferredQuotaCheck(res, check) {
|
|
23
|
+
res.locals[SLOT] = check;
|
|
24
|
+
}
|
|
25
|
+
/** `requireAuth`'s `next()`: run the armed quota check, if any, then continue. */
|
|
26
|
+
export function runDeferredQuotaCheck(req, res, next) {
|
|
27
|
+
const check = res.locals?.[SLOT];
|
|
28
|
+
if (!check)
|
|
29
|
+
return next();
|
|
30
|
+
delete res.locals[SLOT];
|
|
31
|
+
void check(req, res, next);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmZXJyZWQtcXVvdGEtY2hlY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlkZGxld2FyZS9kZWZlcnJlZC1xdW90YS1jaGVjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBSXRDOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxJQUFJLEdBQUcsb0JBQW9CLENBQUM7QUFFbEMsMkRBQTJEO0FBQzNELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxHQUFhLEVBQUUsS0FBcUI7SUFDeEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDM0IsQ0FBQztBQUVELGtGQUFrRjtBQUNsRixNQUFNLFVBQVUscUJBQXFCLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQjtJQUNuRixNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUErQixDQUFDO0lBQy9ELElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUMxQixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsS0FBSyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgTmV4dEZ1bmN0aW9uLCBSZXF1ZXN0LCBSZXF1ZXN0SGFuZGxlciwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcblxuLyoqXG4gKiBBIHF1b3RhIGNoZWNrIGFybWVkIGF0IE1PVU5UIHRpbWUgYW5kIHJ1biBieSBgcmVxdWlyZUF1dGhgIG9uY2UgdGhlIGNhbGxlciBpc1xuICogdmVyaWZpZWQuXG4gKlxuICogV2h5IGRlZmVycmVkOiB0aGUgYXBpQ2FsbHMgbWV0ZXIgKyBjaGVjayBtb3VudCBPTkNFIHBlciBzZXJ2aWNlLCBhaGVhZCBvZiBpdHNcbiAqIHdob2xlIHVzZXIgc3VyZmFjZSAoYXBpLXNlcnZlciBgYXBpQ2FsbHNRdW90YWApLCBidXQgYXV0aGVudGljYXRpb24gaXMgcGVyXG4gKiByb3V0ZSDigJQgcm91dGVycyBtaXggcHVibGljLCB1c2VyIGFuZCBtYWNoaW5lIHJvdXRlcyB1bmRlciBvbmUgcHJlZml4LiBBdCBtb3VudFxuICogdGltZSB0aGVyZSBpcyBubyB2ZXJpZmllZCBvcmcgdG8gY2hlY2sgeWV0LCBhbmQgY2hlY2tpbmcgYSBoZWFkZXItZGVyaXZlZCBvclxuICogcGVla2VkIG9uZSB3b3VsZCBoYW5kIGEgZm9yZ2VkIHRva2VuIGEgdmljdGltIG9yZydzIHVzYWdlIGluIHRoZSA0MjkgYm9keS4gU29cbiAqIHRoZSBtb3VudCBvbmx5IEFSTVMgdGhlIGNoZWNrIGhlcmUsIGFuZCBgcmVxdWlyZUF1dGhgIChhcGktY29yZSdzLCBhbmRcbiAqIHBsYXRmb3JtJ3Mgb3duKSBydW5zIGl0IGF0IGl0cyBzaW5nbGUgcG9zdC12ZXJpZmljYXRpb24gY2hva2UgcG9pbnQsIGFmdGVyXG4gKiB0aGUgcmVxdWVzdCBpZGVudGl0eSBoYXMgYmVlbiByZS1kZXJpdmVkIGZyb20gdGhlIEpXVC4gQSByb3V0ZSB0aGF0IG5ldmVyXG4gKiBhdXRoZW50aWNhdGVzIG5ldmVyIHJ1bnMgaXQg4oCUIHRoZXJlIGlzIG5vIG9yZyB0byBiaWxsLlxuICpcbiAqIEF0IG1vc3Qgb25jZSBwZXIgcmVxdWVzdDogcnVubmluZyBpdCBlbXB0aWVzIHRoZSBzbG90LCBzbyBhIHNlY29uZFxuICogYHJlcXVpcmVBdXRoYCBpbiB0aGUgc2FtZSBjaGFpbiBpcyBhIHBsYWluIGBuZXh0KClgLlxuICovXG5jb25zdCBTTE9UID0gJ2RlZmVycmVkUXVvdGFDaGVjayc7XG5cbi8qKiBBcm0gYGNoZWNrYCB0byBydW4gYWZ0ZXIgdGhpcyByZXF1ZXN0IGF1dGhlbnRpY2F0ZXMuICovXG5leHBvcnQgZnVuY3Rpb24gYXJtRGVmZXJyZWRRdW90YUNoZWNrKHJlczogUmVzcG9uc2UsIGNoZWNrOiBSZXF1ZXN0SGFuZGxlcik6IHZvaWQge1xuICByZXMubG9jYWxzW1NMT1RdID0gY2hlY2s7XG59XG5cbi8qKiBgcmVxdWlyZUF1dGhgJ3MgYG5leHQoKWA6IHJ1biB0aGUgYXJtZWQgcXVvdGEgY2hlY2ssIGlmIGFueSwgdGhlbiBjb250aW51ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5EZWZlcnJlZFF1b3RhQ2hlY2socmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkIHtcbiAgY29uc3QgY2hlY2sgPSByZXMubG9jYWxzPy5bU0xPVF0gYXMgUmVxdWVzdEhhbmRsZXIgfCB1bmRlZmluZWQ7XG4gIGlmICghY2hlY2spIHJldHVybiBuZXh0KCk7XG4gIGRlbGV0ZSByZXMubG9jYWxzW1NMT1RdO1xuICB2b2lkIGNoZWNrKHJlcSwgcmVzLCBuZXh0KTtcbn1cbiJdfQ==
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Only the system org manages or approves the ecosystem. A route that exercises
|
|
5
5
|
* a system-org-only permission (`plugins:moderate`, `publishers:verify`) must
|
|
6
|
-
* therefore check three things, and {@link
|
|
6
|
+
* therefore check three things, and {@link requireSystemOrgPermission} composes
|
|
7
7
|
* them so no route can forget one:
|
|
8
8
|
*
|
|
9
9
|
* 1. {@link requireSystemOrg} — the caller's ACTIVE org is the system org. A
|
|
@@ -36,7 +36,7 @@ export declare const requireSystemOrg: (req: Request, res: Response, next: NextF
|
|
|
36
36
|
* as an array, which Express flattens:
|
|
37
37
|
*
|
|
38
38
|
* ```ts
|
|
39
|
-
* router.post('/requests/:id/approve', requireAuth,
|
|
39
|
+
* router.post('/requests/:id/approve', requireAuth, requireSystemOrgPermission('plugins:moderate'),
|
|
40
40
|
* requireStepUp, audited('plugin.request.approve'), handler);
|
|
41
41
|
* ```
|
|
42
42
|
*
|
|
@@ -44,4 +44,4 @@ export declare const requireSystemOrg: (req: Request, res: Response, next: NextF
|
|
|
44
44
|
* system-org-only — a tenant permission behind this gate would be unreachable
|
|
45
45
|
* for every tenant, which is always a wiring mistake.
|
|
46
46
|
*/
|
|
47
|
-
export declare function
|
|
47
|
+
export declare function requireSystemOrgPermission(...permissions: Permission[]): RequestHandler[];
|
|
@@ -36,7 +36,7 @@ export const requireSystemOrg = tagRouteGate(function requireSystemOrg(req, res,
|
|
|
36
36
|
* as an array, which Express flattens:
|
|
37
37
|
*
|
|
38
38
|
* ```ts
|
|
39
|
-
* router.post('/requests/:id/approve', requireAuth,
|
|
39
|
+
* router.post('/requests/:id/approve', requireAuth, requireSystemOrgPermission('plugins:moderate'),
|
|
40
40
|
* requireStepUp, audited('plugin.request.approve'), handler);
|
|
41
41
|
* ```
|
|
42
42
|
*
|
|
@@ -44,12 +44,12 @@ export const requireSystemOrg = tagRouteGate(function requireSystemOrg(req, res,
|
|
|
44
44
|
* system-org-only — a tenant permission behind this gate would be unreachable
|
|
45
45
|
* for every tenant, which is always a wiring mistake.
|
|
46
46
|
*/
|
|
47
|
-
export function
|
|
47
|
+
export function requireSystemOrgPermission(...permissions) {
|
|
48
48
|
if (permissions.length === 0)
|
|
49
|
-
throw new Error('
|
|
49
|
+
throw new Error('requireSystemOrgPermission needs at least one permission');
|
|
50
50
|
const tenant = permissions.filter((p) => !isSystemOrgOnlyPermission(p));
|
|
51
51
|
if (tenant.length > 0) {
|
|
52
|
-
throw new Error(`
|
|
52
|
+
throw new Error(`requireSystemOrgPermission only takes system-org-only permissions; got ${tenant.join(', ')}`);
|
|
53
53
|
}
|
|
54
54
|
return [
|
|
55
55
|
requireSystemOrg,
|
|
@@ -57,4 +57,4 @@ export function requireEcosystemPermission(...permissions) {
|
|
|
57
57
|
requireAssurance({ minAssurance: 2 }),
|
|
58
58
|
];
|
|
59
59
|
}
|
|
60
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNvc3lzdGVtLWd1YXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvZWNvc3lzdGVtLWd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUF3QnRDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLEVBQW1CLE1BQU0seUJBQXlCLENBQUM7QUFDckYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRDsrRUFDK0U7QUFDL0UsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEdBQVk7SUFDN0MsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNqRCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCO0lBQ3BILElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZCxPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLFlBQVksRUFBRSx5QkFBeUIsRUFBRSxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUNELElBQUksa0JBQWtCLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUMzQyxXQUFXLENBQUMsZ0NBQWdDLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztJQUNsRyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDckMsT0FBTyxTQUFTLENBQ2QsR0FBRyxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQ3pCLG1HQUFtRyxFQUNuRyxTQUFTLENBQUMsbUJBQW1CLENBQzlCLENBQUM7QUFDSixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUUxQjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLEdBQUcsV0FBeUI7SUFDckUsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDMUcsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLDBFQUEwRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNqSCxDQUFDO0lBQ0QsT0FBTztRQUNMLGdCQUFnQjtRQUNoQixpQkFBaUIsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUNqQyxnQkFBZ0IsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQztLQUNsQixDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgcGx1Z2luLWVjb3N5c3RlbSBnb3Zlcm5hbmNlIGdhdGUgKGRvY3MvcnVuYm9va3MvZWNvc3lzdGVtLW1vZGVyYXRpb24ubWQpLlxuICpcbiAqIE9ubHkgdGhlIHN5c3RlbSBvcmcgbWFuYWdlcyBvciBhcHByb3ZlcyB0aGUgZWNvc3lzdGVtLiBBIHJvdXRlIHRoYXQgZXhlcmNpc2VzXG4gKiBhIHN5c3RlbS1vcmctb25seSBwZXJtaXNzaW9uIChgcGx1Z2luczptb2RlcmF0ZWAsIGBwdWJsaXNoZXJzOnZlcmlmeWApIG11c3RcbiAqIHRoZXJlZm9yZSBjaGVjayB0aHJlZSB0aGluZ3MsIGFuZCB7QGxpbmsgcmVxdWlyZVN5c3RlbU9yZ1Blcm1pc3Npb259IGNvbXBvc2VzXG4gKiB0aGVtIHNvIG5vIHJvdXRlIGNhbiBmb3JnZXQgb25lOlxuICpcbiAqICAxLiB7QGxpbmsgcmVxdWlyZVN5c3RlbU9yZ30g4oCUIHRoZSBjYWxsZXIncyBBQ1RJVkUgb3JnIGlzIHRoZSBzeXN0ZW0gb3JnLiBBXG4gKiAgICAgdG9rZW4gbWludGVkIGluIGEgdGVuYW50IG9yZyBpcyByZWZ1c2VkIGV2ZW4gZm9yIHRoZSBzYW1lIHBlcnNvbiAoYW5kIGV2ZW5cbiAqICAgICBmb3IgYSBzdXBlcmFkbWluOiB0aGV5IHN3aXRjaCB0byB0aGUgc3lzdGVtIG9yZyB0byBhY3Qgb24gdGhlIGVjb3N5c3RlbSxcbiAqICAgICBzbyBldmVyeSBnb3Zlcm5hbmNlIGRlY2lzaW9uIGlzIHJlY29yZGVkIHdpdGggdGhlIHN5c3RlbSBvcmcncyBpZCkuXG4gKiAgMi4gdGhlIHBlcm1pc3Npb24gaXRzZWxmIChgcmVxdWlyZVBlcm1pc3Npb25gLCBhbnktb2YpO1xuICogIDMuIGFuIE1GQS1ncmFkZSBzZXNzaW9uIChgcmVxdWlyZUFzc3VyYW5jZSh7IG1pbkFzc3VyYW5jZTogMiB9KWApLCB3aGljaCBhbHNvXG4gKiAgICAgcmVmdXNlcyBldmVyeSBtYWNoaW5lIGNyZWRlbnRpYWwuXG4gKlxuICogVGhlIHJvdXRlLWNvdmVyYWdlIGdvdmVybmFuY2UgY2hlY2sgKGBmaW5kU3lzdGVtT3JnR3VhcmRWaW9sYXRpb25zYCBpblxuICogYHRlc3Rpbmcvcm91dGUtY292ZXJhZ2UudHNgKSBmYWlscyBhbnkgcm91dGUgdGhhdCBnYXRlcyBvbiBhIHN5c3RlbS1vcmctb25seVxuICogcGVybWlzc2lvbiB3aXRob3V0IDEgYW5kIDMsIHNvIGEgaGFuZC1yb2xsZWQgY2hhaW4gY2Fubm90IHNsaXAgdGhyb3VnaC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IE5leHRGdW5jdGlvbiwgUmVxdWVzdCwgUmVxdWVzdEhhbmRsZXIsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyByZXF1aXJlQXNzdXJhbmNlIH0gZnJvbSAnLi9hc3N1cmFuY2UuanMnO1xuaW1wb3J0IHsgcmVjb3JkQXV0aHpEZW5pYWwsIHJlcXVpcmVQZXJtaXNzaW9uIH0gZnJvbSAnLi9wZXJtaXNzaW9uLWdhdGVzLmpzJztcbmltcG9ydCB7IHRhZ1JvdXRlR2F0ZSB9IGZyb20gJy4vcm91dGUtdGFibGUuanMnO1xuaW1wb3J0IHsgaXNTeXN0ZW1PcmdJZCB9IGZyb20gJy4vc3lzdGVtLW9yZy5qcyc7XG5pbXBvcnQgeyBIdHRwU3RhdHVzIH0gZnJvbSAnLi4vY29uc3RhbnRzL2h0dHAtc3RhdHVzLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB7IGlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24sIHR5cGUgUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogV2hldGhlciB0aGUgcmVxdWVzdCdzIEFDVElWRSBvcmcgKHRoZSB0b2tlbidzIGBvcmdhbml6YXRpb25JZGApIGlzIHRoZSBzeXN0ZW1cbiAqICBvcmcuIENvbXBhcmVkIGJ5IGlkIG9ubHkg4oCUIGFuIG9yZyBtZXJlbHkgTkFNRUQgXCJzeXN0ZW1cIiBuZXZlciBxdWFsaWZpZXMuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTeXN0ZW1PcmdSZXF1ZXN0KHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNTeXN0ZW1PcmdJZChyZXEudXNlcj8ub3JnYW5pemF0aW9uSWQpO1xufVxuXG4vKipcbiAqIFJlcXVpcmUgdGhhdCB0aGUgY2FsbGVyJ3MgYWN0aXZlIG9yZyBpcyB0aGUgc3lzdGVtIG9yZy4gQ29tcG9zZSBhZnRlclxuICogYHJlcXVpcmVBdXRoYC4gUmVmdXNhbHMgYXJlIDQwMyBgU1lTVEVNX09SR19SRVFVSVJFRGAsIGNvdW50ZWRcbiAqIChgc3lzdGVtX29yZ19ndWFyZF9yZWZ1c2VkX3RvdGFsYCkgYW5kIGF1ZGl0ZWQgdGhyb3VnaCB0aGUgc2hhcmVkXG4gKiBgYXV0aHouZGVuaWVkYCBzaW5rIChgcmVxdWlyZWQ6ICdzeXN0ZW0tb3JnJ2ApLlxuICovXG5leHBvcnQgY29uc3QgcmVxdWlyZVN5c3RlbU9yZyA9IHRhZ1JvdXRlR2F0ZShmdW5jdGlvbiByZXF1aXJlU3lzdGVtT3JnKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghcmVxLnVzZXIpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICB9XG4gIGlmIChpc1N5c3RlbU9yZ1JlcXVlc3QocmVxKSkgcmV0dXJuIG5leHQoKTtcbiAgZW1pdENvdW50ZXIoJ3N5c3RlbV9vcmdfZ3VhcmRfcmVmdXNlZF90b3RhbCcsIHsgcHJpbmNpcGFsOiByZXEudXNlci5wcmluY2lwYWxUeXBlID8/ICd1bmtub3duJyB9KTtcbiAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLW9yZycpO1xuICByZXR1cm4gc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgJ1RoaXMgYWN0aW9uIGlzIHJlc2VydmVkIGZvciB0aGUgc3lzdGVtIG9yZ2FuaXphdGlvbiDigJQgc3dpdGNoIHRvIGl0IHRvIG1hbmFnZSB0aGUgcGx1Z2luIGVjb3N5c3RlbScsXG4gICAgRXJyb3JDb2RlLlNZU1RFTV9PUkdfUkVRVUlSRUQsXG4gICk7XG59LCB7IGtpbmQ6ICdzeXN0ZW1PcmcnIH0pO1xuXG4vKipcbiAqIFRIRSBnYXRlIGZvciBhbiBlY29zeXN0ZW0tZ292ZXJuYW5jZSByb3V0ZTogc3lzdGVtIG9yZyArIChhbnkgb2YpIHRoZSBnaXZlblxuICogc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb24ocykgKyBhbiBNRkEtZ3JhZGUgaHVtYW4gc2Vzc2lvbi4gUmV0dXJucyB0aGUgY2hhaW5cbiAqIGFzIGFuIGFycmF5LCB3aGljaCBFeHByZXNzIGZsYXR0ZW5zOlxuICpcbiAqIGBgYHRzXG4gKiByb3V0ZXIucG9zdCgnL3JlcXVlc3RzLzppZC9hcHByb3ZlJywgcmVxdWlyZUF1dGgsIHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uKCdwbHVnaW5zOm1vZGVyYXRlJyksXG4gKiAgIHJlcXVpcmVTdGVwVXAsIGF1ZGl0ZWQoJ3BsdWdpbi5yZXF1ZXN0LmFwcHJvdmUnKSwgaGFuZGxlcik7XG4gKiBgYGBcbiAqXG4gKiBUaHJvd3MgYXQgcm91dGUtZGVmaW5pdGlvbiB0aW1lIHdoZW4gaGFuZGVkIGEgcGVybWlzc2lvbiB0aGF0IGlzIE5PVFxuICogc3lzdGVtLW9yZy1vbmx5IOKAlCBhIHRlbmFudCBwZXJtaXNzaW9uIGJlaGluZCB0aGlzIGdhdGUgd291bGQgYmUgdW5yZWFjaGFibGVcbiAqIGZvciBldmVyeSB0ZW5hbnQsIHdoaWNoIGlzIGFsd2F5cyBhIHdpcmluZyBtaXN0YWtlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVN5c3RlbU9yZ1Blcm1pc3Npb24oLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSk6IFJlcXVlc3RIYW5kbGVyW10ge1xuICBpZiAocGVybWlzc2lvbnMubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIG5lZWRzIGF0IGxlYXN0IG9uZSBwZXJtaXNzaW9uJyk7XG4gIGNvbnN0IHRlbmFudCA9IHBlcm1pc3Npb25zLmZpbHRlcigocCkgPT4gIWlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24ocCkpO1xuICBpZiAodGVuYW50Lmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIG9ubHkgdGFrZXMgc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb25zOyBnb3QgJHt0ZW5hbnQuam9pbignLCAnKX1gKTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHJlcXVpcmVTeXN0ZW1PcmcsXG4gICAgcmVxdWlyZVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnMpLFxuICAgIHJlcXVpcmVBc3N1cmFuY2UoeyBtaW5Bc3N1cmFuY2U6IDIgfSksXG4gIF0gYXMgUmVxdWVzdEhhbmRsZXJbXTtcbn1cbiJdfQ==
|
|
@@ -5,8 +5,11 @@ export { requireAssurance, refuseWeakSession, refuseForOrgAdminAssurance, requir
|
|
|
5
5
|
export { userHasPermission, setAuthzDenialAuditor, recordAuthzDenial, requirePermission, requireAllPermissions, requirePermissionOrService, requireServicePrincipal, requireInternalService, isSystemAdmin, hasScope, requireSystemAdmin, requireFeature, type AuthzDenialInfo, } from './permission-gates.js';
|
|
6
6
|
export { isSystemOrgId, SYSTEM_ORG_ID, SYSTEM_ORG_SLUG, } from './system-org.js';
|
|
7
7
|
export { serviceNameOf, isServiceTokenDenied, signServiceToken, getServiceAuthHeader, isServicePrincipal, isServiceAccountPrincipal, isServicePrincipalNamed, verifyServicePrincipal, } from './service-tokens.js';
|
|
8
|
-
export { requireSystemOrg,
|
|
8
|
+
export { requireSystemOrg, requireSystemOrgPermission } from './ecosystem-guard.js';
|
|
9
9
|
export { mongoSanitize, MAX_SANITIZE_DEPTH, } from './mongo-sanitize.js';
|
|
10
10
|
export { proposable, ASK_PROVENANCE_REFUSED_COUNTER, } from './ask-provenance.js';
|
|
11
11
|
export { requireStepUp, type StepUpMethod, STRONG_STEP_UP_METHODS, } from './step-up.js';
|
|
12
|
-
export { tagRouteGate, getRouteGates, audited, buildRouteTable, isWriteMethod, summarizeRouteTable, type RouteTableEntry, } from './route-table.js';
|
|
12
|
+
export { tagRouteGate, getRouteGates, audited, dynamicAuthz, buildRouteTable, isWriteMethod, summarizeRouteTable, DYNAMIC_PRINCIPALS, type DynamicPrincipal, type RouteTableEntry, } from './route-table.js';
|
|
13
|
+
export { armDeferredQuotaCheck, runDeferredQuotaCheck, } from './deferred-quota-check.js';
|
|
14
|
+
export { ON_BEHALF_HEADER, ON_BEHALF_CALLERS, onBehalfHeaders, onBehalfCaller, type OnBehalfSubject, } from './on-behalf.js';
|
|
15
|
+
export { QUOTA_EXEMPT_ROUTES, isQuotaExemptRoute, type QuotaExemptRoute, } from './quota-exempt-routes.js';
|
package/lib/middleware/index.js
CHANGED
|
@@ -7,9 +7,12 @@ export { requireAssurance, refuseWeakSession, refuseForOrgAdminAssurance, requir
|
|
|
7
7
|
export { userHasPermission, setAuthzDenialAuditor, recordAuthzDenial, requirePermission, requireAllPermissions, requirePermissionOrService, requireServicePrincipal, requireInternalService, isSystemAdmin, hasScope, requireSystemAdmin, requireFeature, } from './permission-gates.js';
|
|
8
8
|
export { isSystemOrgId, SYSTEM_ORG_ID, SYSTEM_ORG_SLUG, } from './system-org.js';
|
|
9
9
|
export { serviceNameOf, isServiceTokenDenied, signServiceToken, getServiceAuthHeader, isServicePrincipal, isServiceAccountPrincipal, isServicePrincipalNamed, verifyServicePrincipal, } from './service-tokens.js';
|
|
10
|
-
export { requireSystemOrg,
|
|
10
|
+
export { requireSystemOrg, requireSystemOrgPermission } from './ecosystem-guard.js';
|
|
11
11
|
export { mongoSanitize, MAX_SANITIZE_DEPTH, } from './mongo-sanitize.js';
|
|
12
12
|
export { proposable, ASK_PROVENANCE_REFUSED_COUNTER, } from './ask-provenance.js';
|
|
13
13
|
export { requireStepUp, STRONG_STEP_UP_METHODS, } from './step-up.js';
|
|
14
|
-
export { tagRouteGate, getRouteGates, audited, buildRouteTable, isWriteMethod, summarizeRouteTable, } from './route-table.js';
|
|
15
|
-
|
|
14
|
+
export { tagRouteGate, getRouteGates, audited, dynamicAuthz, buildRouteTable, isWriteMethod, summarizeRouteTable, DYNAMIC_PRINCIPALS, } from './route-table.js';
|
|
15
|
+
export { armDeferredQuotaCheck, runDeferredQuotaCheck, } from './deferred-quota-check.js';
|
|
16
|
+
export { ON_BEHALF_HEADER, ON_BEHALF_CALLERS, onBehalfHeaders, onBehalfCaller, } from './on-behalf.js';
|
|
17
|
+
export { QUOTA_EXEMPT_ROUTES, isQuotaExemptRoute, } from './quota-exempt-routes.js';
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlkZGxld2FyZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFDTCxhQUFhLEVBQ2IsaUJBQWlCLEVBQ2pCLHNCQUFzQixHQUN2QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxXQUFXLEdBQ1osTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixvQkFBb0IsR0FDckIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQiwwQkFBMEIsRUFDMUIsd0JBQXdCLEdBRXpCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsYUFBYSxFQUNiLFFBQVEsRUFDUixrQkFBa0IsRUFDbEIsY0FBYyxHQUVmLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsZUFBZSxHQUNoQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEYsT0FBTyxFQUNMLGFBQWEsRUFDYixrQkFBa0IsR0FDbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsVUFBVSxFQUNWLDhCQUE4QixHQUMvQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxhQUFhLEVBRWIsc0JBQXNCLEdBQ3ZCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFDTCxZQUFZLEVBQ1osYUFBYSxFQUNiLE9BQU8sRUFDUCxZQUFZLEVBQ1osZUFBZSxFQUNmLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsa0JBQWtCLEdBR25CLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixxQkFBcUIsR0FDdEIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsY0FBYyxHQUVmLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixrQkFBa0IsR0FFbkIsTUFBTSwwQkFBMEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5leHBvcnQge1xuICB2ZXJpZnlVc2VySnd0LFxuICB2ZXJpZnlCZWFyZXJUb2tlbixcbiAgaGFzVmFsaWRJZGVudGl0eUNsYWltcyxcbn0gZnJvbSAnLi9qd3QtdmVyaWZ5LmpzJztcbmV4cG9ydCB7XG4gIHJlcXVpcmVBdXRoLFxufSBmcm9tICcuL2F1dGguanMnO1xuZXhwb3J0IHtcbiAgc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUsXG4gIGlzQWNjZXNzVG9rZW5SZXZva2VkLFxufSBmcm9tICcuL3Jldm9jYXRpb24uanMnO1xuZXhwb3J0IHtcbiAgcmVxdWlyZUFzc3VyYW5jZSxcbiAgcmVmdXNlV2Vha1Nlc3Npb24sXG4gIHJlZnVzZUZvck9yZ0FkbWluQXNzdXJhbmNlLFxuICByZXF1aXJlT3JnQWRtaW5Bc3N1cmFuY2UsXG4gIHR5cGUgQXNzdXJhbmNlT3B0aW9ucyxcbn0gZnJvbSAnLi9hc3N1cmFuY2UuanMnO1xuZXhwb3J0IHtcbiAgdXNlckhhc1Blcm1pc3Npb24sXG4gIHNldEF1dGh6RGVuaWFsQXVkaXRvcixcbiAgcmVjb3JkQXV0aHpEZW5pYWwsXG4gIHJlcXVpcmVQZXJtaXNzaW9uLFxuICByZXF1aXJlQWxsUGVybWlzc2lvbnMsXG4gIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlLFxuICByZXF1aXJlU2VydmljZVByaW5jaXBhbCxcbiAgcmVxdWlyZUludGVybmFsU2VydmljZSxcbiAgaXNTeXN0ZW1BZG1pbixcbiAgaGFzU2NvcGUsXG4gIHJlcXVpcmVTeXN0ZW1BZG1pbixcbiAgcmVxdWlyZUZlYXR1cmUsXG4gIHR5cGUgQXV0aHpEZW5pYWxJbmZvLFxufSBmcm9tICcuL3Blcm1pc3Npb24tZ2F0ZXMuanMnO1xuZXhwb3J0IHtcbiAgaXNTeXN0ZW1PcmdJZCxcbiAgU1lTVEVNX09SR19JRCxcbiAgU1lTVEVNX09SR19TTFVHLFxufSBmcm9tICcuL3N5c3RlbS1vcmcuanMnO1xuZXhwb3J0IHtcbiAgc2VydmljZU5hbWVPZixcbiAgaXNTZXJ2aWNlVG9rZW5EZW5pZWQsXG4gIHNpZ25TZXJ2aWNlVG9rZW4sXG4gIGdldFNlcnZpY2VBdXRoSGVhZGVyLFxuICBpc1NlcnZpY2VQcmluY2lwYWwsXG4gIGlzU2VydmljZUFjY291bnRQcmluY2lwYWwsXG4gIGlzU2VydmljZVByaW5jaXBhbE5hbWVkLFxuICB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsLFxufSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmV4cG9ydCB7IHJlcXVpcmVTeXN0ZW1PcmcsIHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIH0gZnJvbSAnLi9lY29zeXN0ZW0tZ3VhcmQuanMnO1xuZXhwb3J0IHtcbiAgbW9uZ29TYW5pdGl6ZSxcbiAgTUFYX1NBTklUSVpFX0RFUFRILFxufSBmcm9tICcuL21vbmdvLXNhbml0aXplLmpzJztcbmV4cG9ydCB7XG4gIHByb3Bvc2FibGUsXG4gIEFTS19QUk9WRU5BTkNFX1JFRlVTRURfQ09VTlRFUixcbn0gZnJvbSAnLi9hc2stcHJvdmVuYW5jZS5qcyc7XG5leHBvcnQge1xuICByZXF1aXJlU3RlcFVwLFxuICB0eXBlIFN0ZXBVcE1ldGhvZCxcbiAgU1RST05HX1NURVBfVVBfTUVUSE9EUyxcbn0gZnJvbSAnLi9zdGVwLXVwLmpzJztcbmV4cG9ydCB7XG4gIHRhZ1JvdXRlR2F0ZSxcbiAgZ2V0Um91dGVHYXRlcyxcbiAgYXVkaXRlZCxcbiAgZHluYW1pY0F1dGh6LFxuICBidWlsZFJvdXRlVGFibGUsXG4gIGlzV3JpdGVNZXRob2QsXG4gIHN1bW1hcml6ZVJvdXRlVGFibGUsXG4gIERZTkFNSUNfUFJJTkNJUEFMUyxcbiAgdHlwZSBEeW5hbWljUHJpbmNpcGFsLFxuICB0eXBlIFJvdXRlVGFibGVFbnRyeSxcbn0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5leHBvcnQge1xuICBhcm1EZWZlcnJlZFF1b3RhQ2hlY2ssXG4gIHJ1bkRlZmVycmVkUXVvdGFDaGVjayxcbn0gZnJvbSAnLi9kZWZlcnJlZC1xdW90YS1jaGVjay5qcyc7XG5leHBvcnQge1xuICBPTl9CRUhBTEZfSEVBREVSLFxuICBPTl9CRUhBTEZfQ0FMTEVSUyxcbiAgb25CZWhhbGZIZWFkZXJzLFxuICBvbkJlaGFsZkNhbGxlcixcbiAgdHlwZSBPbkJlaGFsZlN1YmplY3QsXG59IGZyb20gJy4vb24tYmVoYWxmLmpzJztcbmV4cG9ydCB7XG4gIFFVT1RBX0VYRU1QVF9ST1VURVMsXG4gIGlzUXVvdGFFeGVtcHRSb3V0ZSxcbiAgdHlwZSBRdW90YUV4ZW1wdFJvdXRlLFxufSBmcm9tICcuL3F1b3RhLWV4ZW1wdC1yb3V0ZXMuanMnO1xuIl19
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Request } from 'express';
|
|
2
|
+
/** The header carrying the signed on-behalf marker (lower-case, as Node reads it). */
|
|
3
|
+
export declare const ON_BEHALF_HEADER = "x-pb-on-behalf";
|
|
4
|
+
/**
|
|
5
|
+
* Services whose on-behalf marker is honoured: the ones that forward a user's
|
|
6
|
+
* token as a matter of design. A marker signed by any other service — valid
|
|
7
|
+
* signature or not — is ignored, so a compromised peer that never forwards user
|
|
8
|
+
* tokens cannot start waiving its tenants' meters.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ON_BEHALF_CALLERS: readonly string[];
|
|
11
|
+
/** Who a marker vouches for. Defaults to the ambient request's verified principal. */
|
|
12
|
+
export interface OnBehalfSubject {
|
|
13
|
+
/** The user (`sub`) whose token rides the same request. */
|
|
14
|
+
sub: string;
|
|
15
|
+
/** Their active org. */
|
|
16
|
+
organizationId: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Headers to add beside a forwarded user `Authorization` so the peer does not
|
|
20
|
+
* bill the hop a second time. Mint per call (the marker expires in 120 s).
|
|
21
|
+
*
|
|
22
|
+
* The subject defaults to the ambient audit context's VERIFIED principal (the
|
|
23
|
+
* inbound request this call serves). Returns `{}` — the hop is billed normally,
|
|
24
|
+
* the safe direction — when there is no user principal to vouch for, or when
|
|
25
|
+
* this process cannot sign (no service key).
|
|
26
|
+
*/
|
|
27
|
+
export declare function onBehalfHeaders(subject?: OnBehalfSubject): Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* The internal service that vouched for this request with a VALID on-behalf
|
|
30
|
+
* marker, else `undefined`. Requires the request to be authenticated (`req.user`
|
|
31
|
+
* set by requireAuth) — the marker is only meaningful against a verified user.
|
|
32
|
+
*
|
|
33
|
+
* Every rejection of a PRESENT header is counted on
|
|
34
|
+
* `quota_on_behalf_rejected_total{reason}`: a forged header from a user lands
|
|
35
|
+
* there as `invalid` (no service key signs it), and the request is billed.
|
|
36
|
+
*/
|
|
37
|
+
export declare function onBehalfCaller(req: Request): string | undefined;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* ON-BEHALF calls: a service forwarding the end user's own bearer token to a
|
|
5
|
+
* peer, as part of a request that was ALREADY metered where it arrived.
|
|
6
|
+
*
|
|
7
|
+
* The ask agent acts strictly as the calling user — its tools forward the
|
|
8
|
+
* user's token so the peer's tenancy, permission and compliance gates apply as
|
|
9
|
+
* if the user had called them — and pipeline's confirm-placeholder-plugins does
|
|
10
|
+
* the same against the plugin service. Each of those hops is a USER request to
|
|
11
|
+
* the peer, so the peer's `apiCalls` meter billed it: one agent turn was 10-20
|
|
12
|
+
* apiCalls on top of the turn itself (which is metered, and AI-reserved).
|
|
13
|
+
*
|
|
14
|
+
* The marker that waives that second charge has to be something the USER CANNOT
|
|
15
|
+
* PRODUCE, or any member could stop paying for API calls by setting a header.
|
|
16
|
+
* So it is a SIGNED SERVICE TOKEN (the calling service's own ES256 key, the same
|
|
17
|
+
* key material `requireAuth` trusts for service principals), carried in
|
|
18
|
+
* {@link ON_BEHALF_HEADER} beside the user's untouched `Authorization`:
|
|
19
|
+
*
|
|
20
|
+
* - `type: 'on_behalf'` — never `access`, so the marker is useless as a bearer
|
|
21
|
+
* token anywhere (`requireAuth` and `verifyServicePrincipal` both demand
|
|
22
|
+
* `type: 'access'`);
|
|
23
|
+
* - `obo` + `organizationId` — BOUND to the user and org it vouches for, and
|
|
24
|
+
* honoured only when both equal the request's verified `req.user`;
|
|
25
|
+
* - the signer must be on {@link ON_BEHALF_CALLERS} — a service that forwards
|
|
26
|
+
* user tokens by design — and not on the service-token denylist;
|
|
27
|
+
* - 120 s TTL, minted per outbound call.
|
|
28
|
+
*
|
|
29
|
+
* What a valid marker changes is narrow: the apiCalls/automationCalls METER and
|
|
30
|
+
* CHECK skip the request (`callQuotaExemption`). Tenancy, permissions, audit and
|
|
31
|
+
* every reservation-gated quota (aiCalls, pipelines, plugins) apply exactly as
|
|
32
|
+
* before — an on-behalf `/generate` still reserves its own aiCalls slot.
|
|
33
|
+
*/
|
|
34
|
+
import { randomUUID } from 'crypto';
|
|
35
|
+
import { issuerAudienceOptions } from './jwt-verify.js';
|
|
36
|
+
import { isServiceTokenDenied, serviceNameOf } from './service-tokens.js';
|
|
37
|
+
import { currentAuditContext } from '../services/audit-context.js';
|
|
38
|
+
import { isServiceKid, signServiceJwt, verifyServiceJwt } from '../services/service-keys.js';
|
|
39
|
+
import { decodeJwtHeader } from '../utils/jwk.js';
|
|
40
|
+
import { createLogger } from '../utils/logger.js';
|
|
41
|
+
import { emitCounter } from '../utils/metric-emitter.js';
|
|
42
|
+
const logger = createLogger('on-behalf');
|
|
43
|
+
/** The header carrying the signed on-behalf marker (lower-case, as Node reads it). */
|
|
44
|
+
export const ON_BEHALF_HEADER = 'x-pb-on-behalf';
|
|
45
|
+
/**
|
|
46
|
+
* Services whose on-behalf marker is honoured: the ones that forward a user's
|
|
47
|
+
* token as a matter of design. A marker signed by any other service — valid
|
|
48
|
+
* signature or not — is ignored, so a compromised peer that never forwards user
|
|
49
|
+
* tokens cannot start waiving its tenants' meters.
|
|
50
|
+
*/
|
|
51
|
+
export const ON_BEHALF_CALLERS = ['ask', 'pipeline'];
|
|
52
|
+
/** Marker lifetime. Minted per outbound call, so it only has to outlive one hop. */
|
|
53
|
+
const ON_BEHALF_TTL_SECONDS = 120;
|
|
54
|
+
/** The `type` claim that makes the marker unusable as an access token. */
|
|
55
|
+
const ON_BEHALF_TOKEN_TYPE = 'on_behalf';
|
|
56
|
+
/**
|
|
57
|
+
* Headers to add beside a forwarded user `Authorization` so the peer does not
|
|
58
|
+
* bill the hop a second time. Mint per call (the marker expires in 120 s).
|
|
59
|
+
*
|
|
60
|
+
* The subject defaults to the ambient audit context's VERIFIED principal (the
|
|
61
|
+
* inbound request this call serves). Returns `{}` — the hop is billed normally,
|
|
62
|
+
* the safe direction — when there is no user principal to vouch for, or when
|
|
63
|
+
* this process cannot sign (no service key).
|
|
64
|
+
*/
|
|
65
|
+
export function onBehalfHeaders(subject) {
|
|
66
|
+
const principal = subject ?? ambientSubject();
|
|
67
|
+
if (!principal)
|
|
68
|
+
return {};
|
|
69
|
+
try {
|
|
70
|
+
const token = signServiceJwt({
|
|
71
|
+
type: ON_BEHALF_TOKEN_TYPE,
|
|
72
|
+
principalType: 'service',
|
|
73
|
+
obo: principal.sub,
|
|
74
|
+
organizationId: principal.organizationId,
|
|
75
|
+
jti: randomUUID(),
|
|
76
|
+
}, { serviceName: process.env.SERVICE_NAME || 'api', expiresInSeconds: ON_BEHALF_TTL_SECONDS, ...issuerAudienceOptions() });
|
|
77
|
+
return { [ON_BEHALF_HEADER]: token };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
logger.debug('On-behalf marker not minted; the peer will meter the hop', { error: String(err) });
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function ambientSubject() {
|
|
85
|
+
const user = currentAuditContext()?.principal?.();
|
|
86
|
+
if (!user || user.principalType === 'service' || !user.sub || !user.organizationId)
|
|
87
|
+
return undefined;
|
|
88
|
+
return { sub: user.sub, organizationId: user.organizationId };
|
|
89
|
+
}
|
|
90
|
+
/** Memo per request: the meter (on `finish`) and the check (in requireAuth) both ask. */
|
|
91
|
+
const verdicts = new WeakMap();
|
|
92
|
+
/**
|
|
93
|
+
* The internal service that vouched for this request with a VALID on-behalf
|
|
94
|
+
* marker, else `undefined`. Requires the request to be authenticated (`req.user`
|
|
95
|
+
* set by requireAuth) — the marker is only meaningful against a verified user.
|
|
96
|
+
*
|
|
97
|
+
* Every rejection of a PRESENT header is counted on
|
|
98
|
+
* `quota_on_behalf_rejected_total{reason}`: a forged header from a user lands
|
|
99
|
+
* there as `invalid` (no service key signs it), and the request is billed.
|
|
100
|
+
*/
|
|
101
|
+
export function onBehalfCaller(req) {
|
|
102
|
+
const memo = verdicts.get(req);
|
|
103
|
+
if (memo !== undefined)
|
|
104
|
+
return memo ?? undefined;
|
|
105
|
+
const verdict = verifyMarker(req);
|
|
106
|
+
verdicts.set(req, verdict);
|
|
107
|
+
return verdict ?? undefined;
|
|
108
|
+
}
|
|
109
|
+
function verifyMarker(req) {
|
|
110
|
+
const raw = req.headers?.[ON_BEHALF_HEADER];
|
|
111
|
+
const token = Array.isArray(raw) ? raw[0] : raw;
|
|
112
|
+
if (!token)
|
|
113
|
+
return null;
|
|
114
|
+
const reject = (reason) => {
|
|
115
|
+
emitCounter('quota_on_behalf_rejected_total', { reason });
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
const user = req.user;
|
|
119
|
+
if (!user?.sub || !user.organizationId)
|
|
120
|
+
return reject('unauthenticated');
|
|
121
|
+
try {
|
|
122
|
+
const header = decodeJwtHeader(token);
|
|
123
|
+
if (!header?.kid || !isServiceKid(header.kid))
|
|
124
|
+
return reject('invalid');
|
|
125
|
+
const claims = verifyServiceJwt(token, { kid: header.kid, ...issuerAudienceOptions() });
|
|
126
|
+
if (claims.type !== ON_BEHALF_TOKEN_TYPE || claims.principalType !== 'service')
|
|
127
|
+
return reject('invalid');
|
|
128
|
+
const caller = serviceNameOf(claims);
|
|
129
|
+
if (!caller || isServiceTokenDenied(claims))
|
|
130
|
+
return reject('denied');
|
|
131
|
+
if (!ON_BEHALF_CALLERS.includes(caller))
|
|
132
|
+
return reject('caller');
|
|
133
|
+
if (claims.obo !== user.sub)
|
|
134
|
+
return reject('subject');
|
|
135
|
+
if (String(claims.organizationId ?? '').toLowerCase() !== user.organizationId.toLowerCase())
|
|
136
|
+
return reject('org');
|
|
137
|
+
return caller;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return reject('invalid');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib24tYmVoYWxmLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvb24tYmVoYWxmLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFcEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0YsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRXpDLHNGQUFzRjtBQUN0RixNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUVqRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztBQUV4RSxvRkFBb0Y7QUFDcEYsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFFbEMsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsV0FBVyxDQUFDO0FBVXpDOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxPQUF5QjtJQUN2RCxNQUFN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ZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBPTi1CRUhBTEYgY2FsbHM6IGEgc2VydmljZSBmb3J3YXJkaW5nIHRoZSBlbmQgdXNlcidzIG93biBiZWFyZXIgdG9rZW4gdG8gYVxuICogcGVlciwgYXMgcGFydCBvZiBhIHJlcXVlc3QgdGhhdCB3YXMgQUxSRUFEWSBtZXRlcmVkIHdoZXJlIGl0IGFycml2ZWQuXG4gKlxuICogVGhlIGFzayBhZ2VudCBhY3RzIHN0cmljdGx5IGFzIHRoZSBjYWxsaW5nIHVzZXIg4oCUIGl0cyB0b29scyBmb3J3YXJkIHRoZVxuICogdXNlcidzIHRva2VuIHNvIHRoZSBwZWVyJ3MgdGVuYW5jeSwgcGVybWlzc2lvbiBhbmQgY29tcGxpYW5jZSBnYXRlcyBhcHBseSBhc1xuICogaWYgdGhlIHVzZXIgaGFkIGNhbGxlZCB0aGVtIOKAlCBhbmQgcGlwZWxpbmUncyBjb25maXJtLXBsYWNlaG9sZGVyLXBsdWdpbnMgZG9lc1xuICogdGhlIHNhbWUgYWdhaW5zdCB0aGUgcGx1Z2luIHNlcnZpY2UuIEVhY2ggb2YgdGhvc2UgaG9wcyBpcyBhIFVTRVIgcmVxdWVzdCB0b1xuICogdGhlIHBlZXIsIHNvIHRoZSBwZWVyJ3MgYGFwaUNhbGxzYCBtZXRlciBiaWxsZWQgaXQ6IG9uZSBhZ2VudCB0dXJuIHdhcyAxMC0yMFxuICogYXBpQ2FsbHMgb24gdG9wIG9mIHRoZSB0dXJuIGl0c2VsZiAod2hpY2ggaXMgbWV0ZXJlZCwgYW5kIEFJLXJlc2VydmVkKS5cbiAqXG4gKiBUaGUgbWFya2VyIHRoYXQgd2FpdmVzIHRoYXQgc2Vjb25kIGNoYXJnZSBoYXMgdG8gYmUgc29tZXRoaW5nIHRoZSBVU0VSIENBTk5PVFxuICogUFJPRFVDRSwgb3IgYW55IG1lbWJlciBjb3VsZCBzdG9wIHBheWluZyBmb3IgQVBJIGNhbGxzIGJ5IHNldHRpbmcgYSBoZWFkZXIuXG4gKiBTbyBpdCBpcyBhIFNJR05FRCBTRVJWSUNFIFRPS0VOICh0aGUgY2FsbGluZyBzZXJ2aWNlJ3Mgb3duIEVTMjU2IGtleSwgdGhlIHNhbWVcbiAqIGtleSBtYXRlcmlhbCBgcmVxdWlyZUF1dGhgIHRydXN0cyBmb3Igc2VydmljZSBwcmluY2lwYWxzKSwgY2FycmllZCBpblxuICoge0BsaW5rIE9OX0JFSEFMRl9IRUFERVJ9IGJlc2lkZSB0aGUgdXNlcidzIHVudG91Y2hlZCBgQXV0aG9yaXphdGlvbmA6XG4gKlxuICogIC0gYHR5cGU6ICdvbl9iZWhhbGYnYCDigJQgbmV2ZXIgYGFjY2Vzc2AsIHNvIHRoZSBtYXJrZXIgaXMgdXNlbGVzcyBhcyBhIGJlYXJlclxuICogICAgdG9rZW4gYW55d2hlcmUgKGByZXF1aXJlQXV0aGAgYW5kIGB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsYCBib3RoIGRlbWFuZFxuICogICAgYHR5cGU6ICdhY2Nlc3MnYCk7XG4gKiAgLSBgb2JvYCArIGBvcmdhbml6YXRpb25JZGAg4oCUIEJPVU5EIHRvIHRoZSB1c2VyIGFuZCBvcmcgaXQgdm91Y2hlcyBmb3IsIGFuZFxuICogICAgaG9ub3VyZWQgb25seSB3aGVuIGJvdGggZXF1YWwgdGhlIHJlcXVlc3QncyB2ZXJpZmllZCBgcmVxLnVzZXJgO1xuICogIC0gdGhlIHNpZ25lciBtdXN0IGJlIG9uIHtAbGluayBPTl9CRUhBTEZfQ0FMTEVSU30g4oCUIGEgc2VydmljZSB0aGF0IGZvcndhcmRzXG4gKiAgICB1c2VyIHRva2VucyBieSBkZXNpZ24g4oCUIGFuZCBub3Qgb24gdGhlIHNlcnZpY2UtdG9rZW4gZGVueWxpc3Q7XG4gKiAgLSAxMjAgcyBUVEwsIG1pbnRlZCBwZXIgb3V0Ym91bmQgY2FsbC5cbiAqXG4gKiBXaGF0IGEgdmFsaWQgbWFya2VyIGNoYW5nZXMgaXMgbmFycm93OiB0aGUgYXBpQ2FsbHMvYXV0b21hdGlvbkNhbGxzIE1FVEVSIGFuZFxuICogQ0hFQ0sgc2tpcCB0aGUgcmVxdWVzdCAoYGNhbGxRdW90YUV4ZW1wdGlvbmApLiBUZW5hbmN5LCBwZXJtaXNzaW9ucywgYXVkaXQgYW5kXG4gKiBldmVyeSByZXNlcnZhdGlvbi1nYXRlZCBxdW90YSAoYWlDYWxscywgcGlwZWxpbmVzLCBwbHVnaW5zKSBhcHBseSBleGFjdGx5IGFzXG4gKiBiZWZvcmUg4oCUIGFuIG9uLWJlaGFsZiBgL2dlbmVyYXRlYCBzdGlsbCByZXNlcnZlcyBpdHMgb3duIGFpQ2FsbHMgc2xvdC5cbiAqL1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgaXNzdWVyQXVkaWVuY2VPcHRpb25zIH0gZnJvbSAnLi9qd3QtdmVyaWZ5LmpzJztcbmltcG9ydCB7IGlzU2VydmljZVRva2VuRGVuaWVkLCBzZXJ2aWNlTmFtZU9mIH0gZnJvbSAnLi9zZXJ2aWNlLXRva2Vucy5qcyc7XG5pbXBvcnQgeyBjdXJyZW50QXVkaXRDb250ZXh0IH0gZnJvbSAnLi4vc2VydmljZXMvYXVkaXQtY29udGV4dC5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VLaWQsIHNpZ25TZXJ2aWNlSnd0LCB2ZXJpZnlTZXJ2aWNlSnd0IH0gZnJvbSAnLi4vc2VydmljZXMvc2VydmljZS1rZXlzLmpzJztcbmltcG9ydCB7IGRlY29kZUp3dEhlYWRlciB9IGZyb20gJy4uL3V0aWxzL2p3ay5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignb24tYmVoYWxmJyk7XG5cbi8qKiBUaGUgaGVhZGVyIGNhcnJ5aW5nIHRoZSBzaWduZWQgb24tYmVoYWxmIG1hcmtlciAobG93ZXItY2FzZSwgYXMgTm9kZSByZWFkcyBpdCkuICovXG5leHBvcnQgY29uc3QgT05fQkVIQUxGX0hFQURFUiA9ICd4LXBiLW9uLWJlaGFsZic7XG5cbi8qKlxuICogU2VydmljZXMgd2hvc2Ugb24tYmVoYWxmIG1hcmtlciBpcyBob25vdXJlZDogdGhlIG9uZXMgdGhhdCBmb3J3YXJkIGEgdXNlcidzXG4gKiB0b2tlbiBhcyBhIG1hdHRlciBvZiBkZXNpZ24uIEEgbWFya2VyIHNpZ25lZCBieSBhbnkgb3RoZXIgc2VydmljZSDigJQgdmFsaWRcbiAqIHNpZ25hdHVyZSBvciBub3Qg4oCUIGlzIGlnbm9yZWQsIHNvIGEgY29tcHJvbWlzZWQgcGVlciB0aGF0IG5ldmVyIGZvcndhcmRzIHVzZXJcbiAqIHRva2VucyBjYW5ub3Qgc3RhcnQgd2FpdmluZyBpdHMgdGVuYW50cycgbWV0ZXJzLlxuICovXG5leHBvcnQgY29uc3QgT05fQkVIQUxGX0NBTExFUlM6IHJlYWRvbmx5IHN0cmluZ1tdID0gWydhc2snLCAncGlwZWxpbmUnXTtcblxuLyoqIE1hcmtlciBsaWZldGltZS4gTWludGVkIHBlciBvdXRib3VuZCBjYWxsLCBzbyBpdCBvbmx5IGhhcyB0byBvdXRsaXZlIG9uZSBob3AuICovXG5jb25zdCBPTl9CRUhBTEZfVFRMX1NFQ09ORFMgPSAxMjA7XG5cbi8qKiBUaGUgYHR5cGVgIGNsYWltIHRoYXQgbWFrZXMgdGhlIG1hcmtlciB1bnVzYWJsZSBhcyBhbiBhY2Nlc3MgdG9rZW4uICovXG5jb25zdCBPTl9CRUhBTEZfVE9LRU5fVFlQRSA9ICdvbl9iZWhhbGYnO1xuXG4vKiogV2hvIGEgbWFya2VyIHZvdWNoZXMgZm9yLiBEZWZhdWx0cyB0byB0aGUgYW1iaWVudCByZXF1ZXN0J3MgdmVyaWZpZWQgcHJpbmNpcGFsLiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbkJlaGFsZlN1YmplY3Qge1xuICAvKiogVGhlIHVzZXIgKGBzdWJgKSB3aG9zZSB0b2tlbiByaWRlcyB0aGUgc2FtZSByZXF1ZXN0LiAqL1xuICBzdWI6IHN0cmluZztcbiAgLyoqIFRoZWlyIGFjdGl2ZSBvcmcuICovXG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogSGVhZGVycyB0byBhZGQgYmVzaWRlIGEgZm9yd2FyZGVkIHVzZXIgYEF1dGhvcml6YXRpb25gIHNvIHRoZSBwZWVyIGRvZXMgbm90XG4gKiBiaWxsIHRoZSBob3AgYSBzZWNvbmQgdGltZS4gTWludCBwZXIgY2FsbCAodGhlIG1hcmtlciBleHBpcmVzIGluIDEyMCBzKS5cbiAqXG4gKiBUaGUgc3ViamVjdCBkZWZhdWx0cyB0byB0aGUgYW1iaWVudCBhdWRpdCBjb250ZXh0J3MgVkVSSUZJRUQgcHJpbmNpcGFsICh0aGVcbiAqIGluYm91bmQgcmVxdWVzdCB0aGlzIGNhbGwgc2VydmVzKS4gUmV0dXJucyBge31gIOKAlCB0aGUgaG9wIGlzIGJpbGxlZCBub3JtYWxseSxcbiAqIHRoZSBzYWZlIGRpcmVjdGlvbiDigJQgd2hlbiB0aGVyZSBpcyBubyB1c2VyIHByaW5jaXBhbCB0byB2b3VjaCBmb3IsIG9yIHdoZW5cbiAqIHRoaXMgcHJvY2VzcyBjYW5ub3Qgc2lnbiAobm8gc2VydmljZSBrZXkpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb25CZWhhbGZIZWFkZXJzKHN1YmplY3Q/OiBPbkJlaGFsZlN1YmplY3QpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgcHJpbmNpcGFsID0gc3ViamVjdCA/PyBhbWJpZW50U3ViamVjdCgpO1xuICBpZiAoIXByaW5jaXBhbCkgcmV0dXJuIHt9O1xuICB0cnkge1xuICAgIGNvbnN0IHRva2VuID0gc2lnblNlcnZpY2VKd3QoXG4gICAgICB7XG4gICAgICAgIHR5cGU6IE9OX0JFSEFMRl9UT0tFTl9UWVBFLFxuICAgICAgICBwcmluY2lwYWxUeXBlOiAnc2VydmljZScsXG4gICAgICAgIG9ibzogcHJpbmNpcGFsLnN1YixcbiAgICAgICAgb3JnYW5pemF0aW9uSWQ6IHByaW5jaXBhbC5vcmdhbml6YXRpb25JZCxcbiAgICAgICAganRpOiByYW5kb21VVUlEKCksXG4gICAgICB9LFxuICAgICAgeyBzZXJ2aWNlTmFtZTogcHJvY2Vzcy5lbnYuU0VSVklDRV9OQU1FIHx8ICdhcGknLCBleHBpcmVzSW5TZWNvbmRzOiBPTl9CRUhBTEZfVFRMX1NFQ09ORFMsIC4uLmlzc3VlckF1ZGllbmNlT3B0aW9ucygpIH0sXG4gICAgKTtcbiAgICByZXR1cm4geyBbT05fQkVIQUxGX0hFQURFUl06IHRva2VuIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZygnT24tYmVoYWxmIG1hcmtlciBub3QgbWludGVkOyB0aGUgcGVlciB3aWxsIG1ldGVyIHRoZSBob3AnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gYW1iaWVudFN1YmplY3QoKTogT25CZWhhbGZTdWJqZWN0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdXNlciA9IGN1cnJlbnRBdWRpdENvbnRleHQoKT8ucHJpbmNpcGFsPy4oKTtcbiAgaWYgKCF1c2VyIHx8IHVzZXIucHJpbmNpcGFsVHlwZSA9PT0gJ3NlcnZpY2UnIHx8ICF1c2VyLnN1YiB8fCAhdXNlci5vcmdhbml6YXRpb25JZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHsgc3ViOiB1c2VyLnN1Yiwgb3JnYW5pemF0aW9uSWQ6IHVzZXIub3JnYW5pemF0aW9uSWQgfTtcbn1cblxuLyoqIE1lbW8gcGVyIHJlcXVlc3Q6IHRoZSBtZXRlciAob24gYGZpbmlzaGApIGFuZCB0aGUgY2hlY2sgKGluIHJlcXVpcmVBdXRoKSBib3RoIGFzay4gKi9cbmNvbnN0IHZlcmRpY3RzID0gbmV3IFdlYWtNYXA8UmVxdWVzdCwgc3RyaW5nIHwgbnVsbD4oKTtcblxuLyoqXG4gKiBUaGUgaW50ZXJuYWwgc2VydmljZSB0aGF0IHZvdWNoZWQgZm9yIHRoaXMgcmVxdWVzdCB3aXRoIGEgVkFMSUQgb24tYmVoYWxmXG4gKiBtYXJrZXIsIGVsc2UgYHVuZGVmaW5lZGAuIFJlcXVpcmVzIHRoZSByZXF1ZXN0IHRvIGJlIGF1dGhlbnRpY2F0ZWQgKGByZXEudXNlcmBcbiAqIHNldCBieSByZXF1aXJlQXV0aCkg4oCUIHRoZSBtYXJrZXIgaXMgb25seSBtZWFuaW5nZnVsIGFnYWluc3QgYSB2ZXJpZmllZCB1c2VyLlxuICpcbiAqIEV2ZXJ5IHJlamVjdGlvbiBvZiBhIFBSRVNFTlQgaGVhZGVyIGlzIGNvdW50ZWQgb25cbiAqIGBxdW90YV9vbl9iZWhhbGZfcmVqZWN0ZWRfdG90YWx7cmVhc29ufWA6IGEgZm9yZ2VkIGhlYWRlciBmcm9tIGEgdXNlciBsYW5kc1xuICogdGhlcmUgYXMgYGludmFsaWRgIChubyBzZXJ2aWNlIGtleSBzaWducyBpdCksIGFuZCB0aGUgcmVxdWVzdCBpcyBiaWxsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkJlaGFsZkNhbGxlcihyZXE6IFJlcXVlc3QpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBtZW1vID0gdmVyZGljdHMuZ2V0KHJlcSk7XG4gIGlmIChtZW1vICE9PSB1bmRlZmluZWQpIHJldHVybiBtZW1vID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgdmVyZGljdCA9IHZlcmlmeU1hcmtlcihyZXEpO1xuICB2ZXJkaWN0cy5zZXQocmVxLCB2ZXJkaWN0KTtcbiAgcmV0dXJuIHZlcmRpY3QgPz8gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlNYXJrZXIocmVxOiBSZXF1ZXN0KTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHJhdyA9IHJlcS5oZWFkZXJzPy5bT05fQkVIQUxGX0hFQURFUl07XG4gIGNvbnN0IHRva2VuID0gQXJyYXkuaXNBcnJheShyYXcpID8gcmF3WzBdIDogcmF3O1xuICBpZiAoIXRva2VuKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcmVqZWN0ID0gKHJlYXNvbjogc3RyaW5nKTogbnVsbCA9PiB7XG4gICAgZW1pdENvdW50ZXIoJ3F1b3RhX29uX2JlaGFsZl9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uIH0pO1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuICBjb25zdCB1c2VyID0gcmVxLnVzZXI7XG4gIGlmICghdXNlcj8uc3ViIHx8ICF1c2VyLm9yZ2FuaXphdGlvbklkKSByZXR1cm4gcmVqZWN0KCd1bmF1dGhlbnRpY2F0ZWQnKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBoZWFkZXIgPSBkZWNvZGVKd3RIZWFkZXIodG9rZW4pO1xuICAgIGlmICghaGVhZGVyPy5raWQgfHwgIWlzU2VydmljZUtpZChoZWFkZXIua2lkKSkgcmV0dXJuIHJlamVjdCgnaW52YWxpZCcpO1xuICAgIGNvbnN0IGNsYWltcyA9IHZlcmlmeVNlcnZpY2VKd3Q8eyB0eXBlPzogc3RyaW5nOyBwcmluY2lwYWxUeXBlPzogc3RyaW5nOyBzdWI/OiBzdHJpbmc7IG9ibz86IHN0cmluZzsgb3JnYW5pemF0aW9uSWQ/OiBzdHJpbmcgfT4oXG4gICAgICB0b2tlbiwgeyBraWQ6IGhlYWRlci5raWQsIC4uLmlzc3VlckF1ZGllbmNlT3B0aW9ucygpIH0sXG4gICAgKTtcbiAgICBpZiAoY2xhaW1zLnR5cGUgIT09IE9OX0JFSEFMRl9UT0tFTl9UWVBFIHx8IGNsYWltcy5wcmluY2lwYWxUeXBlICE9PSAnc2VydmljZScpIHJldHVybiByZWplY3QoJ2ludmFsaWQnKTtcbiAgICBjb25zdCBjYWxsZXIgPSBzZXJ2aWNlTmFtZU9mKGNsYWltcyk7XG4gICAgaWYgKCFjYWxsZXIgfHwgaXNTZXJ2aWNlVG9rZW5EZW5pZWQoY2xhaW1zKSkgcmV0dXJuIHJlamVjdCgnZGVuaWVkJyk7XG4gICAgaWYgKCFPTl9CRUhBTEZfQ0FMTEVSUy5pbmNsdWRlcyhjYWxsZXIpKSByZXR1cm4gcmVqZWN0KCdjYWxsZXInKTtcbiAgICBpZiAoY2xhaW1zLm9ibyAhPT0gdXNlci5zdWIpIHJldHVybiByZWplY3QoJ3N1YmplY3QnKTtcbiAgICBpZiAoU3RyaW5nKGNsYWltcy5vcmdhbml6YXRpb25JZCA/PyAnJykudG9Mb3dlckNhc2UoKSAhPT0gdXNlci5vcmdhbml6YXRpb25JZC50b0xvd2VyQ2FzZSgpKSByZXR1cm4gcmVqZWN0KCdvcmcnKTtcbiAgICByZXR1cm4gY2FsbGVyO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gcmVqZWN0KCdpbnZhbGlkJyk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* `authz.denied` audit sink they report refusals to.
|
|
4
4
|
*/
|
|
5
5
|
import type { Request, Response, NextFunction } from 'express';
|
|
6
|
+
import { type AuditAuthBlock } from '../services/audit-context.js';
|
|
6
7
|
import { type Permission } from '../types/permissions.js';
|
|
7
8
|
/**
|
|
8
9
|
* Whether the request's user holds `permission`. Superadmins implicitly hold
|
|
@@ -26,6 +27,16 @@ export interface AuthzDenialInfo {
|
|
|
26
27
|
path: string;
|
|
27
28
|
/** What was required: the missing permission(s), or 'system-admin'. */
|
|
28
29
|
required: string;
|
|
30
|
+
/** Client ip (`req.ip`, proxy-resolved). */
|
|
31
|
+
ip?: string;
|
|
32
|
+
/** Sanitized, length-capped User-Agent. */
|
|
33
|
+
userAgent?: string;
|
|
34
|
+
/** The request's correlation id (the ambient audit context's, else a valid `X-Request-Id`). */
|
|
35
|
+
requestId?: string;
|
|
36
|
+
/** The real sysadmin behind an impersonation token, from the verified token. */
|
|
37
|
+
impersonatorId?: string;
|
|
38
|
+
/** The credential that was refused (key id, session, scope, …) — the `_auth` block. */
|
|
39
|
+
auth?: AuditAuthBlock;
|
|
29
40
|
}
|
|
30
41
|
/**
|
|
31
42
|
* Register (or clear, with `undefined`) the process-wide authorization-denial
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { tagRouteGate } from './route-table.js';
|
|
4
4
|
import { isServicePrincipal, serviceNameOf } from './service-tokens.js';
|
|
5
5
|
import { HttpStatus } from '../constants/http-status.js';
|
|
6
|
+
import { auditAuthBlock, currentAuditContext, sanitizeCorrelationId, sanitizeUserAgent } from '../services/audit-context.js';
|
|
6
7
|
import { serviceIdentity } from '../services/service-keys.js';
|
|
7
8
|
import { ErrorCode } from '../types/error-codes.js';
|
|
8
9
|
import { hasPermission } from '../types/permissions.js';
|
|
@@ -60,6 +61,11 @@ export function recordAuthzDenial(req, required) {
|
|
|
60
61
|
// query param, and this path is persisted verbatim into the audit log.
|
|
61
62
|
path: (req.originalUrl || req.url).split('?')[0],
|
|
62
63
|
required,
|
|
64
|
+
ip: req.ip,
|
|
65
|
+
userAgent: sanitizeUserAgent(req.headers?.['user-agent']),
|
|
66
|
+
requestId: currentAuditContext()?.requestId ?? sanitizeCorrelationId(req.headers?.['x-request-id']),
|
|
67
|
+
impersonatorId: req.user?.impersonatorId,
|
|
68
|
+
auth: auditAuthBlock(req.user),
|
|
63
69
|
});
|
|
64
70
|
}
|
|
65
71
|
catch {
|
|
@@ -257,4 +263,4 @@ export function requireFeature(feature) {
|
|
|
257
263
|
next();
|
|
258
264
|
}, { kind: 'feature', feature });
|
|
259
265
|
}
|
|
260
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1nYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQVF0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0M7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUFZLEVBQUUsVUFBc0I7SUFDcEUsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDbEYsQ0FBQztBQW9CRDs7Ozs7OztHQU9HO0FBQ0gsSUFBSSxrQkFBaUUsQ0FBQztBQUV0RTs7O0dBR0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsRUFBaUQ7SUFDckYsa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0FBQzFCLENBQUM7QUFF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QUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVsRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsNERBQTREO1lBQzVELDJEQUEyRDtZQUMzRCxzRUFBc0U7WUFDdEUsaUJBQWlCLENBQUMsR0FBRyxFQUFFLFdBQVcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3QyxPQUFPLFNBQVMsQ0FDZCxHQUFHLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFDekIsd0NBQXdDLE9BQU8sR0FBRyxFQUNsRCxTQUFTLENBQUMsd0JBQXdCLENBQ25DLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEF1dGhvcml6YXRpb24gZ2F0ZXMg4oCUIHBlcm1pc3Npb25zLCBzeXN0ZW0gYWRtaW4sIGZlYXR1cmVzIOKAlCBhbmQgdGhlXG4gKiBgYXV0aHouZGVuaWVkYCBhdWRpdCBzaW5rIHRoZXkgcmVwb3J0IHJlZnVzYWxzIHRvLlxuICovXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdGFnUm91dGVHYXRlIH0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VQcmluY2lwYWwsIHNlcnZpY2VOYW1lT2YgfSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHsgc2VydmljZUlkZW50aXR5IH0gZnJvbSAnLi4vc2VydmljZXMvc2VydmljZS1rZXlzLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB7IHR5cGUgUGVybWlzc2lvbiwgaGFzUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBlbWl0Q291bnRlciB9IGZyb20gJy4uL3V0aWxzL21ldHJpYy1lbWl0dGVyLmpzJztcbmltcG9ydCB7IHNlbmRFcnJvciB9IGZyb20gJy4uL3V0aWxzL3Jlc3BvbnNlLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdhdXRoLW1pZGRsZXdhcmUnKTtcbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHVzZXIgaG9sZHMgYHBlcm1pc3Npb25gLiBTdXBlcmFkbWlucyBpbXBsaWNpdGx5IGhvbGRcbiAqIGV2ZXJ5IHBlcm1pc3Npb24uIFJlYWRzIHRoZSByZXNvbHZlZCBgcGVybWlzc2lvbnNgIGNsYWltIChzZXQgYXQgdG9rZW4gaXNzdWUsXG4gKiBvciByZS1kZXJpdmVkIHBlciByZXF1ZXN0IGJ5IHRoZSBwbGF0Zm9ybSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VySGFzUGVybWlzc2lvbihyZXE6IFJlcXVlc3QsIHBlcm1pc3Npb246IFBlcm1pc3Npb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIGhhc1Blcm1pc3Npb24ocmVxLnVzZXI/LnBlcm1pc3Npb25zLCBwZXJtaXNzaW9uLCByZXEudXNlcj8uaXNTdXBlckFkbWluKTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IHBhc3NlZCB0byBhIHJlZ2lzdGVyZWQgYXV0aG9yaXphdGlvbi1kZW5pYWwgYXVkaXRvciB3aGVuIGFcbiAqIHN0YXRlLWNoYW5naW5nIHJlcXVlc3QgaXMgcmVqZWN0ZWQgYnkgYHJlcXVpcmVQZXJtaXNzaW9uYCAvXG4gKiBgcmVxdWlyZVN5c3RlbUFkbWluYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoekRlbmlhbEluZm8ge1xuICAvKiogVGhlIGRlbmllZCB1c2VyJ3MgaWQgKGBzdWJgKSwgaWYgYXV0aGVudGljYXRlZC4gKi9cbiAgYWN0b3JJZD86IHN0cmluZztcbiAgYWN0b3JFbWFpbD86IHN0cmluZztcbiAgLyoqIFRoZSB1c2VyJ3MgYWN0aXZlIG9yZyBhdCBkZW5pYWwgdGltZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBIVFRQIG1ldGhvZCArIHBhdGggb2YgdGhlIHJlamVjdGVkIHJlcXVlc3QuICovXG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBXaGF0IHdhcyByZXF1aXJlZDogdGhlIG1pc3NpbmcgcGVybWlzc2lvbihzKSwgb3IgJ3N5c3RlbS1hZG1pbicuICovXG4gIHJlcXVpcmVkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9uYWwgc2luayBmb3IgZGVuaWVkLWF1dGhvcml6YXRpb24gZXZlbnRzLiBMZWZ0IHVuc2V0IGJ5IGRlZmF1bHQgc29cbiAqIGFwaS1jb3JlIHN0YXlzIGRlY291cGxlZCBmcm9tIGFueSBhdWRpdCB0cmFuc3BvcnQg4oCUIGEgc2VydmljZSByZWdpc3RlcnMgb25lXG4gKiBhdCBib290ICh0eXBpY2FsbHkgZm9yd2FyZGluZyB0byBpdHMgYFJlbW90ZUF1ZGl0Q2xpZW50YCBhcyBhblxuICogYGF1dGh6LmRlbmllZGAgZXZlbnQsIG9yLCBvbiBwbGF0Zm9ybSwgdG8gdGhlIGxvY2FsIGBhdWRpdCgpYCBoZWxwZXIpLlxuICogTVVTVCBiZSBiZXN0LWVmZm9ydDogaXQgaXMgaW52b2tlZCBpbnNpZGUgdGhlIHJlcXVlc3QgcGF0aCwgc28gaXQgbXVzdCBuZXZlclxuICogdGhyb3cgb3IgYmxvY2sgKHRoZSBnYXRlIHdyYXBzIHRoZSBjYWxsIGluIHRyeS9jYXRjaCByZWdhcmRsZXNzKS5cbiAqL1xubGV0IGF1dGh6RGVuaWFsQXVkaXRvcjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFJlZ2lzdGVyIChvciBjbGVhciwgd2l0aCBgdW5kZWZpbmVkYCkgdGhlIHByb2Nlc3Mtd2lkZSBhdXRob3JpemF0aW9uLWRlbmlhbFxuICogYXVkaXRvci4gSWRlbXBvdGVudDsgdGhlIGxhc3QgcmVnaXN0cmF0aW9uIHdpbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRBdXRoekRlbmlhbEF1ZGl0b3IoZm46ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBhdXRoekRlbmlhbEF1ZGl0b3IgPSBmbjtcbn1cblxuLyoqXG4gKiBFbWl0IGEgZGVuaWFsIGV2ZW50LCBiZXN0LWVmZm9ydC4gT25seSBmaXJlcyBmb3Igc3RhdGUtY2hhbmdpbmcgKG5vbi1HRVQsXG4gKiBub24tSEVBRC9PUFRJT05TKSByZXF1ZXN0cyDigJQgYSByZWplY3RlZCBHRVQgaXMgbG93LXNpZ25hbCBwcm9iaW5nIG5vaXNlIGFuZFxuICogd291bGQgYW1wbGlmeSBhdWRpdCB2b2x1bWUgdW5kZXIgYSBzY2FuLiBOZXZlciB0aHJvd3MuXG4gKlxuICogVGhlIHBlcm1pc3Npb24gZ2F0ZXMgaGVyZSBjYWxsIGl0IHRoZW1zZWx2ZXMuIEV4cG9ydCBpdCBmb3IgZGF0YS1kcml2ZW4gY2hlY2tzXG4gKiBhIHJvdXRlIG1ha2VzIGlubGluZSAoY3Jvc3Mtb3JnIGFjY2Vzcywgc2VydmljZS1vbmx5IGVuZHBvaW50cyksIHNvIHRob3NlIDQwM3NcbiAqIHJlYWNoIHRoZSBzYW1lIGBhdXRoei5kZW5pZWRgIHRyYWlsLiBgcmVxdWlyZWRgIG5hbWVzIHdoYXQgd2FzIG1pc3NpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBdXRoekRlbmlhbChyZXE6IFJlcXVlc3QsIHJlcXVpcmVkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgYXVkaXRvciA9IGF1dGh6RGVuaWFsQXVkaXRvcjtcbiAgaWYgKCFhdWRpdG9yKSByZXR1cm47XG4gIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcgfHwgbWV0aG9kID09PSAnSEVBRCcgfHwgbWV0aG9kID09PSAnT1BUSU9OUycpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBhdWRpdG9yKHtcbiAgICAgIGFjdG9ySWQ6IHJlcS51c2VyPy5zdWIsXG4gICAgICBhY3RvckVtYWlsOiByZXEudXNlcj8uZW1haWwsXG4gICAgICBvcmdJZDogcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkLFxuICAgICAgbWV0aG9kLFxuICAgICAgLy8gU3RyaXAgdGhlIHF1ZXJ5IHN0cmluZyDigJQgYSBkZW5pZWQgcmVxdWVzdCBtYXkgY2FycnkgYSB0b2tlbi9zZWNyZXQgYXMgYVxuICAgICAgLy8gcXVlcnkgcGFyYW0sIGFuZCB0aGlzIHBhdGggaXMgcGVyc2lzdGVkIHZlcmJhdGltIGludG8gdGhlIGF1ZGl0IGxvZy5cbiAgICAgIHBhdGg6IChyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXSxcbiAgICAgIHJlcXVpcmVkLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqIFRoZSBzaGFyZWQgZ2F0ZSBwcmVhbWJsZTogYW5zd2VyIDQwMSBhbmQgcmV0dXJuIGZhbHNlIHdoZW4gdW5hdXRoZW50aWNhdGVkLiAqL1xuZnVuY3Rpb24gcmVxdWlyZVVzZXIocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKTogcmVxIGlzIFJlcXVlc3QgJiB7IHVzZXI6IE5vbk51bGxhYmxlPFJlcXVlc3RbJ3VzZXInXT4gfSB7XG4gIGlmIChyZXEudXNlcikgcmV0dXJuIHRydWU7XG4gIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogQXVkaXQgKyBhbnN3ZXIgYSBwZXJtaXNzaW9uIHJlZnVzYWwgKGBtaXNzaW5nYCBkZWZhdWx0cyB0byBldmVyeSByZXF1aXJlZCBwZXJtaXNzaW9uKS4gKi9cbmZ1bmN0aW9uIGRlbnlQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgcGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSwgbW9kZTogJ29yJyB8ICdhbmQnLCBtaXNzaW5nOiBQZXJtaXNzaW9uW10gPSBwZXJtaXNzaW9ucyk6IHZvaWQge1xuICByZWNvcmRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oYCAke21vZGV9IGApKTtcbiAgc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oYCAke21vZGV9IGApfWAsXG4gICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgZGVueVBlcm1pc3Npb24ocmVxLCByZXMsIHBlcm1pc3Npb25zLCAnb3InKTtcbiAgfSwgeyBraW5kOiAncGVybWlzc2lvbicsIG1vZGU6ICdhbnknLCBwZXJtaXNzaW9ucyB9KTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGRlbnlQZXJtaXNzaW9uKHJlcSwgcmVzLCBwZXJtaXNzaW9ucywgJ2FuZCcsIG1pc3NpbmcpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FsbCcsIHBlcm1pc3Npb25zIH0pO1xufVxuXG4vKipcbiAqIExpa2Uge0BsaW5rIHJlcXVpcmVQZXJtaXNzaW9ufSAoYW55LW9mKSBidXQgQUxTTyBhZG1pdHMgYW4gaW50ZXJuYWwgc2VydmljZVxuICogcHJpbmNpcGFsIChgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCkuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIHRhZ1JvdXRlR2F0ZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcXVpcmVVc2VyKHJlcSwgcmVzKSkgcmV0dXJuO1xuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBkZW55UGVybWlzc2lvbihyZXEsIHJlcywgcGVybWlzc2lvbnMsICdvcicpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FueScsIHBlcm1pc3Npb25zLCBhbGxvd1NlcnZpY2U6IHRydWUgfSk7XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhXG4gKiBgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCBwcmluY2lwYWwgbWludGVkIHZpYSB7QGxpbmsgc2lnblNlcnZpY2VUb2tlbn0gLyBgZ2V0U2VydmljZUF1dGhIZWFkZXJgKS5cbiAqIFJlamVjdHMgYW55IHVzZXIgdG9rZW4uIEZvciBOT04tdXNlci1mYWNpbmcgZW5kcG9pbnRzIOKAlCBlbnRpdHktZXZlbnQgaW5nZXN0LFxuICogYXV0by1zdWJzY3JpYmUsIGFuZCBzaW1pbGFyIHBlZXItc2VydmljZSBob29rcyDigJQgdGhhdCBhIGJyb3dzZXIgbXVzdCBuZXZlclxuICogcmVhY2guIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAvLyA0MDMgKG5vdCA0MDApIOKAlCB0aGlzIGlzIGFuIGF1dGhvcml6YXRpb24gcmVmdXNhbDsgc3RhdHVzIG11c3QgbWF0Y2ggdGhlXG4gICAgLy8gSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TIGNvZGUgYW5kIHRoZSBzaWJsaW5nIGdhdGVzIChyZXF1aXJlUGVybWlzc2lvbiwgZXRjLikuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLCAnSW50ZXJuYWwgc2VydmljZSBjYWxscyBvbmx5JywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gIH1cbiAgbmV4dCgpO1xufVxudGFnUm91dGVHYXRlKHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsLCB7IGtpbmQ6ICdzZXJ2aWNlUHJpbmNpcGFsJyB9KTtcblxuLyoqXG4gKiBUSEUgZ2F0ZSBmb3IgYW4gSU5URVJOQUwgcm91dGUg4oCUIHRoZSBvbmUgZXZlcnkgYC9pbnRlcm5hbC8qYCBwYXRoLCB0aGVcbiAqIHF1b3RhIHVzYWdlIGNvdW50ZXJzLCB0aGUgZW50aXR5LWV2ZW50IGluZ2VzdCBhbmQgdGhlIGF1ZGl0IGluZ2VzdCBnbyB0aHJvdWdoLlxuICpcbiAqIFR3byBydWxlcywgYm90aCBmYWlsLWNsb3NlZDpcbiAqXG4gKiAgMS4gKipObyB1c2VyIHRva2VuLCBldmVyLioqIE5vdCBhIG1lbWJlcidzLCBub3QgYSBzdXBlcmFkbWluJ3MsIG5vdCBhXG4gKiAgICAgc2VydmljZS1hY2NvdW50IGtleSdzLiBBbiBpbnRlcm5hbCByb3V0ZSBpcyBhIHBlZXItc2VydmljZSBBUEkgc3VyZmFjZSwgc29cbiAqICAgICBcImEgc3VmZmljaWVudGx5IHByaXZpbGVnZWQgaHVtYW5cIiBpcyBub3QgYW4gYWNjZXB0YWJsZSBjYWxsZXIg4oCUIHRoYXRcbiAqICAgICBlcXVpdmFsZW5jZSBpcyBleGFjdGx5IGhvdyBhIGJyb3dzZXItcmVhY2hhYmxlIHBhdGggYmVjb21lcyBhIHRlbmFudFxuICogICAgIGJvdW5kYXJ5IGJ1Zy4gYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYCBhbHJlYWR5IHJlZnVzZWQgdXNlcnM7IHRoaXMgYWxzb1xuICogICAgIGNsb3NlcyB0aGUgYHx8IGlzU3lzdGVtQWRtaW4ocmVxKWAgZXNjYXBlIGhhdGNoZXMgdGhhdCBoYWQgZ3Jvd24gYXJvdW5kXG4gKiAgICAgdGhlIGluZGl2aWR1YWwgaW50ZXJuYWwgcm91dGVzLlxuICogIDIuICoqT25seSB0aGUgTkFNRUQgY2FsbGVycy4qKiBgY2FsbGVyc2AgbGlzdHMgdGhlIHNlcnZpY2VzIHRoYXQgbGVnaXRpbWF0ZWx5XG4gKiAgICAgY2FsbCB0aGlzIHJvdXRlLCBhbmQgdGhlIG5hbWUgaXMgY3J5cHRvZ3JhcGhpY2FsbHkgYm91bmQgdG8gdGhlIHNpZ25pbmdcbiAqICAgICBrZXkgKGBzZXJ2aWNlcy9zZXJ2aWNlLWtleXMudHNgKSwgc28gdGhpcyBpcyBhbiBpZGVudGl0eSBjaGVjayByYXRoZXIgdGhhblxuICogICAgIGEgY2xhaW0gY2hlY2suIEl0IGlzIHRoZSBzYW1lIGFsbG93LWxpc3QgdGhlIG1lc2ggcG9saWN5IG5hbWVzLCBhdCB0aGVcbiAqICAgICBsYXllciB0aGF0IGFsc28gaG9sZHMgaW4gZG9ja2VyIGNvbXBvc2UsIHdoZXJlIHRoZXJlIGlzIG5vIG1lc2ggYXQgYWxsIOKAlFxuICogICAgIHRoZSBJc3RpbyBgQXV0aG9yaXphdGlvblBvbGljeWAgaXMgZGVmZW5jZSBpbiBkZXB0aCBvbiB0b3AsIG5ldmVyIHRoZVxuICogICAgIGVuZm9yY2VtZW50LlxuICpcbiAqIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC4gUmVmdXNhbHMgYXJlIGNvdW50ZWRcbiAqIChgaW50ZXJuYWxfcm91dGVfcmVmdXNlZF90b3RhbGApIGFuZCBhdWRpdGVkIHRocm91Z2ggdGhlIHNoYXJlZCBgYXV0aHouZGVuaWVkYFxuICogc2luay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVJbnRlcm5hbFNlcnZpY2Uob3B0aW9uczogeyBjYWxsZXJzOiByZWFkb25seSBzdHJpbmdbXSB9KSB7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KG9wdGlvbnMuY2FsbGVycyk7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVmdXNlID0gKHJlYXNvbjogJ3VuYXV0aGVudGljYXRlZCcgfCAndXNlcl90b2tlbicgfCAnd3JvbmdfY2FsbGVyJyk6IHZvaWQgPT4ge1xuICAgICAgZW1pdENvdW50ZXIoJ2ludGVybmFsX3JvdXRlX3JlZnVzZWRfdG90YWwnLCB7XG4gICAgICAgIHNlcnZpY2U6IHNlcnZpY2VJZGVudGl0eSgpLFxuICAgICAgICByb3V0ZTogcmVxLnJvdXRlPy5wYXRoID8gYCR7cmVxLm1ldGhvZH0gJHtyZXEuYmFzZVVybH0ke3JlcS5yb3V0ZS5wYXRofWAgOiBgJHtyZXEubWV0aG9kfSAkeyhyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXX1gLFxuICAgICAgICByZWFzb24sXG4gICAgICAgIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgPz8gJ25vbmUnLFxuICAgICAgfSk7XG4gICAgICByZWNvcmRBdXRoekRlbmlhbChyZXEsIGBpbnRlcm5hbC1zZXJ2aWNlICgke29wdGlvbnMuY2FsbGVycy5qb2luKCcsICcpfSlgKTtcbiAgICAgIGlmIChyZWFzb24gPT09ICd1bmF1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgICB9XG4gICAgICBsb2dnZXIud2FybignUmVmdXNlZCBhbiBpbnRlcm5hbCByb3V0ZScsIHsgcmVhc29uLCBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgfSk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgICB9O1xuXG4gICAgaWYgKCFyZXEudXNlcikgcmV0dXJuIHJlZnVzZSgndW5hdXRoZW50aWNhdGVkJyk7XG4gICAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkgcmV0dXJuIHJlZnVzZSgndXNlcl90b2tlbicpO1xuICAgIGNvbnN0IGNhbGxlciA9IHNlcnZpY2VOYW1lT2YocmVxLnVzZXIpO1xuICAgIGlmICghY2FsbGVyIHx8ICFhbGxvd2VkLmhhcyhjYWxsZXIpKSByZXR1cm4gcmVmdXNlKCd3cm9uZ19jYWxsZXInKTtcbiAgICBuZXh0KCk7XG4gIH0sIHsga2luZDogJ3NlcnZpY2VQcmluY2lwYWwnIH0sIHsga2luZDogJ2ludGVybmFsU2VydmljZScsIGNhbGxlcnM6IFsuLi5vcHRpb25zLmNhbGxlcnNdIH0pO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSByZXF1ZXN0IGlzIGZyb20gYSBzeXN0ZW0gYWRtaW4uXG4gKlxuICogQXV0aG9yaXR5IGlzIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSB1c2VyLWxldmVsIGBpc1N1cGVyQWRtaW5gIGZsYWcgY2FycmllZFxuICogaW4gdGhlIEpXVCDigJQgbmV2ZXIgYnkgbWVtYmVyc2hpcCBpbiB0aGUgd2VsbC1rbm93biAnc3lzdGVtJyBvcmcsIHdoaWNoIHdvdWxkXG4gKiBjb25mbGF0ZSBhIFBpcGVsaW5lIEJ1aWxkZXIgb3BlcmF0b3Igd2l0aCBhIGN1c3RvbWVyIHRlbmFudCBhbmQgbGV0IGFueVxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnIGF1dGhvcml0eS4gVGhlIGBzeXN0ZW1gIG9yZyBzdGlsbCBleGlzdHMgYXMgYSAqY29udGVudCBob2xkZXIqIGZvciBzaGFyZWRcbiAqIHNhbXBsZSBkYXRhOyBpdCBjb25mZXJzIG5vIHByaXZpbGVnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtQWRtaW4ocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uaXNTdXBlckFkbWluID09PSB0cnVlO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB0b2tlbiBjYXJyaWVzIGEgc3BlY2lmaWMgY2FwYWJpbGl0eSBgc2NvcGVgIChlLmcuXG4gKiBgJ3JlcG9ydGluZzppbmdlc3QnYCkuIFVzZWQgdG8gZ2F0ZSBlbmRwb2ludHMgdGhhdCBhY2NlcHQgYSBuYXJyb3cgbWFjaGluZVxuICogaWRlbnRpdHkg4oCUIGEgbm9ybWFsIGludGVyYWN0aXZlIHVzZXIgdG9rZW4gaGFzIG5vIGBzY29wZWAgYW5kIHJldHVybnMgZmFsc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNTY29wZShyZXE6IFJlcXVlc3QsIHNjb3BlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5zY29wZSA9PT0gc2NvcGU7XG59XG5cbi8qKiBSZXF1aXJlcyBhIHN5c3RlbSBhZG1pbiDigJQgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIGBpc1N1cGVyQWRtaW5gIHRva2VuIGNsYWltLlxuICogIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG50YWdSb3V0ZUdhdGUocmVxdWlyZVN5c3RlbUFkbWluLCB7IGtpbmQ6ICdzeXN0ZW1BZG1pbicgfSk7XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gdGFnUm91dGVHYXRlKChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxdWlyZVVzZXIocmVxLCByZXMpKSByZXR1cm47XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCBgZmVhdHVyZToke2ZlYXR1cmV9YCk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgICBgVGhpcyBmZWF0dXJlIHJlcXVpcmVzIGEgaGlnaGVyIHBsYW4gKCR7ZmVhdHVyZX0pYCxcbiAgICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9LCB7IGtpbmQ6ICdmZWF0dXJlJywgZmVhdHVyZSB9KTtcbn1cblxuIl19
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1nYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQVF0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsY0FBYyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUF1QixNQUFNLDhCQUE4QixDQUFDO0FBQ2xKLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFtQixhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUMvQzs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEdBQVksRUFBRSxVQUFzQjtJQUNwRSxPQUFPLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztBQUNsRixDQUFDO0FBOEJEOzs7Ozs7O0dBT0c7QUFDSCxJQUFJLGtCQUFpRSxDQUFDO0FBRXRFOzs7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QVMsQ0FBQyx3QkFBd0IsQ0FDbkMsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLEVBQUUsQ0FBQztBQUNULENBQUM7QUFDRCxZQUFZLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztBQUUxRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxPQUFlO0lBQzVDLE9BQU8sWUFBWSxDQUFDLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDNUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO1lBQUUsT0FBTztRQUVuQyxxRUFBcUU7UUFDckUsdUVBQXVFO1FBQ3ZFLHFFQUFxRTtRQUNyRSxrQkFBa0I7UUFDbEIsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVsRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsNERBQTREO1lBQzVELDJEQUEyRDtZQUMzRCxzRUFBc0U7WUFDdEUsaUJBQWlCLENBQUMsR0FBRyxFQUFFLFdBQVcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3QyxPQUFPLFNBQVMsQ0FDZCxHQUFHLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFDekIsd0NBQXdDLE9BQU8sR0FBRyxFQUNsRCxTQUFTLENBQUMsd0JBQXdCLENBQ25DLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEF1dGhvcml6YXRpb24gZ2F0ZXMg4oCUIHBlcm1pc3Npb25zLCBzeXN0ZW0gYWRtaW4sIGZlYXR1cmVzIOKAlCBhbmQgdGhlXG4gKiBgYXV0aHouZGVuaWVkYCBhdWRpdCBzaW5rIHRoZXkgcmVwb3J0IHJlZnVzYWxzIHRvLlxuICovXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdGFnUm91dGVHYXRlIH0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VQcmluY2lwYWwsIHNlcnZpY2VOYW1lT2YgfSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHsgYXVkaXRBdXRoQmxvY2ssIGN1cnJlbnRBdWRpdENvbnRleHQsIHNhbml0aXplQ29ycmVsYXRpb25JZCwgc2FuaXRpemVVc2VyQWdlbnQsIHR5cGUgQXVkaXRBdXRoQmxvY2sgfSBmcm9tICcuLi9zZXJ2aWNlcy9hdWRpdC1jb250ZXh0LmpzJztcbmltcG9ydCB7IHNlcnZpY2VJZGVudGl0eSB9IGZyb20gJy4uL3NlcnZpY2VzL3NlcnZpY2Uta2V5cy5qcyc7XG5pbXBvcnQgeyBFcnJvckNvZGUgfSBmcm9tICcuLi90eXBlcy9lcnJvci1jb2Rlcy5qcyc7XG5pbXBvcnQgeyB0eXBlIFBlcm1pc3Npb24sIGhhc1Blcm1pc3Npb24gfSBmcm9tICcuLi90eXBlcy9wZXJtaXNzaW9ucy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5pbXBvcnQgeyBzZW5kRXJyb3IgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignYXV0aC1taWRkbGV3YXJlJyk7XG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB1c2VyIGhvbGRzIGBwZXJtaXNzaW9uYC4gU3VwZXJhZG1pbnMgaW1wbGljaXRseSBob2xkXG4gKiBldmVyeSBwZXJtaXNzaW9uLiBSZWFkcyB0aGUgcmVzb2x2ZWQgYHBlcm1pc3Npb25zYCBjbGFpbSAoc2V0IGF0IHRva2VuIGlzc3VlLFxuICogb3IgcmUtZGVyaXZlZCBwZXIgcmVxdWVzdCBieSB0aGUgcGxhdGZvcm0pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlckhhc1Blcm1pc3Npb24ocmVxOiBSZXF1ZXN0LCBwZXJtaXNzaW9uOiBQZXJtaXNzaW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiBoYXNQZXJtaXNzaW9uKHJlcS51c2VyPy5wZXJtaXNzaW9ucywgcGVybWlzc2lvbiwgcmVxLnVzZXI/LmlzU3VwZXJBZG1pbik7XG59XG5cbi8qKlxuICogQ29udGV4dCBwYXNzZWQgdG8gYSByZWdpc3RlcmVkIGF1dGhvcml6YXRpb24tZGVuaWFsIGF1ZGl0b3Igd2hlbiBhXG4gKiBzdGF0ZS1jaGFuZ2luZyByZXF1ZXN0IGlzIHJlamVjdGVkIGJ5IGByZXF1aXJlUGVybWlzc2lvbmAgL1xuICogYHJlcXVpcmVTeXN0ZW1BZG1pbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aHpEZW5pYWxJbmZvIHtcbiAgLyoqIFRoZSBkZW5pZWQgdXNlcidzIGlkIChgc3ViYCksIGlmIGF1dGhlbnRpY2F0ZWQuICovXG4gIGFjdG9ySWQ/OiBzdHJpbmc7XG4gIGFjdG9yRW1haWw/OiBzdHJpbmc7XG4gIC8qKiBUaGUgdXNlcidzIGFjdGl2ZSBvcmcgYXQgZGVuaWFsIHRpbWUuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogSFRUUCBtZXRob2QgKyBwYXRoIG9mIHRoZSByZWplY3RlZCByZXF1ZXN0LiAqL1xuICBtZXRob2Q6IHN0cmluZztcbiAgcGF0aDogc3RyaW5nO1xuICAvKiogV2hhdCB3YXMgcmVxdWlyZWQ6IHRoZSBtaXNzaW5nIHBlcm1pc3Npb24ocyksIG9yICdzeXN0ZW0tYWRtaW4nLiAqL1xuICByZXF1aXJlZDogc3RyaW5nO1xuICAvKiogQ2xpZW50IGlwIChgcmVxLmlwYCwgcHJveHktcmVzb2x2ZWQpLiAqL1xuICBpcD86IHN0cmluZztcbiAgLyoqIFNhbml0aXplZCwgbGVuZ3RoLWNhcHBlZCBVc2VyLUFnZW50LiAqL1xuICB1c2VyQWdlbnQ/OiBzdHJpbmc7XG4gIC8qKiBUaGUgcmVxdWVzdCdzIGNvcnJlbGF0aW9uIGlkICh0aGUgYW1iaWVudCBhdWRpdCBjb250ZXh0J3MsIGVsc2UgYSB2YWxpZCBgWC1SZXF1ZXN0LUlkYCkuICovXG4gIHJlcXVlc3RJZD86IHN0cmluZztcbiAgLyoqIFRoZSByZWFsIHN5c2FkbWluIGJlaGluZCBhbiBpbXBlcnNvbmF0aW9uIHRva2VuLCBmcm9tIHRoZSB2ZXJpZmllZCB0b2tlbi4gKi9cbiAgaW1wZXJzb25hdG9ySWQ/OiBzdHJpbmc7XG4gIC8qKiBUaGUgY3JlZGVudGlhbCB0aGF0IHdhcyByZWZ1c2VkIChrZXkgaWQsIHNlc3Npb24sIHNjb3BlLCDigKYpIOKAlCB0aGUgYF9hdXRoYCBibG9jay4gKi9cbiAgYXV0aD86IEF1ZGl0QXV0aEJsb2NrO1xufVxuXG4vKipcbiAqIE9wdGlvbmFsIHNpbmsgZm9yIGRlbmllZC1hdXRob3JpemF0aW9uIGV2ZW50cy4gTGVmdCB1bnNldCBieSBkZWZhdWx0IHNvXG4gKiBhcGktY29yZSBzdGF5cyBkZWNvdXBsZWQgZnJvbSBhbnkgYXVkaXQgdHJhbnNwb3J0IOKAlCBhIHNlcnZpY2UgcmVnaXN0ZXJzIG9uZVxuICogYXQgYm9vdCAodHlwaWNhbGx5IGZvcndhcmRpbmcgdG8gaXRzIGBSZW1vdGVBdWRpdENsaWVudGAgYXMgYW5cbiAqIGBhdXRoei5kZW5pZWRgIGV2ZW50LCBvciwgb24gcGxhdGZvcm0sIHRvIHRoZSBsb2NhbCBgYXVkaXQoKWAgaGVscGVyKS5cbiAqIE1VU1QgYmUgYmVzdC1lZmZvcnQ6IGl0IGlzIGludm9rZWQgaW5zaWRlIHRoZSByZXF1ZXN0IHBhdGgsIHNvIGl0IG11c3QgbmV2ZXJcbiAqIHRocm93IG9yIGJsb2NrICh0aGUgZ2F0ZSB3cmFwcyB0aGUgY2FsbCBpbiB0cnkvY2F0Y2ggcmVnYXJkbGVzcykuXG4gKi9cbmxldCBhdXRoekRlbmlhbEF1ZGl0b3I6ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBSZWdpc3RlciAob3IgY2xlYXIsIHdpdGggYHVuZGVmaW5lZGApIHRoZSBwcm9jZXNzLXdpZGUgYXV0aG9yaXphdGlvbi1kZW5pYWxcbiAqIGF1ZGl0b3IuIElkZW1wb3RlbnQ7IHRoZSBsYXN0IHJlZ2lzdHJhdGlvbiB3aW5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0QXV0aHpEZW5pYWxBdWRpdG9yKGZuOiAoKGluZm86IEF1dGh6RGVuaWFsSW5mbykgPT4gdm9pZCkgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgYXV0aHpEZW5pYWxBdWRpdG9yID0gZm47XG59XG5cbi8qKlxuICogRW1pdCBhIGRlbmlhbCBldmVudCwgYmVzdC1lZmZvcnQuIE9ubHkgZmlyZXMgZm9yIHN0YXRlLWNoYW5naW5nIChub24tR0VULFxuICogbm9uLUhFQUQvT1BUSU9OUykgcmVxdWVzdHMg4oCUIGEgcmVqZWN0ZWQgR0VUIGlzIGxvdy1zaWduYWwgcHJvYmluZyBub2lzZSBhbmRcbiAqIHdvdWxkIGFtcGxpZnkgYXVkaXQgdm9sdW1lIHVuZGVyIGEgc2Nhbi4gTmV2ZXIgdGhyb3dzLlxuICpcbiAqIFRoZSBwZXJtaXNzaW9uIGdhdGVzIGhlcmUgY2FsbCBpdCB0aGVtc2VsdmVzLiBFeHBvcnQgaXQgZm9yIGRhdGEtZHJpdmVuIGNoZWNrc1xuICogYSByb3V0ZSBtYWtlcyBpbmxpbmUgKGNyb3NzLW9yZyBhY2Nlc3MsIHNlcnZpY2Utb25seSBlbmRwb2ludHMpLCBzbyB0aG9zZSA0MDNzXG4gKiByZWFjaCB0aGUgc2FtZSBgYXV0aHouZGVuaWVkYCB0cmFpbC4gYHJlcXVpcmVkYCBuYW1lcyB3aGF0IHdhcyBtaXNzaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkQXV0aHpEZW5pYWwocmVxOiBSZXF1ZXN0LCByZXF1aXJlZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGF1ZGl0b3IgPSBhdXRoekRlbmlhbEF1ZGl0b3I7XG4gIGlmICghYXVkaXRvcikgcmV0dXJuO1xuICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnIHx8IG1ldGhvZCA9PT0gJ09QVElPTlMnKSByZXR1cm47XG4gIHRyeSB7XG4gICAgYXVkaXRvcih7XG4gICAgICBhY3RvcklkOiByZXEudXNlcj8uc3ViLFxuICAgICAgYWN0b3JFbWFpbDogcmVxLnVzZXI/LmVtYWlsLFxuICAgICAgb3JnSWQ6IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZCxcbiAgICAgIG1ldGhvZCxcbiAgICAgIC8vIFN0cmlwIHRoZSBxdWVyeSBzdHJpbmcg4oCUIGEgZGVuaWVkIHJlcXVlc3QgbWF5IGNhcnJ5IGEgdG9rZW4vc2VjcmV0IGFzIGFcbiAgICAgIC8vIHF1ZXJ5IHBhcmFtLCBhbmQgdGhpcyBwYXRoIGlzIHBlcnNpc3RlZCB2ZXJiYXRpbSBpbnRvIHRoZSBhdWRpdCBsb2cuXG4gICAgICBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sXG4gICAgICByZXF1aXJlZCxcbiAgICAgIGlwOiByZXEuaXAsXG4gICAgICB1c2VyQWdlbnQ6IHNhbml0aXplVXNlckFnZW50KHJlcS5oZWFkZXJzPy5bJ3VzZXItYWdlbnQnXSksXG4gICAgICByZXF1ZXN0SWQ6IGN1cnJlbnRBdWRpdENvbnRleHQoKT8ucmVxdWVzdElkID8/IHNhbml0aXplQ29ycmVsYXRpb25JZChyZXEuaGVhZGVycz8uWyd4LXJlcXVlc3QtaWQnXSksXG4gICAgICBpbXBlcnNvbmF0b3JJZDogcmVxLnVzZXI/LmltcGVyc29uYXRvcklkLFxuICAgICAgYXV0aDogYXVkaXRBdXRoQmxvY2socmVxLnVzZXIpLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqIFRoZSBzaGFyZWQgZ2F0ZSBwcmVhbWJsZTogYW5zd2VyIDQwMSBhbmQgcmV0dXJuIGZhbHNlIHdoZW4gdW5hdXRoZW50aWNhdGVkLiAqL1xuZnVuY3Rpb24gcmVxdWlyZVVzZXIocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKTogcmVxIGlzIFJlcXVlc3QgJiB7IHVzZXI6IE5vbk51bGxhYmxlPFJlcXVlc3RbJ3VzZXInXT4gfSB7XG4gIGlmIChyZXEudXNlcikgcmV0dXJuIHRydWU7XG4gIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogQXVkaXQgKyBhbnN3ZXIgYSBwZXJtaXNzaW9uIHJlZnVzYWwgKGBtaXNzaW5nYCBkZWZhdWx0cyB0byBldmVyeSByZXF1aXJlZCBwZXJtaXNzaW9uKS4gKi9cbmZ1bmN0aW9uIGRlbnlQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgcGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSwgbW9kZTogJ29yJyB8ICdhbmQnLCBtaXNzaW5nOiBQZXJtaXNzaW9uW10gPSBwZXJtaXNzaW9ucyk6IHZvaWQge1xuICByZWNvcmRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oYCAke21vZGV9IGApKTtcbiAgc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oYCAke21vZGV9IGApfWAsXG4gICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgZGVueVBlcm1pc3Npb24ocmVxLCByZXMsIHBlcm1pc3Npb25zLCAnb3InKTtcbiAgfSwgeyBraW5kOiAncGVybWlzc2lvbicsIG1vZGU6ICdhbnknLCBwZXJtaXNzaW9ucyB9KTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGRlbnlQZXJtaXNzaW9uKHJlcSwgcmVzLCBwZXJtaXNzaW9ucywgJ2FuZCcsIG1pc3NpbmcpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FsbCcsIHBlcm1pc3Npb25zIH0pO1xufVxuXG4vKipcbiAqIExpa2Uge0BsaW5rIHJlcXVpcmVQZXJtaXNzaW9ufSAoYW55LW9mKSBidXQgQUxTTyBhZG1pdHMgYW4gaW50ZXJuYWwgc2VydmljZVxuICogcHJpbmNpcGFsIChgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCkuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIHRhZ1JvdXRlR2F0ZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcXVpcmVVc2VyKHJlcSwgcmVzKSkgcmV0dXJuO1xuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBkZW55UGVybWlzc2lvbihyZXEsIHJlcywgcGVybWlzc2lvbnMsICdvcicpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FueScsIHBlcm1pc3Npb25zLCBhbGxvd1NlcnZpY2U6IHRydWUgfSk7XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhXG4gKiBgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCBwcmluY2lwYWwgbWludGVkIHZpYSB7QGxpbmsgc2lnblNlcnZpY2VUb2tlbn0gLyBgZ2V0U2VydmljZUF1dGhIZWFkZXJgKS5cbiAqIFJlamVjdHMgYW55IHVzZXIgdG9rZW4uIEZvciBOT04tdXNlci1mYWNpbmcgZW5kcG9pbnRzIOKAlCBlbnRpdHktZXZlbnQgaW5nZXN0LFxuICogYXV0by1zdWJzY3JpYmUsIGFuZCBzaW1pbGFyIHBlZXItc2VydmljZSBob29rcyDigJQgdGhhdCBhIGJyb3dzZXIgbXVzdCBuZXZlclxuICogcmVhY2guIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAvLyA0MDMgKG5vdCA0MDApIOKAlCB0aGlzIGlzIGFuIGF1dGhvcml6YXRpb24gcmVmdXNhbDsgc3RhdHVzIG11c3QgbWF0Y2ggdGhlXG4gICAgLy8gSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TIGNvZGUgYW5kIHRoZSBzaWJsaW5nIGdhdGVzIChyZXF1aXJlUGVybWlzc2lvbiwgZXRjLikuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLCAnSW50ZXJuYWwgc2VydmljZSBjYWxscyBvbmx5JywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gIH1cbiAgbmV4dCgpO1xufVxudGFnUm91dGVHYXRlKHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsLCB7IGtpbmQ6ICdzZXJ2aWNlUHJpbmNpcGFsJyB9KTtcblxuLyoqXG4gKiBUSEUgZ2F0ZSBmb3IgYW4gSU5URVJOQUwgcm91dGUg4oCUIHRoZSBvbmUgZXZlcnkgYC9pbnRlcm5hbC8qYCBwYXRoLCB0aGVcbiAqIHF1b3RhIHVzYWdlIGNvdW50ZXJzLCB0aGUgZW50aXR5LWV2ZW50IGluZ2VzdCBhbmQgdGhlIGF1ZGl0IGluZ2VzdCBnbyB0aHJvdWdoLlxuICpcbiAqIFR3byBydWxlcywgYm90aCBmYWlsLWNsb3NlZDpcbiAqXG4gKiAgMS4gKipObyB1c2VyIHRva2VuLCBldmVyLioqIE5vdCBhIG1lbWJlcidzLCBub3QgYSBzdXBlcmFkbWluJ3MsIG5vdCBhXG4gKiAgICAgc2VydmljZS1hY2NvdW50IGtleSdzLiBBbiBpbnRlcm5hbCByb3V0ZSBpcyBhIHBlZXItc2VydmljZSBBUEkgc3VyZmFjZSwgc29cbiAqICAgICBcImEgc3VmZmljaWVudGx5IHByaXZpbGVnZWQgaHVtYW5cIiBpcyBub3QgYW4gYWNjZXB0YWJsZSBjYWxsZXIg4oCUIHRoYXRcbiAqICAgICBlcXVpdmFsZW5jZSBpcyBleGFjdGx5IGhvdyBhIGJyb3dzZXItcmVhY2hhYmxlIHBhdGggYmVjb21lcyBhIHRlbmFudFxuICogICAgIGJvdW5kYXJ5IGJ1Zy4gYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYCBhbHJlYWR5IHJlZnVzZWQgdXNlcnM7IHRoaXMgYWxzb1xuICogICAgIGNsb3NlcyB0aGUgYHx8IGlzU3lzdGVtQWRtaW4ocmVxKWAgZXNjYXBlIGhhdGNoZXMgdGhhdCBoYWQgZ3Jvd24gYXJvdW5kXG4gKiAgICAgdGhlIGluZGl2aWR1YWwgaW50ZXJuYWwgcm91dGVzLlxuICogIDIuICoqT25seSB0aGUgTkFNRUQgY2FsbGVycy4qKiBgY2FsbGVyc2AgbGlzdHMgdGhlIHNlcnZpY2VzIHRoYXQgbGVnaXRpbWF0ZWx5XG4gKiAgICAgY2FsbCB0aGlzIHJvdXRlLCBhbmQgdGhlIG5hbWUgaXMgY3J5cHRvZ3JhcGhpY2FsbHkgYm91bmQgdG8gdGhlIHNpZ25pbmdcbiAqICAgICBrZXkgKGBzZXJ2aWNlcy9zZXJ2aWNlLWtleXMudHNgKSwgc28gdGhpcyBpcyBhbiBpZGVudGl0eSBjaGVjayByYXRoZXIgdGhhblxuICogICAgIGEgY2xhaW0gY2hlY2suIEl0IGlzIHRoZSBzYW1lIGFsbG93LWxpc3QgdGhlIG1lc2ggcG9saWN5IG5hbWVzLCBhdCB0aGVcbiAqICAgICBsYXllciB0aGF0IGFsc28gaG9sZHMgaW4gZG9ja2VyIGNvbXBvc2UsIHdoZXJlIHRoZXJlIGlzIG5vIG1lc2ggYXQgYWxsIOKAlFxuICogICAgIHRoZSBJc3RpbyBgQXV0aG9yaXphdGlvblBvbGljeWAgaXMgZGVmZW5jZSBpbiBkZXB0aCBvbiB0b3AsIG5ldmVyIHRoZVxuICogICAgIGVuZm9yY2VtZW50LlxuICpcbiAqIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC4gUmVmdXNhbHMgYXJlIGNvdW50ZWRcbiAqIChgaW50ZXJuYWxfcm91dGVfcmVmdXNlZF90b3RhbGApIGFuZCBhdWRpdGVkIHRocm91Z2ggdGhlIHNoYXJlZCBgYXV0aHouZGVuaWVkYFxuICogc2luay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVJbnRlcm5hbFNlcnZpY2Uob3B0aW9uczogeyBjYWxsZXJzOiByZWFkb25seSBzdHJpbmdbXSB9KSB7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KG9wdGlvbnMuY2FsbGVycyk7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVmdXNlID0gKHJlYXNvbjogJ3VuYXV0aGVudGljYXRlZCcgfCAndXNlcl90b2tlbicgfCAnd3JvbmdfY2FsbGVyJyk6IHZvaWQgPT4ge1xuICAgICAgZW1pdENvdW50ZXIoJ2ludGVybmFsX3JvdXRlX3JlZnVzZWRfdG90YWwnLCB7XG4gICAgICAgIHNlcnZpY2U6IHNlcnZpY2VJZGVudGl0eSgpLFxuICAgICAgICByb3V0ZTogcmVxLnJvdXRlPy5wYXRoID8gYCR7cmVxLm1ldGhvZH0gJHtyZXEuYmFzZVVybH0ke3JlcS5yb3V0ZS5wYXRofWAgOiBgJHtyZXEubWV0aG9kfSAkeyhyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXX1gLFxuICAgICAgICByZWFzb24sXG4gICAgICAgIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgPz8gJ25vbmUnLFxuICAgICAgfSk7XG4gICAgICByZWNvcmRBdXRoekRlbmlhbChyZXEsIGBpbnRlcm5hbC1zZXJ2aWNlICgke29wdGlvbnMuY2FsbGVycy5qb2luKCcsICcpfSlgKTtcbiAgICAgIGlmIChyZWFzb24gPT09ICd1bmF1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgICB9XG4gICAgICBsb2dnZXIud2FybignUmVmdXNlZCBhbiBpbnRlcm5hbCByb3V0ZScsIHsgcmVhc29uLCBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgfSk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgICB9O1xuXG4gICAgaWYgKCFyZXEudXNlcikgcmV0dXJuIHJlZnVzZSgndW5hdXRoZW50aWNhdGVkJyk7XG4gICAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkgcmV0dXJuIHJlZnVzZSgndXNlcl90b2tlbicpO1xuICAgIGNvbnN0IGNhbGxlciA9IHNlcnZpY2VOYW1lT2YocmVxLnVzZXIpO1xuICAgIGlmICghY2FsbGVyIHx8ICFhbGxvd2VkLmhhcyhjYWxsZXIpKSByZXR1cm4gcmVmdXNlKCd3cm9uZ19jYWxsZXInKTtcbiAgICBuZXh0KCk7XG4gIH0sIHsga2luZDogJ3NlcnZpY2VQcmluY2lwYWwnIH0sIHsga2luZDogJ2ludGVybmFsU2VydmljZScsIGNhbGxlcnM6IFsuLi5vcHRpb25zLmNhbGxlcnNdIH0pO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSByZXF1ZXN0IGlzIGZyb20gYSBzeXN0ZW0gYWRtaW4uXG4gKlxuICogQXV0aG9yaXR5IGlzIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSB1c2VyLWxldmVsIGBpc1N1cGVyQWRtaW5gIGZsYWcgY2FycmllZFxuICogaW4gdGhlIEpXVCDigJQgbmV2ZXIgYnkgbWVtYmVyc2hpcCBpbiB0aGUgd2VsbC1rbm93biAnc3lzdGVtJyBvcmcsIHdoaWNoIHdvdWxkXG4gKiBjb25mbGF0ZSBhIFBpcGVsaW5lIEJ1aWxkZXIgb3BlcmF0b3Igd2l0aCBhIGN1c3RvbWVyIHRlbmFudCBhbmQgbGV0IGFueVxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnIGF1dGhvcml0eS4gVGhlIGBzeXN0ZW1gIG9yZyBzdGlsbCBleGlzdHMgYXMgYSAqY29udGVudCBob2xkZXIqIGZvciBzaGFyZWRcbiAqIHNhbXBsZSBkYXRhOyBpdCBjb25mZXJzIG5vIHByaXZpbGVnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtQWRtaW4ocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uaXNTdXBlckFkbWluID09PSB0cnVlO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB0b2tlbiBjYXJyaWVzIGEgc3BlY2lmaWMgY2FwYWJpbGl0eSBgc2NvcGVgIChlLmcuXG4gKiBgJ3JlcG9ydGluZzppbmdlc3QnYCkuIFVzZWQgdG8gZ2F0ZSBlbmRwb2ludHMgdGhhdCBhY2NlcHQgYSBuYXJyb3cgbWFjaGluZVxuICogaWRlbnRpdHkg4oCUIGEgbm9ybWFsIGludGVyYWN0aXZlIHVzZXIgdG9rZW4gaGFzIG5vIGBzY29wZWAgYW5kIHJldHVybnMgZmFsc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNTY29wZShyZXE6IFJlcXVlc3QsIHNjb3BlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5zY29wZSA9PT0gc2NvcGU7XG59XG5cbi8qKiBSZXF1aXJlcyBhIHN5c3RlbSBhZG1pbiDigJQgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIGBpc1N1cGVyQWRtaW5gIHRva2VuIGNsYWltLlxuICogIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG50YWdSb3V0ZUdhdGUocmVxdWlyZVN5c3RlbUFkbWluLCB7IGtpbmQ6ICdzeXN0ZW1BZG1pbicgfSk7XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gdGFnUm91dGVHYXRlKChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxdWlyZVVzZXIocmVxLCByZXMpKSByZXR1cm47XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCBgZmVhdHVyZToke2ZlYXR1cmV9YCk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgICBgVGhpcyBmZWF0dXJlIHJlcXVpcmVzIGEgaGlnaGVyIHBsYW4gKCR7ZmVhdHVyZX0pYCxcbiAgICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9LCB7IGtpbmQ6ICdmZWF0dXJlJywgZmVhdHVyZSB9KTtcbn1cblxuIl19
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The routes that never spend `apiCalls` (or `automationCalls`), fleet-wide.
|
|
3
|
+
*
|
|
4
|
+
* Every service meters and gates its authenticated user surface on `apiCalls`
|
|
5
|
+
* (`meterQuotaOnSuccess` + `checkQuota`, mounted at the app-routes level). A few
|
|
6
|
+
* reads are made BY THE CONSOLE ITSELF, on every page load or on a timer, not by
|
|
7
|
+
* a person doing something — metering them would burn an idle tab's org budget
|
|
8
|
+
* all day, and gating them would make a quota-exhausted org's console unable to
|
|
9
|
+
* render the very banner that says so. This list is that carve-out, and it is
|
|
10
|
+
* deliberately short: each entry names its caller and why it is free.
|
|
11
|
+
*
|
|
12
|
+
* ONE list, read in three places, so they cannot drift:
|
|
13
|
+
* - `meterQuotaOnSuccess` skips a matching request (no increment);
|
|
14
|
+
* - `checkQuota` skips a matching request (never 429s);
|
|
15
|
+
* - `buildRouteTable` marks the route `quota.exempt`, and the quota coverage
|
|
16
|
+
* check (api-core testing) treats it as covered.
|
|
17
|
+
*
|
|
18
|
+
* Each `path` is matched against BOTH the concrete request path
|
|
19
|
+
* (`/organization/64f…/seat-usage`) and the route-table pattern
|
|
20
|
+
* (`/organization/:id/seat-usage`), so a `:param` segment is written as
|
|
21
|
+
* `[^/]+`. Paths are service-local (nginx strips `/api`).
|
|
22
|
+
*
|
|
23
|
+
* The quota service itself is not on the list because it meters nothing: its
|
|
24
|
+
* reads (`GET /quotas`, which QuotaBanner polls every 60s) never cost a call.
|
|
25
|
+
* Documented in docs/quotas.md ("Exempt routes").
|
|
26
|
+
*/
|
|
27
|
+
export interface QuotaExemptRoute {
|
|
28
|
+
method: 'GET' | 'POST';
|
|
29
|
+
/** Anchored pattern over the service-local path. */
|
|
30
|
+
path: RegExp;
|
|
31
|
+
/** Who calls it, and why it must be free. */
|
|
32
|
+
reason: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const QUOTA_EXEMPT_ROUTES: readonly QuotaExemptRoute[];
|
|
35
|
+
/** Whether `method` + `path` (a request path or a route-table pattern) is quota-exempt. */
|
|
36
|
+
export declare function isQuotaExemptRoute(method: string | undefined, path: string): boolean;
|