@dbx-tools/cli-tunnel 0.6.48 → 0.6.49

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.
@@ -5,7 +5,7 @@
5
5
  * on cold start, so the portr binary and its config are placed under a writable,
6
6
  * cwd-rooted `.home` unconditionally - it costs nothing where `$HOME` is writable.
7
7
  * The install is idempotent (the installer skips when the on-PATH binary is
8
- * current). The config is rendered from `PUBLIC_DOMAIN` (`<subdomain>.<server>`)
8
+ * current). The config is rendered from `TUNNEL_PUBLIC_DOMAIN` (`<subdomain>.<server>`)
9
9
  * + `PORTR_TOKEN` and points portr at the PUBLIC port (the proxy listens there).
10
10
  *
11
11
  * @module
@@ -19,8 +19,8 @@ export interface PortrConfig {
19
19
  port: number;
20
20
  }
21
21
  /**
22
- * Resolve portr config from `PUBLIC_DOMAIN` + `PORTR_TOKEN`, or an explicit
23
- * `subdomain`. `PUBLIC_DOMAIN` is `<subdomain>.<server>` (e.g.
22
+ * Resolve portr config from `TUNNEL_PUBLIC_DOMAIN` + `PORTR_TOKEN`, or an
23
+ * explicit `subdomain`. The domain is `<subdomain>.<server>` (e.g.
24
24
  * `demo.apps.dbx.tools`). Returns `undefined` (no tunnel) when the token or a
25
25
  * usable domain is absent.
26
26
  */
package/lib/src/portr.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * on cold start, so the portr binary and its config are placed under a writable,
6
6
  * cwd-rooted `.home` unconditionally - it costs nothing where `$HOME` is writable.
7
7
  * The install is idempotent (the installer skips when the on-PATH binary is
8
- * current). The config is rendered from `PUBLIC_DOMAIN` (`<subdomain>.<server>`)
8
+ * current). The config is rendered from `TUNNEL_PUBLIC_DOMAIN` (`<subdomain>.<server>`)
9
9
  * + `PORTR_TOKEN` and points portr at the PUBLIC port (the proxy listens there).
10
10
  *
11
11
  * @module
@@ -13,17 +13,19 @@
13
13
  import { spawn, spawnSync } from "node:child_process";
14
14
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
15
15
  import { delimiter, join } from "node:path";
16
- import { log } from "@dbx-tools/shared-core";
16
+ import { env, log } from "@dbx-tools/shared-core";
17
+ import { PUBLIC_DOMAIN_ENV } from "./env.js";
17
18
  const logger = log.logger("tunnel:portr");
18
19
  /**
19
- * Resolve portr config from `PUBLIC_DOMAIN` + `PORTR_TOKEN`, or an explicit
20
- * `subdomain`. `PUBLIC_DOMAIN` is `<subdomain>.<server>` (e.g.
20
+ * Resolve portr config from `TUNNEL_PUBLIC_DOMAIN` + `PORTR_TOKEN`, or an
21
+ * explicit `subdomain`. The domain is `<subdomain>.<server>` (e.g.
21
22
  * `demo.apps.dbx.tools`). Returns `undefined` (no tunnel) when the token or a
22
23
  * usable domain is absent.
23
24
  */
