@dbx-tools/auth 0.9.31 → 0.9.36

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.
Files changed (73) hide show
  1. package/README.md +49 -97
  2. package/index.ts +8 -26
  3. package/lib/index.d.ts +8 -26
  4. package/lib/index.js +6 -22
  5. package/lib/src/{databricks-cli.d.ts → _databricks-cli.d.ts} +3 -7
  6. package/lib/src/_databricks-cli.js +172 -0
  7. package/lib/src/_errors.d.ts +5 -0
  8. package/lib/src/_errors.js +10 -0
  9. package/lib/src/{lifecycle.d.ts → _lifecycle.d.ts} +5 -5
  10. package/lib/src/_lifecycle.js +214 -0
  11. package/lib/src/_logging.d.ts +1 -1
  12. package/lib/src/_logging.js +2 -2
  13. package/lib/src/{personal-access-token.d.ts → _personal-access-token.d.ts} +1 -1
  14. package/lib/src/_personal-access-token.js +30 -0
  15. package/lib/src/_profile-config.d.ts +43 -0
  16. package/lib/src/_profile-config.js +443 -0
  17. package/lib/src/{service-principal.d.ts → _service-principal.d.ts} +1 -1
  18. package/lib/src/_service-principal.js +69 -0
  19. package/lib/src/{storage.d.ts → _storage.d.ts} +4 -6
  20. package/lib/src/_storage.js +94 -0
  21. package/lib/src/_types.d.ts +40 -0
  22. package/lib/src/_types.js +2 -0
  23. package/lib/src/client.d.ts +30 -0
  24. package/lib/src/client.js +223 -0
  25. package/lib/src/config.d.ts +36 -0
  26. package/lib/src/config.js +15 -0
  27. package/lib/src/profile.d.ts +11 -0
  28. package/lib/src/profile.js +21 -0
  29. package/lib/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +34 -10
  31. package/src/{databricks-cli.ts → _databricks-cli.ts} +20 -109
  32. package/src/_errors.ts +11 -0
  33. package/src/{lifecycle.ts → _lifecycle.ts} +24 -48
  34. package/src/_logging.ts +2 -2
  35. package/src/{personal-access-token.ts → _personal-access-token.ts} +1 -1
  36. package/src/_profile-config.ts +545 -0
  37. package/src/{service-principal.ts → _service-principal.ts} +2 -2
  38. package/src/_storage.ts +109 -0
  39. package/src/_types.ts +45 -0
  40. package/src/client.ts +291 -0
  41. package/src/config.ts +44 -0
  42. package/src/profile.ts +33 -0
  43. package/lib/exports.d.ts +0 -2
  44. package/lib/exports.js +0 -3
  45. package/lib/src/_profile-core.d.ts +0 -28
  46. package/lib/src/_profile-core.js +0 -216
  47. package/lib/src/_profile.d.ts +0 -15
  48. package/lib/src/_profile.js +0 -236
  49. package/lib/src/databricks-auth.d.ts +0 -11
  50. package/lib/src/databricks-auth.js +0 -314
  51. package/lib/src/databricks-cli.js +0 -239
  52. package/lib/src/errors.d.ts +0 -7
  53. package/lib/src/errors.js +0 -14
  54. package/lib/src/generated/databricks-cli-assets.json +0 -33
  55. package/lib/src/http-client.d.ts +0 -23
  56. package/lib/src/http-client.js +0 -116
  57. package/lib/src/lifecycle.js +0 -229
  58. package/lib/src/node-storage.d.ts +0 -20
  59. package/lib/src/node-storage.js +0 -207
  60. package/lib/src/personal-access-token.js +0 -30
  61. package/lib/src/service-principal.js +0 -69
  62. package/lib/src/storage.js +0 -98
  63. package/lib/src/types.d.ts +0 -157
  64. package/lib/src/types.js +0 -67
  65. package/src/_profile-core.ts +0 -258
  66. package/src/_profile.ts +0 -319
  67. package/src/databricks-auth.ts +0 -416
  68. package/src/errors.ts +0 -16
  69. package/src/generated/databricks-cli-assets.json +0 -33
  70. package/src/http-client.ts +0 -147
  71. package/src/node-storage.ts +0 -230
  72. package/src/storage.ts +0 -104
  73. package/src/types.ts +0 -188