24
25
  export function resolvePortrConfig(opts) {
25
- const token = opts.token ?? process.env.PORTR_TOKEN;
26
- const domain = opts.publicDomain ?? process.env.PUBLIC_DOMAIN;
26
+ // PORTR_* is upstream portr's own namespace, so it keeps its name.
27
+ const token = env.string(opts.token, "PORTR_TOKEN");
28
+ const domain = env.string(opts.publicDomain, PUBLIC_DOMAIN_ENV);
27
29
  if (!token)
28
30
  return undefined;
29
31
  let subdomain = opts.subdomain;
@@ -32,7 +34,7 @@ export function resolvePortrConfig(opts) {
32
34
  subdomain ??= domain.split(".")[0];
33
35
  server = domain.slice(domain.indexOf(".") + 1);
34
36
  }
35
- server ??= process.env.PORTR_SERVER;
37
+ server ??= env.text("PORTR_SERVER") ?? undefined;
36
38
  if (!subdomain || !server || server === domain)
37
39
  return undefined;
38
40
  return { subdomain, server, token, port: opts.port };
@@ -88,4 +90,4 @@ export function startPortr(config, env) {
88
90
  export function portrInstalled(env) {
89
91
  return existsSync(join(env.HOME, ".portr", "bin", "portr"));
90
92
  }
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydHIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcG9ydHIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM1QyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFN0MsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztBQVUxQzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxJQUtsQztJQUNDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7SUFDcEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztJQUM5RCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDL0IsSUFBSSxNQUEwQixDQUFDO0lBQy9CLElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxTQUFTLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFDRCxNQUFNLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FB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O0FBQzlFLE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBc0I7SUFDbkQsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHBvcnRyIGluc3RhbGwgKyBjb25maWcgKyBsYXVuY2ggZm9yIHRoZSB0dW5uZWwgQ0xJLlxuICpcbiAqIFNvbWUgaG9zdHMgKERhdGFicmlja3MgQXBwcyBhbW9uZyB0aGVtKSBtb3VudCB0aGUgY29udGFpbmVyJ3MgYCRIT01FYCByZWFkLW9ubHlcbiAqIG9uIGNvbGQgc3RhcnQsIHNvIHRoZSBwb3J0ciBiaW5hcnkgYW5kIGl0cyBjb25maWcgYXJlIHBsYWNlZCB1bmRlciBhIHdyaXRhYmxlLFxuICogY3dkLXJvb3RlZCBgLmhvbWVgIHVuY29uZGl0aW9uYWxseSAtIGl0IGNvc3RzIG5vdGhpbmcgd2hlcmUgYCRIT01FYCBpcyB3cml0YWJsZS5cbiAqIFRoZSBpbnN0YWxsIGlzIGlkZW1wb3RlbnQgKHRoZSBpbnN0YWxsZXIgc2tpcHMgd2hlbiB0aGUgb24tUEFUSCBiaW5hcnkgaXNcbiAqIGN1cnJlbnQpLiBUaGUgY29uZmlnIGlzIHJlbmRlcmVkIGZyb20gYFBVQkxJQ19ET01BSU5gIChgPHN1YmRvbWFpbj4uPHNlcnZlcj5gKVxuICogKyBgUE9SVFJfVE9LRU5gIGFuZCBwb2ludHMgcG9ydHIgYXQgdGhlIFBVQkxJQyBwb3J0ICh0aGUgcHJveHkgbGlzdGVucyB0aGVyZSkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHNwYXduLCBzcGF3blN5bmMgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBta2RpclN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgZGVsaW1pdGVyLCBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwb3J0clwiKTtcblxuLyoqIFJlc29sdmVkIHBvcnRyIHdpcmluZywgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyB0dW5uZWwgaXMgY29uZmlndXJlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9ydHJDb25maWcge1xuICBzdWJkb21haW46IHN0cmluZztcbiAgc2VydmVyOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHBvcnRyIGNvbmZpZyBmcm9tIGBQVUJMSUNfRE9NQUlOYCArIGBQT1JUUl9UT0tFTmAsIG9yIGFuIGV4cGxpY2l0XG4gKiBgc3ViZG9tYWluYC4gYFBVQkxJQ19ET01BSU5gIGlzIGA8c3ViZG9tYWluPi48c2VydmVyPmAgKGUuZy5cbiAqIGBkZW1vLmFwcHMuZGJ4LnRvb2xzYCkuIFJldHVybnMgYHVuZGVmaW5lZGAgKG5vIHR1bm5lbCkgd2hlbiB0aGUgdG9rZW4gb3IgYVxuICogdXNhYmxlIGRvbWFpbiBpcyBhYnNlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUG9ydHJDb25maWcob3B0czoge1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgdG9rZW4/OiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbn0pOiBQb3J0ckNvbmZpZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHRva2VuID0gb3B0cy50b2tlbiA/PyBwcm9jZXNzLmVudi5QT1JUUl9UT0tFTjtcbiAgY29uc3QgZG9tYWluID0gb3B0cy5wdWJsaWNEb21haW4gPz8gcHJvY2Vzcy5lbnYuUFVCTElDX0RPTUFJTjtcbiAgaWYgKCF0b2tlbikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbGV0IHN1YmRvbWFpbiA9IG9wdHMuc3ViZG9tYWluO1xuICBsZXQgc2VydmVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGlmIChkb21haW4pIHtcbiAgICBzdWJkb21haW4gPz89IGRvbWFpbi5zcGxpdChcIi5cIilbMF07XG4gICAgc2VydmVyID0gZG9tYWluLnNsaWNlKGRvbWFpbi5pbmRleE9mKFwiLlwiKSArIDEpO1xuICB9XG4gIHNlcnZlciA/Pz0gcHJvY2Vzcy5lbnYuUE9SVFJfU0VSVkVSO1xuICBpZiAoIXN1YmRvbWFpbiB8fCAhc2VydmVyIHx8IHNlcnZlciA9PT0gZG9tYWluKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyBzdWJkb21haW4sIHNlcnZlciwgdG9rZW4sIHBvcnQ6IG9wdHMucG9ydCB9O1xufVxuXG4vKiogVGhlIHdyaXRhYmxlIGhvbWUgcG9ydHIgaW5zdGFsbHMgKyBjb25maWd1cmVzIHVuZGVyIChBcHBzIGAkSE9NRWAgaXMgcmVhZC1vbmx5KS4gKi9cbmZ1bmN0aW9uIHBvcnRySG9tZSgpOiBzdHJpbmcge1xuICBjb25zdCBob21lID0gam9pbihwcm9jZXNzLmN3ZCgpLCBcIi5ob21lXCIpO1xuICBta2RpclN5bmMoam9pbihob21lLCBcIi5wb3J0clwiLCBcImJpblwiKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHJldHVybiBob21lO1xufVxuXG4vKiogSW5zdGFsbCBwb3J0ciAoaWRlbXBvdGVudCkgaW50byB0aGUgY3dkLXJvb3RlZCBob21lIGFuZCByZXR1cm4gdGhlIGNoaWxkIGVudi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsUG9ydHIoKTogTm9kZUpTLlByb2Nlc3NFbnYge1xuICBjb25zdCBob21lID0gcG9ydHJIb21lKCk7XG4gIGNvbnN0IGVudjogTm9kZUpTLlByb2Nlc3NFbnYgPSB7XG4gICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgSE9NRTogaG9tZSxcbiAgICBQT1JUUl9BVVRPX0FERF9QQVRIOiBcIm5vXCIsXG4gICAgUEFUSDogW2pvaW4oaG9tZSwgXCIucG9ydHJcIiwgXCJiaW5cIiksIHByb2Nlc3MuZW52LlBBVEggPz8gXCJcIl0uam9pbihkZWxpbWl0ZXIpLFxuICB9O1xuICBsb2dnZXIuaW5mbyhcImluc3RhbGxpbmcgcG9ydHIgKGlkZW1wb3RlbnQpXCIpO1xuICBjb25zdCByZXMgPSBzcGF3blN5bmMoXCJiYXNoXCIsIFtcIi1jXCIsIFwiY3VybCAtc1NmIGh0dHBzOi8vaW5zdGFsbC5wb3J0ci5kZXYgfCBzaFwiXSwge1xuICAgIGVudixcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuICBpZiAocmVzLnN0YXR1cyAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKFwicG9ydHIgaW5zdGFsbCBmYWlsZWRcIik7XG4gIHJldHVybiBlbnY7XG59XG5cbi8qKiBSZW5kZXIgYH4vLnBvcnRyL2NvbmZpZy55YW1sYCBmb3IgdGhlIHJlc29sdmVkIHR1bm5lbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZVBvcnRyQ29uZmlnKGNvbmZpZzogUG9ydHJDb25maWcsIGVudjogTm9kZUpTLlByb2Nlc3NFbnYpOiB2b2lkIHtcbiAgY29uc3QgcGF0aCA9IGpvaW4oZW52LkhPTUUhLCBcIi5wb3J0clwiLCBcImNvbmZpZy55YW1sXCIpO1xuICB3cml0ZUZpbGVTeW5jKFxuICAgIHBhdGgsXG4gICAgW1xuICAgICAgYHNlcnZlcl91cmw6ICR7Y29uZmlnLnNlcnZlcn1gLFxuICAgICAgYHNzaF91cmw6ICR7Y29uZmlnLnNlcnZlcn06NDQ0NGAsXG4gICAgICBgc2VjcmV0X2tleTogJHtjb25maWcudG9rZW59YCxcbiAgICAgIFwiZGlzYWJsZV9kYXNoYm9hcmQ6IHRydWVcIixcbiAgICAgIFwiZGlzYWJsZV90dWk6IHRydWVcIixcbiAgICAgIFwidHVubmVsczpcIixcbiAgICAgIGAgIC0gbmFtZTogJHtjb25maWcuc3ViZG9tYWlufWAsXG4gICAgICBgICAgIHN1YmRvbWFpbjogJHtjb25maWcuc3ViZG9tYWlufWAsXG4gICAgICBgICAgIHBvcnQ6ICR7Y29uZmlnLnBvcnR9YCxcbiAgICAgIFwiXCIsXG4gICAgXS5qb2luKFwiXFxuXCIpLFxuICApO1xufVxuXG4vKiogTGF1bmNoIGBwb3J0ciBzdGFydGAgYXMgYSBjaGlsZCBwcm9jZXNzIChjYWxsZXIgc3VwZXJ2aXNlcyArIGtpbGxzIGl0KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFBvcnRyKGNvbmZpZzogUG9ydHJDb25maWcsIGVudjogTm9kZUpTLlByb2Nlc3NFbnYpOiBSZXR1cm5UeXBlPHR5cGVvZiBzcGF3bj4ge1xuICAvLyBSZWNsYWltIHRoZSBzdWJkb21haW4gZnJvbSBhbnkgcG9ydHIgbGVmdCBieSBhIHByZXZpb3VzIGJvb3QgaW4gdGhpcyBjb250YWluZXIuXG4gIHNwYXduU3luYyhcInBraWxsXCIsIFtcIi14XCIsIFwicG9ydHJcIl0sIHsgc3RkaW86IFwiaWdub3JlXCIgfSk7XG4gIGxvZ2dlci5pbmZvKGBwb3J0ciB0dW5uZWxpbmcgaHR0cHM6Ly8ke2NvbmZpZy5zdWJkb21haW59LiR7Y29uZmlnLnNlcnZlcn0gLT4gOiR7Y29uZmlnLnBvcnR9YCk7XG4gIHJldHVybiBzcGF3bihcInBvcnRyXCIsIFtcInN0YXJ0XCJdLCB7IGVudiwgc3RkaW86IFwiaW5oZXJpdFwiIH0pO1xufVxuXG4vKiogVHJ1ZSB3aGVuIHRoZSBpbnN0YWxsZWQgcG9ydHIgYmluYXJ5IHBhdGggZXhpc3RzIChwb3N0LWluc3RhbGwgc2FuaXR5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb3J0ckluc3RhbGxlZChlbnY6IE5vZGVKUy5Qcm9jZXNzRW52KTogYm9vbGVhbiB7XG4gIHJldHVybiBleGlzdHNTeW5jKGpvaW4oZW52LkhPTUUhLCBcIi5wb3J0clwiLCBcImJpblwiLCBcInBvcnRyXCIpKTtcbn1cbiJdfQ==
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydHIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcG9ydHIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM1QyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUU3QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBVTFDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLElBS2xDO0lBQ0MsbUVBQW1FO0lBQ25FLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNwRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNoRSxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDL0IsSUFBSSxNQUEwQixDQUFDO0lBQy9CLElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxTQUFTLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxD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LEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBc0I7SUFDbkQsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHBvcnRyIGluc3RhbGwgKyBjb25maWcgKyBsYXVuY2ggZm9yIHRoZSB0dW5uZWwgQ0xJLlxuICpcbiAqIFNvbWUgaG9zdHMgKERhdGFicmlja3MgQXBwcyBhbW9uZyB0aGVtKSBtb3VudCB0aGUgY29udGFpbmVyJ3MgYCRIT01FYCByZWFkLW9ubHlcbiAqIG9uIGNvbGQgc3RhcnQsIHNvIHRoZSBwb3J0ciBiaW5hcnkgYW5kIGl0cyBjb25maWcgYXJlIHBsYWNlZCB1bmRlciBhIHdyaXRhYmxlLFxuICogY3dkLXJvb3RlZCBgLmhvbWVgIHVuY29uZGl0aW9uYWxseSAtIGl0IGNvc3RzIG5vdGhpbmcgd2hlcmUgYCRIT01FYCBpcyB3cml0YWJsZS5cbiAqIFRoZSBpbnN0YWxsIGlzIGlkZW1wb3RlbnQgKHRoZSBpbnN0YWxsZXIgc2tpcHMgd2hlbiB0aGUgb24tUEFUSCBiaW5hcnkgaXNcbiAqIGN1cnJlbnQpLiBUaGUgY29uZmlnIGlzIHJlbmRlcmVkIGZyb20gYFRVTk5FTF9QVUJMSUNfRE9NQUlOYCAoYDxzdWJkb21haW4+LjxzZXJ2ZXI+YClcbiAqICsgYFBPUlRSX1RPS0VOYCBhbmQgcG9pbnRzIHBvcnRyIGF0IHRoZSBQVUJMSUMgcG9ydCAodGhlIHByb3h5IGxpc3RlbnMgdGhlcmUpLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBzcGF3biwgc3Bhd25TeW5jIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZXhpc3RzU3luYywgbWtkaXJTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGRlbGltaXRlciwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGVudiwgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IFBVQkxJQ19ET01BSU5fRU5WIH0gZnJvbSBcIi4vZW52LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6cG9ydHJcIik7XG5cbi8qKiBSZXNvbHZlZCBwb3J0ciB3aXJpbmcsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm8gdHVubmVsIGlzIGNvbmZpZ3VyZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvcnRyQ29uZmlnIHtcbiAgc3ViZG9tYWluOiBzdHJpbmc7XG4gIHNlcnZlcjogc3RyaW5nO1xuICB0b2tlbjogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBwb3J0ciBjb25maWcgZnJvbSBgVFVOTkVMX1BVQkxJQ19ET01BSU5gICsgYFBPUlRSX1RPS0VOYCwgb3IgYW5cbiAqIGV4cGxpY2l0IGBzdWJkb21haW5gLiBUaGUgZG9tYWluIGlzIGA8c3ViZG9tYWluPi48c2VydmVyPmAgKGUuZy5cbiAqIGBkZW1vLmFwcHMuZGJ4LnRvb2xzYCkuIFJldHVybnMgYHVuZGVmaW5lZGAgKG5vIHR1bm5lbCkgd2hlbiB0aGUgdG9rZW4gb3IgYVxuICogdXNhYmxlIGRvbWFpbiBpcyBhYnNlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUG9ydHJDb25maWcob3B0czoge1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgdG9rZW4/OiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbn0pOiBQb3J0ckNvbmZpZyB8IHVuZGVmaW5lZCB7XG4gIC8vIFBPUlRSXyogaXMgdXBzdHJlYW0gcG9ydHIncyBvd24gbmFtZXNwYWNlLCBzbyBpdCBrZWVwcyBpdHMgbmFtZS5cbiAgY29uc3QgdG9rZW4gPSBlbnYuc3RyaW5nKG9wdHMudG9rZW4sIFwiUE9SVFJfVE9LRU5cIik7XG4gIGNvbnN0IGRvbWFpbiA9IGVudi5zdHJpbmcob3B0cy5wdWJsaWNEb21haW4sIFBVQkxJQ19ET01BSU5fRU5WKTtcbiAgaWYgKCF0b2tlbikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbGV0IHN1YmRvbWFpbiA9IG9wdHMuc3ViZG9tYWluO1xuICBsZXQgc2VydmVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGlmIChkb21haW4pIHtcbiAgICBzdWJkb21haW4gPz89IGRvbWFpbi5zcGxpdChcIi5cIilbMF07XG4gICAgc2VydmVyID0gZG9tYWluLnNsaWNlKGRvbWFpbi5pbmRleE9mKFwiLlwiKSArIDEpO1xuICB9XG4gIHNlcnZlciA/Pz0gZW52LnRleHQoXCJQT1JUUl9TRVJWRVJcIikgPz8gdW5kZWZpbmVkO1xuICBpZiAoIXN1YmRvbWFpbiB8fCAhc2VydmVyIHx8IHNlcnZlciA9PT0gZG9tYWluKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyBzdWJkb21haW4sIHNlcnZlciwgdG9rZW4sIHBvcnQ6IG9wdHMucG9ydCB9O1xufVxuXG4vKiogVGhlIHdyaXRhYmxlIGhvbWUgcG9ydHIgaW5zdGFsbHMgKyBjb25maWd1cmVzIHVuZGVyIChBcHBzIGAkSE9NRWAgaXMgcmVhZC1vbmx5KS4gKi9cbmZ1bmN0aW9uIHBvcnRySG9tZSgpOiBzdHJpbmcge1xuICBjb25zdCBob21lID0gam9pbihwcm9jZXNzLmN3ZCgpLCBcIi5ob21lXCIpO1xuICBta2RpclN5bmMoam9pbihob21lLCBcIi5wb3J0clwiLCBcImJpblwiKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHJldHVybiBob21lO1xufVxuXG4vKiogSW5zdGFsbCBwb3J0ciAoaWRlbXBvdGVudCkgaW50byB0aGUgY3dkLXJvb3RlZCBob21lIGFuZCByZXR1cm4gdGhlIGNoaWxkIGVudi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsUG9ydHIoKTogTm9kZUpTLlByb2Nlc3NFbnYge1xuICBjb25zdCBob21lID0gcG9ydHJIb21lKCk7XG4gIGNvbnN0IGVudjogTm9kZUpTLlByb2Nlc3NFbnYgPSB7XG4gICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgSE9NRTogaG9tZSxcbiAgICBQT1JUUl9BVVRPX0FERF9QQVRIOiBcIm5vXCIsXG4gICAgUEFUSDogW2pvaW4oaG9tZSwgXCIucG9ydHJcIiwgXCJiaW5cIiksIHByb2Nlc3MuZW52LlBBVEggPz8gXCJcIl0uam9pbihkZWxpbWl0ZXIpLFxuICB9O1xuICBsb2dnZXIuaW5mbyhcImluc3RhbGxpbmcgcG9ydHIgKGlkZW1wb3RlbnQpXCIpO1xuICBjb25zdCByZXMgPSBzcGF3blN5bmMoXCJiYXNoXCIsIFtcIi1jXCIsIFwiY3VybCAtc1NmIGh0dHBzOi8vaW5zdGFsbC5wb3J0ci5kZXYgfCBzaFwiXSwge1xuICAgIGVudixcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuICBpZiAocmVzLnN0YXR1cyAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKFwicG9ydHIgaW5zdGFsbCBmYWlsZWRcIik7XG4gIHJldHVybiBlbnY7XG59XG5cbi8qKiBSZW5kZXIgYH4vLnBvcnRyL2NvbmZpZy55YW1sYCBmb3IgdGhlIHJlc29sdmVkIHR1bm5lbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZVBvcnRyQ29uZmlnKGNvbmZpZzogUG9ydHJDb25maWcsIGVudjogTm9kZUpTLlByb2Nlc3NFbnYpOiB2b2lkIHtcbiAgY29uc3QgcGF0aCA9IGpvaW4oZW52LkhPTUUhLCBcIi5wb3J0clwiLCBcImNvbmZpZy55YW1sXCIpO1xuICB3cml0ZUZpbGVTeW5jKFxuICAgIHBhdGgsXG4gICAgW1xuICAgICAgYHNlcnZlcl91cmw6ICR7Y29uZmlnLnNlcnZlcn1gLFxuICAgICAgYHNzaF91cmw6ICR7Y29uZmlnLnNlcnZlcn06NDQ0NGAsXG4gICAgICBgc2VjcmV0X2tleTogJHtjb25maWcudG9rZW59YCxcbiAgICAgIFwiZGlzYWJsZV9kYXNoYm9hcmQ6IHRydWVcIixcbiAgICAgIFwiZGlzYWJsZV90dWk6IHRydWVcIixcbiAgICAgIFwidHVubmVsczpcIixcbiAgICAgIGAgIC0gbmFtZTogJHtjb25maWcuc3ViZG9tYWlufWAsXG4gICAgICBgICAgIHN1YmRvbWFpbjogJHtjb25maWcuc3ViZG9tYWlufWAsXG4gICAgICBgICAgIHBvcnQ6ICR7Y29uZmlnLnBvcnR9YCxcbiAgICAgIFwiXCIsXG4gICAgXS5qb2luKFwiXFxuXCIpLFxuICApO1xufVxuXG4vKiogTGF1bmNoIGBwb3J0ciBzdGFydGAgYXMgYSBjaGlsZCBwcm9jZXNzIChjYWxsZXIgc3VwZXJ2aXNlcyArIGtpbGxzIGl0KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFBvcnRyKGNvbmZpZzogUG9ydHJDb25maWcsIGVudjogTm9kZUpTLlByb2Nlc3NFbnYpOiBSZXR1cm5UeXBlPHR5cGVvZiBzcGF3bj4ge1xuICAvLyBSZWNsYWltIHRoZSBzdWJkb21haW4gZnJvbSBhbnkgcG9ydHIgbGVmdCBieSBhIHByZXZpb3VzIGJvb3QgaW4gdGhpcyBjb250YWluZXIuXG4gIHNwYXduU3luYyhcInBraWxsXCIsIFtcIi14XCIsIFwicG9ydHJcIl0sIHsgc3RkaW86IFwiaWdub3JlXCIgfSk7XG4gIGxvZ2dlci5pbmZvKGBwb3J0ciB0dW5uZWxpbmcgaHR0cHM6Ly8ke2NvbmZpZy5zdWJkb21haW59LiR7Y29uZmlnLnNlcnZlcn0gLT4gOiR7Y29uZmlnLnBvcnR9YCk7XG4gIHJldHVybiBzcGF3bihcInBvcnRyXCIsIFtcInN0YXJ0XCJdLCB7IGVudiwgc3RkaW86IFwiaW5oZXJpdFwiIH0pO1xufVxuXG4vKiogVHJ1ZSB3aGVuIHRoZSBpbnN0YWxsZWQgcG9ydHIgYmluYXJ5IHBhdGggZXhpc3RzIChwb3N0LWluc3RhbGwgc2FuaXR5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb3J0ckluc3RhbGxlZChlbnY6IE5vZGVKUy5Qcm9jZXNzRW52KTogYm9vbGVhbiB7XG4gIHJldHVybiBleGlzdHNTeW5jKGpvaW4oZW52LkhPTUUhLCBcIi5wb3J0clwiLCBcImJpblwiLCBcInBvcnRyXCIpKTtcbn1cbiJdfQ==
@@ -37,6 +37,13 @@ export interface ProxyOptions {
37
37
  * operator passed `--insecure` / `TUNNEL_INSECURE=true`.
38
38
  */
39
39
  gate?: AuthGateApi;
40
+ /**
41
+ * Extra `x-` request headers tunnel traffic may forward, as literals, globs, or
42
+ * `/regex/`es - unioned with {@link DEFAULT_FORWARD_HEADERS}. Every other `x-`
43
+ * header is stripped, and {@link PROTECTED_HEADERS} is stripped regardless. See
44
+ * `./headers.ts` for why the policy is an allow-list.
45
+ */
46
+ forwardHeaders?: readonly string[];
40
47
  }
41
48
  /** Start the gate proxy. Resolves once it is listening. */
42
- export declare function startProxy({ publicPort, appPort, gate }: ProxyOptions): Promise<void>;
49
+ export declare function startProxy({ publicPort, appPort, gate, forwardHeaders, }: ProxyOptions): Promise<void>;
package/lib/src/proxy.js CHANGED
@@ -25,9 +25,10 @@
25
25
  * @module
26
26
  */
27
27
  import { createServer } from "node:http";
28
- import { http, json, log } from "@dbx-tools/shared-core";
28
+ import { http, json, log, token } from "@dbx-tools/shared-core";
29
29
  import { authRequestSchema, authVerifySchema, SESSION_COOKIE_NAME } from "@dbx-tools/shared-email";
30
30
  import ProxyModule from "http-proxy-3";
31
+ import { toHeaderPolicy } from "./headers.js";
31
32
  const logger = log.logger("tunnel:proxy");
32
33
  /** Route prefix the login flow lives under (open, answered in-process). */
33
34
  const AUTH_PREFIX = "/api/email/auth";
@@ -56,7 +57,7 @@ function sendJson(res, status, body, setCookie) {
56
57
  res.end(JSON.stringify(body));
57
58
  }
58
59
  /** Start the gate proxy. Resolves once it is listening. */
59
- export function startProxy({ publicPort, appPort, gate }) {
60
+ export function startProxy({ publicPort, appPort, gate, forwardHeaders, }) {
60
61
  const proxy = ProxyModule.createProxyServer({
61
62
  target: { host: "127.0.0.1", port: appPort },
62
63
  ws: true,
@@ -69,6 +70,9 @@ export function startProxy({ publicPort, appPort, gate }) {
69
70
  sendJson(r, 502, { error: "upstream unavailable" });
70
71
  }
71
72
  });
73
+ // Compiled once: the inbound-header allow-list applied to every gated request.
74
+ const headerPolicy = toHeaderPolicy(forwardHeaders);
75
+ logger.debug("inbound header policy", { forward: headerPolicy.patterns });
72
76
  /** The session cookie for a verified email, as a Set-Cookie string. */
73
77
  const sessionCookie = (token, maxAgeSeconds) => [
74
78
  `${SESSION_COOKIE_NAME}=${token}`,
@@ -80,11 +84,25 @@ export function startProxy({ publicPort, appPort, gate }) {
80
84
  ]
81
85
  .filter(Boolean)
82
86
  .join("; ");
83
- /** Client IP for rate-limiting: the portr-forwarded XFF, else the socket. */
87
+ /**
88
+ * Client IP for rate-limiting: the portr client's forwarded XFF, else the socket.
89
+ *
90
+ * Deliberately the RIGHTMOST `x-forwarded-for` entry, not the leftmost. The
91
+ * list grows left-to-right as each hop appends, so the last entry is the one
92
+ * the nearest trusted proxy (portr) wrote and every earlier entry is a value
93
+ * the caller could have sent. Reading the leftmost lets a client vary one
94
+ * header to get a fresh rate-limit bucket per request, which defeats both the
95
+ * per-IP code-request and verify-attempt limiters. Called BEFORE
96
+ * {@link HeaderPolicy.apply} strips the header, so the honest hop value is
97
+ * still available here.
98
+ */
84
99
  const clientIp = (req) => {
85
- const fwd = req.headers["x-forwarded-for"];
86
- const first = Array.isArray(fwd) ? fwd[0] : fwd?.split(",")[0];
87
- return (first ?? req.socket.remoteAddress ?? "unknown").trim();
100
+ const forwarded = req.headers["x-forwarded-for"];
101
+ const chain = (Array.isArray(forwarded) ? forwarded.join(",") : (forwarded ?? ""))
102
+ .split(",")
103
+ .map((entry) => entry.trim())
104
+ .filter(Boolean);
105
+ return chain.at(-1) ?? req.socket.remoteAddress ?? "unknown";
88
106
  };
89
107
  /**
90
108
  * Remove the gate's session cookie from the `Cookie` header before forwarding,
@@ -106,14 +124,38 @@ export function startProxy({ publicPort, appPort, gate }) {
106
124
  };
107
125
  /**
108
126
  * Present an OTP-authenticated caller to the app the SAME way a platform front
109
- * door does: set `x-forwarded-user` / `x-forwarded-email` to the verified
110
- * address (AppKit reads `x-forwarded-user` for the OBO user id), so the app
111
- * needs no gate-specific code path. Any inbound copies are overwritten so a
112
- * client can't spoof identity through the gate.
127
+ * door does: set the front door's own identity headers to the verified address
128
+ * (AppKit reads {@link token.USER_ID_HEADER} for the OBO user id), so the app
129
+ * needs no gate-specific code path. The names come from
130
+ * `@dbx-tools/shared-core`'s `token` module - the same constants AppKit-side
131
+ * code reads them by - rather than being re-spelled here.
132
+ *
133
+ * What the gate CANNOT set is {@link token.ACCESS_TOKEN_HEADER}: an OTP session
134
+ * proves an email address, not possession of a Databricks credential, and
135
+ * there is no way to mint one for the caller. Its absence is exactly what
136
+ * `@dbx-tools/appkit`'s `identity` `"auto"` mode detects, so a gated request
137
+ * runs as the app's service principal instead of throwing.
113
138
  */
114
139
  const injectIdentity = (req, email) => {
115
- req.headers["x-forwarded-user"] = email;
116
- req.headers["x-forwarded-email"] = email;
140
+ req.headers[token.USER_ID_HEADER] = email;
141
+ req.headers[token.USER_EMAIL_HEADER] = email;
142
+ };
143
+ /**
144
+ * Apply the inbound-header policy to a tunnel request: every `x-` header the
145
+ * allow-list does not name is deleted, and the platform identity/transport set
146
+ * is deleted regardless. See `./headers.ts` for the reasoning; the
147
+ * security-critical case is {@link token.ACCESS_TOKEN_HEADER}, which the gate
148
+ * never sets but an app running `identity: "auto"` treats as proof the request
149
+ * can do OBO.
150
+ *
151
+ * `xfwd: true` on the proxy re-adds `x-forwarded-for`/`-proto`/`-port`/`-host`
152
+ * afterwards from the real socket, so the app still sees those - it just sees
153
+ * the honest values rather than the caller's claim.
154
+ */
155
+ const applyHeaderPolicy = (req) => {
156
+ const removed = headerPolicy.apply(req.headers);
157
+ if (removed.length)
158
+ logger.debug("stripped inbound headers", { removed });
117
159
  };
118
160
  const server = createServer(async (req, res) => {
119
161
  const path = (req.url ?? "/").split("?")[0];
@@ -147,10 +189,9 @@ export function startProxy({ publicPort, appPort, gate }) {
147
189
  if (path === `${AUTH_PREFIX}/logout` && req.method === "POST") {
148
190
  return sendJson(res, 200, { ok: true }, `${SESSION_COOKIE_NAME}=; Path=/; HttpOnly; Max-Age=0`);
149
191
  }
150
- // Anti-spoof: strip any inbound identity headers on portr traffic - only the
151
- // gate may set them, below, for a verified session.
152
- delete req.headers["x-forwarded-user"];
153
- delete req.headers["x-forwarded-email"];
192
+ // Anti-spoof: apply the inbound-header allow-list to portr traffic - only the
193
+ // gate may assert identity, and it does so below for a verified session.
194
+ applyHeaderPolicy(req);
154
195
  // Static (non-API) loads freely so the SPA + <AuthGate> can render. Strip the
155
196
  // session cookie so it never leaks to the static handler.
156
197
  if (!path.startsWith("/api/")) {
@@ -179,8 +220,7 @@ export function startProxy({ publicPort, appPort, gate }) {
179
220
  proxy.ws(req, socket, head);
180
221
  return;
181
222
  }
182
- delete req.headers["x-forwarded-user"];
183
- delete req.headers["x-forwarded-email"];
223
+ applyHeaderPolicy(req);
184
224
  if (!(req.url ?? "").startsWith("/api/")) {
185
225
  stripSessionCookie(req);
186
226
  proxy.ws(req, socket, head);
@@ -204,4 +244,4 @@ export function startProxy({ publicPort, appPort, gate }) {
204
244
  });
205
245
  });
206
246
  }
207
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUE2QyxNQUFNLFdBQVcsQ0FBQztBQUVwRixPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRyxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFHdkMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUUxQywyRUFBMkU7QUFDM0UsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUM7QUFFdEMsaUZBQWlGO0FBQ2pGLFNBQVMsVUFBVSxDQUFDLElBQXdCO0lBQzFDLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDeEIsMEVBQTBFO0lBQzFFLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sQ0FBQyxLQUFLLFdBQVcsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLFdBQVcsQ0FBQztBQUN2RixDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLFNBQVMsUUFBUSxDQUFDLEdBQW9CO0lBQ3BDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFDZCxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FB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QUFDLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMseUJBQXlCLFVBQVUscUJBQXFCLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDL0UsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIHR1bm5lbCBnYXRlIHJldmVyc2UtcHJveHkuXG4gKlxuICogQmluZHMgdGhlIFBVQkxJQyBwb3J0ICh0aGUgY29udGFpbmVyJ3MgYERBVEFCUklDS1NfQVBQX1BPUlRgKSBhbmQgZm9yd2FyZHMgdG9cbiAqIHRoZSByZWFsIGFwcCBvbiBhIHByaXZhdGUgbG9vcGJhY2sgcG9ydC4gSXQgaXMgdGhlIHNpbmdsZSBmcm9udCBkb29yIGZvciBib3RoXG4gKiB0cmFmZmljIHBhdGhzIGludG8gdGhlIGNvbnRhaW5lcjpcbiAqXG4gKiAgIC0gKipwb3J0ciBjbGllbnQqKiAoc2FtZSBjb250YWluZXIsIGNvbm5lY3RzIG92ZXIgTE9PUEJBQ0spIC0gdGhlIHB1YmxpY1xuICogICAgIHR1bm5lbC4gVGhpcyBpcyB3aGF0IHRoZSBnYXRlIHByb3RlY3RzLlxuICogICAtICoqdGhlIGhvc3RpbmcgcGxhdGZvcm0ncyBmcm9udCBkb29yKiogKERhdGFicmlja3MgQXBwcycgY29udHJvbCBwbGFuZSwgb3JcbiAqICAgICBhbnkgb3RoZXIgaG9zdCByZWFjaGluZyB0aGUgYDAuMC4wLjBgIHBvcnQgZnJvbSBhIE5PTi1sb29wYmFja1xuICogICAgIGNvbnRhaW5lci1uZXR3b3JrIGFkZHJlc3MpIC0gcGFzc2VkIHRocm91Z2ggVU5HQVRFRCwgcGVyIHRoZSBydWxlIFwiaWYgaXQnc1xuICogICAgIG5vdCBmcm9tIHRoZSBwb3J0ciBjbGllbnQsIGxldCBpdCBpblwiLiBUaGUgcGxhdGZvcm0gYWxyZWFkeSBhdXRoZW50aWNhdGVzXG4gKiAgICAgdGhhdCBwYXRoOyB0aGUgZ2F0ZSBleGlzdHMgZm9yIHRoZSB0dW5uZWwsIHdoaWNoIG5vdGhpbmcgZWxzZSBwcm90ZWN0cy5cbiAqXG4gKiBUaGUgZGlzdGluZ3Vpc2hlciBpcyB0aGUgY29ubmVjdGlvbidzIHNvdXJjZSBhZGRyZXNzOiBhIGxvb3BiYWNrXG4gKiBgcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzYCBpcyB0aGUgcG9ydHIgY2xpZW50OyBhbnl0aGluZyBlbHNlIGlzIHRoZSBwbGF0Zm9ybS5cbiAqXG4gKiBGb3IgcG9ydHIgdHJhZmZpYyB0aGUgZ2F0ZSBpcyBhIHN0YW5kYXJkIFNQQSBnYXRlOiBzdGF0aWMgYXNzZXRzICsgdGhlIGxvZ2luXG4gKiBmbG93IChgL2FwaS9lbWFpbC9hdXRoLypgLCBhbnN3ZXJlZCBJTi1QUk9DRVNTIGJ5IHRoaXMgcHJveHkgdmlhIHRoZVxuICoge0BsaW5rIEF1dGhHYXRlQXBpfSkgYXJlIG9wZW4gc28gdGhlIGJyb3dzZXIgY2FuIGxvYWQgdGhlIGNsaWVudCBhbmQgcmVuZGVyIHRoZVxuICogYDxBdXRoR2F0ZT5gOyBldmVyeSBvdGhlciBgL2FwaS8qYCBuZWVkcyBhIHZhbGlkIHNlc3Npb24gY29va2llIG9yIGdldHMgNDAxLlxuICogV2ViU29ja2V0IHVwZ3JhZGVzIGFyZSBnYXRlZCB0aGUgc2FtZSB3YXkgYW5kIGZvcndhcmRlZCB3aXRoIGBodHRwLXByb3h5LTNgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIsIHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlclJlc3BvbnNlIH0gZnJvbSBcIm5vZGU6aHR0cFwiO1xuaW1wb3J0IHR5cGUgeyBTb2NrZXQgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGh0dHAsIGpzb24sIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBhdXRoUmVxdWVzdFNjaGVtYSwgYXV0aFZlcmlmeVNjaGVtYSwgU0VTU0lPTl9DT09LSUVfTkFNRSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IFByb3h5TW9kdWxlIGZyb20gXCJodHRwLXByb3h5LTNcIjtcbmltcG9ydCB0eXBlIHsgQXV0aEdhdGVBcGkgfSBmcm9tIFwiLi9wbHVnaW4udHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwcm94eVwiKTtcblxuLyoqIFJvdXRlIHByZWZpeCB0aGUgbG9naW4gZmxvdyBsaXZlcyB1bmRlciAob3BlbiwgYW5zd2VyZWQgaW4tcHJvY2VzcykuICovXG5jb25zdCBBVVRIX1BSRUZJWCA9IFwiL2FwaS9lbWFpbC9hdXRoXCI7XG5cbi8qKiBUcnVlIHdoZW4gYSBzb2NrZXQgYWRkcmVzcyBpcyBsb29wYmFjayAodGhlIHBvcnRyIGNsaWVudCwgc2FtZSBjb250YWluZXIpLiAqL1xuZnVuY3Rpb24gaXNMb29wYmFjayhhZGRyOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKCFhZGRyKSByZXR1cm4gZmFsc2U7XG4gIC8vIE5vcm1hbGl6ZSBJUHY0LW1hcHBlZCBJUHY2IChgOjpmZmZmOjEyNy4wLjAuMWApIGFuZCBiYXJlIElQdjYgbG9vcGJhY2suXG4gIGNvbnN0IGEgPSBhZGRyLnJlcGxhY2UoL146OmZmZmY6LywgXCJcIik7XG4gIHJldHVybiBhID09PSBcIjEyNy4wLjAuMVwiIHx8IGEuc3RhcnRzV2l0aChcIjEyNy5cIikgfHwgYSA9PT0gXCI6OjFcIiB8fCBhID09PSBcImxvY2FsaG9zdFwiO1xufVxuXG4vKiogUmVhZCB0aGUgd2hvbGUgcmVxdWVzdCBib2R5IGFzIHRleHQgKHNtYWxsIEpTT04gcGF5bG9hZHMgb25seSkuICovXG5mdW5jdGlvbiByZWFkQm9keShyZXE6IEluY29taW5nTWVzc2FnZSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGxldCBkYXRhID0gXCJcIjtcbiAgICByZXEub24oXCJkYXRhXCIsIChjaHVuaykgPT4gKGRhdGEgKz0gY2h1bmspKTtcbiAgICByZXEub24oXCJlbmRcIiwgKCkgPT4gcmVzb2x2ZShkYXRhKSk7XG4gICAgcmVxLm9uKFwiZXJyb3JcIiwgKCkgPT4gcmVzb2x2ZShkYXRhKSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzZW5kSnNvbihyZXM6IFNlcnZlclJlc3BvbnNlLCBzdGF0dXM6IG51bWJlciwgYm9keTogdW5rbm93biwgc2V0Q29va2llPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7IFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH07XG4gIGlmIChzZXRDb29raWUpIGhlYWRlcnNbXCJzZXQtY29va2llXCJdID0gc2V0Q29va2llO1xuICByZXMud3JpdGVIZWFkKHN0YXR1cywgaGVhZGVycyk7XG4gIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xufVxuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIHN0YXJ0UHJveHl9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm94eU9wdGlvbnMge1xuICAvKiogUHVibGljIHBvcnQgdG8gbGlzdGVuIG9uICh0aGUgY29udGFpbmVyJ3MgREFUQUJSSUNLU19BUFBfUE9SVCkuICovXG4gIHB1YmxpY1BvcnQ6IG51bWJlcjtcbiAgLyoqIFByaXZhdGUgcG9ydCB0aGUgcmVhbCBhcHAgbGlzdGVucyBvbiAobG9vcGJhY2spLiAqL1xuICBhcHBQb3J0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgaW4tcHJvY2VzcyBnYXRlIEFQSSwgb3IgYHVuZGVmaW5lZGAgdG8gcnVuIE9QRU4gKGluc2VjdXJlIG1vZGUpOiBldmVyeVxuICAgKiByZXF1ZXN0IC0gaW5jbHVkaW5nIHBvcnRyIHRyYWZmaWMgLSBpcyBmb3J3YXJkZWQgdW5nYXRlZC4gVXNlZCB3aGVuIHRoZVxuICAgKiBvcGVyYXRvciBwYXNzZWQgYC0taW5zZWN1cmVgIC8gYFRVTk5FTF9JTlNFQ1VSRT10cnVlYC5cbiAgICovXG4gIGdhdGU/OiBBdXRoR2F0ZUFwaTtcbn1cblxuLyoqIFN0YXJ0IHRoZSBnYXRlIHByb3h5LiBSZXNvbHZlcyBvbmNlIGl0IGlzIGxpc3RlbmluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFByb3h5KHsgcHVibGljUG9ydCwgYXBwUG9ydCwgZ2F0ZSB9OiBQcm94eU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJveHkgPSBQcm94eU1vZHVsZS5jcmVhdGVQcm94eVNlcnZlcih7XG4gICAgdGFyZ2V0OiB7IGhvc3Q6IFwiMTI3LjAuMC4xXCIsIHBvcnQ6IGFwcFBvcnQgfSxcbiAgICB3czogdHJ1ZSxcbiAgICB4ZndkOiB0cnVlLFxuICB9KTtcbiAgcHJveHkub24oXCJlcnJvclwiLCAoZXJyOiBFcnJvciwgX3JlcTogdW5rbm93biwgcmVzOiB1bmtub3duKSA9PiB7XG4gICAgbG9nZ2VyLndhcm4oXCJ1cHN0cmVhbSBwcm94eSBlcnJvclwiLCB7IGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBjb25zdCByID0gcmVzIGFzIFNlcnZlclJlc3BvbnNlIHwgdW5kZWZpbmVkO1xuICAgIGlmIChyICYmIFwid3JpdGVIZWFkXCIgaW4gciAmJiAhci5oZWFkZXJzU2VudCkge1xuICAgICAgc2VuZEpzb24ociwgNTAyLCB7IGVycm9yOiBcInVwc3RyZWFtIHVuYXZhaWxhYmxlXCIgfSk7XG4gICAgfVxuICB9KTtcblxuICAvKiogVGhlIHNlc3Npb24gY29va2llIGZvciBhIHZlcmlmaWVkIGVtYWlsLCBhcyBhIFNldC1Db29raWUgc3RyaW5nLiAqL1xuICBjb25zdCBzZXNzaW9uQ29va2llID0gKHRva2VuOiBzdHJpbmcsIG1heEFnZVNlY29uZHM6IG51bWJlcik6IHN0cmluZyA9PlxuICAgIFtcbiAgICAgIGAke1NFU1NJT05fQ09PS0lFX05BTUV9PSR7dG9rZW59YCxcbiAgICAgIFwiUGF0aD0vXCIsXG4gICAgICBcIkh0dHBPbmx5XCIsXG4gICAgICBcIlNhbWVTaXRlPUxheFwiLFxuICAgICAgYE1heC1BZ2U9JHttYXhBZ2VTZWNvbmRzfWAsXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCIgPyBcIlNlY3VyZVwiIDogXCJcIixcbiAgICBdXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAuam9pbihcIjsgXCIpO1xuXG4gIC8qKiBDbGllbnQgSVAgZm9yIHJhdGUtbGltaXRpbmc6IHRoZSBwb3J0ci1mb3J3YXJkZWQgWEZGLCBlbHNlIHRoZSBzb2NrZXQuICovXG4gIGNvbnN0IGNsaWVudElwID0gKHJlcTogSW5jb21pbmdNZXNzYWdlKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCBmd2QgPSByZXEuaGVhZGVyc1tcIngtZm9yd2FyZGVkLWZvclwiXTtcbiAgICBjb25zdCBmaXJzdCA9IEFycmF5LmlzQXJyYXkoZndkKSA/IGZ3ZFswXSA6IGZ3ZD8uc3BsaXQoXCIsXCIpWzBdO1xuICAgIHJldHVybiAoZmlyc3QgPz8gcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzID8/IFwidW5rbm93blwiKS50cmltKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZ2F0ZSdzIHNlc3Npb24gY29va2llIGZyb20gdGhlIGBDb29raWVgIGhlYWRlciBiZWZvcmUgZm9yd2FyZGluZyxcbiAgICogc28gdGhlIGFwcCBuZXZlciBzZWVzIGBkYnhfYXV0aGAgKGl0IGlzIHRoZSBwcm94eSdzIGNvbmNlcm4sIG5vdCB0aGUgYXBwJ3MpLlxuICAgKiBQcmVzZXJ2ZXMgYW55IG90aGVyIGNvb2tpZXMuIFJlbW92ZXMgdGhlIGhlYWRlciBlbnRpcmVseSB3aGVuIGl0IGJlY29tZXMgZW1wdHkuXG4gICAqL1xuICBjb25zdCBzdHJpcFNlc3Npb25Db29raWUgPSAocmVxOiBJbmNvbWluZ01lc3NhZ2UpOiB2b2lkID0+IHtcbiAgICBjb25zdCByYXcgPSByZXEuaGVhZGVycy5jb29raWU7XG4gICAgaWYgKCFyYXcpIHJldHVybjtcbiAgICBjb25zdCBrZXB0ID0gcmF3XG4gICAgICAuc3BsaXQoXCI7XCIpXG4gICAgICAubWFwKChjKSA9PiBjLnRyaW0oKSlcbiAgICAgIC5maWx0ZXIoKGMpID0+IGMgJiYgIWMuc3RhcnRzV2l0aChgJHtTRVNTSU9OX0NPT0tJRV9OQU1FfT1gKSk7XG4gICAgaWYgKGtlcHQubGVuZ3RoKSByZXEuaGVhZGVycy5jb29raWUgPSBrZXB0LmpvaW4oXCI7IFwiKTtcbiAgICBlbHNlIGRlbGV0ZSByZXEuaGVhZGVycy5jb29raWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIFByZXNlbnQgYW4gT1RQLWF1dGhlbnRpY2F0ZWQgY2FsbGVyIHRvIHRoZSBhcHAgdGhlIFNBTUUgd2F5IGEgcGxhdGZvcm0gZnJvbnRcbiAgICogZG9vciBkb2VzOiBzZXQgYHgtZm9yd2FyZGVkLXVzZXJgIC8gYHgtZm9yd2FyZGVkLWVtYWlsYCB0byB0aGUgdmVyaWZpZWRcbiAgICogYWRkcmVzcyAoQXBwS2l0IHJlYWRzIGB4LWZvcndhcmRlZC11c2VyYCBmb3IgdGhlIE9CTyB1c2VyIGlkKSwgc28gdGhlIGFwcFxuICAgKiBuZWVkcyBubyBnYXRlLXNwZWNpZmljIGNvZGUgcGF0aC4gQW55IGluYm91bmQgY29waWVzIGFyZSBvdmVyd3JpdHRlbiBzbyBhXG4gICAqIGNsaWVudCBjYW4ndCBzcG9vZiBpZGVudGl0eSB0aHJvdWdoIHRoZSBnYXRlLlxuICAgKi9cbiAgY29uc3QgaW5qZWN0SWRlbnRpdHkgPSAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIGVtYWlsOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICByZXEuaGVhZGVyc1tcIngtZm9yd2FyZGVkLXVzZXJcIl0gPSBlbWFpbDtcbiAgICByZXEuaGVhZGVyc1tcIngtZm9yd2FyZGVkLWVtYWlsXCJdID0gZW1haWw7XG4gIH07XG5cbiAgY29uc3Qgc2VydmVyID0gY3JlYXRlU2VydmVyKGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IHBhdGggPSAocmVxLnVybCA/PyBcIi9cIikuc3BsaXQoXCI/XCIpWzBdITtcblxuICAgIC8vIEluc2VjdXJlL29wZW4gbW9kZSAobm8gZ2F0ZSkgT1Igbm9uLWxvb3BiYWNrIHRyYWZmaWMgKHRoZSBob3N0aW5nXG4gICAgLy8gcGxhdGZvcm0ncyBmcm9udCBkb29yIC8gY29udHJvbCBwbGFuZSk6IGZvcndhcmQgdW5nYXRlZC5cbiAgICBpZiAoIWdhdGUgfHwgIWlzTG9vcGJhY2socmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzKSkge1xuICAgICAgcHJveHkud2ViKHJlcSwgcmVzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAtLS0gcG9ydHIgdHJhZmZpYzogdGhlIGdhdGUgYXBwbGllcyAtLS1cblxuICAgIC8vIFRoZSBsb2dpbiBmbG93IGlzIGFuc3dlcmVkIElOLVBST0NFU1MgKHRoZSBhcHAgaGFzIG5vIHNlcnZlciB0byBmb3J3YXJkIHRvKS5cbiAgICBpZiAocGF0aCA9PT0gYCR7QVVUSF9QUkVGSVh9L3N0YXR1c2ApIHtcbiAgICAgIGNvbnN0IHRva2VuID0gaHR0cC5wYXJzZUNvb2tpZXMocmVxLmhlYWRlcnMuY29va2llID8/IG51bGwpW1NFU1NJT05fQ09PS0lFX05BTUVdO1xuICAgICAgc2VuZEpzb24ocmVzLCAyMDAsIGF3YWl0IGdhdGUuc3RhdHVzKHRva2VuKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwYXRoID09PSBgJHtBVVRIX1BSRUZJWH0vcmVxdWVzdGAgJiYgcmVxLm1ldGhvZCA9PT0gXCJQT1NUXCIpIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IGF1dGhSZXF1ZXN0U2NoZW1hLnNhZmVQYXJzZShqc29uLnBhcnNlUmVjb3JkKGF3YWl0IHJlYWRCb2R5KHJlcSkpKTtcbiAgICAgIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiBzZW5kSnNvbihyZXMsIDIwMCwgeyBvazogdHJ1ZSB9KTsgLy8gYW50aS1lbnVtZXJhdGlvblxuICAgICAgcmV0dXJuIHNlbmRKc29uKHJlcywgMjAwLCBhd2FpdCBnYXRlLnJlcXVlc3QocGFyc2VkLmRhdGEuZW1haWwsIGNsaWVudElwKHJlcSkpKTtcbiAgICB9XG4gICAgaWYgKHBhdGggPT09IGAke0FVVEhfUFJFRklYfS92ZXJpZnlgICYmIHJlcS5tZXRob2QgPT09IFwiUE9TVFwiKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBhdXRoVmVyaWZ5U2NoZW1hLnNhZmVQYXJzZShqc29uLnBhcnNlUmVjb3JkKGF3YWl0IHJlYWRCb2R5KHJlcSkpKTtcbiAgICAgIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiBzZW5kSnNvbihyZXMsIDIwMCwgeyBvazogZmFsc2UgfSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnYXRlLnZlcmlmeShwYXJzZWQuZGF0YS5lbWFpbCwgcGFyc2VkLmRhdGEuY29kZSwgY2xpZW50SXAocmVxKSk7XG4gICAgICBjb25zdCBjb29raWUgPVxuICAgICAgICByZXN1bHQub2sgJiYgcmVzdWx0LnRva2VuID8gc2Vzc2lvbkNvb2tpZShyZXN1bHQudG9rZW4sIGdhdGUuc2Vzc2lvblR0bFNlY29uZHMpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHNlbmRKc29uKFxuICAgICAgICByZXMsXG4gICAgICAgIDIwMCxcbiAgICAgICAgeyBvazogcmVzdWx0Lm9rLCAuLi4ocmVzdWx0LnJldHJ5QWZ0ZXIgPyB7IHJldHJ5QWZ0ZXI6IHJlc3VsdC5yZXRyeUFmdGVyIH0gOiB7fSkgfSxcbiAgICAgICAgY29va2llLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHBhdGggPT09IGAke0FVVEhfUFJFRklYfS9sb2dvdXRgICYmIHJlcS5tZXRob2QgPT09IFwiUE9TVFwiKSB7XG4gICAgICByZXR1cm4gc2VuZEpzb24oXG4gICAgICAgIHJlcyxcbiAgICAgICAgMjAwLFxuICAgICAgICB7IG9rOiB0cnVlIH0sXG4gICAgICAgIGAke1NFU1NJT05fQ09PS0lFX05BTUV9PTsgUGF0aD0vOyBIdHRwT25seTsgTWF4LUFnZT0wYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQW50aS1zcG9vZjogc3RyaXAgYW55IGluYm91bmQgaWRlbnRpdHkgaGVhZGVycyBvbiBwb3J0ciB0cmFmZmljIC0gb25seSB0aGVcbiAgICAvLyBnYXRlIG1heSBzZXQgdGhlbSwgYmVsb3csIGZvciBhIHZlcmlmaWVkIHNlc3Npb24uXG4gICAgZGVsZXRlIHJlcS5oZWFkZXJzW1wieC1mb3J3YXJkZWQtdXNlclwiXTtcbiAgICBkZWxldGUgcmVxLmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1lbWFpbFwiXTtcblxuICAgIC8vIFN0YXRpYyAobm9uLUFQSSkgbG9hZHMgZnJlZWx5IHNvIHRoZSBTUEEgKyA8QXV0aEdhdGU+IGNhbiByZW5kZXIuIFN0cmlwIHRoZVxuICAgIC8vIHNlc3Npb24gY29va2llIHNvIGl0IG5ldmVyIGxlYWtzIHRvIHRoZSBzdGF0aWMgaGFuZGxlci5cbiAgICBpZiAoIXBhdGguc3RhcnRzV2l0aChcIi9hcGkvXCIpKSB7XG4gICAgICBzdHJpcFNlc3Npb25Db29raWUocmVxKTtcbiAgICAgIHByb3h5LndlYihyZXEsIHJlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRXZlcnkgb3RoZXIgL2FwaS8qIHJlcXVpcmVzIGEgdmFsaWQgc2Vzc2lvbi5cbiAgICBjb25zdCB0b2tlbiA9IGh0dHAucGFyc2VDb29raWVzKHJlcS5oZWFkZXJzLmNvb2tpZSA/PyBudWxsKVtTRVNTSU9OX0NPT0tJRV9OQU1FXTtcbiAgICBjb25zdCBlbWFpbCA9IGF3YWl0IGdhdGUuc2Vzc2lvbih0b2tlbik7XG4gICAgaWYgKGVtYWlsKSB7XG4gICAgICAvLyBQcmVzZW50IHRoZSBPVFAgdXNlciBsaWtlIGEgcGxhdGZvcm0gZnJvbnQgZG9vciwgYW5kIGRyb3AgdGhlIGdhdGVcbiAgICAgIC8vIGNvb2tpZSBzbyB0aGUgYXBwIHNlZXMgYSBjbGVhbiwgZnJvbnQtZG9vci1zaGFwZWQgcmVxdWVzdC5cbiAgICAgIGluamVjdElkZW50aXR5KHJlcSwgZW1haWwpO1xuICAgICAgc3RyaXBTZXNzaW9uQ29va2llKHJlcSk7XG4gICAgICBwcm94eS53ZWIocmVxLCByZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZW5kSnNvbihyZXMsIDQwMSwgeyBlcnJvcjogXCJhdXRoZW50aWNhdGlvbiByZXF1aXJlZFwiLCBsb2dpblBhdGg6IEFVVEhfUFJFRklYIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gV2ViU29ja2V0IHVwZ3JhZGVzOiBmb3J3YXJkIGZyb250LWRvb3IgdHJhZmZpYyB1bnRvdWNoZWQ7IGdhdGUgbG9vcGJhY2tcbiAgLy8gKHBvcnRyKSBBUEkgdXBncmFkZXMgdGhlIHNhbWUgd2F5IGFzIEhUVFAgKHN0cmlwIGNvb2tpZSArIGluamVjdCBpZGVudGl0eSkuXG4gIHNlcnZlci5vbihcInVwZ3JhZGVcIiwgKHJlcTogSW5jb21pbmdNZXNzYWdlLCBzb2NrZXQ6IFNvY2tldCwgaGVhZDogQnVmZmVyKSA9PiB7XG4gICAgaWYgKCFnYXRlIHx8ICFpc0xvb3BiYWNrKHJlcS5zb2NrZXQucmVtb3RlQWRkcmVzcykpIHtcbiAgICAgIHByb3h5LndzKHJlcSwgc29ja2V0LCBoZWFkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVsZXRlIHJlcS5oZWFkZXJzW1wieC1mb3J3YXJkZWQtdXNlclwiXTtcbiAgICBkZWxldGUgcmVxLmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1lbWFpbFwiXTtcbiAgICBpZiAoIShyZXEudXJsID8/IFwiXCIpLnN0YXJ0c1dpdGgoXCIvYXBpL1wiKSkge1xuICAgICAgc3RyaXBTZXNzaW9uQ29va2llKHJlcSk7XG4gICAgICBwcm94eS53cyhyZXEsIHNvY2tldCwgaGVhZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRva2VuID0gaHR0cC5wYXJzZUNvb2tpZXMocmVxLmhlYWRlcnMuY29va2llID8/IG51bGwpW1NFU1NJT05fQ09PS0lFX05BTUVdO1xuICAgIHZvaWQgZ2F0ZS5zZXNzaW9uKHRva2VuKS50aGVuKChlbWFpbCkgPT4ge1xuICAgICAgaWYgKCFlbWFpbCkge1xuICAgICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpbmplY3RJZGVudGl0eShyZXEsIGVtYWlsKTtcbiAgICAgIHN0cmlwU2Vzc2lvbkNvb2tpZShyZXEpO1xuICAgICAgcHJveHkud3MocmVxLCBzb2NrZXQsIGhlYWQpO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXJ2ZXIubGlzdGVuKHB1YmxpY1BvcnQsIFwiMC4wLjAuMFwiLCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgZ2F0ZSBwcm94eSBvbiAwLjAuMC4wOiR7cHVibGljUG9ydH0gLT4gYXBwIDEyNy4wLjAuMToke2FwcFBvcnR9YCk7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuIl19
247
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUE2QyxNQUFNLFdBQVcsQ0FBQztBQUVwRixPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkcsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxjQUFjLEVBQXFCLE1BQU0sY0FBYyxDQUFDO0FBR2pFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFMUMsMkVBQTJFO0FBQzNFLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixDQUFDO0FBRXRDLGlGQUFpRjtBQUNqRixTQUFTLFVBQVUsQ0FBQyxJQUF3QjtJQUMxQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hCLDBFQUEwRTtJQUMxRSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2QyxPQUFPLENBQUMsS0FBSyxXQUFXLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsS0FBSyxXQUFXLENBQUM7QUFDdkYsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxTQUFTLFFBQVEsQ0FBQyxHQUFvQjtJQUNwQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2QsR0FBRyxD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LEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDNUIsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDakYsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pCLE9BQU87WUFDVCxDQUFDO1lBQ0QsY0FBYyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQixrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QixLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMseUJBQXlCLFVBQVUscUJBQXFCLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDL0UsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIHR1bm5lbCBnYXRlIHJldmVyc2UtcHJveHkuXG4gKlxuICogQmluZHMgdGhlIFBVQkxJQyBwb3J0ICh0aGUgY29udGFpbmVyJ3MgYERBVEFCUklDS1NfQVBQX1BPUlRgKSBhbmQgZm9yd2FyZHMgdG9cbiAqIHRoZSByZWFsIGFwcCBvbiBhIHByaXZhdGUgbG9vcGJhY2sgcG9ydC4gSXQgaXMgdGhlIHNpbmdsZSBmcm9udCBkb29yIGZvciBib3RoXG4gKiB0cmFmZmljIHBhdGhzIGludG8gdGhlIGNvbnRhaW5lcjpcbiAqXG4gKiAgIC0gKipwb3J0ciBjbGllbnQqKiAoc2FtZSBjb250YWluZXIsIGNvbm5lY3RzIG92ZXIgTE9PUEJBQ0spIC0gdGhlIHB1YmxpY1xuICogICAgIHR1bm5lbC4gVGhpcyBpcyB3aGF0IHRoZSBnYXRlIHByb3RlY3RzLlxuICogICAtICoqdGhlIGhvc3RpbmcgcGxhdGZvcm0ncyBmcm9udCBkb29yKiogKERhdGFicmlja3MgQXBwcycgY29udHJvbCBwbGFuZSwgb3JcbiAqICAgICBhbnkgb3RoZXIgaG9zdCByZWFjaGluZyB0aGUgYDAuMC4wLjBgIHBvcnQgZnJvbSBhIE5PTi1sb29wYmFja1xuICogICAgIGNvbnRhaW5lci1uZXR3b3JrIGFkZHJlc3MpIC0gcGFzc2VkIHRocm91Z2ggVU5HQVRFRCwgcGVyIHRoZSBydWxlIFwiaWYgaXQnc1xuICogICAgIG5vdCBmcm9tIHRoZSBwb3J0ciBjbGllbnQsIGxldCBpdCBpblwiLiBUaGUgcGxhdGZvcm0gYWxyZWFkeSBhdXRoZW50aWNhdGVzXG4gKiAgICAgdGhhdCBwYXRoOyB0aGUgZ2F0ZSBleGlzdHMgZm9yIHRoZSB0dW5uZWwsIHdoaWNoIG5vdGhpbmcgZWxzZSBwcm90ZWN0cy5cbiAqXG4gKiBUaGUgZGlzdGluZ3Vpc2hlciBpcyB0aGUgY29ubmVjdGlvbidzIHNvdXJjZSBhZGRyZXNzOiBhIGxvb3BiYWNrXG4gKiBgcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzYCBpcyB0aGUgcG9ydHIgY2xpZW50OyBhbnl0aGluZyBlbHNlIGlzIHRoZSBwbGF0Zm9ybS5cbiAqXG4gKiBGb3IgcG9ydHIgdHJhZmZpYyB0aGUgZ2F0ZSBpcyBhIHN0YW5kYXJkIFNQQSBnYXRlOiBzdGF0aWMgYXNzZXRzICsgdGhlIGxvZ2luXG4gKiBmbG93IChgL2FwaS9lbWFpbC9hdXRoLypgLCBhbnN3ZXJlZCBJTi1QUk9DRVNTIGJ5IHRoaXMgcHJveHkgdmlhIHRoZVxuICoge0BsaW5rIEF1dGhHYXRlQXBpfSkgYXJlIG9wZW4gc28gdGhlIGJyb3dzZXIgY2FuIGxvYWQgdGhlIGNsaWVudCBhbmQgcmVuZGVyIHRoZVxuICogYDxBdXRoR2F0ZT5gOyBldmVyeSBvdGhlciBgL2FwaS8qYCBuZWVkcyBhIHZhbGlkIHNlc3Npb24gY29va2llIG9yIGdldHMgNDAxLlxuICogV2ViU29ja2V0IHVwZ3JhZGVzIGFyZSBnYXRlZCB0aGUgc2FtZSB3YXkgYW5kIGZvcndhcmRlZCB3aXRoIGBodHRwLXByb3h5LTNgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIsIHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlclJlc3BvbnNlIH0gZnJvbSBcIm5vZGU6aHR0cFwiO1xuaW1wb3J0IHR5cGUgeyBTb2NrZXQgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGh0dHAsIGpzb24sIGxvZywgdG9rZW4gfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgYXV0aFJlcXVlc3RTY2hlbWEsIGF1dGhWZXJpZnlTY2hlbWEsIFNFU1NJT05fQ09PS0lFX05BTUUgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtZW1haWxcIjtcbmltcG9ydCBQcm94eU1vZHVsZSBmcm9tIFwiaHR0cC1wcm94eS0zXCI7XG5pbXBvcnQgeyB0b0hlYWRlclBvbGljeSwgdHlwZSBIZWFkZXJQb2xpY3kgfSBmcm9tIFwiLi9oZWFkZXJzLnRzXCI7XG5pbXBvcnQgdHlwZSB7IEF1dGhHYXRlQXBpIH0gZnJvbSBcIi4vcGx1Z2luLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6cHJveHlcIik7XG5cbi8qKiBSb3V0ZSBwcmVmaXggdGhlIGxvZ2luIGZsb3cgbGl2ZXMgdW5kZXIgKG9wZW4sIGFuc3dlcmVkIGluLXByb2Nlc3MpLiAqL1xuY29uc3QgQVVUSF9QUkVGSVggPSBcIi9hcGkvZW1haWwvYXV0aFwiO1xuXG4vKiogVHJ1ZSB3aGVuIGEgc29ja2V0IGFkZHJlc3MgaXMgbG9vcGJhY2sgKHRoZSBwb3J0ciBjbGllbnQsIHNhbWUgY29udGFpbmVyKS4gKi9cbmZ1bmN0aW9uIGlzTG9vcGJhY2soYWRkcjogc3RyaW5nIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIGlmICghYWRkcikgcmV0dXJuIGZhbHNlO1xuICAvLyBOb3JtYWxpemUgSVB2NC1tYXBwZWQgSVB2NiAoYDo6ZmZmZjoxMjcuMC4wLjFgKSBhbmQgYmFyZSBJUHY2IGxvb3BiYWNrLlxuICBjb25zdCBhID0gYWRkci5yZXBsYWNlKC9eOjpmZmZmOi8sIFwiXCIpO1xuICByZXR1cm4gYSA9PT0gXCIxMjcuMC4wLjFcIiB8fCBhLnN0YXJ0c1dpdGgoXCIxMjcuXCIpIHx8IGEgPT09IFwiOjoxXCIgfHwgYSA9PT0gXCJsb2NhbGhvc3RcIjtcbn1cblxuLyoqIFJlYWQgdGhlIHdob2xlIHJlcXVlc3QgYm9keSBhcyB0ZXh0IChzbWFsbCBKU09OIHBheWxvYWRzIG9ubHkpLiAqL1xuZnVuY3Rpb24gcmVhZEJvZHkocmVxOiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBsZXQgZGF0YSA9IFwiXCI7XG4gICAgcmVxLm9uKFwiZGF0YVwiLCAoY2h1bmspID0+IChkYXRhICs9IGNodW5rKSk7XG4gICAgcmVxLm9uKFwiZW5kXCIsICgpID0+IHJlc29sdmUoZGF0YSkpO1xuICAgIHJlcS5vbihcImVycm9yXCIsICgpID0+IHJlc29sdmUoZGF0YSkpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gc2VuZEpzb24ocmVzOiBTZXJ2ZXJSZXNwb25zZSwgc3RhdHVzOiBudW1iZXIsIGJvZHk6IHVua25vd24sIHNldENvb2tpZT86IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9O1xuICBpZiAoc2V0Q29va2llKSBoZWFkZXJzW1wic2V0LWNvb2tpZVwiXSA9IHNldENvb2tpZTtcbiAgcmVzLndyaXRlSGVhZChzdGF0dXMsIGhlYWRlcnMpO1xuICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBzdGFydFByb3h5fS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJveHlPcHRpb25zIHtcbiAgLyoqIFB1YmxpYyBwb3J0IHRvIGxpc3RlbiBvbiAodGhlIGNvbnRhaW5lcidzIERBVEFCUklDS1NfQVBQX1BPUlQpLiAqL1xuICBwdWJsaWNQb3J0OiBudW1iZXI7XG4gIC8qKiBQcml2YXRlIHBvcnQgdGhlIHJlYWwgYXBwIGxpc3RlbnMgb24gKGxvb3BiYWNrKS4gKi9cbiAgYXBwUG9ydDogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGluLXByb2Nlc3MgZ2F0ZSBBUEksIG9yIGB1bmRlZmluZWRgIHRvIHJ1biBPUEVOIChpbnNlY3VyZSBtb2RlKTogZXZlcnlcbiAgICogcmVxdWVzdCAtIGluY2x1ZGluZyBwb3J0ciB0cmFmZmljIC0gaXMgZm9yd2FyZGVkIHVuZ2F0ZWQuIFVzZWQgd2hlbiB0aGVcbiAgICogb3BlcmF0b3IgcGFzc2VkIGAtLWluc2VjdXJlYCAvIGBUVU5ORUxfSU5TRUNVUkU9dHJ1ZWAuXG4gICAqL1xuICBnYXRlPzogQXV0aEdhdGVBcGk7XG4gIC8qKlxuICAgKiBFeHRyYSBgeC1gIHJlcXVlc3QgaGVhZGVycyB0dW5uZWwgdHJhZmZpYyBtYXkgZm9yd2FyZCwgYXMgbGl0ZXJhbHMsIGdsb2JzLCBvclxuICAgKiBgL3JlZ2V4L2BlcyAtIHVuaW9uZWQgd2l0aCB7QGxpbmsgREVGQVVMVF9GT1JXQVJEX0hFQURFUlN9LiBFdmVyeSBvdGhlciBgeC1gXG4gICAqIGhlYWRlciBpcyBzdHJpcHBlZCwgYW5kIHtAbGluayBQUk9URUNURURfSEVBREVSU30gaXMgc3RyaXBwZWQgcmVnYXJkbGVzcy4gU2VlXG4gICAqIGAuL2hlYWRlcnMudHNgIGZvciB3aHkgdGhlIHBvbGljeSBpcyBhbiBhbGxvdy1saXN0LlxuICAgKi9cbiAgZm9yd2FyZEhlYWRlcnM/OiByZWFkb25seSBzdHJpbmdbXTtcbn1cblxuLyoqIFN0YXJ0IHRoZSBnYXRlIHByb3h5LiBSZXNvbHZlcyBvbmNlIGl0IGlzIGxpc3RlbmluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFByb3h5KHtcbiAgcHVibGljUG9ydCxcbiAgYXBwUG9ydCxcbiAgZ2F0ZSxcbiAgZm9yd2FyZEhlYWRlcnMsXG59OiBQcm94eU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJveHkgPSBQcm94eU1vZHVsZS5jcmVhdGVQcm94eVNlcnZlcih7XG4gICAgdGFyZ2V0OiB7IGhvc3Q6IFwiMTI3LjAuMC4xXCIsIHBvcnQ6IGFwcFBvcnQgfSxcbiAgICB3czogdHJ1ZSxcbiAgICB4ZndkOiB0cnVlLFxuICB9KTtcbiAgcHJveHkub24oXCJlcnJvclwiLCAoZXJyOiBFcnJvciwgX3JlcTogdW5rbm93biwgcmVzOiB1bmtub3duKSA9PiB7XG4gICAgbG9nZ2VyLndhcm4oXCJ1cHN0cmVhbSBwcm94eSBlcnJvclwiLCB7IGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBjb25zdCByID0gcmVzIGFzIFNlcnZlclJlc3BvbnNlIHwgdW5kZWZpbmVkO1xuICAgIGlmIChyICYmIFwid3JpdGVIZWFkXCIgaW4gciAmJiAhci5oZWFkZXJzU2VudCkge1xuICAgICAgc2VuZEpzb24ociwgNTAyLCB7IGVycm9yOiBcInVwc3RyZWFtIHVuYXZhaWxhYmxlXCIgfSk7XG4gICAgfVxuICB9KTtcblxuICAvLyBDb21waWxlZCBvbmNlOiB0aGUgaW5ib3VuZC1oZWFkZXIgYWxsb3ctbGlzdCBhcHBsaWVkIHRvIGV2ZXJ5IGdhdGVkIHJlcXVlc3QuXG4gIGNvbnN0IGhlYWRlclBvbGljeSA9IHRvSGVhZGVyUG9saWN5KGZvcndhcmRIZWFkZXJzKTtcbiAgbG9nZ2VyLmRlYnVnKFwiaW5ib3VuZCBoZWFkZXIgcG9saWN5XCIsIHsgZm9yd2FyZDogaGVhZGVyUG9saWN5LnBhdHRlcm5zIH0pO1xuXG4gIC8qKiBUaGUgc2Vzc2lvbiBjb29raWUgZm9yIGEgdmVyaWZpZWQgZW1haWwsIGFzIGEgU2V0LUNvb2tpZSBzdHJpbmcuICovXG4gIGNvbnN0IHNlc3Npb25Db29raWUgPSAodG9rZW46IHN0cmluZywgbWF4QWdlU2Vjb25kczogbnVtYmVyKTogc3RyaW5nID0+XG4gICAgW1xuICAgICAgYCR7U0VTU0lPTl9DT09LSUVfTkFNRX09JHt0b2tlbn1gLFxuICAgICAgXCJQYXRoPS9cIixcbiAgICAgIFwiSHR0cE9ubHlcIixcbiAgICAgIFwiU2FtZVNpdGU9TGF4XCIsXG4gICAgICBgTWF4LUFnZT0ke21heEFnZVNlY29uZHN9YCxcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInByb2R1Y3Rpb25cIiA/IFwiU2VjdXJlXCIgOiBcIlwiLFxuICAgIF1cbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKFwiOyBcIik7XG5cbiAgLyoqXG4gICAqIENsaWVudCBJUCBmb3IgcmF0ZS1saW1pdGluZzogdGhlIHBvcnRyIGNsaWVudCdzIGZvcndhcmRlZCBYRkYsIGVsc2UgdGhlIHNvY2tldC5cbiAgICpcbiAgICogRGVsaWJlcmF0ZWx5IHRoZSBSSUdIVE1PU1QgYHgtZm9yd2FyZGVkLWZvcmAgZW50cnksIG5vdCB0aGUgbGVmdG1vc3QuIFRoZVxuICAgKiBsaXN0IGdyb3dzIGxlZnQtdG8tcmlnaHQgYXMgZWFjaCBob3AgYXBwZW5kcywgc28gdGhlIGxhc3QgZW50cnkgaXMgdGhlIG9uZVxuICAgKiB0aGUgbmVhcmVzdCB0cnVzdGVkIHByb3h5IChwb3J0cikgd3JvdGUgYW5kIGV2ZXJ5IGVhcmxpZXIgZW50cnkgaXMgYSB2YWx1ZVxuICAgKiB0aGUgY2FsbGVyIGNvdWxkIGhhdmUgc2VudC4gUmVhZGluZyB0aGUgbGVmdG1vc3QgbGV0cyBhIGNsaWVudCB2YXJ5IG9uZVxuICAgKiBoZWFkZXIgdG8gZ2V0IGEgZnJlc2ggcmF0ZS1saW1pdCBidWNrZXQgcGVyIHJlcXVlc3QsIHdoaWNoIGRlZmVhdHMgYm90aCB0aGVcbiAgICogcGVyLUlQIGNvZGUtcmVxdWVzdCBhbmQgdmVyaWZ5LWF0dGVtcHQgbGltaXRlcnMuIENhbGxlZCBCRUZPUkVcbiAgICoge0BsaW5rIEhlYWRlclBvbGljeS5hcHBseX0gc3RyaXBzIHRoZSBoZWFkZXIsIHNvIHRoZSBob25lc3QgaG9wIHZhbHVlIGlzXG4gICAqIHN0aWxsIGF2YWlsYWJsZSBoZXJlLlxuICAgKi9cbiAgY29uc3QgY2xpZW50SXAgPSAocmVxOiBJbmNvbWluZ01lc3NhZ2UpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IGZvcndhcmRlZCA9IHJlcS5oZWFkZXJzW1wieC1mb3J3YXJkZWQtZm9yXCJdO1xuICAgIGNvbnN0IGNoYWluID0gKEFycmF5LmlzQXJyYXkoZm9yd2FyZGVkKSA/IGZvcndhcmRlZC5qb2luKFwiLFwiKSA6IChmb3J3YXJkZWQgPz8gXCJcIikpXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChlbnRyeSkgPT4gZW50cnkudHJpbSgpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICByZXR1cm4gY2hhaW4uYXQoLTEpID8/IHJlcS5zb2NrZXQucmVtb3RlQWRkcmVzcyA/PyBcInVua25vd25cIjtcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBjb29raWUgZnJvbSB0aGUgYENvb2tpZWAgaGVhZGVyIGJlZm9yZSBmb3J3YXJkaW5nLFxuICAgKiBzbyB0aGUgYXBwIG5ldmVyIHNlZXMgYGRieF9hdXRoYCAoaXQgaXMgdGhlIHByb3h5J3MgY29uY2Vybiwgbm90IHRoZSBhcHAncykuXG4gICAqIFByZXNlcnZlcyBhbnkgb3RoZXIgY29va2llcy4gUmVtb3ZlcyB0aGUgaGVhZGVyIGVudGlyZWx5IHdoZW4gaXQgYmVjb21lcyBlbXB0eS5cbiAgICovXG4gIGNvbnN0IHN0cmlwU2Vzc2lvbkNvb2tpZSA9IChyZXE6IEluY29taW5nTWVzc2FnZSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHJhdyA9IHJlcS5oZWFkZXJzLmNvb2tpZTtcbiAgICBpZiAoIXJhdykgcmV0dXJuO1xuICAgIGNvbnN0IGtlcHQgPSByYXdcbiAgICAgIC5zcGxpdChcIjtcIilcbiAgICAgIC5tYXAoKGMpID0+IGMudHJpbSgpKVxuICAgICAgLmZpbHRlcigoYykgPT4gYyAmJiAhYy5zdGFydHNXaXRoKGAke1NFU1NJT05fQ09PS0lFX05BTUV9PWApKTtcbiAgICBpZiAoa2VwdC5sZW5ndGgpIHJlcS5oZWFkZXJzLmNvb2tpZSA9IGtlcHQuam9pbihcIjsgXCIpO1xuICAgIGVsc2UgZGVsZXRlIHJlcS5oZWFkZXJzLmNvb2tpZTtcbiAgfTtcblxuICAvKipcbiAgICogUHJlc2VudCBhbiBPVFAtYXV0aGVudGljYXRlZCBjYWxsZXIgdG8gdGhlIGFwcCB0aGUgU0FNRSB3YXkgYSBwbGF0Zm9ybSBmcm9udFxuICAgKiBkb29yIGRvZXM6IHNldCB0aGUgZnJvbnQgZG9vcidzIG93biBpZGVudGl0eSBoZWFkZXJzIHRvIHRoZSB2ZXJpZmllZCBhZGRyZXNzXG4gICAqIChBcHBLaXQgcmVhZHMge0BsaW5rIHRva2VuLlVTRVJfSURfSEVBREVSfSBmb3IgdGhlIE9CTyB1c2VyIGlkKSwgc28gdGhlIGFwcFxuICAgKiBuZWVkcyBubyBnYXRlLXNwZWNpZmljIGNvZGUgcGF0aC4gVGhlIG5hbWVzIGNvbWUgZnJvbVxuICAgKiBgQGRieC10b29scy9zaGFyZWQtY29yZWAncyBgdG9rZW5gIG1vZHVsZSAtIHRoZSBzYW1lIGNvbnN0YW50cyBBcHBLaXQtc2lkZVxuICAgKiBjb2RlIHJlYWRzIHRoZW0gYnkgLSByYXRoZXIgdGhhbiBiZWluZyByZS1zcGVsbGVkIGhlcmUuXG4gICAqXG4gICAqIFdoYXQgdGhlIGdhdGUgQ0FOTk9UIHNldCBpcyB7QGxpbmsgdG9rZW4uQUNDRVNTX1RPS0VOX0hFQURFUn06IGFuIE9UUCBzZXNzaW9uXG4gICAqIHByb3ZlcyBhbiBlbWFpbCBhZGRyZXNzLCBub3QgcG9zc2Vzc2lvbiBvZiBhIERhdGFicmlja3MgY3JlZGVudGlhbCwgYW5kXG4gICAqIHRoZXJlIGlzIG5vIHdheSB0byBtaW50IG9uZSBmb3IgdGhlIGNhbGxlci4gSXRzIGFic2VuY2UgaXMgZXhhY3RseSB3aGF0XG4gICAqIGBAZGJ4LXRvb2xzL2FwcGtpdGAncyBgaWRlbnRpdHlgIGBcImF1dG9cImAgbW9kZSBkZXRlY3RzLCBzbyBhIGdhdGVkIHJlcXVlc3RcbiAgICogcnVucyBhcyB0aGUgYXBwJ3Mgc2VydmljZSBwcmluY2lwYWwgaW5zdGVhZCBvZiB0aHJvd2luZy5cbiAgICovXG4gIGNvbnN0IGluamVjdElkZW50aXR5ID0gKHJlcTogSW5jb21pbmdNZXNzYWdlLCBlbWFpbDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgcmVxLmhlYWRlcnNbdG9rZW4uVVNFUl9JRF9IRUFERVJdID0gZW1haWw7XG4gICAgcmVxLmhlYWRlcnNbdG9rZW4uVVNFUl9FTUFJTF9IRUFERVJdID0gZW1haWw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRoZSBpbmJvdW5kLWhlYWRlciBwb2xpY3kgdG8gYSB0dW5uZWwgcmVxdWVzdDogZXZlcnkgYHgtYCBoZWFkZXIgdGhlXG4gICAqIGFsbG93LWxpc3QgZG9lcyBub3QgbmFtZSBpcyBkZWxldGVkLCBhbmQgdGhlIHBsYXRmb3JtIGlkZW50aXR5L3RyYW5zcG9ydCBzZXRcbiAgICogaXMgZGVsZXRlZCByZWdhcmRsZXNzLiBTZWUgYC4vaGVhZGVycy50c2AgZm9yIHRoZSByZWFzb25pbmc7IHRoZVxuICAgKiBzZWN1cml0eS1jcml0aWNhbCBjYXNlIGlzIHtAbGluayB0b2tlbi5BQ0NFU1NfVE9LRU5fSEVBREVSfSwgd2hpY2ggdGhlIGdhdGVcbiAgICogbmV2ZXIgc2V0cyBidXQgYW4gYXBwIHJ1bm5pbmcgYGlkZW50aXR5OiBcImF1dG9cImAgdHJlYXRzIGFzIHByb29mIHRoZSByZXF1ZXN0XG4gICAqIGNhbiBkbyBPQk8uXG4gICAqXG4gICAqIGB4ZndkOiB0cnVlYCBvbiB0aGUgcHJveHkgcmUtYWRkcyBgeC1mb3J3YXJkZWQtZm9yYC9gLXByb3RvYC9gLXBvcnRgL2AtaG9zdGBcbiAgICogYWZ0ZXJ3YXJkcyBmcm9tIHRoZSByZWFsIHNvY2tldCwgc28gdGhlIGFwcCBzdGlsbCBzZWVzIHRob3NlIC0gaXQganVzdCBzZWVzXG4gICAqIHRoZSBob25lc3QgdmFsdWVzIHJhdGhlciB0aGFuIHRoZSBjYWxsZXIncyBjbGFpbS5cbiAgICovXG4gIGNvbnN0IGFwcGx5SGVhZGVyUG9saWN5ID0gKHJlcTogSW5jb21pbmdNZXNzYWdlKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVtb3ZlZCA9IGhlYWRlclBvbGljeS5hcHBseShyZXEuaGVhZGVycyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG4gICAgaWYgKHJlbW92ZWQubGVuZ3RoKSBsb2dnZXIuZGVidWcoXCJzdHJpcHBlZCBpbmJvdW5kIGhlYWRlcnNcIiwgeyByZW1vdmVkIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcihhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCBwYXRoID0gKHJlcS51cmwgPz8gXCIvXCIpLnNwbGl0KFwiP1wiKVswXSE7XG5cbiAgICAvLyBJbnNlY3VyZS9vcGVuIG1vZGUgKG5vIGdhdGUpIE9SIG5vbi1sb29wYmFjayB0cmFmZmljICh0aGUgaG9zdGluZ1xuICAgIC8vIHBsYXRmb3JtJ3MgZnJvbnQgZG9vciAvIGNvbnRyb2wgcGxhbmUpOiBmb3J3YXJkIHVuZ2F0ZWQuXG4gICAgaWYgKCFnYXRlIHx8ICFpc0xvb3BiYWNrKHJlcS5zb2NrZXQucmVtb3RlQWRkcmVzcykpIHtcbiAgICAgIHByb3h5LndlYihyZXEsIHJlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gLS0tIHBvcnRyIHRyYWZmaWM6IHRoZSBnYXRlIGFwcGxpZXMgLS0tXG5cbiAgICAvLyBUaGUgbG9naW4gZmxvdyBpcyBhbnN3ZXJlZCBJTi1QUk9DRVNTICh0aGUgYXBwIGhhcyBubyBzZXJ2ZXIgdG8gZm9yd2FyZCB0bykuXG4gICAgaWYgKHBhdGggPT09IGAke0FVVEhfUFJFRklYfS9zdGF0dXNgKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IGh0dHAucGFyc2VDb29raWVzKHJlcS5oZWFkZXJzLmNvb2tpZSA/PyBudWxsKVtTRVNTSU9OX0NPT0tJRV9OQU1FXTtcbiAgICAgIHNlbmRKc29uKHJlcywgMjAwLCBhd2FpdCBnYXRlLnN0YXR1cyh0b2tlbikpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAocGF0aCA9PT0gYCR7QVVUSF9QUkVGSVh9L3JlcXVlc3RgICYmIHJlcS5tZXRob2QgPT09IFwiUE9TVFwiKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBhdXRoUmVxdWVzdFNjaGVtYS5zYWZlUGFyc2UoanNvbi5wYXJzZVJlY29yZChhd2FpdCByZWFkQm9keShyZXEpKSk7XG4gICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSByZXR1cm4gc2VuZEpzb24ocmVzLCAyMDAsIHsgb2s6IHRydWUgfSk7IC8vIGFudGktZW51bWVyYXRpb25cbiAgICAgIHJldHVybiBzZW5kSnNvbihyZXMsIDIwMCwgYXdhaXQgZ2F0ZS5yZXF1ZXN0KHBhcnNlZC5kYXRhLmVtYWlsLCBjbGllbnRJcChyZXEpKSk7XG4gICAgfVxuICAgIGlmIChwYXRoID09PSBgJHtBVVRIX1BSRUZJWH0vdmVyaWZ5YCAmJiByZXEubWV0aG9kID09PSBcIlBPU1RcIikge1xuICAgICAgY29uc3QgcGFyc2VkID0gYXV0aFZlcmlmeVNjaGVtYS5zYWZlUGFyc2UoanNvbi5wYXJzZVJlY29yZChhd2FpdCByZWFkQm9keShyZXEpKSk7XG4gICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSByZXR1cm4gc2VuZEpzb24ocmVzLCAyMDAsIHsgb2s6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2F0ZS52ZXJpZnkocGFyc2VkLmRhdGEuZW1haWwsIHBhcnNlZC5kYXRhLmNvZGUsIGNsaWVudElwKHJlcSkpO1xuICAgICAgY29uc3QgY29va2llID1cbiAgICAgICAgcmVzdWx0Lm9rICYmIHJlc3VsdC50b2tlbiA/IHNlc3Npb25Db29raWUocmVzdWx0LnRva2VuLCBnYXRlLnNlc3Npb25UdGxTZWNvbmRzKSA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBzZW5kSnNvbihcbiAgICAgICAgcmVzLFxuICAgICAgICAyMDAsXG4gICAgICAgIHsgb2s6IHJlc3VsdC5vaywgLi4uKHJlc3VsdC5yZXRyeUFmdGVyID8geyByZXRyeUFmdGVyOiByZXN1bHQucmV0cnlBZnRlciB9IDoge30pIH0sXG4gICAgICAgIGNvb2tpZSxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChwYXRoID09PSBgJHtBVVRIX1BSRUZJWH0vbG9nb3V0YCAmJiByZXEubWV0aG9kID09PSBcIlBPU1RcIikge1xuICAgICAgcmV0dXJuIHNlbmRKc29uKFxuICAgICAgICByZXMsXG4gICAgICAgIDIwMCxcbiAgICAgICAgeyBvazogdHJ1ZSB9LFxuICAgICAgICBgJHtTRVNTSU9OX0NPT0tJRV9OQU1FfT07IFBhdGg9LzsgSHR0cE9ubHk7IE1heC1BZ2U9MGAsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEFudGktc3Bvb2Y6IGFwcGx5IHRoZSBpbmJvdW5kLWhlYWRlciBhbGxvdy1saXN0IHRvIHBvcnRyIHRyYWZmaWMgLSBvbmx5IHRoZVxuICAgIC8vIGdhdGUgbWF5IGFzc2VydCBpZGVudGl0eSwgYW5kIGl0IGRvZXMgc28gYmVsb3cgZm9yIGEgdmVyaWZpZWQgc2Vzc2lvbi5cbiAgICBhcHBseUhlYWRlclBvbGljeShyZXEpO1xuXG4gICAgLy8gU3RhdGljIChub24tQVBJKSBsb2FkcyBmcmVlbHkgc28gdGhlIFNQQSArIDxBdXRoR2F0ZT4gY2FuIHJlbmRlci4gU3RyaXAgdGhlXG4gICAgLy8gc2Vzc2lvbiBjb29raWUgc28gaXQgbmV2ZXIgbGVha3MgdG8gdGhlIHN0YXRpYyBoYW5kbGVyLlxuICAgIGlmICghcGF0aC5zdGFydHNXaXRoKFwiL2FwaS9cIikpIHtcbiAgICAgIHN0cmlwU2Vzc2lvbkNvb2tpZShyZXEpO1xuICAgICAgcHJveHkud2ViKHJlcSwgcmVzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBFdmVyeSBvdGhlciAvYXBpLyogcmVxdWlyZXMgYSB2YWxpZCBzZXNzaW9uLlxuICAgIGNvbnN0IHRva2VuID0gaHR0cC5wYXJzZUNvb2tpZXMocmVxLmhlYWRlcnMuY29va2llID8/IG51bGwpW1NFU1NJT05fQ09PS0lFX05BTUVdO1xuICAgIGNvbnN0IGVtYWlsID0gYXdhaXQgZ2F0ZS5zZXNzaW9uKHRva2VuKTtcbiAgICBpZiAoZW1haWwpIHtcbiAgICAgIC8vIFByZXNlbnQgdGhlIE9UUCB1c2VyIGxpa2UgYSBwbGF0Zm9ybSBmcm9udCBkb29yLCBhbmQgZHJvcCB0aGUgZ2F0ZVxuICAgICAgLy8gY29va2llIHNvIHRoZSBhcHAgc2VlcyBhIGNsZWFuLCBmcm9udC1kb29yLXNoYXBlZCByZXF1ZXN0LlxuICAgICAgaW5qZWN0SWRlbnRpdHkocmVxLCBlbWFpbCk7XG4gICAgICBzdHJpcFNlc3Npb25Db29raWUocmVxKTtcbiAgICAgIHByb3h5LndlYihyZXEsIHJlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbmRKc29uKHJlcywgNDAxLCB7IGVycm9yOiBcImF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkXCIsIGxvZ2luUGF0aDogQVVUSF9QUkVGSVggfSk7XG4gICAgfVxuICB9KTtcblxuICAvLyBXZWJTb2NrZXQgdXBncmFkZXM6IGZvcndhcmQgZnJvbnQtZG9vciB0cmFmZmljIHVudG91Y2hlZDsgZ2F0ZSBsb29wYmFja1xuICAvLyAocG9ydHIpIEFQSSB1cGdyYWRlcyB0aGUgc2FtZSB3YXkgYXMgSFRUUCAoc3RyaXAgY29va2llICsgaW5qZWN0IGlkZW50aXR5KS5cbiAgc2VydmVyLm9uKFwidXBncmFkZVwiLCAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHNvY2tldDogU29ja2V0LCBoZWFkOiBCdWZmZXIpID0+IHtcbiAgICBpZiAoIWdhdGUgfHwgIWlzTG9vcGJhY2socmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzKSkge1xuICAgICAgcHJveHkud3MocmVxLCBzb2NrZXQsIGhlYWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhcHBseUhlYWRlclBvbGljeShyZXEpO1xuICAgIGlmICghKHJlcS51cmwgPz8gXCJcIikuc3RhcnRzV2l0aChcIi9hcGkvXCIpKSB7XG4gICAgICBzdHJpcFNlc3Npb25Db29raWUocmVxKTtcbiAgICAgIHByb3h5LndzKHJlcSwgc29ja2V0LCBoZWFkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBodHRwLnBhcnNlQ29va2llcyhyZXEuaGVhZGVycy5jb29raWUgPz8gbnVsbClbU0VTU0lPTl9DT09LSUVfTkFNRV07XG4gICAgdm9pZCBnYXRlLnNlc3Npb24odG9rZW4pLnRoZW4oKGVtYWlsKSA9PiB7XG4gICAgICBpZiAoIWVtYWlsKSB7XG4gICAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGluamVjdElkZW50aXR5KHJlcSwgZW1haWwpO1xuICAgICAgc3RyaXBTZXNzaW9uQ29va2llKHJlcSk7XG4gICAgICBwcm94eS53cyhyZXEsIHNvY2tldCwgaGVhZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHNlcnZlci5saXN0ZW4ocHVibGljUG9ydCwgXCIwLjAuMC4wXCIsICgpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGBnYXRlIHByb3h5IG9uIDAuMC4wLjA6JHtwdWJsaWNQb3J0fSAtPiBhcHAgMTI3LjAuMC4xOiR7YXBwUG9ydH1gKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXX0=
@@ -1 +1 @@
1
- {"root":["../src/allowlist.ts","../src/app.ts","../src/cli.ts","../src/otp.ts","../src/plugin.ts","../src/portr.ts","../src/proxy.ts","../src/rate-limit.ts","../index.ts","../bin/dbx-tools-tunnel.ts"],"version":"5.9.3"}
1
+ {"root":["../src/allowlist.ts","../src/app.ts","../src/cli.ts","../src/env.ts","../src/headers.ts","../src/otp.ts","../src/plugin.ts","../src/portr.ts","../src/proxy.ts","../src/rate-limit.ts","../index.ts","../bin/dbx-tools-tunnel.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@clack/prompts": "^1.7.0",
31
31
  "@databricks/appkit": "^0.43.0",
32
- "@dbx-tools/appkit": "0.6.48",
33
- "@dbx-tools/core": "0.6.48",
34
- "@dbx-tools/email": "0.6.48",
35
- "@dbx-tools/shared-core": "0.6.48",
36
- "@dbx-tools/shared-email": "0.6.48",
32
+ "@dbx-tools/appkit": "0.6.49",
33
+ "@dbx-tools/core": "0.6.49",
34
+ "@dbx-tools/email": "0.6.49",
35
+ "@dbx-tools/shared-core": "0.6.49",
36
+ "@dbx-tools/shared-email": "0.6.49",
37
37
  "commander": "^15.0.0",
38
38
  "http-proxy-3": "^1.23.3",
39
39
  "jose": "^6.2.3"
@@ -65,6 +65,14 @@
65
65
  "types": "./lib/src/cli.d.ts",
66
66
  "default": "./lib/src/cli.js"
67
67
  },
68
+ "./env": {
69
+ "types": "./lib/src/env.d.ts",
70
+ "default": "./lib/src/env.js"
71
+ },
72
+ "./headers": {
73
+ "types": "./lib/src/headers.d.ts",
74
+ "default": "./lib/src/headers.js"
75
+ },
68
76
  "./otp": {
69
77
  "types": "./lib/src/otp.d.ts",
70
78
  "default": "./lib/src/otp.js"
@@ -88,7 +96,7 @@
88
96
  "./package.json": "./package.json"
89
97
  }
90
98
  },
91
- "version": "0.6.48",
99
+ "version": "0.6.49",
92
100
  "types": "./lib/index.d.ts",
93
101
  "type": "module",
94
102
  "exports": {
@@ -108,6 +116,14 @@
108
116
  "types": "./lib/src/cli.d.ts",
109
117
  "default": "./lib/src/cli.js"
110
118
  },
119
+ "./env": {
120
+ "types": "./lib/src/env.d.ts",
121
+ "default": "./lib/src/env.js"
122
+ },
123
+ "./headers": {
124
+ "types": "./lib/src/headers.d.ts",
125
+ "default": "./lib/src/headers.js"
126
+ },
111
127
  "./otp": {
112
128
  "types": "./lib/src/otp.d.ts",
113
129
  "default": "./lib/src/otp.js"
package/src/allowlist.ts CHANGED
@@ -1,17 +1,22 @@
1
1
  /**
2
2
  * Unified access allow-list matching for the email-OTP gate.
3
3
  *
4
- * Each pattern in the configured list is one of three shapes, tried in order:
4
+ * Each pattern in the configured list is one of three shapes:
5
5
  *
6
6
  * - **domain shortcut** - `example.com` or `@example.com`: matches any
7
- * address whose domain equals it (case-insensitive). The leading `@` is
8
- * optional and stripped.
9
- * - **glob** - contains `*` or `?`, e.g. `*.example.com` or
10
- * `*@example.com`: matched against the WHOLE address with shell-style
11
- * wildcards (`*` = any run, `?` = one char).
12
- * - **regex** - wrapped in slashes, `/.../ [flags]`: compiled and tested
13
- * against the whole address. An invalid regex never matches (it is skipped
14
- * with a warning rather than throwing).
7
+ * address whose domain equals it. This is the gate's OWN semantic (a bare
8
+ * value means "the domain", not "the whole address"), so it is handled here.
9
+ * - **glob** - contains `*` or `?`, e.g. `*@example.com`: matched against the
10
+ * WHOLE address with shell-style wildcards.
11
+ * - **regex** - wrapped in slashes, `/.../ [flags]`: tested against the whole
12
+ * address. An invalid regex never matches (it is skipped with a warning
13
+ * rather than throwing).
14
+ *
15
+ * Only the first shape is this module's business: the glob and regex shapes are
16
+ * delegated to `@dbx-tools/shared-core`'s {@link pattern.toPattern}, which is
17
+ * where that compilation lives for every allow-list in the repo (the tunnel's
18
+ * inbound-header policy uses the same one). Matching is case-insensitive
19
+ * throughout.
15
20
  *
16
21
  * An EMPTY list matches nobody (fail closed): an app that enables the gate but
17
22
  * configures no patterns lets no one in, which is the safe default.
@@ -19,58 +24,25 @@
19
24
  * @module
20
25
  */
21
26
 
22
- import { log } from "@dbx-tools/shared-core";
23
-
24
- const logger = log.logger("tunnel:allowlist");
25
-
26
- /** Escape a string for literal use inside a `RegExp`. */
27
- function escapeRegExp(value: string): string {
28
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29
- }
30
-
31
- /** Compile a shell-style glob (`*`, `?`) into an anchored, case-insensitive RegExp. */
32
- function globToRegExp(glob: string): RegExp {
33
- const body = glob
34
- .split(/([*?])/)
35
- .map((part) => (part === "*" ? ".*" : part === "?" ? "." : escapeRegExp(part)))
36
- .join("");
37
- return new RegExp(`^${body}$`, "i");
38
- }
39
-
40
- /** Parse a `/pattern/flags` string into a RegExp, or `undefined` if malformed. */
41
- function parseRegexLiteral(pattern: string): RegExp | undefined {
42
- const match = /^\/(.+)\/([a-z]*)$/is.exec(pattern);
43
- if (!match) return undefined;
44
- try {
45
- const flags = match[2]!.includes("i") ? match[2]! : `${match[2]!}i`;
46
- return new RegExp(match[1]!, flags);
47
- } catch (error) {
48
- logger.warn("ignoring invalid regex allow-list pattern", { pattern, error });
49
- return undefined;
50
- }
51
- }
27
+ import { pattern } from "@dbx-tools/shared-core";
52
28
 
53
29
  /** True when `email` matches a single allow-list `pattern`. */
54
- function matchesPattern(email: string, pattern: string): boolean {
55
- const trimmed = pattern.trim();
30
+ function matchesPattern(email: string, entry: string): boolean {
31
+ const trimmed = entry.trim();
56
32
  if (!trimmed) return false;
57
33
  const address = email.trim().toLowerCase();
58
34
 
59
- // Regex literal: /.../
60
- if (trimmed.startsWith("/")) {
61
- const re = parseRegexLiteral(trimmed);
62
- return re ? re.test(address) : false;
63
- }
64
-
65
- // Glob: contains a wildcard.
66
- if (trimmed.includes("*") || trimmed.includes("?")) {
67
- return globToRegExp(trimmed).test(address);
35
+ // A bare value with no wildcard and no regex delimiters is a DOMAIN shortcut,
36
+ // the one shape shared-core cannot infer: there it would mean whole-string
37
+ // equality against the address, which is never what an operator writing
38
+ // `example.com` in an access list intends.
39
+ if (!trimmed.startsWith("/") && !trimmed.includes("*") && !trimmed.includes("?")) {
40
+ const domain = trimmed.replace(/^@/, "").toLowerCase();
41
+ const at = address.lastIndexOf("@");
42
+ return at >= 0 && address.slice(at + 1) === domain;
68
43
  }
69
44
 
70
- // Domain shortcut: `@d.com` or `d.com` -> match the address's domain.
71
- const domain = trimmed.replace(/^@/, "").toLowerCase();
72
- const at = address.lastIndexOf("@");
73
- return at >= 0 && address.slice(at + 1) === domain;
45
+ return pattern.toPattern(trimmed)?.(address) ?? false;
74
46
  }
75
47
 
76
48
  /**
@@ -79,7 +51,7 @@ function matchesPattern(email: string, pattern: string): boolean {
79
51
  */
80
52
  export function matchesAllowlist(email: string, patterns: readonly string[] | undefined): boolean {
81
53
  if (!email || !patterns || patterns.length === 0) return false;
82
- return patterns.some((pattern) => matchesPattern(email, pattern));
54
+ return patterns.some((entry) => matchesPattern(email, entry));
83
55
  }
84
56
 
85
57
  /** Rough shape check so a clearly-invalid address is rejected before any work. */