@@ -0,0 +1,443 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { isAbsolute, resolve } from "node:path";
5
+ import { AuthType, TargetKind } from "@dbx-tools/shared-auth/config";
6
+ import * as environmentUtils from "@dbx-tools/shared-core/environment-utils";
7
+ import * as object from "@dbx-tools/shared-core/object";
8
+ import * as stringUtils from "@dbx-tools/shared-core/string-utils";
9
+ import { trimToUndefined } from "@dbx-tools/shared-core/string-utils";
10
+ import { parse as parseIni } from "ini";
11
+ import { AuthError } from "./_errors.js";
12
+ import { authLogger } from "./_logging.js";
13
+ import { DEFAULT_ACCESS_TOKEN_HEADER, DEFAULT_CLIENT_ID, DEFAULT_CONFIG_FILE, } from "./config.js";
14
+ const logger = authLogger("profile-selection");
15
+ const configCache = new Map();
16
+ export const SETTINGS_SECTION = "__settings__";
17
+ /** Resolve the selected Databricks configuration path. */
18
+ export function resolveConfigFile(explicit, environment = process.env) {
19
+ const selected = trimToUndefined(explicit) ??
20
+ trimToUndefined(environment.DATABRICKS_CONFIG_FILE) ??
21
+ DEFAULT_CONFIG_FILE;
22
+ const expanded = selected === "~"
23
+ ? homedir()
24
+ : selected.startsWith("~/")
25
+ ? resolve(homedir(), selected.slice(2))
26
+ : selected;
27
+ return isAbsolute(expanded) ? expanded : resolve(expanded);
28
+ }
29
+ /** Load and cache the selected Databricks configuration. */
30
+ export function loadConfig(configFile, refresh = false, environment = process.env) {
31
+ const path = resolveConfigFile(configFile, environment);
32
+ if (refresh)
33
+ configCache.delete(path);
34
+ if (configCache.has(path)) {
35
+ const cached = configCache.get(path);
36
+ if (cached instanceof Error)
37
+ throw cached;
38
+ return cached;
39
+ }
40
+ if (!existsSync(path)) {
41
+ configCache.set(path, undefined);
42
+ return undefined;
43
+ }
44
+ try {
45
+ const config = parseDatabricksConfig(readFileSync(path, "utf8"));
46
+ configCache.set(path, config);
47
+ return config;
48
+ }
49
+ catch (cause) {
50
+ const error = cause instanceof Error ? cause : new AuthError("config", `Could not read ${path}`, { cause });
51
+ configCache.set(path, error);
52
+ throw error;
53
+ }
54
+ }
55
+ /** Invalidate cached configuration after an external write. */
56
+ export function invalidateConfigFile(configFile) {
57
+ configCache.delete(resolveConfigFile(configFile));
58
+ }
59
+ /** Parse Databricks INI text through the maintained `ini` package. */
60
+ export function parseDatabricksConfig(source) {
61
+ let parsed;
62
+ try {
63
+ parsed = parseIni(source);
64
+ }
65
+ catch (cause) {
66
+ throw new AuthError("config", "Databricks configuration is not valid INI", { cause });
67
+ }
68
+ const config = new Map();
69
+ for (const [name, value] of Object.entries(parsed)) {
70
+ if (!name.trim() || !object.isRecord(value)) {
71
+ throw new AuthError("config", "Databricks configuration values must belong to a profile");
72
+ }
73
+ const section = new Map();
74
+ for (const [key, entry] of Object.entries(value)) {
75
+ if (entry === undefined || entry === null)
76
+ continue;
77
+ section.set(key.trim().toLowerCase(), String(entry).trim());
78
+ }
79
+ config.set(name.trim(), section);
80
+ }
81
+ return config;
82
+ }
83
+ export function loadRawProfile(config, name) {
84
+ const section = config?.get(name);
85
+ return {
86
+ host: section?.get("host"),
87
+ accountId: section?.get("account_id"),
88
+ workspaceId: section?.get("workspace_id"),
89
+ clientId: section?.get("client_id"),
90
+ clientSecret: section?.get("client_secret"),
91
+ accessToken: section?.get("token"),
92
+ groupId: section?.get("group_id"),
93
+ scopes: section?.get("scopes"),
94
+ authType: trimToUndefined(section?.get("auth_type"))?.toLowerCase(),
95
+ };
96
+ }
97
+ export function resolveProfileName(requested, explicit, config, preferUserToMachine) {
98
+ let selected = requested;
99
+ let source = requested ? "requested" : undefined;
100
+ if (!selected) {
101
+ selected = trimToUndefined(config?.get(SETTINGS_SECTION)?.get("default_profile"));
102
+ if (selected)
103
+ source = "settings-default";
104
+ }
105
+ if (!selected && config?.has("DEFAULT")) {
106
+ selected = "DEFAULT";
107
+ source = "default-section";
108
+ }
109
+ if (!selected) {
110
+ const profiles = [...(config?.keys() ?? [])].filter((name) => name !== SETTINGS_SECTION);
111
+ if (profiles.length === 1) {
112
+ selected = profiles[0];
113
+ source = "sole-profile";
114
+ }
115
+ }
116
+ if (!selected) {
117
+ selected = "DEFAULT";
118
+ source = "fallback";
119
+ }
120
+ if (selected === SETTINGS_SECTION) {
121
+ throw new AuthError("config", `${SETTINGS_SECTION} is reserved`);
122
+ }
123
+ if (explicit || !preferUserToMachine || !config) {
124
+ logger.debug("selected Databricks profile", {
125
+ profile: selected,
126
+ source,
127
+ explicit,
128
+ preferUserToMachine,
129
+ });
130
+ return selected;
131
+ }
132
+ const current = loadRawProfile(config, selected);
133
+ if (!isM2mProfile(current) || !current.host) {
134
+ logger.debug("selected Databricks profile", {
135
+ profile: selected,
136
+ source,
137
+ explicit,
138
+ preferUserToMachine,
139
+ });
140
+ return selected;
141
+ }
142
+ const matches = [...config.keys()].filter((name) => {
143
+ if (name === selected || name === SETTINGS_SECTION)
144
+ return false;
145
+ const candidate = loadRawProfile(config, name);
146
+ return candidate.authType === "databricks-cli" && sameTarget(current, candidate);
147
+ });
148
+ const preferred = matches.length === 1 ? matches[0] : selected;
149
+ logger.debug("selected Databricks profile", {
150
+ profile: preferred,
151
+ source: preferred === selected ? source : "matching-cli-profile",
152
+ originalProfile: preferred === selected ? undefined : selected,
153
+ explicit,
154
+ preferUserToMachine,
155
+ matchingCliProfiles: matches.length,
156
+ });
157
+ return preferred;
158
+ }
159
+ /** Normalize Databricks hosts and require TLS outside loopback development. */
160
+ export function normalizeHost(value, profile = "DEFAULT") {
161
+ const selected = trimToUndefined(value);
162
+ if (!selected)
163
+ throw new AuthError("config", `Profile ${profile} has no host`);
164
+ const withScheme = /^https?:\/\//i.test(selected) ? selected : `https://${selected}`;
165
+ let url;
166
+ try {
167
+ url = new URL(withScheme);
168
+ }
169
+ catch (cause) {
170
+ throw new AuthError("config", `Profile ${profile} has an invalid host`, { cause });
171
+ }
172
+ if (url.protocol !== "https:" && url.hostname !== "localhost" && url.hostname !== "127.0.0.1") {
173
+ throw new AuthError("config", "Databricks host must use HTTPS");
174
+ }
175
+ return url.toString().replace(/\/$/, "");
176
+ }
177
+ export function resolveAuthType(authType, clientId, clientSecret, accessToken) {
178
+ switch (authType) {
179
+ case AuthType.DatabricksCli:
180
+ return AuthType.DatabricksCli;
181
+ case AuthType.OAuthM2M:
182
+ if (!clientId || !clientSecret) {
183
+ throw new AuthError("config", "oauth-m2m requires client_id and client_secret");
184
+ }
185
+ return AuthType.OAuthM2M;
186
+ case AuthType.PersonalAccessToken:
187
+ if (!accessToken)
188
+ throw new AuthError("config", "pat requires token");
189
+ return AuthType.PersonalAccessToken;
190
+ case AuthType.AppOnBehalfOf:
191
+ if (!accessToken) {
192
+ throw new AuthError("config", "app_obo requires the configured access token header");
193
+ }
194
+ return AuthType.AppOnBehalfOf;
195
+ case AuthType.AppServicePrincipal:
196
+ if (!clientId || !clientSecret) {
197
+ throw new AuthError("config", "app_sp requires client id and secret");
198
+ }
199
+ return AuthType.AppServicePrincipal;
200
+ case undefined:
201
+ if (clientId && clientSecret)
202
+ return AuthType.OAuthM2M;
203
+ if (clientSecret)
204
+ throw new AuthError("config", "oauth-m2m client_secret requires client_id");
205
+ return accessToken ? AuthType.PersonalAccessToken : AuthType.DatabricksCli;
206
+ }
207
+ }
208
+ /** Parse one external auth-type value into the canonical enum. */
209
+ export function parseAuthType(value) {
210
+ const selected = trimToUndefined(value)?.toLowerCase();
211
+ if (selected === undefined)
212
+ return undefined;
213
+ if (Object.values(AuthType).includes(selected))
214
+ return selected;
215
+ throw new AuthError("config", `Authentication type ${selected} is not supported`);
216
+ }
217
+ export function requestOboToken(headers, headerName = DEFAULT_ACCESS_TOKEN_HEADER) {
218
+ const entry = Object.entries(headers ?? {}).find(([name]) => name.toLowerCase() === headerName.toLowerCase());
219
+ const value = trimToUndefined(entry?.[1]);
220
+ if (!value)
221
+ return undefined;
222
+ if (headerName.toLowerCase() !== DEFAULT_ACCESS_TOKEN_HEADER)
223
+ return value;
224
+ const [scheme, ...parts] = value.split(/\s+/);
225
+ return scheme?.toLowerCase() === "bearer" ? trimToUndefined(parts.join(" ")) : undefined;
226
+ }
227
+ export function inferTarget(host, accountId) {
228
+ if (accountId && host) {
229
+ try {
230
+ if (new URL(normalizeHost(host)).hostname === "accounts.cloud.databricks.com") {
231
+ return TargetKind.Account;
232
+ }
233
+ }
234
+ catch { }
235
+ }
236
+ return TargetKind.Workspace;
237
+ }
238
+ export function parseTarget(value) {
239
+ switch (value.trim().toLowerCase()) {
240
+ case TargetKind.Workspace:
241
+ return TargetKind.Workspace;
242
+ case TargetKind.Account:
243
+ return TargetKind.Account;
244
+ case TargetKind.Unified:
245
+ return TargetKind.Unified;
246
+ default:
247
+ throw new AuthError("config", "Target must be workspace, account, or unified");
248
+ }
249
+ }
250
+ export function missing(profile, field) {
251
+ throw new AuthError("config", `Profile ${profile} requires ${field}`);
252
+ }
253
+ function sameTarget(left, right) {
254
+ try {
255
+ if (normalizeHost(left.host) !== normalizeHost(right.host))
256
+ return false;
257
+ }
258
+ catch {
259
+ return false;
260
+ }
261
+ return ((!left.accountId || left.accountId === right.accountId) &&
262
+ (!left.workspaceId || left.workspaceId === right.workspaceId));
263
+ }
264
+ function isM2mProfile(profile) {
265
+ return (profile.authType === AuthType.OAuthM2M ||
266
+ (!profile.authType && Boolean(profile.clientId && profile.clientSecret)));
267
+ }
268
+ /** Enumerate secret-free profile metadata from cached configuration. */
269
+ export function listDatabricksProfiles(configFile, refresh = false, environment = process.env) {
270
+ const path = resolveConfigFile(configFile, environment);
271
+ const config = loadConfig(configFile, refresh, environment);
272
+ if (!config) {
273
+ logger.debug("listed Databricks profiles", { path, refresh, count: 0 });
274
+ return [];
275
+ }
276
+ const profiles = [...config.keys()]
277
+ .filter((name) => name !== SETTINGS_SECTION)
278
+ .map((name) => {
279
+ const profile = loadRawProfile(config, name);
280
+ const host = stringUtils.trimToUndefined(profile.host);
281
+ const accountId = stringUtils.trimToUndefined(profile.accountId);
282
+ const workspaceId = stringUtils.trimToUndefined(profile.workspaceId);
283
+ const authType = resolveAuthType(parseAuthType(profile.authType), profile.clientId, profile.clientSecret, profile.accessToken);
284
+ return {
285
+ name,
286
+ ...(host ? { host } : {}),
287
+ ...(accountId ? { accountId } : {}),
288
+ ...(workspaceId ? { workspaceId } : {}),
289
+ target: inferTarget(host, accountId),
290
+ authType,
291
+ principal: authType === AuthType.OAuthM2M || authType === AuthType.AppServicePrincipal
292
+ ? (stringUtils.trimToUndefined(profile.clientId) ?? name)
293
+ : name,
294
+ };
295
+ })
296
+ .sort((left, right) => left.name.localeCompare(right.name));
297
+ logger.debug("listed Databricks profiles", { path, refresh, count: profiles.length });
298
+ return profiles;
299
+ }
300
+ /** Resolve options, environment, request headers, and configuration into credentials. */
301
+ export function resolveDatabricksProfile(options, environment = process.env) {
302
+ const inApp = environmentUtils.isDatabricksAppEnv({ ...environment });
303
+ const environmentProfile = stringUtils.trimToUndefined(environment.DATABRICKS_CONFIG_PROFILE);
304
+ const explicitProfile = Boolean(stringUtils.trimToUndefined(options.profile) ?? environmentProfile);
305
+ const requestToken = requestOboToken(options.requestHeaders, options.accessTokenHeader);
306
+ const explicitAuthType = options.authType ??
307
+ (!inApp && !explicitProfile ? parseAuthType(environment.DATABRICKS_AUTH_TYPE) : undefined);
308
+ const appServicePrincipal = [
309
+ environment.DATABRICKS_HOST,
310
+ environment.DATABRICKS_CLIENT_ID,
311
+ environment.DATABRICKS_CLIENT_SECRET,
312
+ ].every((value) => Boolean(stringUtils.trimToUndefined(value)));
313
+ const selectedAuthType = !inApp || explicitProfile || explicitAuthType
314
+ ? explicitAuthType
315
+ : requestToken
316
+ ? AuthType.AppOnBehalfOf
317
+ : appServicePrincipal
318
+ ? AuthType.AppServicePrincipal
319
+ : undefined;
320
+ const appAuth = selectedAuthType === AuthType.AppOnBehalfOf ||
321
+ selectedAuthType === AuthType.AppServicePrincipal;
322
+ const ignoreAmbientCredentials = explicitProfile && !appAuth;
323
+ const configPath = resolveConfigFile(options.configFile, environment);
324
+ const config = loadConfig(options.configFile, false, environment);
325
+ const requestedName = stringUtils.trimToUndefined(options.profile) ?? environmentProfile;
326
+ const profileName = resolveProfileName(requestedName, explicitProfile, config, options.preferUserToMachine ?? true);
327
+ const ambientCredentials = [
328
+ options.accessToken,
329
+ options.clientId,
330
+ options.clientSecret,
331
+ environment.DATABRICKS_TOKEN,
332
+ environment.DATABRICKS_CLIENT_ID,
333
+ environment.DATABRICKS_CLIENT_SECRET,
334
+ ].some((value) => Boolean(stringUtils.trimToUndefined(value)));
335
+ const selectedProfile = explicitProfile || (!ambientCredentials && config?.has(profileName)) ? profileName : undefined;
336
+ const configured = loadRawProfile(config, profileName);
337
+ const ambient = (name) => ignoreAmbientCredentials ? undefined : stringUtils.trimToUndefined(environment[name]);
338
+ const host = normalizeHost(options.host ?? ambient("DATABRICKS_HOST") ?? configured.host, profileName);
339
+ const accountId = stringUtils.trimToUndefined(options.accountId) ??
340
+ ambient("DATABRICKS_ACCOUNT_ID") ??
341
+ stringUtils.trimToUndefined(configured.accountId);
342
+ const workspaceId = stringUtils.trimToUndefined(options.workspaceId) ??
343
+ ambient("DATABRICKS_WORKSPACE_ID") ??
344
+ stringUtils.trimToUndefined(configured.workspaceId);
345
+ const clientIdValue = stringUtils.trimToUndefined(options.clientId) ??
346
+ ambient("DATABRICKS_CLIENT_ID") ??
347
+ stringUtils.trimToUndefined(configured.clientId);
348
+ const clientSecret = stringUtils.trimToUndefined(options.clientSecret) ??
349
+ ambient("DATABRICKS_CLIENT_SECRET") ??
350
+ stringUtils.trimToUndefined(configured.clientSecret);
351
+ const accessToken = selectedAuthType === AuthType.AppOnBehalfOf
352
+ ? requestToken
353
+ : (stringUtils.trimToUndefined(options.accessToken) ??
354
+ ambient("DATABRICKS_TOKEN") ??
355
+ stringUtils.trimToUndefined(configured.accessToken));
356
+ const configuredAuthType = selectedAuthType ??
357
+ parseAuthType(ambient("DATABRICKS_AUTH_TYPE")) ??
358
+ parseAuthType(configured.authType);
359
+ const authType = resolveAuthType(configuredAuthType, clientIdValue, clientSecret, accessToken);
360
+ const clientId = authType === AuthType.DatabricksCli
361
+ ? (clientIdValue ?? DEFAULT_CLIENT_ID)
362
+ : authType === AuthType.OAuthM2M || authType === AuthType.AppServicePrincipal
363
+ ? (clientIdValue ?? missing(profileName, "client_id"))
364
+ : (clientIdValue ?? "");
365
+ const scopes = options.scopes?.length
366
+ ? stringUtils.parseList(options.scopes)
367
+ : stringUtils.parseList(configured.scopes?.split(",") ?? ["all-apis"]);
368
+ const target = options.target ? parseTarget(options.target) : inferTarget(host, accountId);
369
+ const groupId = stringUtils.trimToUndefined(options.groupId) ??
370
+ ambient("DATABRICKS_GROUP_ID") ??
371
+ stringUtils.trimToUndefined(configured.groupId);
372
+ const principal = authType === AuthType.OAuthM2M || authType === AuthType.AppServicePrincipal
373
+ ? clientId
374
+ : profileName;
375
+ const cacheKey = credentialCacheKey({
376
+ name: profileName,
377
+ host,
378
+ accountId,
379
+ workspaceId,
380
+ clientId,
381
+ groupId,
382
+ scopes,
383
+ authType,
384
+ accessToken,
385
+ });
386
+ logger.debug("resolved Databricks profile", {
387
+ profile: profileName,
388
+ host,
389
+ authType,
390
+ target,
391
+ inApp,
392
+ explicitProfile,
393
+ configuredAuthType: configuredAuthType ?? "automatic",
394
+ hasAccountId: Boolean(accountId),
395
+ hasWorkspaceId: Boolean(workspaceId),
396
+ hasGroupId: Boolean(groupId),
397
+ scopeCount: scopes.length,
398
+ configPath,
399
+ });
400
+ return {
401
+ name: profileName,
402
+ ...(selectedProfile ? { selectedProfile } : {}),
403
+ host,
404
+ ...(accountId ? { accountId } : {}),
405
+ ...(workspaceId ? { workspaceId } : {}),
406
+ clientId,
407
+ ...(groupId ? { groupId } : {}),
408
+ scopes,
409
+ target,
410
+ authType,
411
+ ...(clientSecret ? { clientSecret } : {}),
412
+ ...(accessToken ? { accessToken } : {}),
413
+ cacheKey,
414
+ principal,
415
+ };
416
+ }
417
+ /** Normalize OAuth scopes for machine credentials. */
418
+ export function machineScopes(scopes) {
419
+ return stringUtils.parseList(scopes.length ? scopes : ["all-apis"]).sort();
420
+ }
421
+ function credentialCacheKey(profile) {
422
+ if (profile.authType === AuthType.DatabricksCli)
423
+ return profile.name;
424
+ if (profile.authType === AuthType.PersonalAccessToken) {
425
+ const digest = createHash("sha256")
426
+ .update(profile.accessToken ?? "")
427
+ .digest("hex");
428
+ return `${profile.name}-pat-${digest}`;
429
+ }
430
+ if (profile.authType === AuthType.AppOnBehalfOf)
431
+ return `${profile.name}-app-obo`;
432
+ const identity = [
433
+ profile.host,
434
+ profile.accountId ?? "",
435
+ profile.workspaceId ?? "",
436
+ profile.clientId,
437
+ profile.groupId ?? "",
438
+ machineScopes(profile.scopes).join(" "),
439
+ ].join("\0");
440
+ const digest = createHash("sha256").update(identity).digest("hex");
441
+ return `${profile.name}-${profile.authType === AuthType.AppServicePrincipal ? "app-sp" : "oauth-m2m"}-${digest}`;
442
+ }
443
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3Byb2ZpbGUtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL19wcm9maWxlLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVyRSxPQUFPLEtBQUssZ0JBQWdCLE1BQU0sMENBQTBDLENBQUM7QUFDN0UsT0FBTyxLQUFLLE1BQU0sTUFBTSwrQkFBK0IsQ0FBQztBQUN4RCxPQUFPLEtBQUssV0FBVyxNQUFNLHFDQUFxQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN0RSxPQUFPLEVBQUUsS0FBSyxJQUFJLFFBQVEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUVMLDJCQUEyQixFQUMzQixpQkFBaUIsRUFDakIsbUJBQW1CLEdBQ3BCLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBQy9DLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUF5QyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLGNBQWMsQ0FBQztBQWlCL0MsMERBQTBEO0FBQzFELE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsUUFB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LENBQUM7UUFDdEQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQzthQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7YUFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pCLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxRQUFRLE1BQU0sRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLGFBQWE7UUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksVUFBVSxDQUFDO0lBQ2xGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsT0FBTyxDQUFDLElBQUk7UUFDWixPQUFPLENBQUMsU0FBUyxJQUFJLEVBQUU7UUFDdkIsT0FBTyxDQUFDLFdBQVcsSUFBSSxFQUFFO1FBQ3pCLE9BQU8sQ0FBQyxRQUFRO1FBQ2hCLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRTtRQUNyQixhQUFhLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7S0FDeEMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDYixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuRSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLElBQUksTUFBTSxFQUFFLENBQUM7QUFDbkgsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGlzQWJzb2x1dGUsIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmltcG9ydCB7IEF1dGhUeXBlLCBUYXJnZXRLaW5kIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWF1dGgvY29uZmlnXCI7XG5pbXBvcnQgdHlwZSB7IERhdGFicmlja3NQcm9maWxlU3VtbWFyeSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1hdXRoL3Byb2ZpbGVcIjtcbmltcG9ydCAqIGFzIGVudmlyb25tZW50VXRpbHMgZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvZW52aXJvbm1lbnQtdXRpbHNcIjtcbmltcG9ydCAqIGFzIG9iamVjdCBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZS9vYmplY3RcIjtcbmltcG9ydCAqIGFzIHN0cmluZ1V0aWxzIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL3N0cmluZy11dGlsc1wiO1xuaW1wb3J0IHsgdHJpbVRvVW5kZWZpbmVkIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvc3RyaW5nLXV0aWxzXCI7XG5pbXBvcnQgeyBwYXJzZSBhcyBwYXJzZUluaSB9IGZyb20gXCJpbmlcIjtcblxuaW1wb3J0IHsgQXV0aEVycm9yIH0gZnJvbSBcIi4vX2Vycm9ycy50c1wiO1xuaW1wb3J0IHsgYXV0aExvZ2dlciB9IGZyb20gXCIuL19sb2dnaW5nLnRzXCI7XG5pbXBvcnQgdHlwZSB7IERhdGFicmlja3NQcm9maWxlIH0gZnJvbSBcIi4vX3R5cGVzLnRzXCI7XG5pbXBvcnQge1xuICB0eXBlIERhdGFicmlja3NBdXRoT3B0aW9ucyxcbiAgREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSLFxuICBERUZBVUxUX0NMSUVOVF9JRCxcbiAgREVGQVVMVF9DT05GSUdfRklMRSxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGF1dGhMb2dnZXIoXCJwcm9maWxlLXNlbGVjdGlvblwiKTtcbmNvbnN0IGNvbmZpZ0NhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEluaUNvbmZpZyB8IEVycm9yIHwgdW5kZWZpbmVkPigpO1xuXG5leHBvcnQgY29uc3QgU0VUVElOR1NfU0VDVElPTiA9IFwiX19zZXR0aW5nc19fXCI7XG5cbmV4cG9ydCB0eXBlIEVudmlyb25tZW50ID0gUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj47XG5leHBvcnQgdHlwZSBJbmlDb25maWcgPSBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBzdHJpbmc+PjtcblxuZXhwb3J0IGludGVyZmFjZSBSYXdQcm9maWxlIHtcbiAgaG9zdD86IHN0cmluZztcbiAgYWNjb3VudElkPzogc3RyaW5nO1xuICB3b3Jrc3BhY2VJZD86IHN0cmluZztcbiAgY2xpZW50SWQ/OiBzdHJpbmc7XG4gIGNsaWVudFNlY3JldD86IHN0cmluZztcbiAgYWNjZXNzVG9rZW4/OiBzdHJpbmc7XG4gIGdyb3VwSWQ/OiBzdHJpbmc7XG4gIHNjb3Blcz86IHN0cmluZztcbiAgYXV0aFR5cGU/OiBzdHJpbmc7XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBzZWxlY3RlZCBEYXRhYnJpY2tzIGNvbmZpZ3VyYXRpb24gcGF0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQ29uZmlnRmlsZShcbiAgZXhwbGljaXQ/OiBzdHJpbmcsXG4gIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCA9IHByb2Nlc3MuZW52LFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc2VsZWN0ZWQgPVxuICAgIHRyaW1Ub1VuZGVmaW5lZChleHBsaWNpdCkgPz9cbiAgICB0cmltVG9VbmRlZmluZWQoZW52aXJvbm1lbnQuREFUQUJSSUNLU19DT05GSUdfRklMRSkgPz9cbiAgICBERUZBVUxUX0NPTkZJR19GSUxFO1xuICBjb25zdCBleHBhbmRlZCA9XG4gICAgc2VsZWN0ZWQgPT09IFwiflwiXG4gICAgICA/IGhvbWVkaXIoKVxuICAgICAgOiBzZWxlY3RlZC5zdGFydHNXaXRoKFwifi9cIilcbiAgICAgICAgPyByZXNvbHZlKGhvbWVkaXIoKSwgc2VsZWN0ZWQuc2xpY2UoMikpXG4gICAgICAgIDogc2VsZWN0ZWQ7XG4gIHJldHVybiBpc0Fic29sdXRlKGV4cGFuZGVkKSA/IGV4cGFuZGVkIDogcmVzb2x2ZShleHBhbmRlZCk7XG59XG5cbi8qKiBMb2FkIGFuZCBjYWNoZSB0aGUgc2VsZWN0ZWQgRGF0YWJyaWNrcyBjb25maWd1cmF0aW9uLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWRDb25maWcoXG4gIGNvbmZpZ0ZpbGU/OiBzdHJpbmcsXG4gIHJlZnJlc2ggPSBmYWxzZSxcbiAgZW52aXJvbm1lbnQ6IEVudmlyb25tZW50ID0gcHJvY2Vzcy5lbnYsXG4pOiBJbmlDb25maWcgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXRoID0gcmVzb2x2ZUNvbmZpZ0ZpbGUoY29uZmlnRmlsZSwgZW52aXJvbm1lbnQpO1xuICBpZiAocmVmcmVzaCkgY29uZmlnQ2FjaGUuZGVsZXRlKHBhdGgpO1xuICBpZiAoY29uZmlnQ2FjaGUuaGFzKHBhdGgpKSB7XG4gICAgY29uc3QgY2FjaGVkID0gY29uZmlnQ2FjaGUuZ2V0KHBhdGgpO1xuICAgIGlmIChjYWNoZWQgaW5zdGFuY2VvZiBFcnJvcikgdGhyb3cgY2FjaGVkO1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cbiAgaWYgKCFleGlzdHNTeW5jKHBhdGgpKSB7XG4gICAgY29uZmlnQ2FjaGUuc2V0KHBhdGgsIHVuZGVmaW5lZCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHBhcnNlRGF0YWJyaWNrc0NvbmZpZyhyZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpKTtcbiAgICBjb25maWdDYWNoZS5zZXQocGF0aCwgY29uZmlnKTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9IGNhdGNoIChjYXVzZSkge1xuICAgIGNvbnN0IGVycm9yID1cbiAgICAgIGNhdXNlIGluc3RhbmNlb2YgRXJyb3IgPyBjYXVzZSA6IG5ldyBBdXRoRXJyb3IoXCJjb25maWdcIiwgYENvdWxkIG5vdCByZWFkICR7cGF0aH1gLCB7IGNhdXNlIH0pO1xuICAgIGNvbmZpZ0NhY2hlLnNldChwYXRoLCBlcnJvcik7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuLyoqIEludmFsaWRhdGUgY2FjaGVkIGNvbmZpZ3VyYXRpb24gYWZ0ZXIgYW4gZXh0ZXJuYWwgd3JpdGUuICovXG5leHBvcnQgZnVuY3Rpb24gaW52YWxpZGF0ZUNvbmZpZ0ZpbGUoY29uZmlnRmlsZT86IHN0cmluZyk6IHZvaWQge1xuICBjb25maWdDYWNoZS5kZWxldGUocmVzb2x2ZUNvbmZpZ0ZpbGUoY29uZmlnRmlsZSkpO1xufVxuXG4vKiogUGFyc2UgRGF0YWJyaWNrcyBJTkkgdGV4dCB0aHJvdWdoIHRoZSBtYWludGFpbmVkIGBpbmlgIHBhY2thZ2UuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEYXRhYnJpY2tzQ29uZmlnKHNvdXJjZTogc3RyaW5nKTogSW5pQ29uZmlnIHtcbiAgbGV0IHBhcnNlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gcGFyc2VJbmkoc291cmNlKSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiRGF0YWJyaWNrcyBjb25maWd1cmF0aW9uIGlzIG5vdCB2YWxpZCBJTklcIiwgeyBjYXVzZSB9KTtcbiAgfVxuICBjb25zdCBjb25maWc6IEluaUNvbmZpZyA9IG5ldyBNYXAoKTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHBhcnNlZCkpIHtcbiAgICBpZiAoIW5hbWUudHJpbSgpIHx8ICFvYmplY3QuaXNSZWNvcmQodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiRGF0YWJyaWNrcyBjb25maWd1cmF0aW9uIHZhbHVlcyBtdXN0IGJlbG9uZyB0byBhIHByb2ZpbGVcIik7XG4gICAgfVxuICAgIGNvbnN0IHNlY3Rpb24gPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgW2tleSwgZW50cnldIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgaWYgKGVudHJ5ID09PSB1bmRlZmluZWQgfHwgZW50cnkgPT09IG51bGwpIGNvbnRpbnVlO1xuICAgICAgc2VjdGlvbi5zZXQoa2V5LnRyaW0oKS50b0xvd2VyQ2FzZSgpLCBTdHJpbmcoZW50cnkpLnRyaW0oKSk7XG4gICAgfVxuICAgIGNvbmZpZy5zZXQobmFtZS50cmltKCksIHNlY3Rpb24pO1xuICB9XG4gIHJldHVybiBjb25maWc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkUmF3UHJvZmlsZShjb25maWc6IEluaUNvbmZpZyB8IHVuZGVmaW5lZCwgbmFtZTogc3RyaW5nKTogUmF3UHJvZmlsZSB7XG4gIGNvbnN0IHNlY3Rpb24gPSBjb25maWc/LmdldChuYW1lKTtcbiAgcmV0dXJuIHtcbiAgICBob3N0OiBzZWN0aW9uPy5nZXQoXCJob3N0XCIpLFxuICAgIGFjY291bnRJZDogc2VjdGlvbj8uZ2V0KFwiYWNjb3VudF9pZFwiKSxcbiAgICB3b3Jrc3BhY2VJZDogc2VjdGlvbj8uZ2V0KFwid29ya3NwYWNlX2lkXCIpLFxuICAgIGNsaWVudElkOiBzZWN0aW9uPy5nZXQoXCJjbGllbnRfaWRcIiksXG4gICAgY2xpZW50U2VjcmV0OiBzZWN0aW9uPy5nZXQoXCJjbGllbnRfc2VjcmV0XCIpLFxuICAgIGFjY2Vzc1Rva2VuOiBzZWN0aW9uPy5nZXQoXCJ0b2tlblwiKSxcbiAgICBncm91cElkOiBzZWN0aW9uPy5nZXQoXCJncm91cF9pZFwiKSxcbiAgICBzY29wZXM6IHNlY3Rpb24/LmdldChcInNjb3Blc1wiKSxcbiAgICBhdXRoVHlwZTogdHJpbVRvVW5kZWZpbmVkKHNlY3Rpb24/LmdldChcImF1dGhfdHlwZVwiKSk/LnRvTG93ZXJDYXNlKCksXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUHJvZmlsZU5hbWUoXG4gIHJlcXVlc3RlZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBleHBsaWNpdDogYm9vbGVhbixcbiAgY29uZmlnOiBJbmlDb25maWcgfCB1bmRlZmluZWQsXG4gIHByZWZlclVzZXJUb01hY2hpbmU6IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBsZXQgc2VsZWN0ZWQgPSByZXF1ZXN0ZWQ7XG4gIGxldCBzb3VyY2UgPSByZXF1ZXN0ZWQgPyBcInJlcXVlc3RlZFwiIDogdW5kZWZpbmVkO1xuICBpZiAoIXNlbGVjdGVkKSB7XG4gICAgc2VsZWN0ZWQgPSB0cmltVG9VbmRlZmluZWQoY29uZmlnPy5nZXQoU0VUVElOR1NfU0VDVElPTik/LmdldChcImRlZmF1bHRfcHJvZmlsZVwiKSk7XG4gICAgaWYgKHNlbGVjdGVkKSBzb3VyY2UgPSBcInNldHRpbmdzLWRlZmF1bHRcIjtcbiAgfVxuICBpZiAoIXNlbGVjdGVkICYmIGNvbmZpZz8uaGFzKFwiREVGQVVMVFwiKSkge1xuICAgIHNlbGVjdGVkID0gXCJERUZBVUxUXCI7XG4gICAgc291cmNlID0gXCJkZWZhdWx0LXNlY3Rpb25cIjtcbiAgfVxuICBpZiAoIXNlbGVjdGVkKSB7XG4gICAgY29uc3QgcHJvZmlsZXMgPSBbLi4uKGNvbmZpZz8ua2V5cygpID8/IFtdKV0uZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBTRVRUSU5HU19TRUNUSU9OKTtcbiAgICBpZiAocHJvZmlsZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBzZWxlY3RlZCA9IHByb2ZpbGVzWzBdO1xuICAgICAgc291cmNlID0gXCJzb2xlLXByb2ZpbGVcIjtcbiAgICB9XG4gIH1cbiAgaWYgKCFzZWxlY3RlZCkge1xuICAgIHNlbGVjdGVkID0gXCJERUZBVUxUXCI7XG4gICAgc291cmNlID0gXCJmYWxsYmFja1wiO1xuICB9XG4gIGlmIChzZWxlY3RlZCA9PT0gU0VUVElOR1NfU0VDVElPTikge1xuICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJjb25maWdcIiwgYCR7U0VUVElOR1NfU0VDVElPTn0gaXMgcmVzZXJ2ZWRgKTtcbiAgfVxuICBpZiAoZXhwbGljaXQgfHwgIXByZWZlclVzZXJUb01hY2hpbmUgfHwgIWNvbmZpZykge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNlbGVjdGVkIERhdGFicmlja3MgcHJvZmlsZVwiLCB7XG4gICAgICBwcm9maWxlOiBzZWxlY3RlZCxcbiAgICAgIHNvdXJjZSxcbiAgICAgIGV4cGxpY2l0LFxuICAgICAgcHJlZmVyVXNlclRvTWFjaGluZSxcbiAgICB9KTtcbiAgICByZXR1cm4gc2VsZWN0ZWQ7XG4gIH1cbiAgY29uc3QgY3VycmVudCA9IGxvYWRSYXdQcm9maWxlKGNvbmZpZywgc2VsZWN0ZWQpO1xuICBpZiAoIWlzTTJtUHJvZmlsZShjdXJyZW50KSB8fCAhY3VycmVudC5ob3N0KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwic2VsZWN0ZWQgRGF0YWJyaWNrcyBwcm9maWxlXCIsIHtcbiAgICAgIHByb2ZpbGU6IHNlbGVjdGVkLFxuICAgICAgc291cmNlLFxuICAgICAgZXhwbGljaXQsXG4gICAgICBwcmVmZXJVc2VyVG9NYWNoaW5lLFxuICAgIH0pO1xuICAgIHJldHVybiBzZWxlY3RlZDtcbiAgfVxuICBjb25zdCBtYXRjaGVzID0gWy4uLmNvbmZpZy5rZXlzKCldLmZpbHRlcigobmFtZSkgPT4ge1xuICAgIGlmIChuYW1lID09PSBzZWxlY3RlZCB8fCBuYW1lID09PSBTRVRUSU5HU19TRUNUSU9OKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gbG9hZFJhd1Byb2ZpbGUoY29uZmlnLCBuYW1lKTtcbiAgICByZXR1cm4gY2FuZGlkYXRlLmF1dGhUeXBlID09PSBcImRhdGFicmlja3MtY2xpXCIgJiYgc2FtZVRhcmdldChjdXJyZW50LCBjYW5kaWRhdGUpO1xuICB9KTtcbiAgY29uc3QgcHJlZmVycmVkID0gbWF0Y2hlcy5sZW5ndGggPT09IDEgPyBtYXRjaGVzWzBdISA6IHNlbGVjdGVkO1xuICBsb2dnZXIuZGVidWcoXCJzZWxlY3RlZCBEYXRhYnJpY2tzIHByb2ZpbGVcIiwge1xuICAgIHByb2ZpbGU6IHByZWZlcnJlZCxcbiAgICBzb3VyY2U6IHByZWZlcnJlZCA9PT0gc2VsZWN0ZWQgPyBzb3VyY2UgOiBcIm1hdGNoaW5nLWNsaS1wcm9maWxlXCIsXG4gICAgb3JpZ2luYWxQcm9maWxlOiBwcmVmZXJyZWQgPT09IHNlbGVjdGVkID8gdW5kZWZpbmVkIDogc2VsZWN0ZWQsXG4gICAgZXhwbGljaXQsXG4gICAgcHJlZmVyVXNlclRvTWFjaGluZSxcbiAgICBtYXRjaGluZ0NsaVByb2ZpbGVzOiBtYXRjaGVzLmxlbmd0aCxcbiAgfSk7XG4gIHJldHVybiBwcmVmZXJyZWQ7XG59XG5cbi8qKiBOb3JtYWxpemUgRGF0YWJyaWNrcyBob3N0cyBhbmQgcmVxdWlyZSBUTFMgb3V0c2lkZSBsb29wYmFjayBkZXZlbG9wbWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVIb3N0KHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHByb2ZpbGUgPSBcIkRFRkFVTFRcIik6IHN0cmluZyB7XG4gIGNvbnN0IHNlbGVjdGVkID0gdHJpbVRvVW5kZWZpbmVkKHZhbHVlKTtcbiAgaWYgKCFzZWxlY3RlZCkgdGhyb3cgbmV3IEF1dGhFcnJvcihcImNvbmZpZ1wiLCBgUHJvZmlsZSAke3Byb2ZpbGV9IGhhcyBubyBob3N0YCk7XG4gIGNvbnN0IHdpdGhTY2hlbWUgPSAvXmh0dHBzPzpcXC9cXC8vaS50ZXN0KHNlbGVjdGVkKSA/IHNlbGVjdGVkIDogYGh0dHBzOi8vJHtzZWxlY3RlZH1gO1xuICBsZXQgdXJsOiBVUkw7XG4gIHRyeSB7XG4gICAgdXJsID0gbmV3IFVSTCh3aXRoU2NoZW1lKTtcbiAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIGBQcm9maWxlICR7cHJvZmlsZX0gaGFzIGFuIGludmFsaWQgaG9zdGAsIHsgY2F1c2UgfSk7XG4gIH1cbiAgaWYgKHVybC5wcm90b2NvbCAhPT0gXCJodHRwczpcIiAmJiB1cmwuaG9zdG5hbWUgIT09IFwibG9jYWxob3N0XCIgJiYgdXJsLmhvc3RuYW1lICE9PSBcIjEyNy4wLjAuMVwiKSB7XG4gICAgdGhyb3cgbmV3IEF1dGhFcnJvcihcImNvbmZpZ1wiLCBcIkRhdGFicmlja3MgaG9zdCBtdXN0IHVzZSBIVFRQU1wiKTtcbiAgfVxuICByZXR1cm4gdXJsLnRvU3RyaW5nKCkucmVwbGFjZSgvXFwvJC8sIFwiXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUF1dGhUeXBlKFxuICBhdXRoVHlwZTogQXV0aFR5cGUgfCB1bmRlZmluZWQsXG4gIGNsaWVudElkOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIGNsaWVudFNlY3JldDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBhY2Nlc3NUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkLFxuKTogQXV0aFR5cGUge1xuICBzd2l0Y2ggKGF1dGhUeXBlKSB7XG4gICAgY2FzZSBBdXRoVHlwZS5EYXRhYnJpY2tzQ2xpOlxuICAgICAgcmV0dXJuIEF1dGhUeXBlLkRhdGFicmlja3NDbGk7XG4gICAgY2FzZSBBdXRoVHlwZS5PQXV0aE0yTTpcbiAgICAgIGlmICghY2xpZW50SWQgfHwgIWNsaWVudFNlY3JldCkge1xuICAgICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwib2F1dGgtbTJtIHJlcXVpcmVzIGNsaWVudF9pZCBhbmQgY2xpZW50X3NlY3JldFwiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBBdXRoVHlwZS5PQXV0aE0yTTtcbiAgICBjYXNlIEF1dGhUeXBlLlBlcnNvbmFsQWNjZXNzVG9rZW46XG4gICAgICBpZiAoIWFjY2Vzc1Rva2VuKSB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwicGF0IHJlcXVpcmVzIHRva2VuXCIpO1xuICAgICAgcmV0dXJuIEF1dGhUeXBlLlBlcnNvbmFsQWNjZXNzVG9rZW47XG4gICAgY2FzZSBBdXRoVHlwZS5BcHBPbkJlaGFsZk9mOlxuICAgICAgaWYgKCFhY2Nlc3NUb2tlbikge1xuICAgICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiYXBwX29ibyByZXF1aXJlcyB0aGUgY29uZmlndXJlZCBhY2Nlc3MgdG9rZW4gaGVhZGVyXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIEF1dGhUeXBlLkFwcE9uQmVoYWxmT2Y7XG4gICAgY2FzZSBBdXRoVHlwZS5BcHBTZXJ2aWNlUHJpbmNpcGFsOlxuICAgICAgaWYgKCFjbGllbnRJZCB8fCAhY2xpZW50U2VjcmV0KSB7XG4gICAgICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJjb25maWdcIiwgXCJhcHBfc3AgcmVxdWlyZXMgY2xpZW50IGlkIGFuZCBzZWNyZXRcIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gQXV0aFR5cGUuQXBwU2VydmljZVByaW5jaXBhbDtcbiAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgIGlmIChjbGllbnRJZCAmJiBjbGllbnRTZWNyZXQpIHJldHVybiBBdXRoVHlwZS5PQXV0aE0yTTtcbiAgICAgIGlmIChjbGllbnRTZWNyZXQpIHRocm93IG5ldyBBdXRoRXJyb3IoXCJjb25maWdcIiwgXCJvYXV0aC1tMm0gY2xpZW50X3NlY3JldCByZXF1aXJlcyBjbGllbnRfaWRcIik7XG4gICAgICByZXR1cm4gYWNjZXNzVG9rZW4gPyBBdXRoVHlwZS5QZXJzb25hbEFjY2Vzc1Rva2VuIDogQXV0aFR5cGUuRGF0YWJyaWNrc0NsaTtcbiAgfVxufVxuXG4vKiogUGFyc2Ugb25lIGV4dGVybmFsIGF1dGgtdHlwZSB2YWx1ZSBpbnRvIHRoZSBjYW5vbmljYWwgZW51bS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUF1dGhUeXBlKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBBdXRoVHlwZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlbGVjdGVkID0gdHJpbVRvVW5kZWZpbmVkKHZhbHVlKT8udG9Mb3dlckNhc2UoKTtcbiAgaWYgKHNlbGVjdGVkID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChPYmplY3QudmFsdWVzKEF1dGhUeXBlKS5pbmNsdWRlcyhzZWxlY3RlZCBhcyBBdXRoVHlwZSkpIHJldHVybiBzZWxlY3RlZCBhcyBBdXRoVHlwZTtcbiAgdGhyb3cgbmV3IEF1dGhFcnJvcihcImNvbmZpZ1wiLCBgQXV0aGVudGljYXRpb24gdHlwZSAke3NlbGVjdGVkfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1ZXN0T2JvVG9rZW4oXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICBoZWFkZXJOYW1lID0gREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSLFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZW50cnkgPSBPYmplY3QuZW50cmllcyhoZWFkZXJzID8/IHt9KS5maW5kKFxuICAgIChbbmFtZV0pID0+IG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gaGVhZGVyTmFtZS50b0xvd2VyQ2FzZSgpLFxuICApO1xuICBjb25zdCB2YWx1ZSA9IHRyaW1Ub1VuZGVmaW5lZChlbnRyeT8uWzFdKTtcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKGhlYWRlck5hbWUudG9Mb3dlckNhc2UoKSAhPT0gREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSKSByZXR1cm4gdmFsdWU7XG4gIGNvbnN0IFtzY2hlbWUsIC4uLnBhcnRzXSA9IHZhbHVlLnNwbGl0KC9cXHMrLyk7XG4gIHJldHVybiBzY2hlbWU/LnRvTG93ZXJDYXNlKCkgPT09IFwiYmVhcmVyXCIgPyB0cmltVG9VbmRlZmluZWQocGFydHMuam9pbihcIiBcIikpIDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5mZXJUYXJnZXQoaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkLCBhY2NvdW50SWQ6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFRhcmdldEtpbmQge1xuICBpZiAoYWNjb3VudElkICYmIGhvc3QpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKG5ldyBVUkwobm9ybWFsaXplSG9zdChob3N0KSkuaG9zdG5hbWUgPT09IFwiYWNjb3VudHMuY2xvdWQuZGF0YWJyaWNrcy5jb21cIikge1xuICAgICAgICByZXR1cm4gVGFyZ2V0S2luZC5BY2NvdW50O1xuICAgICAgfVxuICAgIH0gY2F0Y2gge31cbiAgfVxuICByZXR1cm4gVGFyZ2V0S2luZC5Xb3Jrc3BhY2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVRhcmdldCh2YWx1ZTogc3RyaW5nKTogVGFyZ2V0S2luZCB7XG4gIHN3aXRjaCAodmFsdWUudHJpbSgpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlIFRhcmdldEtpbmQuV29ya3NwYWNlOlxuICAgICAgcmV0dXJuIFRhcmdldEtpbmQuV29ya3NwYWNlO1xuICAgIGNhc2UgVGFyZ2V0S2luZC5BY2NvdW50OlxuICAgICAgcmV0dXJuIFRhcmdldEtpbmQuQWNjb3VudDtcbiAgICBjYXNlIFRhcmdldEtpbmQuVW5pZmllZDpcbiAgICAgIHJldHVybiBUYXJnZXRLaW5kLlVuaWZpZWQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJjb25maWdcIiwgXCJUYXJnZXQgbXVzdCBiZSB3b3Jrc3BhY2UsIGFjY291bnQsIG9yIHVuaWZpZWRcIik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1pc3NpbmcocHJvZmlsZTogc3RyaW5nLCBmaWVsZDogc3RyaW5nKTogbmV2ZXIge1xuICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIGBQcm9maWxlICR7cHJvZmlsZX0gcmVxdWlyZXMgJHtmaWVsZH1gKTtcbn1cblxuZnVuY3Rpb24gc2FtZVRhcmdldChsZWZ0OiBSYXdQcm9maWxlLCByaWdodDogUmF3UHJvZmlsZSk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIGlmIChub3JtYWxpemVIb3N0KGxlZnQuaG9zdCkgIT09IG5vcm1hbGl6ZUhvc3QocmlnaHQuaG9zdCkpIHJldHVybiBmYWxzZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoXG4gICAgKCFsZWZ0LmFjY291bnRJZCB8fCBsZWZ0LmFjY291bnRJZCA9PT0gcmlnaHQuYWNjb3VudElkKSAmJlxuICAgICghbGVmdC53b3Jrc3BhY2VJZCB8fCBsZWZ0LndvcmtzcGFjZUlkID09PSByaWdodC53b3Jrc3BhY2VJZClcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNNMm1Qcm9maWxlKHByb2ZpbGU6IFJhd1Byb2ZpbGUpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBwcm9maWxlLmF1dGhUeXBlID09PSBBdXRoVHlwZS5PQXV0aE0yTSB8fFxuICAgICghcHJvZmlsZS5hdXRoVHlwZSAmJiBCb29sZWFuKHByb2ZpbGUuY2xpZW50SWQgJiYgcHJvZmlsZS5jbGllbnRTZWNyZXQpKVxuICApO1xufVxuXG4vKiogRW51bWVyYXRlIHNlY3JldC1mcmVlIHByb2ZpbGUgbWV0YWRhdGEgZnJvbSBjYWNoZWQgY29uZmlndXJhdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0RGF0YWJyaWNrc1Byb2ZpbGVzKFxuICBjb25maWdGaWxlPzogc3RyaW5nLFxuICByZWZyZXNoID0gZmFsc2UsXG4gIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCA9IHByb2Nlc3MuZW52LFxuKTogRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5W10ge1xuICBjb25zdCBwYXRoID0gcmVzb2x2ZUNvbmZpZ0ZpbGUoY29uZmlnRmlsZSwgZW52aXJvbm1lbnQpO1xuICBjb25zdCBjb25maWcgPSBsb2FkQ29uZmlnKGNvbmZpZ0ZpbGUsIHJlZnJlc2gsIGVudmlyb25tZW50KTtcbiAgaWYgKCFjb25maWcpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJsaXN0ZWQgRGF0YWJyaWNrcyBwcm9maWxlc1wiLCB7IHBhdGgsIHJlZnJlc2gsIGNvdW50OiAwIH0pO1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBjb25zdCBwcm9maWxlcyA9IFsuLi5jb25maWcua2V5cygpXVxuICAgIC5maWx0ZXIoKG5hbWUpID0+IG5hbWUgIT09IFNFVFRJTkdTX1NFQ1RJT04pXG4gICAgLm1hcCgobmFtZSkgPT4ge1xuICAgICAgY29uc3QgcHJvZmlsZSA9IGxvYWRSYXdQcm9maWxlKGNvbmZpZywgbmFtZSk7XG4gICAgICBjb25zdCBob3N0ID0gc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKHByb2ZpbGUuaG9zdCk7XG4gICAgICBjb25zdCBhY2NvdW50SWQgPSBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQocHJvZmlsZS5hY2NvdW50SWQpO1xuICAgICAgY29uc3Qgd29ya3NwYWNlSWQgPSBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQocHJvZmlsZS53b3Jrc3BhY2VJZCk7XG4gICAgICBjb25zdCBhdXRoVHlwZSA9IHJlc29sdmVBdXRoVHlwZShcbiAgICAgICAgcGFyc2VBdXRoVHlwZShwcm9maWxlLmF1dGhUeXBlKSxcbiAgICAgICAgcHJvZmlsZS5jbGllbnRJZCxcbiAgICAgICAgcHJvZmlsZS5jbGllbnRTZWNyZXQsXG4gICAgICAgIHByb2ZpbGUuYWNjZXNzVG9rZW4sXG4gICAgICApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgLi4uKGhvc3QgPyB7IGhvc3QgfSA6IHt9KSxcbiAgICAgICAgLi4uKGFjY291bnRJZCA/IHsgYWNjb3VudElkIH0gOiB7fSksXG4gICAgICAgIC4uLih3b3Jrc3BhY2VJZCA/IHsgd29ya3NwYWNlSWQgfSA6IHt9KSxcbiAgICAgICAgdGFyZ2V0OiBpbmZlclRhcmdldChob3N0LCBhY2NvdW50SWQpLFxuICAgICAgICBhdXRoVHlwZSxcbiAgICAgICAgcHJpbmNpcGFsOlxuICAgICAgICAgIGF1dGhUeXBlID09PSBBdXRoVHlwZS5PQXV0aE0yTSB8fCBhdXRoVHlwZSA9PT0gQXV0aFR5cGUuQXBwU2VydmljZVByaW5jaXBhbFxuICAgICAgICAgICAgPyAoc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKHByb2ZpbGUuY2xpZW50SWQpID8/IG5hbWUpXG4gICAgICAgICAgICA6IG5hbWUsXG4gICAgICB9O1xuICAgIH0pXG4gICAgLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBsZWZ0Lm5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5uYW1lKSk7XG4gIGxvZ2dlci5kZWJ1ZyhcImxpc3RlZCBEYXRhYnJpY2tzIHByb2ZpbGVzXCIsIHsgcGF0aCwgcmVmcmVzaCwgY291bnQ6IHByb2ZpbGVzLmxlbmd0aCB9KTtcbiAgcmV0dXJuIHByb2ZpbGVzO1xufVxuXG4vKiogUmVzb2x2ZSBvcHRpb25zLCBlbnZpcm9ubWVudCwgcmVxdWVzdCBoZWFkZXJzLCBhbmQgY29uZmlndXJhdGlvbiBpbnRvIGNyZWRlbnRpYWxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVEYXRhYnJpY2tzUHJvZmlsZShcbiAgb3B0aW9uczogRGF0YWJyaWNrc0F1dGhPcHRpb25zLFxuICBlbnZpcm9ubWVudDogRW52aXJvbm1lbnQgPSBwcm9jZXNzLmVudixcbik6IERhdGFicmlja3NQcm9maWxlIHtcbiAgY29uc3QgaW5BcHAgPSBlbnZpcm9ubWVudFV0aWxzLmlzRGF0YWJyaWNrc0FwcEVudih7IC4uLmVudmlyb25tZW50IH0pO1xuICBjb25zdCBlbnZpcm9ubWVudFByb2ZpbGUgPSBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQoZW52aXJvbm1lbnQuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSk7XG4gIGNvbnN0IGV4cGxpY2l0UHJvZmlsZSA9IEJvb2xlYW4oXG4gICAgc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKG9wdGlvbnMucHJvZmlsZSkgPz8gZW52aXJvbm1lbnRQcm9maWxlLFxuICApO1xuICBjb25zdCByZXF1ZXN0VG9rZW4gPSByZXF1ZXN0T2JvVG9rZW4ob3B0aW9ucy5yZXF1ZXN0SGVhZGVycywgb3B0aW9ucy5hY2Nlc3NUb2tlbkhlYWRlcik7XG4gIGNvbnN0IGV4cGxpY2l0QXV0aFR5cGUgPVxuICAgIG9wdGlvbnMuYXV0aFR5cGUgPz9cbiAgICAoIWluQXBwICYmICFleHBsaWNpdFByb2ZpbGUgPyBwYXJzZUF1dGhUeXBlKGVudmlyb25tZW50LkRBVEFCUklDS1NfQVVUSF9UWVBFKSA6IHVuZGVmaW5lZCk7XG4gIGNvbnN0IGFwcFNlcnZpY2VQcmluY2lwYWwgPSBbXG4gICAgZW52aXJvbm1lbnQuREFUQUJSSUNLU19IT1NULFxuICAgIGVudmlyb25tZW50LkRBVEFCUklDS1NfQ0xJRU5UX0lELFxuICAgIGVudmlyb25tZW50LkRBVEFCUklDS1NfQ0xJRU5UX1NFQ1JFVCxcbiAgXS5ldmVyeSgodmFsdWUpID0+IEJvb2xlYW4oc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKHZhbHVlKSkpO1xuICBjb25zdCBzZWxlY3RlZEF1dGhUeXBlID1cbiAgICAhaW5BcHAgfHwgZXhwbGljaXRQcm9maWxlIHx8IGV4cGxpY2l0QXV0aFR5cGVcbiAgICAgID8gZXhwbGljaXRBdXRoVHlwZVxuICAgICAgOiByZXF1ZXN0VG9rZW5cbiAgICAgICAgPyBBdXRoVHlwZS5BcHBPbkJlaGFsZk9mXG4gICAgICAgIDogYXBwU2VydmljZVByaW5jaXBhbFxuICAgICAgICAgID8gQXV0aFR5cGUuQXBwU2VydmljZVByaW5jaXBhbFxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCBhcHBBdXRoID1cbiAgICBzZWxlY3RlZEF1dGhUeXBlID09PSBBdXRoVHlwZS5BcHBPbkJlaGFsZk9mIHx8XG4gICAgc2VsZWN0ZWRBdXRoVHlwZSA9PT0gQXV0aFR5cGUuQXBwU2VydmljZVByaW5jaXBhbDtcbiAgY29uc3QgaWdub3JlQW1iaWVudENyZWRlbnRpYWxzID0gZXhwbGljaXRQcm9maWxlICYmICFhcHBBdXRoO1xuICBjb25zdCBjb25maWdQYXRoID0gcmVzb2x2ZUNvbmZpZ0ZpbGUob3B0aW9ucy5jb25maWdGaWxlLCBlbnZpcm9ubWVudCk7XG4gIGNvbnN0IGNvbmZpZyA9IGxvYWRDb25maWcob3B0aW9ucy5jb25maWdGaWxlLCBmYWxzZSwgZW52aXJvbm1lbnQpO1xuICBjb25zdCByZXF1ZXN0ZWROYW1lID0gc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKG9wdGlvbnMucHJvZmlsZSkgPz8gZW52aXJvbm1lbnRQcm9maWxlO1xuICBjb25zdCBwcm9maWxlTmFtZSA9IHJlc29sdmVQcm9maWxlTmFtZShcbiAgICByZXF1ZXN0ZWROYW1lLFxuICAgIGV4cGxpY2l0UHJvZmlsZSxcbiAgICBjb25maWcsXG4gICAgb3B0aW9ucy5wcmVmZXJVc2VyVG9NYWNoaW5lID8/IHRydWUsXG4gICk7XG4gIGNvbnN0IGFtYmllbnRDcmVkZW50aWFscyA9IFtcbiAgICBvcHRpb25zLmFjY2Vzc1Rva2VuLFxuICAgIG9wdGlvbnMuY2xpZW50SWQsXG4gICAgb3B0aW9ucy5jbGllbnRTZWNyZXQsXG4gICAgZW52aXJvbm1lbnQuREFUQUJSSUNLU19UT0tFTixcbiAgICBlbnZpcm9ubWVudC5EQVRBQlJJQ0tTX0NMSUVOVF9JRCxcbiAgICBlbnZpcm9ubWVudC5EQVRBQlJJQ0tTX0NMSUVOVF9TRUNSRVQsXG4gIF0uc29tZSgodmFsdWUpID0+IEJvb2xlYW4oc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKHZhbHVlKSkpO1xuICBjb25zdCBzZWxlY3RlZFByb2ZpbGUgPVxuICAgIGV4cGxpY2l0UHJvZmlsZSB8fCAoIWFtYmllbnRDcmVkZW50aWFscyAmJiBjb25maWc/Lmhhcyhwcm9maWxlTmFtZSkpID8gcHJvZmlsZU5hbWUgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGNvbmZpZ3VyZWQgPSBsb2FkUmF3UHJvZmlsZShjb25maWcsIHByb2ZpbGVOYW1lKTtcbiAgY29uc3QgYW1iaWVudCA9IChuYW1lOiBrZXlvZiBOb2RlSlMuUHJvY2Vzc0Vudik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PlxuICAgIGlnbm9yZUFtYmllbnRDcmVkZW50aWFscyA/IHVuZGVmaW5lZCA6IHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChlbnZpcm9ubWVudFtuYW1lXSk7XG4gIGNvbnN0IGhvc3QgPSBub3JtYWxpemVIb3N0KFxuICAgIG9wdGlvbnMuaG9zdCA/PyBhbWJpZW50KFwiREFUQUJSSUNLU19IT1NUXCIpID8/IGNvbmZpZ3VyZWQuaG9zdCxcbiAgICBwcm9maWxlTmFtZSxcbiAgKTtcbiAgY29uc3QgYWNjb3VudElkID1cbiAgICBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQob3B0aW9ucy5hY2NvdW50SWQpID8/XG4gICAgYW1iaWVudChcIkRBVEFCUklDS1NfQUNDT1VOVF9JRFwiKSA/P1xuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChjb25maWd1cmVkLmFjY291bnRJZCk7XG4gIGNvbnN0IHdvcmtzcGFjZUlkID1cbiAgICBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQob3B0aW9ucy53b3Jrc3BhY2VJZCkgPz9cbiAgICBhbWJpZW50KFwiREFUQUJSSUNLU19XT1JLU1BBQ0VfSURcIikgPz9cbiAgICBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQoY29uZmlndXJlZC53b3Jrc3BhY2VJZCk7XG4gIGNvbnN0IGNsaWVudElkVmFsdWUgPVxuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChvcHRpb25zLmNsaWVudElkKSA/P1xuICAgIGFtYmllbnQoXCJEQVRBQlJJQ0tTX0NMSUVOVF9JRFwiKSA/P1xuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChjb25maWd1cmVkLmNsaWVudElkKTtcbiAgY29uc3QgY2xpZW50U2VjcmV0ID1cbiAgICBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQob3B0aW9ucy5jbGllbnRTZWNyZXQpID8/XG4gICAgYW1iaWVudChcIkRBVEFCUklDS1NfQ0xJRU5UX1NFQ1JFVFwiKSA/P1xuICAgIHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChjb25maWd1cmVkLmNsaWVudFNlY3JldCk7XG4gIGNvbnN0IGFjY2Vzc1Rva2VuID1cbiAgICBzZWxlY3RlZEF1dGhUeXBlID09PSBBdXRoVHlwZS5BcHBPbkJlaGFsZk9mXG4gICAgICA/IHJlcXVlc3RUb2tlblxuICAgICAgOiAoc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKG9wdGlvbnMuYWNjZXNzVG9rZW4pID8/XG4gICAgICAgIGFtYmllbnQoXCJEQVRBQlJJQ0tTX1RPS0VOXCIpID8/XG4gICAgICAgIHN0cmluZ1V0aWxzLnRyaW1Ub1VuZGVmaW5lZChjb25maWd1cmVkLmFjY2Vzc1Rva2VuKSk7XG4gIGNvbnN0IGNvbmZpZ3VyZWRBdXRoVHlwZSA9XG4gICAgc2VsZWN0ZWRBdXRoVHlwZSA/P1xuICAgIHBhcnNlQXV0aFR5cGUoYW1iaWVudChcIkRBVEFCUklDS1NfQVVUSF9UWVBFXCIpKSA/P1xuICAgIHBhcnNlQXV0aFR5cGUoY29uZmlndXJlZC5hdXRoVHlwZSk7XG4gIGNvbnN0IGF1dGhUeXBlID0gcmVzb2x2ZUF1dGhUeXBlKGNvbmZpZ3VyZWRBdXRoVHlwZSwgY2xpZW50SWRWYWx1ZSwgY2xpZW50U2VjcmV0LCBhY2Nlc3NUb2tlbik7XG4gIGNvbnN0IGNsaWVudElkID1cbiAgICBhdXRoVHlwZSA9PT0gQXV0aFR5cGUuRGF0YWJyaWNrc0NsaVxuICAgICAgPyAoY2xpZW50SWRWYWx1ZSA/PyBERUZBVUxUX0NMSUVOVF9JRClcbiAgICAgIDogYXV0aFR5cGUgPT09IEF1dGhUeXBlLk9BdXRoTTJNIHx8IGF1dGhUeXBlID09PSBBdXRoVHlwZS5BcHBTZXJ2aWNlUHJpbmNpcGFsXG4gICAgICAgID8gKGNsaWVudElkVmFsdWUgPz8gbWlzc2luZyhwcm9maWxlTmFtZSwgXCJjbGllbnRfaWRcIikpXG4gICAgICAgIDogKGNsaWVudElkVmFsdWUgPz8gXCJcIik7XG4gIGNvbnN0IHNjb3BlcyA9IG9wdGlvbnMuc2NvcGVzPy5sZW5ndGhcbiAgICA/IHN0cmluZ1V0aWxzLnBhcnNlTGlzdChvcHRpb25zLnNjb3BlcylcbiAgICA6IHN0cmluZ1V0aWxzLnBhcnNlTGlzdChjb25maWd1cmVkLnNjb3Blcz8uc3BsaXQoXCIsXCIpID8/IFtcImFsbC1hcGlzXCJdKTtcbiAgY29uc3QgdGFyZ2V0ID0gb3B0aW9ucy50YXJnZXQgPyBwYXJzZVRhcmdldChvcHRpb25zLnRhcmdldCkgOiBpbmZlclRhcmdldChob3N0LCBhY2NvdW50SWQpO1xuICBjb25zdCBncm91cElkID1cbiAgICBzdHJpbmdVdGlscy50cmltVG9VbmRlZmluZWQob3B0aW9ucy5ncm91cElkKSA/P1xuICAgIGFtYmllbnQoXCJEQVRBQlJJQ0tTX0dST1VQX0lEXCIpID8/XG4gICAgc3RyaW5nVXRpbHMudHJpbVRvVW5kZWZpbmVkKGNvbmZpZ3VyZWQuZ3JvdXBJZCk7XG4gIGNvbnN0IHByaW5jaXBhbCA9XG4gICAgYXV0aFR5cGUgPT09IEF1dGhUeXBlLk9BdXRoTTJNIHx8IGF1dGhUeXBlID09PSBBdXRoVHlwZS5BcHBTZXJ2aWNlUHJpbmNpcGFsXG4gICAgICA/IGNsaWVudElkXG4gICAgICA6IHByb2ZpbGVOYW1lO1xuICBjb25zdCBjYWNoZUtleSA9IGNyZWRlbnRpYWxDYWNoZUtleSh7XG4gICAgbmFtZTogcHJvZmlsZU5hbWUsXG4gICAgaG9zdCxcbiAgICBhY2NvdW50SWQsXG4gICAgd29ya3NwYWNlSWQsXG4gICAgY2xpZW50SWQsXG4gICAgZ3JvdXBJZCxcbiAgICBzY29wZXMsXG4gICAgYXV0aFR5cGUsXG4gICAgYWNjZXNzVG9rZW4sXG4gIH0pO1xuICBsb2dnZXIuZGVidWcoXCJyZXNvbHZlZCBEYXRhYnJpY2tzIHByb2ZpbGVcIiwge1xuICAgIHByb2ZpbGU6IHByb2ZpbGVOYW1lLFxuICAgIGhvc3QsXG4gICAgYXV0aFR5cGUsXG4gICAgdGFyZ2V0LFxuICAgIGluQXBwLFxuICAgIGV4cGxpY2l0UHJvZmlsZSxcbiAgICBjb25maWd1cmVkQXV0aFR5cGU6IGNvbmZpZ3VyZWRBdXRoVHlwZSA/PyBcImF1dG9tYXRpY1wiLFxuICAgIGhhc0FjY291bnRJZDogQm9vbGVhbihhY2NvdW50SWQpLFxuICAgIGhhc1dvcmtzcGFjZUlkOiBCb29sZWFuKHdvcmtzcGFjZUlkKSxcbiAgICBoYXNHcm91cElkOiBCb29sZWFuKGdyb3VwSWQpLFxuICAgIHNjb3BlQ291bnQ6IHNjb3Blcy5sZW5ndGgsXG4gICAgY29uZmlnUGF0aCxcbiAgfSk7XG4gIHJldHVybiB7XG4gICAgbmFtZTogcHJvZmlsZU5hbWUsXG4gICAgLi4uKHNlbGVjdGVkUHJvZmlsZSA/IHsgc2VsZWN0ZWRQcm9maWxlIH0gOiB7fSksXG4gICAgaG9zdCxcbiAgICAuLi4oYWNjb3VudElkID8geyBhY2NvdW50SWQgfSA6IHt9KSxcbiAgICAuLi4od29ya3NwYWNlSWQgPyB7IHdvcmtzcGFjZUlkIH0gOiB7fSksXG4gICAgY2xpZW50SWQsXG4gICAgLi4uKGdyb3VwSWQgPyB7IGdyb3VwSWQgfSA6IHt9KSxcbiAgICBzY29wZXMsXG4gICAgdGFyZ2V0LFxuICAgIGF1dGhUeXBlLFxuICAgIC4uLihjbGllbnRTZWNyZXQgPyB7IGNsaWVudFNlY3JldCB9IDoge30pLFxuICAgIC4uLihhY2Nlc3NUb2tlbiA/IHsgYWNjZXNzVG9rZW4gfSA6IHt9KSxcbiAgICBjYWNoZUtleSxcbiAgICBwcmluY2lwYWwsXG4gIH07XG59XG5cbi8qKiBOb3JtYWxpemUgT0F1dGggc2NvcGVzIGZvciBtYWNoaW5lIGNyZWRlbnRpYWxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hY2hpbmVTY29wZXMoc2NvcGVzOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHN0cmluZ1V0aWxzLnBhcnNlTGlzdChzY29wZXMubGVuZ3RoID8gc2NvcGVzIDogW1wiYWxsLWFwaXNcIl0pLnNvcnQoKTtcbn1cblxuZnVuY3Rpb24gY3JlZGVudGlhbENhY2hlS2V5KFxuICBwcm9maWxlOiBQaWNrPFxuICAgIERhdGFicmlja3NQcm9maWxlLFxuICAgIHwgXCJuYW1lXCJcbiAgICB8IFwiaG9zdFwiXG4gICAgfCBcImFjY291bnRJZFwiXG4gICAgfCBcIndvcmtzcGFjZUlkXCJcbiAgICB8IFwiY2xpZW50SWRcIlxuICAgIHwgXCJncm91cElkXCJcbiAgICB8IFwic2NvcGVzXCJcbiAgICB8IFwiYXV0aFR5cGVcIlxuICAgIHwgXCJhY2Nlc3NUb2tlblwiXG4gID4sXG4pOiBzdHJpbmcge1xuICBpZiAocHJvZmlsZS5hdXRoVHlwZSA9PT0gQXV0aFR5cGUuRGF0YWJyaWNrc0NsaSkgcmV0dXJuIHByb2ZpbGUubmFtZTtcbiAgaWYgKHByb2ZpbGUuYXV0aFR5cGUgPT09IEF1dGhUeXBlLlBlcnNvbmFsQWNjZXNzVG9rZW4pIHtcbiAgICBjb25zdCBkaWdlc3QgPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgICAudXBkYXRlKHByb2ZpbGUuYWNjZXNzVG9rZW4gPz8gXCJcIilcbiAgICAgIC5kaWdlc3QoXCJoZXhcIik7XG4gICAgcmV0dXJuIGAke3Byb2ZpbGUubmFtZX0tcGF0LSR7ZGlnZXN0fWA7XG4gIH1cbiAgaWYgKHByb2ZpbGUuYXV0aFR5cGUgPT09IEF1dGhUeXBlLkFwcE9uQmVoYWxmT2YpIHJldHVybiBgJHtwcm9maWxlLm5hbWV9LWFwcC1vYm9gO1xuICBjb25zdCBpZGVudGl0eSA9IFtcbiAgICBwcm9maWxlLmhvc3QsXG4gICAgcHJvZmlsZS5hY2NvdW50SWQgPz8gXCJcIixcbiAgICBwcm9maWxlLndvcmtzcGFjZUlkID8/IFwiXCIsXG4gICAgcHJvZmlsZS5jbGllbnRJZCxcbiAgICBwcm9maWxlLmdyb3VwSWQgPz8gXCJcIixcbiAgICBtYWNoaW5lU2NvcGVzKHByb2ZpbGUuc2NvcGVzKS5qb2luKFwiIFwiKSxcbiAgXS5qb2luKFwiXFwwXCIpO1xuICBjb25zdCBkaWdlc3QgPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShpZGVudGl0eSkuZGlnZXN0KFwiaGV4XCIpO1xuICByZXR1cm4gYCR7cHJvZmlsZS5uYW1lfS0ke3Byb2ZpbGUuYXV0aFR5cGUgPT09IEF1dGhUeXBlLkFwcFNlcnZpY2VQcmluY2lwYWwgPyBcImFwcC1zcFwiIDogXCJvYXV0aC1tMm1cIn0tJHtkaWdlc3R9YDtcbn1cbiJdfQ==
@@ -1,4 +1,4 @@
1
- import type { Token, TokenProvider } from "./types.ts";
1
+ import type { Token, TokenProvider } from "./_types.ts";
2
2
  /** Client-credentials inputs and transport options for Databricks OAuth. */
3
3
  export interface DatabricksServicePrincipalConfig {
4
4
  tokenEndpoint: string;
@@ -0,0 +1,69 @@
1
+ import * as oauth from "oauth4webapi";
2
+ import { AuthError } from "./_errors.js";
3
+ import { authLogger, failureMetadata, tokenMetadata } from "./_logging.js";
4
+ const logger = authLogger("service-principal");
5
+ /** Databricks service-principal provider backed by client credentials. */
6
+ export class DatabricksServicePrincipalProvider {
7
+ config;
8
+ authorizationServer;
9
+ client;
10
+ requestOptions;
11
+ constructor(config) {
12
+ this.config = config;
13
+ this.authorizationServer = {
14
+ issuer: new URL(config.tokenEndpoint).origin,
15
+ token_endpoint: config.tokenEndpoint,
16
+ };
17
+ this.client = { client_id: config.clientId };
18
+ this.requestOptions = {
19
+ ...(config.fetch ? { [oauth.customFetch]: config.fetch } : {}),
20
+ ...(config.allowInsecureRequests ? { [oauth.allowInsecureRequests]: true } : {}),
21
+ };
22
+ }
23
+ authenticate() {
24
+ return this.acquire();
25
+ }
26
+ login() {
27
+ return this.acquire();
28
+ }
29
+ refresh() {
30
+ return this.acquire();
31
+ }
32
+ canAuthenticateSilently() {
33
+ return true;
34
+ }
35
+ async acquire() {
36
+ logger.debug("requesting service-principal token", {
37
+ tokenOrigin: new URL(this.config.tokenEndpoint).origin,
38
+ scopeCount: this.config.scopes.length,
39
+ hasGroupId: Boolean(this.config.groupId),
40
+ allowInsecureRequests: Boolean(this.config.allowInsecureRequests),
41
+ });
42
+ try {
43
+ const response = await oauth.clientCredentialsGrantRequest(this.authorizationServer, this.client, oauth.ClientSecretBasic(this.config.clientSecret), {
44
+ scope: [...new Set(this.config.scopes)].sort().join(" "),
45
+ ...(this.config.groupId ? { assume_group: this.config.groupId } : {}),
46
+ }, this.requestOptions);
47
+ const value = await oauth.processClientCredentialsResponse(this.authorizationServer, this.client, response);
48
+ const token = {
49
+ accessToken: value.access_token,
50
+ tokenType: value.token_type.toLowerCase() === "bearer" ? "Bearer" : value.token_type,
51
+ ...(value.expires_in !== undefined
52
+ ? { expiry: new Date(Date.now() + value.expires_in * 1000).toISOString() }
53
+ : {}),
54
+ scopes: value.scope?.split(/\s+/).filter(Boolean) ?? [...this.config.scopes],
55
+ };
56
+ logger.debug("received service-principal token", { token: tokenMetadata(token) });
57
+ return token;
58
+ }
59
+ catch (cause) {
60
+ logger.debug("service-principal token request failed", {
61
+ error: failureMetadata(cause),
62
+ });
63
+ throw new AuthError("oauth", "Databricks service-principal authentication failed", {
64
+ cause,
65
+ });
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX3NlcnZpY2UtcHJpbmNpcGFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL19zZXJ2aWNlLXByaW5jaXBhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQztBQUV0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczRSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQWEvQywwRUFBMEU7QUFDMUUsTUFBTSxPQUFPLGtDQUFrQztJQUtoQjtJQUpaLG1CQUFtQixDQUE0QjtJQUMvQyxNQUFNLENBQWU7SUFDckIsY0FBYyxDQUFvRDtJQUVuRixZQUE2QixNQUF3QztRQUF4QyxXQUFNLEdBQU4sTUFBTSxDQUFrQztRQUNuRSxJQUFJLENBQUMsbUJBQW1CLEdBQUc7WUFDekIsTUFBTSxFQUFFLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNO1lBQzVDLGNBQWMsRUFBRSxNQUFNLENBQUMsYUFBYTtTQUNyQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLGNBQWMsR0FBRztZQUNwQixHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBZ0MsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDakYsQ0FBQztJQUNKLENBQUM7SUFFRCxZQUFZO1FBQ1YsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELEtBQUs7UUFDSCxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCx1QkFBdUI7UUFDckIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sS0FBSyxDQUFDLE9BQU87UUFDbkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRTtZQUNqRCxXQUFXLEVBQUUsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNO1lBQ3RELFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNO1lBQ3JDLFVBQVUsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7WUFDeEMscUJBQXFCLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMscUJBQXFCLENBQUM7U0FDbEUsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsNkJBQTZCLENBQ3hELElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsSUFBSSxDQUFDLE1BQU0sRUFDWCxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFDakQ7Z0JBQ0UsS0FBSyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFDeEQsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDdEUsRUFDRCxJQUFJLENBQUMsY0FBYyxDQUNwQixDQUFDO1lBQ0YsTUFBTSxLQUFLLEdBQUcsTUFBTSxLQUFLLENBQUMsZ0NBQWdDLENBQ3hELElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsSUFBSSxDQUFDLE1BQU0sRUFDWCxRQUFRLENBQ1QsQ0FBQztZQUNGLE1BQU0sS0FBSyxHQUFHO2dCQUNaLFdBQVcsRUFBRSxLQUFLLENBQUMsWUFBWTtnQkFDL0IsU0FBUyxFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVO2dCQUNwRixHQUFHLENBQUMsS0FBSyxDQUFDLFVBQVUsS0FBSyxTQUFTO29CQUNoQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUU7b0JBQzFFLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ1AsTUFBTSxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7YUFDN0UsQ0FBQztZQUNGLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsRixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyx3Q0FBd0MsRUFBRTtnQkFDckQsS0FBSyxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUM7YUFDOUIsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxJQUFJLFNBQVMsQ0FBQyxPQUFPLEVBQUUsb0RBQW9ELEVBQUU7Z0JBQ2pGLEtBQUs7YUFDTixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgb2F1dGggZnJvbSBcIm9hdXRoNHdlYmFwaVwiO1xuXG5pbXBvcnQgeyBBdXRoRXJyb3IgfSBmcm9tIFwiLi9fZXJyb3JzLnRzXCI7XG5pbXBvcnQgeyBhdXRoTG9nZ2VyLCBmYWlsdXJlTWV0YWRhdGEsIHRva2VuTWV0YWRhdGEgfSBmcm9tIFwiLi9fbG9nZ2luZy50c1wiO1xuaW1wb3J0IHR5cGUgeyBUb2tlbiwgVG9rZW5Qcm92aWRlciB9IGZyb20gXCIuL190eXBlcy50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBhdXRoTG9nZ2VyKFwic2VydmljZS1wcmluY2lwYWxcIik7XG5cbi8qKiBDbGllbnQtY3JlZGVudGlhbHMgaW5wdXRzIGFuZCB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgRGF0YWJyaWNrcyBPQXV0aC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJyaWNrc1NlcnZpY2VQcmluY2lwYWxDb25maWcge1xuICB0b2tlbkVuZHBvaW50OiBzdHJpbmc7XG4gIGNsaWVudElkOiBzdHJpbmc7XG4gIGNsaWVudFNlY3JldDogc3RyaW5nO1xuICBzY29wZXM6IHN0cmluZ1tdO1xuICBncm91cElkPzogc3RyaW5nO1xuICBmZXRjaD86IHR5cGVvZiBnbG9iYWxUaGlzLmZldGNoO1xuICBhbGxvd0luc2VjdXJlUmVxdWVzdHM/OiBib29sZWFuO1xufVxuXG4vKiogRGF0YWJyaWNrcyBzZXJ2aWNlLXByaW5jaXBhbCBwcm92aWRlciBiYWNrZWQgYnkgY2xpZW50IGNyZWRlbnRpYWxzLiAqL1xuZXhwb3J0IGNsYXNzIERhdGFicmlja3NTZXJ2aWNlUHJpbmNpcGFsUHJvdmlkZXIgaW1wbGVtZW50cyBUb2tlblByb3ZpZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhdXRob3JpemF0aW9uU2VydmVyOiBvYXV0aC5BdXRob3JpemF0aW9uU2VydmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogb2F1dGguQ2xpZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHJlcXVlc3RPcHRpb25zOiBvYXV0aC5IdHRwUmVxdWVzdE9wdGlvbnM8c3RyaW5nLCBVUkxTZWFyY2hQYXJhbXM+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBEYXRhYnJpY2tzU2VydmljZVByaW5jaXBhbENvbmZpZykge1xuICAgIHRoaXMuYXV0aG9yaXphdGlvblNlcnZlciA9IHtcbiAgICAgIGlzc3VlcjogbmV3IFVSTChjb25maWcudG9rZW5FbmRwb2ludCkub3JpZ2luLFxuICAgICAgdG9rZW5fZW5kcG9pbnQ6IGNvbmZpZy50b2tlbkVuZHBvaW50LFxuICAgIH07XG4gICAgdGhpcy5jbGllbnQgPSB7IGNsaWVudF9pZDogY29uZmlnLmNsaWVudElkIH07XG4gICAgdGhpcy5yZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgIC4uLihjb25maWcuZmV0Y2ggPyB7IFtvYXV0aC5jdXN0b21GZXRjaF06IGNvbmZpZy5mZXRjaCBhcyB0eXBlb2YgZ2xvYmFsVGhpcy5mZXRjaCB9IDoge30pLFxuICAgICAgLi4uKGNvbmZpZy5hbGxvd0luc2VjdXJlUmVxdWVzdHMgPyB7IFtvYXV0aC5hbGxvd0luc2VjdXJlUmVxdWVzdHNdOiB0cnVlIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIGF1dGhlbnRpY2F0ZSgpOiBQcm9taXNlPFRva2VuPiB7XG4gICAgcmV0dXJuIHRoaXMuYWNxdWlyZSgpO1xuICB9XG5cbiAgbG9naW4oKTogUHJvbWlzZTxUb2tlbj4ge1xuICAgIHJldHVybiB0aGlzLmFjcXVpcmUoKTtcbiAgfVxuXG4gIHJlZnJlc2goKTogUHJvbWlzZTxUb2tlbj4ge1xuICAgIHJldHVybiB0aGlzLmFjcXVpcmUoKTtcbiAgfVxuXG4gIGNhbkF1dGhlbnRpY2F0ZVNpbGVudGx5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhY3F1aXJlKCk6IFByb21pc2U8VG9rZW4+IHtcbiAgICBsb2dnZXIuZGVidWcoXCJyZXF1ZXN0aW5nIHNlcnZpY2UtcHJpbmNpcGFsIHRva2VuXCIsIHtcbiAgICAgIHRva2VuT3JpZ2luOiBuZXcgVVJMKHRoaXMuY29uZmlnLnRva2VuRW5kcG9pbnQpLm9yaWdpbixcbiAgICAgIHNjb3BlQ291bnQ6IHRoaXMuY29uZmlnLnNjb3Blcy5sZW5ndGgsXG4gICAgICBoYXNHcm91cElkOiBCb29sZWFuKHRoaXMuY29uZmlnLmdyb3VwSWQpLFxuICAgICAgYWxsb3dJbnNlY3VyZVJlcXVlc3RzOiBCb29sZWFuKHRoaXMuY29uZmlnLmFsbG93SW5zZWN1cmVSZXF1ZXN0cyksXG4gICAgfSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgb2F1dGguY2xpZW50Q3JlZGVudGlhbHNHcmFudFJlcXVlc3QoXG4gICAgICAgIHRoaXMuYXV0aG9yaXphdGlvblNlcnZlcixcbiAgICAgICAgdGhpcy5jbGllbnQsXG4gICAgICAgIG9hdXRoLkNsaWVudFNlY3JldEJhc2ljKHRoaXMuY29uZmlnLmNsaWVudFNlY3JldCksXG4gICAgICAgIHtcbiAgICAgICAgICBzY29wZTogWy4uLm5ldyBTZXQodGhpcy5jb25maWcuc2NvcGVzKV0uc29ydCgpLmpvaW4oXCIgXCIpLFxuICAgICAgICAgIC4uLih0aGlzLmNvbmZpZy5ncm91cElkID8geyBhc3N1bWVfZ3JvdXA6IHRoaXMuY29uZmlnLmdyb3VwSWQgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhpcy5yZXF1ZXN0T3B0aW9ucyxcbiAgICAgICk7XG4gICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IG9hdXRoLnByb2Nlc3NDbGllbnRDcmVkZW50aWFsc1Jlc3BvbnNlKFxuICAgICAgICB0aGlzLmF1dGhvcml6YXRpb25TZXJ2ZXIsXG4gICAgICAgIHRoaXMuY2xpZW50LFxuICAgICAgICByZXNwb25zZSxcbiAgICAgICk7XG4gICAgICBjb25zdCB0b2tlbiA9IHtcbiAgICAgICAgYWNjZXNzVG9rZW46IHZhbHVlLmFjY2Vzc190b2tlbixcbiAgICAgICAgdG9rZW5UeXBlOiB2YWx1ZS50b2tlbl90eXBlLnRvTG93ZXJDYXNlKCkgPT09IFwiYmVhcmVyXCIgPyBcIkJlYXJlclwiIDogdmFsdWUudG9rZW5fdHlwZSxcbiAgICAgICAgLi4uKHZhbHVlLmV4cGlyZXNfaW4gIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8geyBleHBpcnk6IG5ldyBEYXRlKERhdGUubm93KCkgKyB2YWx1ZS5leHBpcmVzX2luICogMTAwMCkudG9JU09TdHJpbmcoKSB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICAgIHNjb3BlczogdmFsdWUuc2NvcGU/LnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pID8/IFsuLi50aGlzLmNvbmZpZy5zY29wZXNdLFxuICAgICAgfTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcInJlY2VpdmVkIHNlcnZpY2UtcHJpbmNpcGFsIHRva2VuXCIsIHsgdG9rZW46IHRva2VuTWV0YWRhdGEodG9rZW4pIH0pO1xuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJzZXJ2aWNlLXByaW5jaXBhbCB0b2tlbiByZXF1ZXN0IGZhaWxlZFwiLCB7XG4gICAgICAgIGVycm9yOiBmYWlsdXJlTWV0YWRhdGEoY2F1c2UpLFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwib2F1dGhcIiwgXCJEYXRhYnJpY2tzIHNlcnZpY2UtcHJpbmNpcGFsIGF1dGhlbnRpY2F0aW9uIGZhaWxlZFwiLCB7XG4gICAgICAgIGNhdXNlLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=