@dbx-tools/cli-tunnel 0.6.95 → 0.6.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/src/cli.js CHANGED
@@ -69,6 +69,8 @@ function addOptions(command) {
69
69
  .option("--auth-storage <mode>", "auth database: auto, lakebase, or sqlite")
70
70
  .option("--auth-sqlite-path <path>", "local Better Auth SQLite file")
71
71
  .option("--forward-headers <patterns...>", "extra x- headers tunnel traffic may forward")
72
+ .option("--gate-path <prefix...>", "path prefixes to gate beyond /api/ (e.g. /ws)")
73
+ .option("--bind <host...>", "interface IPs the gate listens on (default: 0.0.0.0)")
72
74
  .option("--insecure", "run open, with no gate");
73
75
  }
74
76
  /**
@@ -96,25 +98,36 @@ function supervise(children) {
96
98
  }
97
99
  async function run(raw, command) {
98
100
  const [executable, ...args] = command;
99
- if (!executable) {
100
- throw new CommanderError(1, "tunnel.no-command", "no command given - pass it after `--`");
101
- }
102
101
  const resolved = resolveTunnelOptions(raw);
103
- // The wrapped app must not be reachable from outside: it binds loopback on a
104
- // private port, and the wrapper is the only thing that talks to it. An
105
- // unresolved `--app-port` becomes a free ephemeral port rather than a fixed
106
- // guess, so two tunnels can run side by side.
107
- const appPort = resolved.appPort ?? (await freePort());
108
- const app = spawn(executable, args, {
109
- env: {
110
- ...process.env,
111
- DATABRICKS_APP_PORT: String(appPort),
112
- PORT: String(appPort),
113
- HOST: "127.0.0.1",
114
- },
115
- stdio: "inherit",
116
- });
117
- const children = [app];
102
+ const children = [];
103
+ // Two upstream modes:
104
+ // - WRAP: a command after `--`. The wrapper spawns it on a private loopback
105
+ // port and is the only thing that talks to it.
106
+ // - ATTACH: no command, but `--app-port` names an already-running upstream
107
+ // (e.g. a local reverse proxy). The gate fronts it without spawning a
108
+ // child. This is what lets the gate sit on an interface in front of a
109
+ // separately-supervised stack.
110
+ let appPort;
111
+ if (executable) {
112
+ appPort = resolved.appPort ?? (await freePort());
113
+ const app = spawn(executable, args, {
114
+ env: {
115
+ ...process.env,
116
+ DATABRICKS_APP_PORT: String(appPort),
117
+ PORT: String(appPort),
118
+ HOST: "127.0.0.1",
119
+ },
120
+ stdio: "inherit",
121
+ });
122
+ children.push(app);
123
+ }
124
+ else if (resolved.appPort) {
125
+ appPort = resolved.appPort;
126
+ logger.info("attaching gate to existing upstream", { appPort });
127
+ }
128
+ else {
129
+ throw new CommanderError(1, "tunnel.no-upstream", "no command given (pass it after `--`) and no --app-port to attach to");
130
+ }
118
131
  // Dynamic import: the gate is the only thing here that needs AppKit + SMTP, so
119
132
  // an `--insecure` run never loads either.
120
133
  const gate = resolved.gate.insecure
@@ -130,6 +143,9 @@ async function run(raw, command) {
130
143
  appPort,
131
144
  gate,
132
145
  forwardHeaders: resolved.gate.forwardHeaders,
146
+ gatePaths: resolved.gate.gatePaths,
147
+ brandName: resolved.gate.brandName,
148
+ bindHosts: resolved.bindHosts,
133
149
  });
134
150
  if (resolved.portr) {
135
151
  const portrEnv = await portr.installPortr();
@@ -176,4 +192,4 @@ export function buildProgram(name = "dbx tunnel") {
176
192
  });
177
193
  return program;
178
194
  }
179
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxjQUFjLENBQUM7QUFDeEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxpRkFBaUY7QUFDakYsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFFaEM7Ozs7R0FJRztBQUNILFNBQVMsUUFBUTtJQUNmLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsTUFBTSxLQUFLLEdBQUcsWUFBWSxFQUFFLENBQUM7UUFDN0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTtZQUNoQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZFLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxPQUFnQjtJQUNsQyxPQUFPLE9BQU87U0FDWCxNQUFNLENBQUMsd0JBQXdCLEVBQUUsNENBQTRDLENBQUM7U0FDOUUsTUFBTSxDQUFDLG9CQUFvQixFQUFFLHVEQUF1RCxDQUFDO1NBQ3JGLE1BQU0sQ0FBQyxlQUFlLEVBQUUsb0NBQW9DLENBQUM7U0FDN0QsTUFBTSxDQUFDLG1CQUFtQixFQUFFLDhDQUE4QyxDQUFDO1NBQzNFLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSw0Q0FBNEMsQ0FBQztTQUM3RSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsNEJBQTRCLENBQUM7U0FDeEQsTUFBTSxDQUFDLHFCQUFxQixFQUFFLCtCQUErQixDQUFDO1NBQzlELE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSw0QkFBNEIsQ0FBQztTQUN4RCxNQUFNLENBQUMseUJBQXlCLEVBQUUsa0JBQWtCLENBQUM7U0FDckQsTUFBTSxDQUFDLHNCQUFzQixFQUFFLHdCQUF3QixDQUFDO1NBQ3hELE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSw2Q0FBNkMsQ0FBQztTQUNoRixNQUFNLENBQUMsdUJBQXVCLEVBQUUsMENBQTBDLENBQUM7U0FDM0UsTUFBTSxDQUFDLDJCQUEyQixFQUFFLCtCQUErQixDQUFDO1NBQ3BFLE1BQU0sQ0FBQyxpQ0FBaUMsRUFBRSw2Q0FBNkMsQ0FBQztTQUN4RixNQUFNLENBQUMsWUFBWSxFQUFFLHdCQUF3QixDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxTQUFTLENBQUMsUUFBaUM7SUFDbEQsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBWSxFQUFRLEVBQUU7UUFDbEMsSUFBSSxRQUFRO1lBQUUsT0FBTztRQUNyQixRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ2hCLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUTtZQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDbEUsQ0FBQyxDQUFDO0lBQ0YsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRO1FBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRSxLQUFLLE1BQU0sTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQVUsRUFBRSxDQUFDO1FBQzlELE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7QUFDSCxDQUFDO0FBRUQsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQixFQUFFLE9BQTBCO0lBQy9ELE1BQU0sQ0FBQyxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUM7SUFDdEMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sSUFBSSxjQUFjLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLHVDQUF1QyxDQUFDLENBQUM7SUFDNUYsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTNDLDZFQUE2RTtJQUM3RSx1RUFBdUU7SUFDdkUsNEVBQTRFO0lBQzVFLDhDQUE4QztJQUM5QyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFO1FBQ2xDLEdBQUcsRUFBRTtZQUNILEdBQUcsT0FBTyxDQUFDLEdBQUc7WUFDZCxtQkFBbUIsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQ3BDLElBQUksRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQ3JCLElBQUksRUFBRSxXQUFXO1NBQ2xCO1FBQ0QsS0FBSyxFQUFFLFNBQVM7S0FDakIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxRQUFRLEdBQW1CLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFdkMsK0VBQStFO0lBQy9FLDBDQUEwQztJQUMxQyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVE7UUFDakMsQ0FBQyxDQUFDLFNBQVM7UUFDWCxDQUFDLENBQUMsTUFBTSxDQUNKLE1BQU0sTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUN6QixDQUFDLFlBQVksQ0FBQztZQUNiLEdBQUcsUUFBUSxDQUFDLFVBQVU7WUFDdEIsWUFBWSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLGFBQWEsUUFBUSxDQUFDLFVBQVUsRUFBRTtTQUMvRSxDQUFDLENBQUM7SUFDUCxJQUFJLENBQUMsSUFBSTtRQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsbURBQW1ELENBQUMsQ0FBQztJQUU1RSxNQUFNLFVBQVUsQ0FBQztRQUNmLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtRQUMvQixPQUFPO1FBQ1AsSUFBSTtRQUNKLGNBQWMsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLGNBQWM7S0FDN0MsQ0FBQyxDQUFDO0lBRUgsSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkIsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDNUMsTUFBTSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RCxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEUsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLENBQUMsSUFBSSxDQUFDLDhEQUE4RCxFQUFFO1lBQzFFLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtTQUNoQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCw4REFBOEQ7QUFDOUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUFJLEdBQUcsWUFBWTtJQUM5QyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQ3hCLElBQUksT0FBTyxFQUFFO1NBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNWLFdBQVcsQ0FBQywyREFBMkQsQ0FBQyxDQUM1RSxDQUFDO0lBRUYsZ0ZBQWdGO0lBQ2hGLDJFQUEyRTtJQUMzRSx3REFBd0Q7SUFDeEQsT0FBTztTQUNKLFFBQVEsQ0FBQyxjQUFjLEVBQUUsaUNBQWlDLENBQUM7U0FDM0QsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFpQixFQUFFLFFBQXVCLEVBQUUsR0FBWSxFQUFFLEVBQUU7UUFDekUsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNoRCxDQUFDLENBQUMsQ0FBQztJQUVMLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1NBQ2xGLFFBQVEsQ0FBQyxjQUFjLEVBQUUsaUNBQWlDLENBQUM7U0FDM0QsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFpQixFQUFFLFFBQXVCLEVBQUUsR0FBWSxFQUFFLEVBQUU7UUFDekUsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNoRCxDQUFDLENBQUMsQ0FBQztJQUVMLDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsK0NBQStDO0lBQy9DLFVBQVUsQ0FDUixPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVcsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUNoRixDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQXVCLEVBQUUsR0FBWSxFQUFFLEVBQUU7UUFDakQsTUFBTSxRQUFRLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksRUFBaUIsQ0FBQyxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFdBQVcsQ0FBQyxtQ0FBbUMsQ0FBQztTQUNoRCxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDakIsTUFBTSxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgZGJ4IHR1bm5lbGAgLSBmcm9udCBhIGNvbW1hbmQgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgYW5kIHBhc3N3b3JkbGVzcyBnYXRlLlxuICpcbiAqIFRoaXMgaXMgdGhlIFdSQVBQRVIgcGF0aCwgYW5kIGl0IGV4aXN0cyBmb3Igb25lIGNhc2U6IGEgcHJvamVjdCB0aGF0IGRvZXMgbm90XG4gKiB1c2UgYEBkYngtdG9vbHMvYXBwa2l0YCdzIGBjcmVhdGVBcHBgLCBhbmQgdGhlcmVmb3JlIGNhbm5vdCByZWdpc3RlclxuICogYHR1bm5lbEludGVyY2VwdG9yKClgICsgdGhlIGBhdXRoR2F0ZWAgcGx1Z2luIGluLXByb2Nlc3MuIEFuIEFwcEtpdCBhcHAgc2hvdWxkXG4gKiBzdGlsbCB0YWtlIHRoZSBwbHVnaW4gcGF0aCAtIG9uZSBwcm9jZXNzLCBubyBwcm94eSBob3AsIG5vIGR1cGxpY2F0ZWQgaGVhZGVyXG4gKiBoYW5kbGluZy5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IChgREFUQUJSSUNLU19BUFBfUE9SVGAsIHRoZSBwb3J0IHRoZVxuICogcGxhdGZvcm0gYW5kIHBvcnRyIHJvdXRlIHRvKSwgbW92ZXMgdGhlIHdyYXBwZWQgYXBwIHRvIGEgcHJpdmF0ZSBvbmUsIGFuZFxuICogcmV2ZXJzZS1wcm94aWVzIGJldHdlZW4gdGhlbSBzbyB0aGUgZ2F0ZSBzaXRzIGluIGZyb250IG9mIHRyYWZmaWMgaXQgd291bGRcbiAqIG90aGVyd2lzZSBoYXZlIG5vIHdheSB0byBpbnRlcmNlcHQuIEV2ZXJ5dGhpbmcgZWxzZSBpcyBkZWxlZ2F0ZWQ6IHRoZSBnYXRlXG4gKiBjb25maWcgY29tZXMgZnJvbSBgcGx1Z2luLnJlc29sdmVBdXRoR2F0ZUNvbmZpZ2AsIHRoZSBwb3J0ciBsaWZlY3ljbGUgZnJvbVxuICogYHBvcnRyLipgIC0gYm90aCB0aGUgc2FtZSBmdW5jdGlvbnMgdGhlIGluLXByb2Nlc3MgcGF0aCB1c2VzLlxuICpcbiAqIFNoaXBzIG5vIGJpbi4gYEBkYngtdG9vbHMvY2xpYCBtb3VudHMgYGJ1aWxkUHJvZ3JhbSgpYCBhcyBgZGJ4IHR1bm5lbGAgbGF6aWx5LFxuICogc28gYGRieCBkZXZgIHBheXMgZm9yIG5vbmUgb2YgdGhpcywgYW5kIGAtLWluc2VjdXJlYCAvIGBzdGF0dXNgIC8gYGluc3RhbGxgXG4gKiBuZXZlciBsb2FkIEFwcEtpdCBvciB0aGUgU01UUCBzdGFjayBlaXRoZXIgKHRoZSBnYXRlIGFwcCBpcyBiZWhpbmQgYSBkeW5hbWljXG4gKiBpbXBvcnQpLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBwb3J0ciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyByZXNvbHZlVHVubmVsT3B0aW9ucywgdHlwZSBUdW5uZWxPcHRpb25zIH0gZnJvbSBcIi4vb3B0aW9ucy50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBIb3cgbG9uZyBhIGNoaWxkIGdldHMgdG8gZXhpdCBvbiBTSUdURVJNIGJlZm9yZSB0aGUgd3JhcHBlciBsZWF2ZXMgYW55d2F5LiAqL1xuY29uc3QgU0hVVERPV05fR1JBQ0VfTVMgPSAzXzAwMDtcblxuLyoqXG4gKiBBIGZyZWUgbG9vcGJhY2sgcG9ydCwgZnJvbSB0aGUgT1MgcmF0aGVyIHRoYW4gYSByYW5kb20gZ3Vlc3M6IGJpbmRpbmcgYDBgIGFuZFxuICogcmVhZGluZyBiYWNrIHdoYXQgd2FzIGFzc2lnbmVkIGlzIHRoZSBvbmx5IHdheSB0byBrbm93IHRoZSBwb3J0IGlzIGFjdHVhbGx5XG4gKiBhdmFpbGFibGUsIHNvIHR3byB0dW5uZWxzIGNhbiBydW4gc2lkZSBieSBzaWRlIHdpdGhvdXQgY29sbGlkaW5nLlxuICovXG5mdW5jdGlvbiBmcmVlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb2JlID0gY3JlYXRlU2VydmVyKCk7XG4gICAgcHJvYmUub24oXCJlcnJvclwiLCByZWplY3QpO1xuICAgIHByb2JlLmxpc3RlbigwLCBcIjEyNy4wLjAuMVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvYmUuYWRkcmVzcygpO1xuICAgICAgY29uc3QgcG9ydCA9IHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiICYmIGFkZHJlc3MgPyBhZGRyZXNzLnBvcnQgOiAwO1xuICAgICAgcHJvYmUuY2xvc2UoKCkgPT4gKHBvcnQgPiAwID8gcmVzb2x2ZShwb3J0KSA6IHJlamVjdChuZXcgRXJyb3IoXCJubyBmcmVlIHBvcnRcIikpKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV2ZXJ5IGdhdGUvcG9ydHIgZmxhZy4gRGVjbGFyZWQgb24gdGhlIHJvb3QgY29tbWFuZCBBTkQgb24gYHJ1bmAvYHN0YXR1c2Agc29cbiAqIGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBjbWRgIGFuZCBgZGJ4IHR1bm5lbCBydW4gLS1hbGxvdyB4IC0tIGNtZGAgYmVoYXZlXG4gKiBpZGVudGljYWxseSAtIGNvbW1hbmRlciBkb2VzIG5vdCBpbmhlcml0IG9wdGlvbnMgZG93bndhcmQuXG4gKi9cbmZ1bmN0aW9uIGFkZE9wdGlvbnMoY29tbWFuZDogQ29tbWFuZCk6IENvbW1hbmQge1xuICByZXR1cm4gY29tbWFuZFxuICAgIC5vcHRpb24oXCItLXB1YmxpYy1kb21haW4gPGhvc3Q+XCIsIFwicG9ydHIgcHVibGljIGRvbWFpbiAoPHN1YmRvbWFpbj4uPHNlcnZlcj4pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViZG9tYWluIDxuYW1lPlwiLCBcInBvcnRyIHN1YmRvbWFpbiAoZWxzZSBkZXJpdmVkIGZyb20gdGhlIHB1YmxpYyBkb21haW4pXCIpXG4gICAgLm9wdGlvbihcIi0tcG9ydCA8cG9ydD5cIiwgXCJwdWJsaWMgcG9ydCB0aGUgd3JhcHBlciBsaXN0ZW5zIG9uXCIpXG4gICAgLm9wdGlvbihcIi0tYXBwLXBvcnQgPHBvcnQ+XCIsIFwicHJpdmF0ZSBwb3J0IHRoZSB3cmFwcGVkIGFwcCBpcyB0b2xkIHRvIGJpbmRcIilcbiAgICAub3B0aW9uKFwiLS1hbGxvdyA8cGF0dGVybnMuLi4+XCIsIFwiZW1haWwgYWxsb3ctbGlzdCAoZG9tYWluIC8gZ2xvYiAvIC9yZWdleC8pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViamVjdCA8dGV4dD5cIiwgXCJ2ZXJpZmljYXRpb24gZW1haWwgc3ViamVjdFwiKVxuICAgIC5vcHRpb24oXCItLWJyYW5kLW5hbWUgPG5hbWU+XCIsIFwidmVyaWZpY2F0aW9uIGVtYWlsIGJyYW5kIG5hbWVcIilcbiAgICAub3B0aW9uKFwiLS1tZXNzYWdlIDx0ZXh0PlwiLCBcInZlcmlmaWNhdGlvbiBlbWFpbCBtZXNzYWdlXCIpXG4gICAgLm9wdGlvbihcIi0tc2Vzc2lvbi10dGwgPHNlY29uZHM+XCIsIFwic2Vzc2lvbiBsaWZldGltZVwiKVxuICAgIC5vcHRpb24oXCItLWNvZGUtdHRsIDxzZWNvbmRzPlwiLCBcIm9uZS10aW1lLWNvZGUgbGlmZXRpbWVcIilcbiAgICAub3B0aW9uKFwiLS1zZXNzaW9uLWN1dG9mZiA8d2hlbj5cIiwgXCJpbnZhbGlkYXRlIGV2ZXJ5IHNlc3Npb24gaXNzdWVkIGJlZm9yZSB0aGlzXCIpXG4gICAgLm9wdGlvbihcIi0tYXV0aC1zdG9yYWdlIDxtb2RlPlwiLCBcImF1dGggZGF0YWJhc2U6IGF1dG8sIGxha2ViYXNlLCBvciBzcWxpdGVcIilcbiAgICAub3B0aW9uKFwiLS1hdXRoLXNxbGl0ZS1wYXRoIDxwYXRoPlwiLCBcImxvY2FsIEJldHRlciBBdXRoIFNRTGl0ZSBmaWxlXCIpXG4gICAgLm9wdGlvbihcIi0tZm9yd2FyZC1oZWFkZXJzIDxwYXR0ZXJucy4uLj5cIiwgXCJleHRyYSB4LSBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkXCIpXG4gICAgLm9wdGlvbihcIi0taW5zZWN1cmVcIiwgXCJydW4gb3Blbiwgd2l0aCBubyBnYXRlXCIpO1xufVxuXG4vKipcbiAqIFRpZSB0aGUgd3JhcHBlcidzIGxpZmV0aW1lIHRvIGl0cyBjaGlsZHJlbidzLCBpbiBib3RoIGRpcmVjdGlvbnM6IGEgY2hpbGQgdGhhdFxuICogZXhpdHMgdGFrZXMgdGhlIHdyYXBwZXIgZG93biB3aXRoIGl0cyBjb2RlLCBhbmQgYSBzaWduYWwgdG8gdGhlIHdyYXBwZXIgaXNcbiAqIGZvcndhcmRlZCBiZWZvcmUgaXQgbGVhdmVzLiBXaXRob3V0IHRoaXMgYSBjcmFzaGVkIGFwcCBsZWF2ZXMgYSBwb3J0ciB0dW5uZWxcbiAqIHNlcnZpbmcgYSBkZWFkIHBvcnQsIHdoaWNoIGxvb2tzIGxpa2UgYSBoYW5nIHJhdGhlciB0aGFuIGEgZmFpbHVyZS5cbiAqL1xuZnVuY3Rpb24gc3VwZXJ2aXNlKGNoaWxkcmVuOiByZWFkb25seSBDaGlsZFByb2Nlc3NbXSk6IHZvaWQge1xuICBsZXQgc3RvcHBpbmcgPSBmYWxzZTtcbiAgY29uc3Qgc3RvcCA9IChjb2RlOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICBpZiAoc3RvcHBpbmcpIHJldHVybjtcbiAgICBzdG9wcGluZyA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCBTSFVURE9XTl9HUkFDRV9NUykudW5yZWYoKTtcbiAgfTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiBzdG9wKGNvZGUgPz8gMSkpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWduYWwsICgpID0+IHN0b3AoMCkpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bihyYXc6IFR1bm5lbE9wdGlvbnMsIGNvbW1hbmQ6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IFtleGVjdXRhYmxlLCAuLi5hcmdzXSA9IGNvbW1hbmQ7XG4gIGlmICghZXhlY3V0YWJsZSkge1xuICAgIHRocm93IG5ldyBDb21tYW5kZXJFcnJvcigxLCBcInR1bm5lbC5uby1jb21tYW5kXCIsIFwibm8gY29tbWFuZCBnaXZlbiAtIHBhc3MgaXQgYWZ0ZXIgYC0tYFwiKTtcbiAgfVxuICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVUdW5uZWxPcHRpb25zKHJhdyk7XG5cbiAgLy8gVGhlIHdyYXBwZWQgYXBwIG11c3Qgbm90IGJlIHJlYWNoYWJsZSBmcm9tIG91dHNpZGU6IGl0IGJpbmRzIGxvb3BiYWNrIG9uIGFcbiAgLy8gcHJpdmF0ZSBwb3J0LCBhbmQgdGhlIHdyYXBwZXIgaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCB0YWxrcyB0byBpdC4gQW5cbiAgLy8gdW5yZXNvbHZlZCBgLS1hcHAtcG9ydGAgYmVjb21lcyBhIGZyZWUgZXBoZW1lcmFsIHBvcnQgcmF0aGVyIHRoYW4gYSBmaXhlZFxuICAvLyBndWVzcywgc28gdHdvIHR1bm5lbHMgY2FuIHJ1biBzaWRlIGJ5IHNpZGUuXG4gIGNvbnN0IGFwcFBvcnQgPSByZXNvbHZlZC5hcHBQb3J0ID8/IChhd2FpdCBmcmVlUG9ydCgpKTtcbiAgY29uc3QgYXBwID0gc3Bhd24oZXhlY3V0YWJsZSwgYXJncywge1xuICAgIGVudjoge1xuICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICBEQVRBQlJJQ0tTX0FQUF9QT1JUOiBTdHJpbmcoYXBwUG9ydCksXG4gICAgICBQT1JUOiBTdHJpbmcoYXBwUG9ydCksXG4gICAgICBIT1NUOiBcIjEyNy4wLjAuMVwiLFxuICAgIH0sXG4gICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICB9KTtcbiAgY29uc3QgY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdID0gW2FwcF07XG5cbiAgLy8gRHluYW1pYyBpbXBvcnQ6IHRoZSBnYXRlIGlzIHRoZSBvbmx5IHRoaW5nIGhlcmUgdGhhdCBuZWVkcyBBcHBLaXQgKyBTTVRQLCBzb1xuICAvLyBhbiBgLS1pbnNlY3VyZWAgcnVuIG5ldmVyIGxvYWRzIGVpdGhlci5cbiAgY29uc3QgZ2F0ZSA9IHJlc29sdmVkLmdhdGUuaW5zZWN1cmVcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoXCIuL2FwcC50c1wiKVxuICAgICAgKS5zdGFydEdhdGVBcHAoe1xuICAgICAgICAuLi5yZXNvbHZlZC5nYXRlQ29uZmlnLFxuICAgICAgICBwdWJsaWNEb21haW46IHJlc29sdmVkLmdhdGUucHVibGljRG9tYWluID8/IGBsb2NhbGhvc3Q6JHtyZXNvbHZlZC5wdWJsaWNQb3J0fWAsXG4gICAgICB9KTtcbiAgaWYgKCFnYXRlKSBsb2dnZXIud2FybihcInJ1bm5pbmcgT1BFTiAtIG5vIGdhdGUgaXMgaW4gZnJvbnQgb2YgdGhpcyB0dW5uZWxcIik7XG5cbiAgYXdhaXQgc3RhcnRQcm94eSh7XG4gICAgcHVibGljUG9ydDogcmVzb2x2ZWQucHVibGljUG9ydCxcbiAgICBhcHBQb3J0LFxuICAgIGdhdGUsXG4gICAgZm9yd2FyZEhlYWRlcnM6IHJlc29sdmVkLmdhdGUuZm9yd2FyZEhlYWRlcnMsXG4gIH0pO1xuXG4gIGlmIChyZXNvbHZlZC5wb3J0cikge1xuICAgIGNvbnN0IHBvcnRyRW52ID0gYXdhaXQgcG9ydHIuaW5zdGFsbFBvcnRyKCk7XG4gICAgYXdhaXQgcG9ydHIud3JpdGVQb3J0ckNvbmZpZyhyZXNvbHZlZC5wb3J0ciwgcG9ydHJFbnYpO1xuICAgIGNoaWxkcmVuLnB1c2goYXdhaXQgcG9ydHIuc3RhcnRQb3J0cihyZXNvbHZlZC5wb3J0ciwgcG9ydHJFbnYpKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuaW5mbyhcIm5vIFBPUlRSX1RPS0VOIC8gVFVOTkVMX1BVQkxJQ19ET01BSU4gLSBzZXJ2aW5nIGxvY2FsbHkgb25seVwiLCB7XG4gICAgICBwdWJsaWNQb3J0OiByZXNvbHZlZC5wdWJsaWNQb3J0LFxuICAgIH0pO1xuICB9XG4gIHN1cGVydmlzZShjaGlsZHJlbik7XG59XG5cbi8qKiBUaGUgYGRieCB0dW5uZWxgIHByb2dyYW0uIE5vIHNpZGUgZWZmZWN0cyB1bnRpbCBwYXJzZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQcm9ncmFtKG5hbWUgPSBcImRieCB0dW5uZWxcIik6IENvbW1hbmQge1xuICBjb25zdCBwcm9ncmFtID0gYWRkT3B0aW9ucyhcbiAgICBuZXcgQ29tbWFuZCgpXG4gICAgICAubmFtZShuYW1lKVxuICAgICAgLmRlc2NyaXB0aW9uKFwiRnJvbnQgYSBjb21tYW5kIHdpdGggYSBwb3J0ciB0dW5uZWwgYW5kIHBhc3N3b3JkbGVzcyBhdXRoXCIpLFxuICApO1xuXG4gIC8vIGBydW5gIGlzIHRoZSBERUZBVUxUIGFjdGlvbiBhcyB3ZWxsIGFzIGEgbmFtZWQgc3ViY29tbWFuZCwgcHJlc2VydmluZyB0aGUgb2xkXG4gIC8vIHdyYXBwZXIncyBlcmdvbm9taWNzIChgZGJ4IHR1bm5lbCAtLWFsbG93IHggLS0gYnVuIHNyYy9zZXJ2ZXIudHNgKSB3aGlsZVxuICAvLyBsZWF2aW5nIHNvbWV3aGVyZSBmb3IgYHN0YXR1c2AgYW5kIGBpbnN0YWxsYCB0byBsaXZlLlxuICBwcm9ncmFtXG4gICAgLmFyZ3VtZW50KFwiW2NvbW1hbmQuLi5dXCIsIFwidGhlIGNvbW1hbmQgdG8gd3JhcCwgYWZ0ZXIgYC0tYFwiKVxuICAgIC5hY3Rpb24oYXN5bmMgKGNvbW1hbmQ6IHN0cmluZ1tdLCBfb3B0aW9uczogVHVubmVsT3B0aW9ucywgY21kOiBDb21tYW5kKSA9PiB7XG4gICAgICBhd2FpdCBydW4oY21kLm9wdHM8VHVubmVsT3B0aW9ucz4oKSwgY29tbWFuZCk7XG4gICAgfSk7XG5cbiAgYWRkT3B0aW9ucyhwcm9ncmFtLmNvbW1hbmQoXCJydW5cIikuZGVzY3JpcHRpb24oXCJXcmFwIGEgY29tbWFuZCAodGhlIGRlZmF1bHQgYWN0aW9uKVwiKSlcbiAgICAuYXJndW1lbnQoXCI8Y29tbWFuZC4uLj5cIiwgXCJ0aGUgY29tbWFuZCB0byB3cmFwLCBhZnRlciBgLS1gXCIpXG4gICAgLmFjdGlvbihhc3luYyAoY29tbWFuZDogc3RyaW5nW10sIF9vcHRpb25zOiBUdW5uZWxPcHRpb25zLCBjbWQ6IENvbW1hbmQpID0+IHtcbiAgICAgIGF3YWl0IHJ1bihjbWQub3B0czxUdW5uZWxPcHRpb25zPigpLCBjb21tYW5kKTtcbiAgICB9KTtcblxuICAvLyBXb3J0aCBpdHMgb3duIGNvbW1hbmQ6IHRoZSBtb3N0IGNvbW1vbiBmYWlsdXJlIGlzIGEgdHVubmVsIHRoYXQgc2lsZW50bHlcbiAgLy8gZG9lcyBub3RoaW5nIGJlY2F1c2Ugbm8gdG9rZW4gb3IgZG9tYWluIHJlc29sdmVkLCBhbmQgdGhpcyBwcmludHMgZXhhY3RseVxuICAvLyB3aGF0IHdvdWxkIGhhcHBlbiB3aXRob3V0IHN0YXJ0aW5nIGFueXRoaW5nLlxuICBhZGRPcHRpb25zKFxuICAgIHByb2dyYW0uY29tbWFuZChcInN0YXR1c1wiKS5kZXNjcmlwdGlvbihcIlJlc29sdmUgdGhlIGNvbmZpZ3VyYXRpb24gYW5kIHByaW50IGl0XCIpLFxuICApLmFjdGlvbigoX29wdGlvbnM6IFR1bm5lbE9wdGlvbnMsIGNtZDogQ29tbWFuZCkgPT4ge1xuICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVR1bm5lbE9wdGlvbnMoY21kLm9wdHM8VHVubmVsT3B0aW9ucz4oKSk7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCR7SlNPTi5zdHJpbmdpZnkocmVzb2x2ZWQsIG51bGwsIDIpfVxcbmApO1xuICB9KTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoXCJpbnN0YWxsXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiSW5zdGFsbCB0aGUgcG9ydHIgYmluYXJ5IGFuZCBleGl0XCIpXG4gICAgLmFjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBwb3J0ci5pbnN0YWxsUG9ydHIoKTtcbiAgICB9KTtcblxuICByZXR1cm4gcHJvZ3JhbTtcbn1cbiJdfQ==
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxjQUFjLENBQUM7QUFDeEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxpRkFBaUY7QUFDakYsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFFaEM7Ozs7R0FJRztBQUNILFNBQVMsUUFBUTtJQUNmLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsTUFBTSxLQUFLLEdBQUcsWUFBWSxFQUFFLENBQUM7UUFDN0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTtZQUNoQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxD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QUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFdBQVcsQ0FBQyxtQ0FBbUMsQ0FBQztTQUNoRCxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDakIsTUFBTSxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgZGJ4IHR1bm5lbGAgLSBmcm9udCBhIGNvbW1hbmQgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgYW5kIHBhc3N3b3JkbGVzcyBnYXRlLlxuICpcbiAqIFRoaXMgaXMgdGhlIFdSQVBQRVIgcGF0aCwgYW5kIGl0IGV4aXN0cyBmb3Igb25lIGNhc2U6IGEgcHJvamVjdCB0aGF0IGRvZXMgbm90XG4gKiB1c2UgYEBkYngtdG9vbHMvYXBwa2l0YCdzIGBjcmVhdGVBcHBgLCBhbmQgdGhlcmVmb3JlIGNhbm5vdCByZWdpc3RlclxuICogYHR1bm5lbEludGVyY2VwdG9yKClgICsgdGhlIGBhdXRoR2F0ZWAgcGx1Z2luIGluLXByb2Nlc3MuIEFuIEFwcEtpdCBhcHAgc2hvdWxkXG4gKiBzdGlsbCB0YWtlIHRoZSBwbHVnaW4gcGF0aCAtIG9uZSBwcm9jZXNzLCBubyBwcm94eSBob3AsIG5vIGR1cGxpY2F0ZWQgaGVhZGVyXG4gKiBoYW5kbGluZy5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IChgREFUQUJSSUNLU19BUFBfUE9SVGAsIHRoZSBwb3J0IHRoZVxuICogcGxhdGZvcm0gYW5kIHBvcnRyIHJvdXRlIHRvKSwgbW92ZXMgdGhlIHdyYXBwZWQgYXBwIHRvIGEgcHJpdmF0ZSBvbmUsIGFuZFxuICogcmV2ZXJzZS1wcm94aWVzIGJldHdlZW4gdGhlbSBzbyB0aGUgZ2F0ZSBzaXRzIGluIGZyb250IG9mIHRyYWZmaWMgaXQgd291bGRcbiAqIG90aGVyd2lzZSBoYXZlIG5vIHdheSB0byBpbnRlcmNlcHQuIEV2ZXJ5dGhpbmcgZWxzZSBpcyBkZWxlZ2F0ZWQ6IHRoZSBnYXRlXG4gKiBjb25maWcgY29tZXMgZnJvbSBgcGx1Z2luLnJlc29sdmVBdXRoR2F0ZUNvbmZpZ2AsIHRoZSBwb3J0ciBsaWZlY3ljbGUgZnJvbVxuICogYHBvcnRyLipgIC0gYm90aCB0aGUgc2FtZSBmdW5jdGlvbnMgdGhlIGluLXByb2Nlc3MgcGF0aCB1c2VzLlxuICpcbiAqIFNoaXBzIG5vIGJpbi4gYEBkYngtdG9vbHMvY2xpYCBtb3VudHMgYGJ1aWxkUHJvZ3JhbSgpYCBhcyBgZGJ4IHR1bm5lbGAgbGF6aWx5LFxuICogc28gYGRieCBkZXZgIHBheXMgZm9yIG5vbmUgb2YgdGhpcywgYW5kIGAtLWluc2VjdXJlYCAvIGBzdGF0dXNgIC8gYGluc3RhbGxgXG4gKiBuZXZlciBsb2FkIEFwcEtpdCBvciB0aGUgU01UUCBzdGFjayBlaXRoZXIgKHRoZSBnYXRlIGFwcCBpcyBiZWhpbmQgYSBkeW5hbWljXG4gKiBpbXBvcnQpLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBwb3J0ciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyByZXNvbHZlVHVubmVsT3B0aW9ucywgdHlwZSBUdW5uZWxPcHRpb25zIH0gZnJvbSBcIi4vb3B0aW9ucy50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBIb3cgbG9uZyBhIGNoaWxkIGdldHMgdG8gZXhpdCBvbiBTSUdURVJNIGJlZm9yZSB0aGUgd3JhcHBlciBsZWF2ZXMgYW55d2F5LiAqL1xuY29uc3QgU0hVVERPV05fR1JBQ0VfTVMgPSAzXzAwMDtcblxuLyoqXG4gKiBBIGZyZWUgbG9vcGJhY2sgcG9ydCwgZnJvbSB0aGUgT1MgcmF0aGVyIHRoYW4gYSByYW5kb20gZ3Vlc3M6IGJpbmRpbmcgYDBgIGFuZFxuICogcmVhZGluZyBiYWNrIHdoYXQgd2FzIGFzc2lnbmVkIGlzIHRoZSBvbmx5IHdheSB0byBrbm93IHRoZSBwb3J0IGlzIGFjdHVhbGx5XG4gKiBhdmFpbGFibGUsIHNvIHR3byB0dW5uZWxzIGNhbiBydW4gc2lkZSBieSBzaWRlIHdpdGhvdXQgY29sbGlkaW5nLlxuICovXG5mdW5jdGlvbiBmcmVlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb2JlID0gY3JlYXRlU2VydmVyKCk7XG4gICAgcHJvYmUub24oXCJlcnJvclwiLCByZWplY3QpO1xuICAgIHByb2JlLmxpc3RlbigwLCBcIjEyNy4wLjAuMVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvYmUuYWRkcmVzcygpO1xuICAgICAgY29uc3QgcG9ydCA9IHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiICYmIGFkZHJlc3MgPyBhZGRyZXNzLnBvcnQgOiAwO1xuICAgICAgcHJvYmUuY2xvc2UoKCkgPT4gKHBvcnQgPiAwID8gcmVzb2x2ZShwb3J0KSA6IHJlamVjdChuZXcgRXJyb3IoXCJubyBmcmVlIHBvcnRcIikpKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV2ZXJ5IGdhdGUvcG9ydHIgZmxhZy4gRGVjbGFyZWQgb24gdGhlIHJvb3QgY29tbWFuZCBBTkQgb24gYHJ1bmAvYHN0YXR1c2Agc29cbiAqIGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBjbWRgIGFuZCBgZGJ4IHR1bm5lbCBydW4gLS1hbGxvdyB4IC0tIGNtZGAgYmVoYXZlXG4gKiBpZGVudGljYWxseSAtIGNvbW1hbmRlciBkb2VzIG5vdCBpbmhlcml0IG9wdGlvbnMgZG93bndhcmQuXG4gKi9cbmZ1bmN0aW9uIGFkZE9wdGlvbnMoY29tbWFuZDogQ29tbWFuZCk6IENvbW1hbmQge1xuICByZXR1cm4gY29tbWFuZFxuICAgIC5vcHRpb24oXCItLXB1YmxpYy1kb21haW4gPGhvc3Q+XCIsIFwicG9ydHIgcHVibGljIGRvbWFpbiAoPHN1YmRvbWFpbj4uPHNlcnZlcj4pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViZG9tYWluIDxuYW1lPlwiLCBcInBvcnRyIHN1YmRvbWFpbiAoZWxzZSBkZXJpdmVkIGZyb20gdGhlIHB1YmxpYyBkb21haW4pXCIpXG4gICAgLm9wdGlvbihcIi0tcG9ydCA8cG9ydD5cIiwgXCJwdWJsaWMgcG9ydCB0aGUgd3JhcHBlciBsaXN0ZW5zIG9uXCIpXG4gICAgLm9wdGlvbihcIi0tYXBwLXBvcnQgPHBvcnQ+XCIsIFwicHJpdmF0ZSBwb3J0IHRoZSB3cmFwcGVkIGFwcCBpcyB0b2xkIHRvIGJpbmRcIilcbiAgICAub3B0aW9uKFwiLS1hbGxvdyA8cGF0dGVybnMuLi4+XCIsIFwiZW1haWwgYWxsb3ctbGlzdCAoZG9tYWluIC8gZ2xvYiAvIC9yZWdleC8pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViamVjdCA8dGV4dD5cIiwgXCJ2ZXJpZmljYXRpb24gZW1haWwgc3ViamVjdFwiKVxuICAgIC5vcHRpb24oXCItLWJyYW5kLW5hbWUgPG5hbWU+XCIsIFwidmVyaWZpY2F0aW9uIGVtYWlsIGJyYW5kIG5hbWVcIilcbiAgICAub3B0aW9uKFwiLS1tZXNzYWdlIDx0ZXh0PlwiLCBcInZlcmlmaWNhdGlvbiBlbWFpbCBtZXNzYWdlXCIpXG4gICAgLm9wdGlvbihcIi0tc2Vzc2lvbi10dGwgPHNlY29uZHM+XCIsIFwic2Vzc2lvbiBsaWZldGltZVwiKVxuICAgIC5vcHRpb24oXCItLWNvZGUtdHRsIDxzZWNvbmRzPlwiLCBcIm9uZS10aW1lLWNvZGUgbGlmZXRpbWVcIilcbiAgICAub3B0aW9uKFwiLS1zZXNzaW9uLWN1dG9mZiA8d2hlbj5cIiwgXCJpbnZhbGlkYXRlIGV2ZXJ5IHNlc3Npb24gaXNzdWVkIGJlZm9yZSB0aGlzXCIpXG4gICAgLm9wdGlvbihcIi0tYXV0aC1zdG9yYWdlIDxtb2RlPlwiLCBcImF1dGggZGF0YWJhc2U6IGF1dG8sIGxha2ViYXNlLCBvciBzcWxpdGVcIilcbiAgICAub3B0aW9uKFwiLS1hdXRoLXNxbGl0ZS1wYXRoIDxwYXRoPlwiLCBcImxvY2FsIEJldHRlciBBdXRoIFNRTGl0ZSBmaWxlXCIpXG4gICAgLm9wdGlvbihcIi0tZm9yd2FyZC1oZWFkZXJzIDxwYXR0ZXJucy4uLj5cIiwgXCJleHRyYSB4LSBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkXCIpXG4gICAgLm9wdGlvbihcIi0tZ2F0ZS1wYXRoIDxwcmVmaXguLi4+XCIsIFwicGF0aCBwcmVmaXhlcyB0byBnYXRlIGJleW9uZCAvYXBpLyAoZS5nLiAvd3MpXCIpXG4gICAgLm9wdGlvbihcIi0tYmluZCA8aG9zdC4uLj5cIiwgXCJpbnRlcmZhY2UgSVBzIHRoZSBnYXRlIGxpc3RlbnMgb24gKGRlZmF1bHQ6IDAuMC4wLjApXCIpXG4gICAgLm9wdGlvbihcIi0taW5zZWN1cmVcIiwgXCJydW4gb3Blbiwgd2l0aCBubyBnYXRlXCIpO1xufVxuXG4vKipcbiAqIFRpZSB0aGUgd3JhcHBlcidzIGxpZmV0aW1lIHRvIGl0cyBjaGlsZHJlbidzLCBpbiBib3RoIGRpcmVjdGlvbnM6IGEgY2hpbGQgdGhhdFxuICogZXhpdHMgdGFrZXMgdGhlIHdyYXBwZXIgZG93biB3aXRoIGl0cyBjb2RlLCBhbmQgYSBzaWduYWwgdG8gdGhlIHdyYXBwZXIgaXNcbiAqIGZvcndhcmRlZCBiZWZvcmUgaXQgbGVhdmVzLiBXaXRob3V0IHRoaXMgYSBjcmFzaGVkIGFwcCBsZWF2ZXMgYSBwb3J0ciB0dW5uZWxcbiAqIHNlcnZpbmcgYSBkZWFkIHBvcnQsIHdoaWNoIGxvb2tzIGxpa2UgYSBoYW5nIHJhdGhlciB0aGFuIGEgZmFpbHVyZS5cbiAqL1xuZnVuY3Rpb24gc3VwZXJ2aXNlKGNoaWxkcmVuOiByZWFkb25seSBDaGlsZFByb2Nlc3NbXSk6IHZvaWQge1xuICBsZXQgc3RvcHBpbmcgPSBmYWxzZTtcbiAgY29uc3Qgc3RvcCA9IChjb2RlOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICBpZiAoc3RvcHBpbmcpIHJldHVybjtcbiAgICBzdG9wcGluZyA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCBTSFVURE9XTl9HUkFDRV9NUykudW5yZWYoKTtcbiAgfTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiBzdG9wKGNvZGUgPz8gMSkpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWduYWwsICgpID0+IHN0b3AoMCkpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bihyYXc6IFR1bm5lbE9wdGlvbnMsIGNvbW1hbmQ6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IFtleGVjdXRhYmxlLCAuLi5hcmdzXSA9IGNvbW1hbmQ7XG4gIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVR1bm5lbE9wdGlvbnMocmF3KTtcbiAgY29uc3QgY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdID0gW107XG5cbiAgLy8gVHdvIHVwc3RyZWFtIG1vZGVzOlxuICAvLyAgIC0gV1JBUDogYSBjb21tYW5kIGFmdGVyIGAtLWAuIFRoZSB3cmFwcGVyIHNwYXducyBpdCBvbiBhIHByaXZhdGUgbG9vcGJhY2tcbiAgLy8gICAgIHBvcnQgYW5kIGlzIHRoZSBvbmx5IHRoaW5nIHRoYXQgdGFsa3MgdG8gaXQuXG4gIC8vICAgLSBBVFRBQ0g6IG5vIGNvbW1hbmQsIGJ1dCBgLS1hcHAtcG9ydGAgbmFtZXMgYW4gYWxyZWFkeS1ydW5uaW5nIHVwc3RyZWFtXG4gIC8vICAgICAoZS5nLiBhIGxvY2FsIHJldmVyc2UgcHJveHkpLiBUaGUgZ2F0ZSBmcm9udHMgaXQgd2l0aG91dCBzcGF3bmluZyBhXG4gIC8vICAgICBjaGlsZC4gVGhpcyBpcyB3aGF0IGxldHMgdGhlIGdhdGUgc2l0IG9uIGFuIGludGVyZmFjZSBpbiBmcm9udCBvZiBhXG4gIC8vICAgICBzZXBhcmF0ZWx5LXN1cGVydmlzZWQgc3RhY2suXG4gIGxldCBhcHBQb3J0OiBudW1iZXI7XG4gIGlmIChleGVjdXRhYmxlKSB7XG4gICAgYXBwUG9ydCA9IHJlc29sdmVkLmFwcFBvcnQgPz8gKGF3YWl0IGZyZWVQb3J0KCkpO1xuICAgIGNvbnN0IGFwcCA9IHNwYXduKGV4ZWN1dGFibGUsIGFyZ3MsIHtcbiAgICAgIGVudjoge1xuICAgICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgICAgREFUQUJSSUNLU19BUFBfUE9SVDogU3RyaW5nKGFwcFBvcnQpLFxuICAgICAgICBQT1JUOiBTdHJpbmcoYXBwUG9ydCksXG4gICAgICAgIEhPU1Q6IFwiMTI3LjAuMC4xXCIsXG4gICAgICB9LFxuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgIH0pO1xuICAgIGNoaWxkcmVuLnB1c2goYXBwKTtcbiAgfSBlbHNlIGlmIChyZXNvbHZlZC5hcHBQb3J0KSB7XG4gICAgYXBwUG9ydCA9IHJlc29sdmVkLmFwcFBvcnQ7XG4gICAgbG9nZ2VyLmluZm8oXCJhdHRhY2hpbmcgZ2F0ZSB0byBleGlzdGluZyB1cHN0cmVhbVwiLCB7IGFwcFBvcnQgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IENvbW1hbmRlckVycm9yKFxuICAgICAgMSxcbiAgICAgIFwidHVubmVsLm5vLXVwc3RyZWFtXCIsXG4gICAgICBcIm5vIGNvbW1hbmQgZ2l2ZW4gKHBhc3MgaXQgYWZ0ZXIgYC0tYCkgYW5kIG5vIC0tYXBwLXBvcnQgdG8gYXR0YWNoIHRvXCIsXG4gICAgKTtcbiAgfVxuXG4gIC8vIER5bmFtaWMgaW1wb3J0OiB0aGUgZ2F0ZSBpcyB0aGUgb25seSB0aGluZyBoZXJlIHRoYXQgbmVlZHMgQXBwS2l0ICsgU01UUCwgc29cbiAgLy8gYW4gYC0taW5zZWN1cmVgIHJ1biBuZXZlciBsb2FkcyBlaXRoZXIuXG4gIGNvbnN0IGdhdGUgPSByZXNvbHZlZC5nYXRlLmluc2VjdXJlXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IGF3YWl0IChcbiAgICAgICAgYXdhaXQgaW1wb3J0KFwiLi9hcHAudHNcIilcbiAgICAgICkuc3RhcnRHYXRlQXBwKHtcbiAgICAgICAgLi4ucmVzb2x2ZWQuZ2F0ZUNvbmZpZyxcbiAgICAgICAgcHVibGljRG9tYWluOiByZXNvbHZlZC5nYXRlLnB1YmxpY0RvbWFpbiA/PyBgbG9jYWxob3N0OiR7cmVzb2x2ZWQucHVibGljUG9ydH1gLFxuICAgICAgfSk7XG4gIGlmICghZ2F0ZSkgbG9nZ2VyLndhcm4oXCJydW5uaW5nIE9QRU4gLSBubyBnYXRlIGlzIGluIGZyb250IG9mIHRoaXMgdHVubmVsXCIpO1xuXG4gIGF3YWl0IHN0YXJ0UHJveHkoe1xuICAgIHB1YmxpY1BvcnQ6IHJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgYXBwUG9ydCxcbiAgICBnYXRlLFxuICAgIGZvcndhcmRIZWFkZXJzOiByZXNvbHZlZC5nYXRlLmZvcndhcmRIZWFkZXJzLFxuICAgIGdhdGVQYXRoczogcmVzb2x2ZWQuZ2F0ZS5nYXRlUGF0aHMsXG4gICAgYnJhbmROYW1lOiByZXNvbHZlZC5nYXRlLmJyYW5kTmFtZSxcbiAgICBiaW5kSG9zdHM6IHJlc29sdmVkLmJpbmRIb3N0cyxcbiAgfSk7XG5cbiAgaWYgKHJlc29sdmVkLnBvcnRyKSB7XG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBwb3J0ci5pbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCBwb3J0ci53cml0ZVBvcnRyQ29uZmlnKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudik7XG4gICAgY2hpbGRyZW4ucHVzaChhd2FpdCBwb3J0ci5zdGFydFBvcnRyKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudikpO1xuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5pbmZvKFwibm8gUE9SVFJfVE9LRU4gLyBUVU5ORUxfUFVCTElDX0RPTUFJTiAtIHNlcnZpbmcgbG9jYWxseSBvbmx5XCIsIHtcbiAgICAgIHB1YmxpY1BvcnQ6IHJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgfSk7XG4gIH1cbiAgc3VwZXJ2aXNlKGNoaWxkcmVuKTtcbn1cblxuLyoqIFRoZSBgZGJ4IHR1bm5lbGAgcHJvZ3JhbS4gTm8gc2lkZSBlZmZlY3RzIHVudGlsIHBhcnNlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFByb2dyYW0obmFtZSA9IFwiZGJ4IHR1bm5lbFwiKTogQ29tbWFuZCB7XG4gIGNvbnN0IHByb2dyYW0gPSBhZGRPcHRpb25zKFxuICAgIG5ldyBDb21tYW5kKClcbiAgICAgIC5uYW1lKG5hbWUpXG4gICAgICAuZGVzY3JpcHRpb24oXCJGcm9udCBhIGNvbW1hbmQgd2l0aCBhIHBvcnRyIHR1bm5lbCBhbmQgcGFzc3dvcmRsZXNzIGF1dGhcIiksXG4gICk7XG5cbiAgLy8gYHJ1bmAgaXMgdGhlIERFRkFVTFQgYWN0aW9uIGFzIHdlbGwgYXMgYSBuYW1lZCBzdWJjb21tYW5kLCBwcmVzZXJ2aW5nIHRoZSBvbGRcbiAgLy8gd3JhcHBlcidzIGVyZ29ub21pY3MgKGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBidW4gc3JjL3NlcnZlci50c2ApIHdoaWxlXG4gIC8vIGxlYXZpbmcgc29tZXdoZXJlIGZvciBgc3RhdHVzYCBhbmQgYGluc3RhbGxgIHRvIGxpdmUuXG4gIHByb2dyYW1cbiAgICAuYXJndW1lbnQoXCJbY29tbWFuZC4uLl1cIiwgXCJ0aGUgY29tbWFuZCB0byB3cmFwLCBhZnRlciBgLS1gXCIpXG4gICAgLmFjdGlvbihhc3luYyAoY29tbWFuZDogc3RyaW5nW10sIF9vcHRpb25zOiBUdW5uZWxPcHRpb25zLCBjbWQ6IENvbW1hbmQpID0+IHtcbiAgICAgIGF3YWl0IHJ1bihjbWQub3B0czxUdW5uZWxPcHRpb25zPigpLCBjb21tYW5kKTtcbiAgICB9KTtcblxuICBhZGRPcHRpb25zKHByb2dyYW0uY29tbWFuZChcInJ1blwiKS5kZXNjcmlwdGlvbihcIldyYXAgYSBjb21tYW5kICh0aGUgZGVmYXVsdCBhY3Rpb24pXCIpKVxuICAgIC5hcmd1bWVudChcIjxjb21tYW5kLi4uPlwiLCBcInRoZSBjb21tYW5kIHRvIHdyYXAsIGFmdGVyIGAtLWBcIilcbiAgICAuYWN0aW9uKGFzeW5jIChjb21tYW5kOiBzdHJpbmdbXSwgX29wdGlvbnM6IFR1bm5lbE9wdGlvbnMsIGNtZDogQ29tbWFuZCkgPT4ge1xuICAgICAgYXdhaXQgcnVuKGNtZC5vcHRzPFR1bm5lbE9wdGlvbnM+KCksIGNvbW1hbmQpO1xuICAgIH0pO1xuXG4gIC8vIFdvcnRoIGl0cyBvd24gY29tbWFuZDogdGhlIG1vc3QgY29tbW9uIGZhaWx1cmUgaXMgYSB0dW5uZWwgdGhhdCBzaWxlbnRseVxuICAvLyBkb2VzIG5vdGhpbmcgYmVjYXVzZSBubyB0b2tlbiBvciBkb21haW4gcmVzb2x2ZWQsIGFuZCB0aGlzIHByaW50cyBleGFjdGx5XG4gIC8vIHdoYXQgd291bGQgaGFwcGVuIHdpdGhvdXQgc3RhcnRpbmcgYW55dGhpbmcuXG4gIGFkZE9wdGlvbnMoXG4gICAgcHJvZ3JhbS5jb21tYW5kKFwic3RhdHVzXCIpLmRlc2NyaXB0aW9uKFwiUmVzb2x2ZSB0aGUgY29uZmlndXJhdGlvbiBhbmQgcHJpbnQgaXRcIiksXG4gICkuYWN0aW9uKChfb3B0aW9uczogVHVubmVsT3B0aW9ucywgY21kOiBDb21tYW5kKSA9PiB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlVHVubmVsT3B0aW9ucyhjbWQub3B0czxUdW5uZWxPcHRpb25zPigpKTtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtKU09OLnN0cmluZ2lmeShyZXNvbHZlZCwgbnVsbCwgMil9XFxuYCk7XG4gIH0pO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImluc3RhbGxcIilcbiAgICAuZGVzY3JpcHRpb24oXCJJbnN0YWxsIHRoZSBwb3J0ciBiaW5hcnkgYW5kIGV4aXRcIilcbiAgICAuYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHBvcnRyLmluc3RhbGxQb3J0cigpO1xuICAgIH0pO1xuXG4gIHJldHVybiBwcm9ncmFtO1xufVxuIl19
@@ -29,6 +29,8 @@ export interface TunnelOptions {
29
29
  authStorage?: AuthStorageMode;
30
30
  authSqlitePath?: string;
31
31
  forwardHeaders?: string[];
32
+ gatePath?: string[];
33
+ bind?: string[];
32
34
  insecure?: boolean;
33
35
  }
34
36
  export interface ResolvedTunnelOptions {
@@ -36,6 +38,8 @@ export interface ResolvedTunnelOptions {
36
38
  publicPort: number;
37
39
  /** The private port the wrapped app is told to bind. Unset means "pick one". */
38
40
  appPort?: number;
41
+ /** Interface IPs the gate listens on. Empty means the default (0.0.0.0). */
42
+ bindHosts: string[];
39
43
  /**
40
44
  * The gate config as the `authGate` PLUGIN takes it - flags only, nothing
41
45
  * resolved. Passed straight to the plugin so it applies its own fallbacks
@@ -34,6 +34,7 @@ export function resolveTunnelOptions(options) {
34
34
  storage: options.authStorage,
35
35
  sqlitePath: options.authSqlitePath,
36
36
  forwardHeaders: options.forwardHeaders,
37
+ gatePaths: options.gatePath,
37
38
  insecure: options.insecure,
38
39
  publicDomain: options.publicDomain,
39
40
  };
@@ -41,6 +42,7 @@ export function resolveTunnelOptions(options) {
41
42
  return {
42
43
  publicPort,
43
44
  ...(appPort > 0 ? { appPort } : {}),
45
+ bindHosts: options.bind ?? [],
44
46
  gateConfig,
45
47
  gate,
46
48
  portr: portr.resolvePortrConfig({
@@ -50,4 +52,4 @@ export function resolveTunnelOptions(options) {
50
52
  }),
51
53
  };
52
54
  }
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7R0FZRztBQUdILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUF1QixNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFxQ3ZFLE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxPQUFzQjtJQUN6RCwrREFBK0Q7SUFDL0QsNkVBQTZFO0lBQzdFLG9CQUFvQjtJQUNwQixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNsRixNQUFNLFVBQVUsR0FBbUI7UUFDakMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTztRQUN4QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7UUFDNUIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLDBFQUEwRTtRQUMxRSw0RUFBNEU7UUFDNUUsa0RBQWtEO1FBQ2xELGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUN0RCxjQUFjLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQ2hELGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtRQUNwQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFdBQVc7UUFDNUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxjQUFjO1FBQ2xDLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztRQUN0QyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7UUFDMUIsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO0tBQ25DLENBQUM7SUFDRixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdEQsT0FBTztRQUNMLFVBQVU7UUFDVixHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ25DLFVBQVU7UUFDVixJQUFJO1FBQ0osS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDL0IsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLElBQUksRUFBRSxVQUFVO1NBQ2pCLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmxhZyAtPiBjb25maWcgLT4gZGVmYXVsdCByZXNvbHV0aW9uIGZvciBgZGJ4IHR1bm5lbGAuXG4gKlxuICogVGhlIHBvaW50IG9mIHRoaXMgbW9kdWxlIGlzIHRoYXQgaXQgZG9lcyBhbG1vc3QgTk9USElORyBpdHNlbGY6IGV2ZXJ5IGdhdGVcbiAqIHNldHRpbmcgaXMgaGFuZGVkIHN0cmFpZ2h0IHRvIGBAZGJ4LXRvb2xzL3R1bm5lbGAncyBvd25cbiAqIGBwbHVnaW4ucmVzb2x2ZUF1dGhHYXRlQ29uZmlnYCwgd2hpY2ggaXMgdGhlIHNhbWUgZnVuY3Rpb24gdGhlIGluLXByb2Nlc3NcbiAqIHBsdWdpbiBwYXRoIGNhbGxzLiBUaGUgQ0xJIHRoZXJlZm9yZSBjYW5ub3QgZHJpZnQgZnJvbSB0aGUgcGx1Z2luIG9uIGEgZGVmYXVsdCxcbiAqIGFuIGVudiBuYW1lLCBvciBhIGNvZXJjaW9uIHJ1bGUgLSBhIGZsYWcgaXMganVzdCBhIHZhbHVlIHBhc3NlZCB3aGVyZSB0aGVcbiAqIHBsdWdpbidzIGBjb25maWdgIG9iamVjdCB3b3VsZCBnbywgYW5kIGBjb25maWcuKmAgZmlsbHMgdGhlIHJlc3QgaW4gZnJvbSB0aGVcbiAqIGVudmlyb25tZW50LCBhIGAuZW52YCBmaWxlLCBvciBgZGF0YWJyaWNrcy55bWxgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEF1dGhTdG9yYWdlTW9kZSB9IGZyb20gXCJAZGJ4LXRvb2xzL2F1dGhcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyB0eXBlIEF1dGhHYXRlQ29uZmlnLCBwbHVnaW4sIHBvcnRyIH0gZnJvbSBcIkBkYngtdG9vbHMvdHVubmVsXCI7XG5cbi8qKiBSYXcgY29tbWFuZGVyIGZsYWcgdmFsdWVzIChldmVyeSBudW1lcmljIGZsYWcgYXJyaXZlcyBhcyBhIHN0cmluZykuICovXG5leHBvcnQgaW50ZXJmYWNlIFR1bm5lbE9wdGlvbnMge1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgcG9ydD86IHN0cmluZyB8IG51bWJlcjtcbiAgYXBwUG9ydD86IHN0cmluZyB8IG51bWJlcjtcbiAgYWxsb3c/OiBzdHJpbmdbXTtcbiAgc3ViamVjdD86IHN0cmluZztcbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBzZXNzaW9uVHRsPzogc3RyaW5nIHwgbnVtYmVyO1xuICBjb2RlVHRsPzogc3RyaW5nIHwgbnVtYmVyO1xuICBzZXNzaW9uQ3V0b2ZmPzogc3RyaW5nO1xuICBhdXRoU3RvcmFnZT86IEF1dGhTdG9yYWdlTW9kZTtcbiAgYXV0aFNxbGl0ZVBhdGg/OiBzdHJpbmc7XG4gIGZvcndhcmRIZWFkZXJzPzogc3RyaW5nW107XG4gIGluc2VjdXJlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZFR1bm5lbE9wdGlvbnMge1xuICAvKiogVGhlIHBvcnQgdGhlIHdyYXBwZXIgaXRzZWxmIGxpc3RlbnMgb24gLSB3aGF0IHBvcnRyIGZvcndhcmRzIHRvLiAqL1xuICBwdWJsaWNQb3J0OiBudW1iZXI7XG4gIC8qKiBUaGUgcHJpdmF0ZSBwb3J0IHRoZSB3cmFwcGVkIGFwcCBpcyB0b2xkIHRvIGJpbmQuIFVuc2V0IG1lYW5zIFwicGljayBvbmVcIi4gKi9cbiAgYXBwUG9ydD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBnYXRlIGNvbmZpZyBhcyB0aGUgYGF1dGhHYXRlYCBQTFVHSU4gdGFrZXMgaXQgLSBmbGFncyBvbmx5LCBub3RoaW5nXG4gICAqIHJlc29sdmVkLiBQYXNzZWQgc3RyYWlnaHQgdG8gdGhlIHBsdWdpbiBzbyBpdCBhcHBsaWVzIGl0cyBvd24gZmFsbGJhY2tzXG4gICAqIGV4YWN0bHkgb25jZSwgaW4gdGhlIG9uZSBwbGFjZSB0aGF0IG93bnMgdGhlbS5cbiAgICovXG4gIGdhdGVDb25maWc6IEF1dGhHYXRlQ29uZmlnO1xuICAvKiogVGhlIHNhbWUgY29uZmlnIGFmdGVyIHRoZSBwbHVnaW4ncyByZXNvbHV0aW9uLCBmb3IgYHN0YXR1c2AgYW5kIGZvciByb3V0aW5nLiAqL1xuICBnYXRlOiBwbHVnaW4uUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZztcbiAgcG9ydHI6IFJldHVyblR5cGU8dHlwZW9mIHBvcnRyLnJlc29sdmVQb3J0ckNvbmZpZz47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlVHVubmVsT3B0aW9ucyhvcHRpb25zOiBUdW5uZWxPcHRpb25zKTogUmVzb2x2ZWRUdW5uZWxPcHRpb25zIHtcbiAgLy8gVGhlIERhdGFicmlja3MgQXBwcyBydW50aW1lIGNvbnRyYWN0OiB0aGUgcGxhdGZvcm0gcm91dGVzIHRvXG4gIC8vIERBVEFCUklDS1NfQVBQX1BPUlQsIHNvIHRoZSBXUkFQUEVSIGNsYWltcyBpdCBhbmQgdGhlIHdyYXBwZWQgYXBwIGlzIG1vdmVkXG4gIC8vIHRvIGEgcHJpdmF0ZSBvbmUuXG4gIGNvbnN0IHB1YmxpY1BvcnQgPSBjb25maWcucG9ydChvcHRpb25zLnBvcnQsIFwiREFUQUJSSUNLU19BUFBfUE9SVFwiLCA4MDAwKTtcbiAgY29uc3QgYXBwUG9ydCA9IGNvbmZpZy5wb3J0KG9wdGlvbnMuYXBwUG9ydCwgXCJBUFBfUE9SVFwiLCAwLCB7IHByZWZpeDogXCJUVU5ORUxcIiB9KTtcbiAgY29uc3QgZ2F0ZUNvbmZpZzogQXV0aEdhdGVDb25maWcgPSB7XG4gICAgYWxsb3c6IG9wdGlvbnMuYWxsb3csXG4gICAgc3ViamVjdDogb3B0aW9ucy5zdWJqZWN0LFxuICAgIGJyYW5kTmFtZTogb3B0aW9ucy5icmFuZE5hbWUsXG4gICAgbWVzc2FnZTogb3B0aW9ucy5tZXNzYWdlLFxuICAgIC8vIENvZXJjZWQsIG5vdCByZXNvbHZlZDogdGhlIHBsdWdpbiBvd25zIHRoZSBlbnYgbmFtZSBhbmQgdGhlIGRlZmF1bHQgZm9yXG4gICAgLy8gdGhlc2UsIHNvIHRoZSBmbGFnIGlzIHBhc3NlZCB0aHJvdWdoIGFzIHRoZSBgY29uZmlnYCB2YWx1ZSBpdCBleHBlY3RzIGFuZFxuICAgIC8vIG9ubHkgbmVlZHMgYSBzdHJpbmcgLT4gbnVtYmVyIG51ZGdlIG9uIHRoZSB3YXkuXG4gICAgc2Vzc2lvblR0bFNlY29uZHM6IG9iamVjdC50b051bWJlcihvcHRpb25zLnNlc3Npb25UdGwpLFxuICAgIGNvZGVUdGxTZWNvbmRzOiBvYmplY3QudG9OdW1iZXIob3B0aW9ucy5jb2RlVHRsKSxcbiAgICBzZXNzaW9uQ3V0b2ZmOiBvcHRpb25zLnNlc3Npb25DdXRvZmYsXG4gICAgc3RvcmFnZTogb3B0aW9ucy5hdXRoU3RvcmFnZSxcbiAgICBzcWxpdGVQYXRoOiBvcHRpb25zLmF1dGhTcWxpdGVQYXRoLFxuICAgIGZvcndhcmRIZWFkZXJzOiBvcHRpb25zLmZvcndhcmRIZWFkZXJzLFxuICAgIGluc2VjdXJlOiBvcHRpb25zLmluc2VjdXJlLFxuICAgIHB1YmxpY0RvbWFpbjogb3B0aW9ucy5wdWJsaWNEb21haW4sXG4gIH07XG4gIGNvbnN0IGdhdGUgPSBwbHVnaW4ucmVzb2x2ZUF1dGhHYXRlQ29uZmlnKGdhdGVDb25maWcpO1xuICByZXR1cm4ge1xuICAgIHB1YmxpY1BvcnQsXG4gICAgLi4uKGFwcFBvcnQgPiAwID8geyBhcHBQb3J0IH0gOiB7fSksXG4gICAgZ2F0ZUNvbmZpZyxcbiAgICBnYXRlLFxuICAgIHBvcnRyOiBwb3J0ci5yZXNvbHZlUG9ydHJDb25maWcoe1xuICAgICAgcHVibGljRG9tYWluOiBnYXRlLnB1YmxpY0RvbWFpbixcbiAgICAgIHN1YmRvbWFpbjogb3B0aW9ucy5zdWJkb21haW4sXG4gICAgICBwb3J0OiBwdWJsaWNQb3J0LFxuICAgIH0pLFxuICB9O1xufVxuIl19
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7R0FZRztBQUdILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUF1QixNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUF5Q3ZFLE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxPQUFzQjtJQUN6RCwrREFBK0Q7SUFDL0QsNkVBQTZFO0lBQzdFLG9CQUFvQjtJQUNwQixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNsRixNQUFNLFVBQVUsR0FBbUI7UUFDakMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTztRQUN4QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7UUFDNUIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLDBFQUEwRTtRQUMxRSw0RUFBNEU7UUFDNUUsa0RBQWtEO1FBQ2xELGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUN0RCxjQUFjLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQ2hELGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtRQUNwQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFdBQVc7UUFDNUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxjQUFjO1FBQ2xDLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztRQUN0QyxTQUFTLEVBQUUsT0FBTyxDQUFDLFFBQVE7UUFDM0IsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1FBQzFCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtLQUNuQyxDQUFDO0lBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELE9BQU87UUFDTCxVQUFVO1FBQ1YsR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNuQyxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO1FBQzdCLFVBQVU7UUFDVixJQUFJO1FBQ0osS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDL0IsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLElBQUksRUFBRSxVQUFVO1NBQ2pCLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmxhZyAtPiBjb25maWcgLT4gZGVmYXVsdCByZXNvbHV0aW9uIGZvciBgZGJ4IHR1bm5lbGAuXG4gKlxuICogVGhlIHBvaW50IG9mIHRoaXMgbW9kdWxlIGlzIHRoYXQgaXQgZG9lcyBhbG1vc3QgTk9USElORyBpdHNlbGY6IGV2ZXJ5IGdhdGVcbiAqIHNldHRpbmcgaXMgaGFuZGVkIHN0cmFpZ2h0IHRvIGBAZGJ4LXRvb2xzL3R1bm5lbGAncyBvd25cbiAqIGBwbHVnaW4ucmVzb2x2ZUF1dGhHYXRlQ29uZmlnYCwgd2hpY2ggaXMgdGhlIHNhbWUgZnVuY3Rpb24gdGhlIGluLXByb2Nlc3NcbiAqIHBsdWdpbiBwYXRoIGNhbGxzLiBUaGUgQ0xJIHRoZXJlZm9yZSBjYW5ub3QgZHJpZnQgZnJvbSB0aGUgcGx1Z2luIG9uIGEgZGVmYXVsdCxcbiAqIGFuIGVudiBuYW1lLCBvciBhIGNvZXJjaW9uIHJ1bGUgLSBhIGZsYWcgaXMganVzdCBhIHZhbHVlIHBhc3NlZCB3aGVyZSB0aGVcbiAqIHBsdWdpbidzIGBjb25maWdgIG9iamVjdCB3b3VsZCBnbywgYW5kIGBjb25maWcuKmAgZmlsbHMgdGhlIHJlc3QgaW4gZnJvbSB0aGVcbiAqIGVudmlyb25tZW50LCBhIGAuZW52YCBmaWxlLCBvciBgZGF0YWJyaWNrcy55bWxgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEF1dGhTdG9yYWdlTW9kZSB9IGZyb20gXCJAZGJ4LXRvb2xzL2F1dGhcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyB0eXBlIEF1dGhHYXRlQ29uZmlnLCBwbHVnaW4sIHBvcnRyIH0gZnJvbSBcIkBkYngtdG9vbHMvdHVubmVsXCI7XG5cbi8qKiBSYXcgY29tbWFuZGVyIGZsYWcgdmFsdWVzIChldmVyeSBudW1lcmljIGZsYWcgYXJyaXZlcyBhcyBhIHN0cmluZykuICovXG5leHBvcnQgaW50ZXJmYWNlIFR1bm5lbE9wdGlvbnMge1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgcG9ydD86IHN0cmluZyB8IG51bWJlcjtcbiAgYXBwUG9ydD86IHN0cmluZyB8IG51bWJlcjtcbiAgYWxsb3c/OiBzdHJpbmdbXTtcbiAgc3ViamVjdD86IHN0cmluZztcbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBzZXNzaW9uVHRsPzogc3RyaW5nIHwgbnVtYmVyO1xuICBjb2RlVHRsPzogc3RyaW5nIHwgbnVtYmVyO1xuICBzZXNzaW9uQ3V0b2ZmPzogc3RyaW5nO1xuICBhdXRoU3RvcmFnZT86IEF1dGhTdG9yYWdlTW9kZTtcbiAgYXV0aFNxbGl0ZVBhdGg/OiBzdHJpbmc7XG4gIGZvcndhcmRIZWFkZXJzPzogc3RyaW5nW107XG4gIGdhdGVQYXRoPzogc3RyaW5nW107XG4gIGJpbmQ/OiBzdHJpbmdbXTtcbiAgaW5zZWN1cmU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkVHVubmVsT3B0aW9ucyB7XG4gIC8qKiBUaGUgcG9ydCB0aGUgd3JhcHBlciBpdHNlbGYgbGlzdGVucyBvbiAtIHdoYXQgcG9ydHIgZm9yd2FyZHMgdG8uICovXG4gIHB1YmxpY1BvcnQ6IG51bWJlcjtcbiAgLyoqIFRoZSBwcml2YXRlIHBvcnQgdGhlIHdyYXBwZWQgYXBwIGlzIHRvbGQgdG8gYmluZC4gVW5zZXQgbWVhbnMgXCJwaWNrIG9uZVwiLiAqL1xuICBhcHBQb3J0PzogbnVtYmVyO1xuICAvKiogSW50ZXJmYWNlIElQcyB0aGUgZ2F0ZSBsaXN0ZW5zIG9uLiBFbXB0eSBtZWFucyB0aGUgZGVmYXVsdCAoMC4wLjAuMCkuICovXG4gIGJpbmRIb3N0czogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgZ2F0ZSBjb25maWcgYXMgdGhlIGBhdXRoR2F0ZWAgUExVR0lOIHRha2VzIGl0IC0gZmxhZ3Mgb25seSwgbm90aGluZ1xuICAgKiByZXNvbHZlZC4gUGFzc2VkIHN0cmFpZ2h0IHRvIHRoZSBwbHVnaW4gc28gaXQgYXBwbGllcyBpdHMgb3duIGZhbGxiYWNrc1xuICAgKiBleGFjdGx5IG9uY2UsIGluIHRoZSBvbmUgcGxhY2UgdGhhdCBvd25zIHRoZW0uXG4gICAqL1xuICBnYXRlQ29uZmlnOiBBdXRoR2F0ZUNvbmZpZztcbiAgLyoqIFRoZSBzYW1lIGNvbmZpZyBhZnRlciB0aGUgcGx1Z2luJ3MgcmVzb2x1dGlvbiwgZm9yIGBzdGF0dXNgIGFuZCBmb3Igcm91dGluZy4gKi9cbiAgZ2F0ZTogcGx1Z2luLlJlc29sdmVkQXV0aEdhdGVDb25maWc7XG4gIHBvcnRyOiBSZXR1cm5UeXBlPHR5cGVvZiBwb3J0ci5yZXNvbHZlUG9ydHJDb25maWc+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVR1bm5lbE9wdGlvbnMob3B0aW9uczogVHVubmVsT3B0aW9ucyk6IFJlc29sdmVkVHVubmVsT3B0aW9ucyB7XG4gIC8vIFRoZSBEYXRhYnJpY2tzIEFwcHMgcnVudGltZSBjb250cmFjdDogdGhlIHBsYXRmb3JtIHJvdXRlcyB0b1xuICAvLyBEQVRBQlJJQ0tTX0FQUF9QT1JULCBzbyB0aGUgV1JBUFBFUiBjbGFpbXMgaXQgYW5kIHRoZSB3cmFwcGVkIGFwcCBpcyBtb3ZlZFxuICAvLyB0byBhIHByaXZhdGUgb25lLlxuICBjb25zdCBwdWJsaWNQb3J0ID0gY29uZmlnLnBvcnQob3B0aW9ucy5wb3J0LCBcIkRBVEFCUklDS1NfQVBQX1BPUlRcIiwgODAwMCk7XG4gIGNvbnN0IGFwcFBvcnQgPSBjb25maWcucG9ydChvcHRpb25zLmFwcFBvcnQsIFwiQVBQX1BPUlRcIiwgMCwgeyBwcmVmaXg6IFwiVFVOTkVMXCIgfSk7XG4gIGNvbnN0IGdhdGVDb25maWc6IEF1dGhHYXRlQ29uZmlnID0ge1xuICAgIGFsbG93OiBvcHRpb25zLmFsbG93LFxuICAgIHN1YmplY3Q6IG9wdGlvbnMuc3ViamVjdCxcbiAgICBicmFuZE5hbWU6IG9wdGlvbnMuYnJhbmROYW1lLFxuICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZSxcbiAgICAvLyBDb2VyY2VkLCBub3QgcmVzb2x2ZWQ6IHRoZSBwbHVnaW4gb3ducyB0aGUgZW52IG5hbWUgYW5kIHRoZSBkZWZhdWx0IGZvclxuICAgIC8vIHRoZXNlLCBzbyB0aGUgZmxhZyBpcyBwYXNzZWQgdGhyb3VnaCBhcyB0aGUgYGNvbmZpZ2AgdmFsdWUgaXQgZXhwZWN0cyBhbmRcbiAgICAvLyBvbmx5IG5lZWRzIGEgc3RyaW5nIC0+IG51bWJlciBudWRnZSBvbiB0aGUgd2F5LlxuICAgIHNlc3Npb25UdGxTZWNvbmRzOiBvYmplY3QudG9OdW1iZXIob3B0aW9ucy5zZXNzaW9uVHRsKSxcbiAgICBjb2RlVHRsU2Vjb25kczogb2JqZWN0LnRvTnVtYmVyKG9wdGlvbnMuY29kZVR0bCksXG4gICAgc2Vzc2lvbkN1dG9mZjogb3B0aW9ucy5zZXNzaW9uQ3V0b2ZmLFxuICAgIHN0b3JhZ2U6IG9wdGlvbnMuYXV0aFN0b3JhZ2UsXG4gICAgc3FsaXRlUGF0aDogb3B0aW9ucy5hdXRoU3FsaXRlUGF0aCxcbiAgICBmb3J3YXJkSGVhZGVyczogb3B0aW9ucy5mb3J3YXJkSGVhZGVycyxcbiAgICBnYXRlUGF0aHM6IG9wdGlvbnMuZ2F0ZVBhdGgsXG4gICAgaW5zZWN1cmU6IG9wdGlvbnMuaW5zZWN1cmUsXG4gICAgcHVibGljRG9tYWluOiBvcHRpb25zLnB1YmxpY0RvbWFpbixcbiAgfTtcbiAgY29uc3QgZ2F0ZSA9IHBsdWdpbi5yZXNvbHZlQXV0aEdhdGVDb25maWcoZ2F0ZUNvbmZpZyk7XG4gIHJldHVybiB7XG4gICAgcHVibGljUG9ydCxcbiAgICAuLi4oYXBwUG9ydCA+IDAgPyB7IGFwcFBvcnQgfSA6IHt9KSxcbiAgICBiaW5kSG9zdHM6IG9wdGlvbnMuYmluZCA/PyBbXSxcbiAgICBnYXRlQ29uZmlnLFxuICAgIGdhdGUsXG4gICAgcG9ydHI6IHBvcnRyLnJlc29sdmVQb3J0ckNvbmZpZyh7XG4gICAgICBwdWJsaWNEb21haW46IGdhdGUucHVibGljRG9tYWluLFxuICAgICAgc3ViZG9tYWluOiBvcHRpb25zLnN1YmRvbWFpbixcbiAgICAgIHBvcnQ6IHB1YmxpY1BvcnQsXG4gICAgfSksXG4gIH07XG59XG4iXX0=
@@ -26,6 +26,17 @@ export interface ProxyOptions {
26
26
  gate?: AuthGateApi;
27
27
  /** Extra `x-` headers tunnel traffic may forward. */
28
28
  forwardHeaders?: readonly string[];
29
+ /** Path prefixes to gate beyond `/api/` (e.g. `/ws` for a WebSocket app). */
30
+ gatePaths?: readonly string[];
31
+ /** Brand name for the hosted login page shown on a denied browser navigation. */
32
+ brandName?: string;
33
+ /**
34
+ * Addresses to listen on. Defaults to a single `0.0.0.0` (every interface),
35
+ * the portr/platform case. Pass specific interface IPs to expose the gate on
36
+ * only those - e.g. an overlay/LAN address while loopback reaches the upstream
37
+ * directly and ungated.
38
+ */
39
+ bindHosts?: readonly string[];
29
40
  }
30
41
  /**
31
42
  * Start the proxy and resolve once it is listening.
package/lib/src/proxy.js CHANGED
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { createServer } from "node:http";
20
20
  import { log } from "@dbx-tools/shared-core";
21
- import { gate as tunnelGate, headers as tunnelHeaders } from "@dbx-tools/tunnel";
21
+ import { gate as tunnelGate, headers as tunnelHeaders, loginPage as tunnelLoginPage, } from "@dbx-tools/tunnel";
22
22
  import ProxyModule from "http-proxy-3";
23
23
  const logger = log.logger("tunnel:proxy");
24
24
  function sendJson(response, status, body, setCookie) {
@@ -57,7 +57,7 @@ async function handleAuthRoute(request, response, path, gate) {
57
57
  * to tell them apart by `Host`. Passing the request's own host keeps the shared
58
58
  * decision function's contract satisfied without weakening it.
59
59
  */
60
- export function startProxy(options) {
60
+ export async function startProxy(options) {
61
61
  const proxy = ProxyModule.createProxyServer({
62
62
  target: `http://127.0.0.1:${options.appPort}`,
63
63
  ws: true,
@@ -70,15 +70,27 @@ export function startProxy(options) {
70
70
  gate,
71
71
  publicDomain: (request.headers.host ?? "").split(":")[0] || "localhost",
72
72
  headerPolicy,
73
+ gatePaths: options.gatePaths,
73
74
  })
74
75
  : Promise.resolve("pass");
75
- const server = createServer((request, response) => {
76
+ const onRequest = (request, response) => {
76
77
  void (async () => {
77
78
  const path = (request.url ?? "/").split("?")[0] ?? "/";
78
79
  if (gate && (await handleAuthRoute(request, response, path, gate)))
79
80
  return;
80
81
  if ((await decide(request)) === "deny") {
81
- sendJson(response, 401, tunnelGate.UNAUTHORIZED_BODY);
82
+ // A denied browser navigation gets the hosted login page; anything else
83
+ // (an XHR, a /ws upgrade probe, a non-HTML fetch) gets the 401 JSON.
84
+ if (gate && tunnelGate.wantsLoginPage(request)) {
85
+ const html = tunnelLoginPage.loginPageHtml({
86
+ brandName: options.brandName ?? "this app",
87
+ });
88
+ response.writeHead(401, { "content-type": "text/html; charset=utf-8" });
89
+ response.end(html);
90
+ }
91
+ else {
92
+ sendJson(response, 401, tunnelGate.UNAUTHORIZED_BODY);
93
+ }
82
94
  return;
83
95
  }
84
96
  proxy.web(request, response);
@@ -89,11 +101,11 @@ export function startProxy(options) {
89
101
  else
90
102
  response.end();
91
103
  });
92
- });
104
+ };
93
105
  // A websocket upgrade cannot be answered with a 401 body, so a denied one is
94
106
  // destroyed - the client sees the handshake fail, which is what a browser's
95
107
  // WebSocket error handler expects.
96
- server.on("upgrade", (request, socket, head) => {
108
+ const onUpgrade = (request, socket, head) => {
97
109
  const upgradeSocket = socket;
98
110
  upgradeSocket.destroySoon ??= () => upgradeSocket.end();
99
111
  void decide(request)
@@ -104,12 +116,23 @@ export function startProxy(options) {
104
116
  proxy.ws(request, upgradeSocket, head);
105
117
  })
106
118
  .catch(() => upgradeSocket.destroy());
107
- });
108
- return new Promise((resolve) => {
109
- server.listen(options.publicPort, "0.0.0.0", () => {
110
- logger.info("proxy listening", { publicPort: options.publicPort, appPort: options.appPort });
119
+ };
120
+ // One net.Server binds one address, so listen each host on its own server that
121
+ // shares the same handlers. Binding specific interface IPs (rather than the
122
+ // default 0.0.0.0) is what lets the gate front an overlay/LAN address while
123
+ // loopback reaches the upstream ungated.
124
+ const hosts = options.bindHosts?.length ? options.bindHosts : ["0.0.0.0"];
125
+ await Promise.all(hosts.map((host) => new Promise((resolve) => {
126
+ const server = createServer(onRequest);
127
+ server.on("upgrade", onUpgrade);
128
+ server.listen(options.publicPort, host, () => {
129
+ logger.info("proxy listening", {
130
+ host,
131
+ publicPort: options.publicPort,
132
+ appPort: options.appPort,
133
+ });
111
134
  resolve();
112
135
  });
113
- });
136
+ })));
114
137
  }
115
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBNkMsTUFBTSxXQUFXLENBQUM7QUFFcEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxJQUFJLElBQUksVUFBVSxFQUFFLE9BQU8sSUFBSSxhQUFhLEVBQW9CLE1BQU0sbUJBQW1CLENBQUM7QUFDbkcsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFlMUMsU0FBUyxRQUFRLENBQ2YsUUFBd0IsRUFDeEIsTUFBYyxFQUNkLElBQWEsRUFDYixTQUFrQjtJQUVsQixRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtRQUN6QixjQUFjLEVBQUUsa0JBQWtCO1FBQ2xDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDbEQsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLGVBQWUsQ0FDNUIsT0FBd0IsRUFDeEIsUUFBd0IsRUFDeEIsSUFBWSxFQUNaLElBQWlCO0lBRWpCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUM7SUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDM0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFD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SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSByZXZlcnNlIHByb3h5IHRoYXQgbWFrZXMgdGhlIHdyYXBwZXIgcGF0aCBwb3NzaWJsZS5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IGFuZCB0aGUgd3JhcHBlZCBhcHAgcnVucyBhcyBhIGNoaWxkIHByb2Nlc3NcbiAqIG9uIGEgcHJpdmF0ZSBsb29wYmFjayBwb3J0LCBzbyAtIHVubGlrZSB0aGUgaW4tcHJvY2VzcyBwbHVnaW4gLSB0aGVyZSBpcyBub1xuICogbWlkZGxld2FyZSBjaGFpbiB0byBpbnNlcnQgdGhlIGdhdGUgaW50by4gVGhpcyBwcm94eSBpcyB0aGF0IGluc2VydGlvbiBwb2ludDogaXRcbiAqIGFuc3dlcnMgdGhlIGxvZ2luIHJvdXRlcyBpdHNlbGYsIGFwcGxpZXMgdGhlIGdhdGUgdG8gZXZlcnl0aGluZyBlbHNlLCBhbmRcbiAqIGZvcndhcmRzIHdoYXQgc3Vydml2ZXMgdG8gdGhlIGNoaWxkLlxuICpcbiAqIFRoZSBnYXRpbmcgREVDSVNJT04gaXMgbm90IHJlaW1wbGVtZW50ZWQgaGVyZS4gYEBkYngtdG9vbHMvdHVubmVsYCdzXG4gKiBgZ2F0ZS5nYXRlUmVxdWVzdGAgbWFrZXMgaXQgLSB0aGUgc2FtZSBmdW5jdGlvbiB0aGUgRXhwcmVzcyBtaWRkbGV3YXJlIGNhbGxzIC1cbiAqIGFuZCB0aGlzIG1vZHVsZSBvbmx5IGRpZmZlcnMgaW4gaG93IHRoZSBvdXRjb21lIGlzIHdyaXR0ZW46IGEgcHJveGllZCByZXF1ZXN0XG4gKiBpbnN0ZWFkIG9mIGBuZXh0KClgLCBhIGB3cml0ZUhlYWRgIGluc3RlYWQgb2YgYHJlcy5qc29uYC4gVGhhdCBpcyBkZWxpYmVyYXRlOlxuICogdHdvIGluZGVwZW5kZW50IGltcGxlbWVudGF0aW9ucyBvZiBcIndoaWNoIHJlcXVlc3RzIGFyZSBnYXRlZCBhbmQgd2hpY2ggaGVhZGVyc1xuICogYXJlIHN0cmlwcGVkXCIgaXMgdGhlIG9uZSB3YXkgdGhpcyBwYWNrYWdlIGNvdWxkIGJlY29tZSBhIHNlY3VyaXR5IGJ1Zy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyLCB0eXBlIEluY29taW5nTWVzc2FnZSwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJub2RlOmh0dHBcIjtcbmltcG9ydCB0eXBlIHsgU29ja2V0IH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZ2F0ZSBhcyB0dW5uZWxHYXRlLCBoZWFkZXJzIGFzIHR1bm5lbEhlYWRlcnMsIHR5cGUgQXV0aEdhdGVBcGkgfSBmcm9tIFwiQGRieC10b29scy90dW5uZWxcIjtcbmltcG9ydCBQcm94eU1vZHVsZSBmcm9tIFwiaHR0cC1wcm94eS0zXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6cHJveHlcIik7XG5cbnR5cGUgVXBncmFkZVNvY2tldCA9IFNvY2tldCAmIHsgZGVzdHJveVNvb24/OiAoKSA9PiB2b2lkIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJveHlPcHRpb25zIHtcbiAgLyoqIFRoZSBwb3J0IHRoaXMgcHJveHkgbGlzdGVucyBvbiAtIHRoZSBwb3J0IHBvcnRyIGFuZCB0aGUgcGxhdGZvcm0gcm91dGUgdG8uICovXG4gIHB1YmxpY1BvcnQ6IG51bWJlcjtcbiAgLyoqIFRoZSBwcml2YXRlIGxvb3BiYWNrIHBvcnQgdGhlIHdyYXBwZWQgYXBwIGxpc3RlbnMgb24uICovXG4gIGFwcFBvcnQ6IG51bWJlcjtcbiAgLyoqIFRoZSBnYXRlIGhhbmRsZXJzLiBPbWl0dGVkIChhbiBgLS1pbnNlY3VyZWAgcnVuKSBmb3J3YXJkcyBldmVyeXRoaW5nLiAqL1xuICBnYXRlPzogQXV0aEdhdGVBcGk7XG4gIC8qKiBFeHRyYSBgeC1gIGhlYWRlcnMgdHVubmVsIHRyYWZmaWMgbWF5IGZvcndhcmQuICovXG4gIGZvcndhcmRIZWFkZXJzPzogcmVhZG9ubHkgc3RyaW5nW107XG59XG5cbmZ1bmN0aW9uIHNlbmRKc29uKFxuICByZXNwb25zZTogU2VydmVyUmVzcG9uc2UsXG4gIHN0YXR1czogbnVtYmVyLFxuICBib2R5OiB1bmtub3duLFxuICBzZXRDb29raWU/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgcmVzcG9uc2Uud3JpdGVIZWFkKHN0YXR1cywge1xuICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgIC4uLihzZXRDb29raWUgPyB7IFwic2V0LWNvb2tpZVwiOiBzZXRDb29raWUgfSA6IHt9KSxcbiAgfSk7XG4gIHJlc3BvbnNlLmVuZChKU09OLnN0cmluZ2lmeShib2R5KSk7XG59XG5cbi8qKlxuICogSGFuZCBldmVyeSBCZXR0ZXIgQXV0aCBhbmQgY29tcGF0aWJpbGl0eSByb3V0ZSB0byB0aGUgc2hhcmVkIGdhdGUgcnVudGltZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaGFuZGxlQXV0aFJvdXRlKFxuICByZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UsXG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZSxcbiAgcGF0aDogc3RyaW5nLFxuICBnYXRlOiBBdXRoR2F0ZUFwaSxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCBwcmVmaXggPSB0dW5uZWxHYXRlLkFVVEhfUFJFRklYO1xuICBpZiAoIXBhdGguc3RhcnRzV2l0aChwcmVmaXgpKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdhdGUuaGFuZGxlcihhd2FpdCB0dW5uZWxHYXRlLndlYlJlcXVlc3QocmVxdWVzdCkpO1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT4gPSB7fTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIHJlc3VsdC5oZWFkZXJzLmVudHJpZXMoKSkge1xuICAgIGlmIChuYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwic2V0LWNvb2tpZVwiKSBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gIH1cbiAgY29uc3QgY29va2llcyA9IHJlc3VsdC5oZWFkZXJzLmdldFNldENvb2tpZSgpO1xuICBpZiAoY29va2llcy5sZW5ndGgpIGhlYWRlcnNbXCJzZXQtY29va2llXCJdID0gY29va2llcztcbiAgcmVzcG9uc2Uud3JpdGVIZWFkKHJlc3VsdC5zdGF0dXMsIGhlYWRlcnMpO1xuICByZXNwb25zZS5lbmQoQnVmZmVyLmZyb20oYXdhaXQgcmVzdWx0LmFycmF5QnVmZmVyKCkpKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogU3RhcnQgdGhlIHByb3h5IGFuZCByZXNvbHZlIG9uY2UgaXQgaXMgbGlzdGVuaW5nLlxuICpcbiAqIGBwdWJsaWNEb21haW5gIGlzIGludGVudGlvbmFsbHkgTk9UIHBhc3NlZCB0byBgZ2F0ZVJlcXVlc3RgOiBvbiB0aGlzIHBhdGggZXZlcnlcbiAqIHJlcXVlc3QgYXJyaXZlZCBvbiB0aGUgcHVibGljIHBvcnQsIHNvIGl0IElTIHR1bm5lbCB0cmFmZmljIGJ5IGNvbnN0cnVjdGlvbiAtXG4gKiB3aGVyZWFzIHRoZSBpbi1wcm9jZXNzIGdhdGUgc2hhcmVzIGEgcG9ydCB3aXRoIHRoZSBwbGF0Zm9ybSBmcm9udCBkb29yIGFuZCBoYXNcbiAqIHRvIHRlbGwgdGhlbSBhcGFydCBieSBgSG9zdGAuIFBhc3NpbmcgdGhlIHJlcXVlc3QncyBvd24gaG9zdCBrZWVwcyB0aGUgc2hhcmVkXG4gKiBkZWNpc2lvbiBmdW5jdGlvbidzIGNvbnRyYWN0IHNhdGlzZmllZCB3aXRob3V0IHdlYWtlbmluZyBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0UHJveHkob3B0aW9uczogUHJveHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3h5ID0gUHJveHlNb2R1bGUuY3JlYXRlUHJveHlTZXJ2ZXIoe1xuICAgIHRhcmdldDogYGh0dHA6Ly8xMjcuMC4wLjE6JHtvcHRpb25zLmFwcFBvcnR9YCxcbiAgICB3czogdHJ1ZSxcbiAgICB4ZndkOiB0cnVlLFxuICB9KTtcbiAgY29uc3QgaGVhZGVyUG9saWN5ID0gdHVubmVsSGVhZGVycy50b0hlYWRlclBvbGljeShvcHRpb25zLmZvcndhcmRIZWFkZXJzKTtcbiAgY29uc3QgZ2F0ZSA9IG9wdGlvbnMuZ2F0ZTtcblxuICBjb25zdCBkZWNpZGUgPSAocmVxdWVzdDogSW5jb21pbmdNZXNzYWdlKTogUHJvbWlzZTx0dW5uZWxHYXRlLkdhdGVBY3Rpb24+ID0+XG4gICAgZ2F0ZVxuICAgICAgPyB0dW5uZWxHYXRlLmdhdGVSZXF1ZXN0KHJlcXVlc3QsIHtcbiAgICAgICAgICBnYXRlLFxuICAgICAgICAgIHB1YmxpY0RvbWFpbjogKHJlcXVlc3QuaGVhZGVycy5ob3N0ID8/IFwiXCIpLnNwbGl0KFwiOlwiKVswXSB8fCBcImxvY2FsaG9zdFwiLFxuICAgICAgICAgIGhlYWRlclBvbGljeSxcbiAgICAgICAgfSlcbiAgICAgIDogUHJvbWlzZS5yZXNvbHZlPHR1bm5lbEdhdGUuR2F0ZUFjdGlvbj4oXCJwYXNzXCIpO1xuXG4gIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigocmVxdWVzdCwgcmVzcG9uc2UpID0+IHtcbiAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gKHJlcXVlc3QudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIilbMF0gPz8gXCIvXCI7XG4gICAgICBpZiAoZ2F0ZSAmJiAoYXdhaXQgaGFuZGxlQXV0aFJvdXRlKHJlcXVlc3QsIHJlc3BvbnNlLCBwYXRoLCBnYXRlKSkpIHJldHVybjtcbiAgICAgIGlmICgoYXdhaXQgZGVjaWRlKHJlcXVlc3QpKSA9PT0gXCJkZW55XCIpIHtcbiAgICAgICAgc2VuZEpzb24ocmVzcG9uc2UsIDQwMSwgdHVubmVsR2F0ZS5VTkFVVEhPUklaRURfQk9EWSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHByb3h5LndlYihyZXF1ZXN0LCByZXNwb25zZSk7XG4gICAgfSkoKS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihcInByb3h5IHJlcXVlc3QgZmFpbGVkXCIsIHsgZXJyb3IgfSk7XG4gICAgICBpZiAoIXJlc3BvbnNlLmhlYWRlcnNTZW50KSBzZW5kSnNvbihyZXNwb25zZSwgNTAyLCB7IGVycm9yOiBcImJhZCBnYXRld2F5XCIgfSk7XG4gICAgICBlbHNlIHJlc3BvbnNlLmVuZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBBIHdlYnNvY2tldCB1cGdyYWRlIGNhbm5vdCBiZSBhbnN3ZXJlZCB3aXRoIGEgNDAxIGJvZHksIHNvIGEgZGVuaWVkIG9uZSBpc1xuICAvLyBkZXN0cm95ZWQgLSB0aGUgY2xpZW50IHNlZXMgdGhlIGhhbmRzaGFrZSBmYWlsLCB3aGljaCBpcyB3aGF0IGEgYnJvd3NlcidzXG4gIC8vIFdlYlNvY2tldCBlcnJvciBoYW5kbGVyIGV4cGVjdHMuXG4gIHNlcnZlci5vbihcInVwZ3JhZGVcIiwgKHJlcXVlc3Q6IEluY29taW5nTWVzc2FnZSwgc29ja2V0OiBTb2NrZXQsIGhlYWQ6IEJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IHVwZ3JhZGVTb2NrZXQgPSBzb2NrZXQgYXMgVXBncmFkZVNvY2tldDtcbiAgICB1cGdyYWRlU29ja2V0LmRlc3Ryb3lTb29uID8/PSAoKSA9PiB1cGdyYWRlU29ja2V0LmVuZCgpO1xuICAgIHZvaWQgZGVjaWRlKHJlcXVlc3QpXG4gICAgICAudGhlbigoYWN0aW9uKSA9PiB7XG4gICAgICAgIGlmIChhY3Rpb24gPT09IFwiZGVueVwiKSB1cGdyYWRlU29ja2V0LmRlc3Ryb3koKTtcbiAgICAgICAgZWxzZSBwcm94eS53cyhyZXF1ZXN0LCB1cGdyYWRlU29ja2V0LCBoZWFkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4gdXBncmFkZVNvY2tldC5kZXN0cm95KCkpO1xuICB9KTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXJ2ZXIubGlzdGVuKG9wdGlvbnMucHVibGljUG9ydCwgXCIwLjAuMC4wXCIsICgpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKFwicHJveHkgbGlzdGVuaW5nXCIsIHsgcHVibGljUG9ydDogb3B0aW9ucy5wdWJsaWNQb3J0LCBhcHBQb3J0OiBvcHRpb25zLmFwcFBvcnQgfSk7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuIl19
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBNkMsTUFBTSxXQUFXLENBQUM7QUFFcEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFDTCxJQUFJLElBQUksVUFBVSxFQUNsQixPQUFPLElBQUksYUFBYSxFQUN4QixTQUFTLElBQUksZUFBZSxHQUU3QixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sV0FBVyxNQUFNLGNBQWMsQ0FBQztBQUV2QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBMEIxQyxTQUFTLFFBQVEsQ0FDZixRQUF3QixFQUN4QixNQUFjLEVBQ2QsSUFBYSxFQUNiLFNBQWtCO0lBRWxCLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFO1FBQ3pCLGNBQWMsRUFBRSxrQkFBa0I7UUFDbEMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNsRCxDQUFDLENBQUM7SUFDSCxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsZUFBZSxDQUM1QixPQUF3QixFQUN4QixRQUF3QixFQUN4QixJQUFZLEVBQ1osSUFBaUI7SUFFakIsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQztJQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzQyxNQUFNLE1BQU0sR0FBRyxN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QUksQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQzthQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUM7SUFFRiwrRUFBK0U7SUFDL0UsNEVBQTRFO0lBQzVFLDRFQUE0RTtJQUM1RSx5Q0FBeUM7SUFDekMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDMUUsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNmLEtBQUssQ0FBQyxHQUFHLENBQ1AsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUNQLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDNUIsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFO1lBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQzdCLElBQUk7Z0JBQ0osVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO2dCQUM5QixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87YUFDekIsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUNMLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSByZXZlcnNlIHByb3h5IHRoYXQgbWFrZXMgdGhlIHdyYXBwZXIgcGF0aCBwb3NzaWJsZS5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IGFuZCB0aGUgd3JhcHBlZCBhcHAgcnVucyBhcyBhIGNoaWxkIHByb2Nlc3NcbiAqIG9uIGEgcHJpdmF0ZSBsb29wYmFjayBwb3J0LCBzbyAtIHVubGlrZSB0aGUgaW4tcHJvY2VzcyBwbHVnaW4gLSB0aGVyZSBpcyBub1xuICogbWlkZGxld2FyZSBjaGFpbiB0byBpbnNlcnQgdGhlIGdhdGUgaW50by4gVGhpcyBwcm94eSBpcyB0aGF0IGluc2VydGlvbiBwb2ludDogaXRcbiAqIGFuc3dlcnMgdGhlIGxvZ2luIHJvdXRlcyBpdHNlbGYsIGFwcGxpZXMgdGhlIGdhdGUgdG8gZXZlcnl0aGluZyBlbHNlLCBhbmRcbiAqIGZvcndhcmRzIHdoYXQgc3Vydml2ZXMgdG8gdGhlIGNoaWxkLlxuICpcbiAqIFRoZSBnYXRpbmcgREVDSVNJT04gaXMgbm90IHJlaW1wbGVtZW50ZWQgaGVyZS4gYEBkYngtdG9vbHMvdHVubmVsYCdzXG4gKiBgZ2F0ZS5nYXRlUmVxdWVzdGAgbWFrZXMgaXQgLSB0aGUgc2FtZSBmdW5jdGlvbiB0aGUgRXhwcmVzcyBtaWRkbGV3YXJlIGNhbGxzIC1cbiAqIGFuZCB0aGlzIG1vZHVsZSBvbmx5IGRpZmZlcnMgaW4gaG93IHRoZSBvdXRjb21lIGlzIHdyaXR0ZW46IGEgcHJveGllZCByZXF1ZXN0XG4gKiBpbnN0ZWFkIG9mIGBuZXh0KClgLCBhIGB3cml0ZUhlYWRgIGluc3RlYWQgb2YgYHJlcy5qc29uYC4gVGhhdCBpcyBkZWxpYmVyYXRlOlxuICogdHdvIGluZGVwZW5kZW50IGltcGxlbWVudGF0aW9ucyBvZiBcIndoaWNoIHJlcXVlc3RzIGFyZSBnYXRlZCBhbmQgd2hpY2ggaGVhZGVyc1xuICogYXJlIHN0cmlwcGVkXCIgaXMgdGhlIG9uZSB3YXkgdGhpcyBwYWNrYWdlIGNvdWxkIGJlY29tZSBhIHNlY3VyaXR5IGJ1Zy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyLCB0eXBlIEluY29taW5nTWVzc2FnZSwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJub2RlOmh0dHBcIjtcbmltcG9ydCB0eXBlIHsgU29ja2V0IH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgZ2F0ZSBhcyB0dW5uZWxHYXRlLFxuICBoZWFkZXJzIGFzIHR1bm5lbEhlYWRlcnMsXG4gIGxvZ2luUGFnZSBhcyB0dW5uZWxMb2dpblBhZ2UsXG4gIHR5cGUgQXV0aEdhdGVBcGksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IFByb3h5TW9kdWxlIGZyb20gXCJodHRwLXByb3h5LTNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwcm94eVwiKTtcblxudHlwZSBVcGdyYWRlU29ja2V0ID0gU29ja2V0ICYgeyBkZXN0cm95U29vbj86ICgpID0+IHZvaWQgfTtcblxuZXhwb3J0IGludGVyZmFjZSBQcm94eU9wdGlvbnMge1xuICAvKiogVGhlIHBvcnQgdGhpcyBwcm94eSBsaXN0ZW5zIG9uIC0gdGhlIHBvcnQgcG9ydHIgYW5kIHRoZSBwbGF0Zm9ybSByb3V0ZSB0by4gKi9cbiAgcHVibGljUG9ydDogbnVtYmVyO1xuICAvKiogVGhlIHByaXZhdGUgbG9vcGJhY2sgcG9ydCB0aGUgd3JhcHBlZCBhcHAgbGlzdGVucyBvbi4gKi9cbiAgYXBwUG9ydDogbnVtYmVyO1xuICAvKiogVGhlIGdhdGUgaGFuZGxlcnMuIE9taXR0ZWQgKGFuIGAtLWluc2VjdXJlYCBydW4pIGZvcndhcmRzIGV2ZXJ5dGhpbmcuICovXG4gIGdhdGU/OiBBdXRoR2F0ZUFwaTtcbiAgLyoqIEV4dHJhIGB4LWAgaGVhZGVycyB0dW5uZWwgdHJhZmZpYyBtYXkgZm9yd2FyZC4gKi9cbiAgZm9yd2FyZEhlYWRlcnM/OiByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIFBhdGggcHJlZml4ZXMgdG8gZ2F0ZSBiZXlvbmQgYC9hcGkvYCAoZS5nLiBgL3dzYCBmb3IgYSBXZWJTb2NrZXQgYXBwKS4gKi9cbiAgZ2F0ZVBhdGhzPzogcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKiBCcmFuZCBuYW1lIGZvciB0aGUgaG9zdGVkIGxvZ2luIHBhZ2Ugc2hvd24gb24gYSBkZW5pZWQgYnJvd3NlciBuYXZpZ2F0aW9uLiAqL1xuICBicmFuZE5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBZGRyZXNzZXMgdG8gbGlzdGVuIG9uLiBEZWZhdWx0cyB0byBhIHNpbmdsZSBgMC4wLjAuMGAgKGV2ZXJ5IGludGVyZmFjZSksXG4gICAqIHRoZSBwb3J0ci9wbGF0Zm9ybSBjYXNlLiBQYXNzIHNwZWNpZmljIGludGVyZmFjZSBJUHMgdG8gZXhwb3NlIHRoZSBnYXRlIG9uXG4gICAqIG9ubHkgdGhvc2UgLSBlLmcuIGFuIG92ZXJsYXkvTEFOIGFkZHJlc3Mgd2hpbGUgbG9vcGJhY2sgcmVhY2hlcyB0aGUgdXBzdHJlYW1cbiAgICogZGlyZWN0bHkgYW5kIHVuZ2F0ZWQuXG4gICAqL1xuICBiaW5kSG9zdHM/OiByZWFkb25seSBzdHJpbmdbXTtcbn1cblxuZnVuY3Rpb24gc2VuZEpzb24oXG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZSxcbiAgc3RhdHVzOiBudW1iZXIsXG4gIGJvZHk6IHVua25vd24sXG4gIHNldENvb2tpZT86IHN0cmluZyxcbik6IHZvaWQge1xuICByZXNwb25zZS53cml0ZUhlYWQoc3RhdHVzLCB7XG4gICAgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgLi4uKHNldENvb2tpZSA/IHsgXCJzZXQtY29va2llXCI6IHNldENvb2tpZSB9IDoge30pLFxuICB9KTtcbiAgcmVzcG9uc2UuZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKTtcbn1cblxuLyoqXG4gKiBIYW5kIGV2ZXJ5IEJldHRlciBBdXRoIGFuZCBjb21wYXRpYmlsaXR5IHJvdXRlIHRvIHRoZSBzaGFyZWQgZ2F0ZSBydW50aW1lLlxuICovXG5hc3luYyBmdW5jdGlvbiBoYW5kbGVBdXRoUm91dGUoXG4gIHJlcXVlc3Q6IEluY29taW5nTWVzc2FnZSxcbiAgcmVzcG9uc2U6IFNlcnZlclJlc3BvbnNlLFxuICBwYXRoOiBzdHJpbmcsXG4gIGdhdGU6IEF1dGhHYXRlQXBpLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHByZWZpeCA9IHR1bm5lbEdhdGUuQVVUSF9QUkVGSVg7XG4gIGlmICghcGF0aC5zdGFydHNXaXRoKHByZWZpeCkpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2F0ZS5oYW5kbGVyKGF3YWl0IHR1bm5lbEdhdGUud2ViUmVxdWVzdChyZXF1ZXN0KSk7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgcmVzdWx0LmhlYWRlcnMuZW50cmllcygpKSB7XG4gICAgaWYgKG5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJzZXQtY29va2llXCIpIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgfVxuICBjb25zdCBjb29raWVzID0gcmVzdWx0LmhlYWRlcnMuZ2V0U2V0Q29va2llKCk7XG4gIGlmIChjb29raWVzLmxlbmd0aCkgaGVhZGVyc1tcInNldC1jb29raWVcIl0gPSBjb29raWVzO1xuICByZXNwb25zZS53cml0ZUhlYWQocmVzdWx0LnN0YXR1cywgaGVhZGVycyk7XG4gIHJlc3BvbnNlLmVuZChCdWZmZXIuZnJvbShhd2FpdCByZXN1bHQuYXJyYXlCdWZmZXIoKSkpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBTdGFydCB0aGUgcHJveHkgYW5kIHJlc29sdmUgb25jZSBpdCBpcyBsaXN0ZW5pbmcuXG4gKlxuICogYHB1YmxpY0RvbWFpbmAgaXMgaW50ZW50aW9uYWxseSBOT1QgcGFzc2VkIHRvIGBnYXRlUmVxdWVzdGA6IG9uIHRoaXMgcGF0aCBldmVyeVxuICogcmVxdWVzdCBhcnJpdmVkIG9uIHRoZSBwdWJsaWMgcG9ydCwgc28gaXQgSVMgdHVubmVsIHRyYWZmaWMgYnkgY29uc3RydWN0aW9uIC1cbiAqIHdoZXJlYXMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBzaGFyZXMgYSBwb3J0IHdpdGggdGhlIHBsYXRmb3JtIGZyb250IGRvb3IgYW5kIGhhc1xuICogdG8gdGVsbCB0aGVtIGFwYXJ0IGJ5IGBIb3N0YC4gUGFzc2luZyB0aGUgcmVxdWVzdCdzIG93biBob3N0IGtlZXBzIHRoZSBzaGFyZWRcbiAqIGRlY2lzaW9uIGZ1bmN0aW9uJ3MgY29udHJhY3Qgc2F0aXNmaWVkIHdpdGhvdXQgd2Vha2VuaW5nIGl0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQcm94eShvcHRpb25zOiBQcm94eU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJveHkgPSBQcm94eU1vZHVsZS5jcmVhdGVQcm94eVNlcnZlcih7XG4gICAgdGFyZ2V0OiBgaHR0cDovLzEyNy4wLjAuMToke29wdGlvbnMuYXBwUG9ydH1gLFxuICAgIHdzOiB0cnVlLFxuICAgIHhmd2Q6IHRydWUsXG4gIH0pO1xuICBjb25zdCBoZWFkZXJQb2xpY3kgPSB0dW5uZWxIZWFkZXJzLnRvSGVhZGVyUG9saWN5KG9wdGlvbnMuZm9yd2FyZEhlYWRlcnMpO1xuICBjb25zdCBnYXRlID0gb3B0aW9ucy5nYXRlO1xuXG4gIGNvbnN0IGRlY2lkZSA9IChyZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHR1bm5lbEdhdGUuR2F0ZUFjdGlvbj4gPT5cbiAgICBnYXRlXG4gICAgICA/IHR1bm5lbEdhdGUuZ2F0ZVJlcXVlc3QocmVxdWVzdCwge1xuICAgICAgICAgIGdhdGUsXG4gICAgICAgICAgcHVibGljRG9tYWluOiAocmVxdWVzdC5oZWFkZXJzLmhvc3QgPz8gXCJcIikuc3BsaXQoXCI6XCIpWzBdIHx8IFwibG9jYWxob3N0XCIsXG4gICAgICAgICAgaGVhZGVyUG9saWN5LFxuICAgICAgICAgIGdhdGVQYXRoczogb3B0aW9ucy5nYXRlUGF0aHMsXG4gICAgICAgIH0pXG4gICAgICA6IFByb21pc2UucmVzb2x2ZTx0dW5uZWxHYXRlLkdhdGVBY3Rpb24+KFwicGFzc1wiKTtcblxuICBjb25zdCBvblJlcXVlc3QgPSAocmVxdWVzdDogSW5jb21pbmdNZXNzYWdlLCByZXNwb25zZTogU2VydmVyUmVzcG9uc2UpOiB2b2lkID0+IHtcbiAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gKHJlcXVlc3QudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIilbMF0gPz8gXCIvXCI7XG4gICAgICBpZiAoZ2F0ZSAmJiAoYXdhaXQgaGFuZGxlQXV0aFJvdXRlKHJlcXVlc3QsIHJlc3BvbnNlLCBwYXRoLCBnYXRlKSkpIHJldHVybjtcbiAgICAgIGlmICgoYXdhaXQgZGVjaWRlKHJlcXVlc3QpKSA9PT0gXCJkZW55XCIpIHtcbiAgICAgICAgLy8gQSBkZW5pZWQgYnJvd3NlciBuYXZpZ2F0aW9uIGdldHMgdGhlIGhvc3RlZCBsb2dpbiBwYWdlOyBhbnl0aGluZyBlbHNlXG4gICAgICAgIC8vIChhbiBYSFIsIGEgL3dzIHVwZ3JhZGUgcHJvYmUsIGEgbm9uLUhUTUwgZmV0Y2gpIGdldHMgdGhlIDQwMSBKU09OLlxuICAgICAgICBpZiAoZ2F0ZSAmJiB0dW5uZWxHYXRlLndhbnRzTG9naW5QYWdlKHJlcXVlc3QpKSB7XG4gICAgICAgICAgY29uc3QgaHRtbCA9IHR1bm5lbExvZ2luUGFnZS5sb2dpblBhZ2VIdG1sKHtcbiAgICAgICAgICAgIGJyYW5kTmFtZTogb3B0aW9ucy5icmFuZE5hbWUgPz8gXCJ0aGlzIGFwcFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg0MDEsIHsgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIiB9KTtcbiAgICAgICAgICByZXNwb25zZS5lbmQoaHRtbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VuZEpzb24ocmVzcG9uc2UsIDQwMSwgdHVubmVsR2F0ZS5VTkFVVEhPUklaRURfQk9EWSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcHJveHkud2ViKHJlcXVlc3QsIHJlc3BvbnNlKTtcbiAgICB9KSgpLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKFwicHJveHkgcmVxdWVzdCBmYWlsZWRcIiwgeyBlcnJvciB9KTtcbiAgICAgIGlmICghcmVzcG9uc2UuaGVhZGVyc1NlbnQpIHNlbmRKc29uKHJlc3BvbnNlLCA1MDIsIHsgZXJyb3I6IFwiYmFkIGdhdGV3YXlcIiB9KTtcbiAgICAgIGVsc2UgcmVzcG9uc2UuZW5kKCk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gQSB3ZWJzb2NrZXQgdXBncmFkZSBjYW5ub3QgYmUgYW5zd2VyZWQgd2l0aCBhIDQwMSBib2R5LCBzbyBhIGRlbmllZCBvbmUgaXNcbiAgLy8gZGVzdHJveWVkIC0gdGhlIGNsaWVudCBzZWVzIHRoZSBoYW5kc2hha2UgZmFpbCwgd2hpY2ggaXMgd2hhdCBhIGJyb3dzZXInc1xuICAvLyBXZWJTb2NrZXQgZXJyb3IgaGFuZGxlciBleHBlY3RzLlxuICBjb25zdCBvblVwZ3JhZGUgPSAocmVxdWVzdDogSW5jb21pbmdNZXNzYWdlLCBzb2NrZXQ6IFNvY2tldCwgaGVhZDogQnVmZmVyKTogdm9pZCA9PiB7XG4gICAgY29uc3QgdXBncmFkZVNvY2tldCA9IHNvY2tldCBhcyBVcGdyYWRlU29ja2V0O1xuICAgIHVwZ3JhZGVTb2NrZXQuZGVzdHJveVNvb24gPz89ICgpID0+IHVwZ3JhZGVTb2NrZXQuZW5kKCk7XG4gICAgdm9pZCBkZWNpZGUocmVxdWVzdClcbiAgICAgIC50aGVuKChhY3Rpb24pID0+IHtcbiAgICAgICAgaWYgKGFjdGlvbiA9PT0gXCJkZW55XCIpIHVwZ3JhZGVTb2NrZXQuZGVzdHJveSgpO1xuICAgICAgICBlbHNlIHByb3h5LndzKHJlcXVlc3QsIHVwZ3JhZGVTb2NrZXQsIGhlYWQpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB1cGdyYWRlU29ja2V0LmRlc3Ryb3koKSk7XG4gIH07XG5cbiAgLy8gT25lIG5ldC5TZXJ2ZXIgYmluZHMgb25lIGFkZHJlc3MsIHNvIGxpc3RlbiBlYWNoIGhvc3Qgb24gaXRzIG93biBzZXJ2ZXIgdGhhdFxuICAvLyBzaGFyZXMgdGhlIHNhbWUgaGFuZGxlcnMuIEJpbmRpbmcgc3BlY2lmaWMgaW50ZXJmYWNlIElQcyAocmF0aGVyIHRoYW4gdGhlXG4gIC8vIGRlZmF1bHQgMC4wLjAuMCkgaXMgd2hhdCBsZXRzIHRoZSBnYXRlIGZyb250IGFuIG92ZXJsYXkvTEFOIGFkZHJlc3Mgd2hpbGVcbiAgLy8gbG9vcGJhY2sgcmVhY2hlcyB0aGUgdXBzdHJlYW0gdW5nYXRlZC5cbiAgY29uc3QgaG9zdHMgPSBvcHRpb25zLmJpbmRIb3N0cz8ubGVuZ3RoID8gb3B0aW9ucy5iaW5kSG9zdHMgOiBbXCIwLjAuMC4wXCJdO1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBob3N0cy5tYXAoXG4gICAgICAoaG9zdCkgPT5cbiAgICAgICAgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIob25SZXF1ZXN0KTtcbiAgICAgICAgICBzZXJ2ZXIub24oXCJ1cGdyYWRlXCIsIG9uVXBncmFkZSk7XG4gICAgICAgICAgc2VydmVyLmxpc3RlbihvcHRpb25zLnB1YmxpY1BvcnQsIGhvc3QsICgpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFwicHJveHkgbGlzdGVuaW5nXCIsIHtcbiAgICAgICAgICAgICAgaG9zdCxcbiAgICAgICAgICAgICAgcHVibGljUG9ydDogb3B0aW9ucy5wdWJsaWNQb3J0LFxuICAgICAgICAgICAgICBhcHBQb3J0OiBvcHRpb25zLmFwcFBvcnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgKSxcbiAgKTtcbn1cbiJdfQ==
package/package.json CHANGED
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@databricks/appkit": "^0.43.0",
27
- "@dbx-tools/appkit": "0.6.95",
28
- "@dbx-tools/auth": "0.6.95",
29
- "@dbx-tools/core": "0.6.95",
30
- "@dbx-tools/email": "0.6.95",
31
- "@dbx-tools/shared-core": "0.6.95",
32
- "@dbx-tools/shared-email": "0.6.95",
33
- "@dbx-tools/tunnel": "0.6.95",
27
+ "@dbx-tools/appkit": "0.6.97",
28
+ "@dbx-tools/auth": "0.6.97",
29
+ "@dbx-tools/core": "0.6.97",
30
+ "@dbx-tools/email": "0.6.97",
31
+ "@dbx-tools/shared-core": "0.6.97",
32
+ "@dbx-tools/shared-email": "0.6.97",
33
+ "@dbx-tools/tunnel": "0.6.97",
34
34
  "commander": "^15.0.0",
35
35
  "http-proxy-3": "^1.23.1"
36
36
  },
@@ -64,7 +64,7 @@
64
64
  "./package.json": "./package.json"
65
65
  }
66
66
  },
67
- "version": "0.6.95",
67
+ "version": "0.6.97",
68
68
  "types": "./lib/index.d.ts",
69
69
  "type": "module",
70
70
  "exports": {
package/src/cli.ts CHANGED
@@ -75,6 +75,8 @@ function addOptions(command: Command): Command {
75
75
  .option("--auth-storage <mode>", "auth database: auto, lakebase, or sqlite")
76
76
  .option("--auth-sqlite-path <path>", "local Better Auth SQLite file")
77
77
  .option("--forward-headers <patterns...>", "extra x- headers tunnel traffic may forward")
78
+ .option("--gate-path <prefix...>", "path prefixes to gate beyond /api/ (e.g. /ws)")
79
+ .option("--bind <host...>", "interface IPs the gate listens on (default: 0.0.0.0)")
78
80
  .option("--insecure", "run open, with no gate");
79
81
  }
80
82
 
@@ -100,26 +102,39 @@ function supervise(children: readonly ChildProcess[]): void {
100
102
 
101
103
  async function run(raw: TunnelOptions, command: readonly string[]): Promise<void> {
102
104
  const [executable, ...args] = command;
103
- if (!executable) {
104
- throw new CommanderError(1, "tunnel.no-command", "no command given - pass it after `--`");
105
- }
106
105
  const resolved = resolveTunnelOptions(raw);
107
-
108
- // The wrapped app must not be reachable from outside: it binds loopback on a
109
- // private port, and the wrapper is the only thing that talks to it. An
110
- // unresolved `--app-port` becomes a free ephemeral port rather than a fixed
111
- // guess, so two tunnels can run side by side.
112
- const appPort = resolved.appPort ?? (await freePort());
113
- const app = spawn(executable, args, {
114
- env: {
115
- ...process.env,
116
- DATABRICKS_APP_PORT: String(appPort),
117
- PORT: String(appPort),
118
- HOST: "127.0.0.1",
119
- },
120
- stdio: "inherit",
121
- });
122
- const children: ChildProcess[] = [app];
106
+ const children: ChildProcess[] = [];
107
+
108
+ // Two upstream modes:
109
+ // - WRAP: a command after `--`. The wrapper spawns it on a private loopback
110
+ // port and is the only thing that talks to it.
111
+ // - ATTACH: no command, but `--app-port` names an already-running upstream
112
+ // (e.g. a local reverse proxy). The gate fronts it without spawning a
113
+ // child. This is what lets the gate sit on an interface in front of a
114
+ // separately-supervised stack.
115
+ let appPort: number;
116
+ if (executable) {
117
+ appPort = resolved.appPort ?? (await freePort());
118
+ const app = spawn(executable, args, {
119
+ env: {
120
+ ...process.env,
121
+ DATABRICKS_APP_PORT: String(appPort),
122
+ PORT: String(appPort),
123
+ HOST: "127.0.0.1",
124
+ },
125
+ stdio: "inherit",
126
+ });
127
+ children.push(app);
128
+ } else if (resolved.appPort) {
129
+ appPort = resolved.appPort;
130
+ logger.info("attaching gate to existing upstream", { appPort });
131
+ } else {
132
+ throw new CommanderError(
133
+ 1,
134
+ "tunnel.no-upstream",
135
+ "no command given (pass it after `--`) and no --app-port to attach to",
136
+ );
137
+ }
123
138
 
124
139
  // Dynamic import: the gate is the only thing here that needs AppKit + SMTP, so
125
140
  // an `--insecure` run never loads either.
@@ -138,6 +153,9 @@ async function run(raw: TunnelOptions, command: readonly string[]): Promise<void
138
153
  appPort,
139
154
  gate,
140
155
  forwardHeaders: resolved.gate.forwardHeaders,
156
+ gatePaths: resolved.gate.gatePaths,
157
+ brandName: resolved.gate.brandName,
158
+ bindHosts: resolved.bindHosts,
141
159
  });
142
160
 
143
161
  if (resolved.portr) {
package/src/options.ts CHANGED
@@ -33,6 +33,8 @@ export interface TunnelOptions {
33
33
  authStorage?: AuthStorageMode;
34
34
  authSqlitePath?: string;
35
35
  forwardHeaders?: string[];
36
+ gatePath?: string[];
37
+ bind?: string[];
36
38
  insecure?: boolean;
37
39
  }
38
40
 
@@ -41,6 +43,8 @@ export interface ResolvedTunnelOptions {
41
43
  publicPort: number;
42
44
  /** The private port the wrapped app is told to bind. Unset means "pick one". */
43
45
  appPort?: number;
46
+ /** Interface IPs the gate listens on. Empty means the default (0.0.0.0). */
47
+ bindHosts: string[];
44
48
  /**
45
49
  * The gate config as the `authGate` PLUGIN takes it - flags only, nothing
46
50
  * resolved. Passed straight to the plugin so it applies its own fallbacks
@@ -72,6 +76,7 @@ export function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOpti
72
76
  storage: options.authStorage,
73
77
  sqlitePath: options.authSqlitePath,
74
78
  forwardHeaders: options.forwardHeaders,
79
+ gatePaths: options.gatePath,
75
80
  insecure: options.insecure,
76
81
  publicDomain: options.publicDomain,
77
82
  };
@@ -79,6 +84,7 @@ export function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOpti
79
84
  return {
80
85
  publicPort,
81
86
  ...(appPort > 0 ? { appPort } : {}),
87
+ bindHosts: options.bind ?? [],
82
88
  gateConfig,
83
89
  gate,
84
90
  portr: portr.resolvePortrConfig({
package/src/proxy.ts CHANGED
@@ -20,7 +20,12 @@
20
20
  import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
21
21
  import type { Socket } from "node:net";
22
22
  import { log } from "@dbx-tools/shared-core";
23
- import { gate as tunnelGate, headers as tunnelHeaders, type AuthGateApi } from "@dbx-tools/tunnel";
23
+ import {
24
+ gate as tunnelGate,
25
+ headers as tunnelHeaders,
26
+ loginPage as tunnelLoginPage,
27
+ type AuthGateApi,
28
+ } from "@dbx-tools/tunnel";
24
29
  import ProxyModule from "http-proxy-3";
25
30
 
26
31
  const logger = log.logger("tunnel:proxy");
@@ -36,6 +41,17 @@ export interface ProxyOptions {
36
41
  gate?: AuthGateApi;
37
42
  /** Extra `x-` headers tunnel traffic may forward. */
38
43
  forwardHeaders?: readonly string[];
44
+ /** Path prefixes to gate beyond `/api/` (e.g. `/ws` for a WebSocket app). */
45
+ gatePaths?: readonly string[];
46
+ /** Brand name for the hosted login page shown on a denied browser navigation. */
47
+ brandName?: string;
48
+ /**
49
+ * Addresses to listen on. Defaults to a single `0.0.0.0` (every interface),
50
+ * the portr/platform case. Pass specific interface IPs to expose the gate on
51
+ * only those - e.g. an overlay/LAN address while loopback reaches the upstream
52
+ * directly and ungated.
53
+ */
54
+ bindHosts?: readonly string[];
39
55
  }
40
56
 
41
57
  function sendJson(
@@ -83,7 +99,7 @@ async function handleAuthRoute(
83
99
  * to tell them apart by `Host`. Passing the request's own host keeps the shared
84
100
  * decision function's contract satisfied without weakening it.
85
101
  */
86
- export function startProxy(options: ProxyOptions): Promise<void> {
102
+ export async function startProxy(options: ProxyOptions): Promise<void> {
87
103
  const proxy = ProxyModule.createProxyServer({
88
104
  target: `http://127.0.0.1:${options.appPort}`,
89
105
  ws: true,
@@ -98,15 +114,26 @@ export function startProxy(options: ProxyOptions): Promise<void> {
98
114
  gate,
99
115
  publicDomain: (request.headers.host ?? "").split(":")[0] || "localhost",
100
116
  headerPolicy,
117
+ gatePaths: options.gatePaths,
101
118
  })
102
119
  : Promise.resolve<tunnelGate.GateAction>("pass");
103
120
 
104
- const server = createServer((request, response) => {
121
+ const onRequest = (request: IncomingMessage, response: ServerResponse): void => {
105
122
  void (async () => {
106
123
  const path = (request.url ?? "/").split("?")[0] ?? "/";
107
124
  if (gate && (await handleAuthRoute(request, response, path, gate))) return;
108
125
  if ((await decide(request)) === "deny") {
109
- sendJson(response, 401, tunnelGate.UNAUTHORIZED_BODY);
126
+ // A denied browser navigation gets the hosted login page; anything else
127
+ // (an XHR, a /ws upgrade probe, a non-HTML fetch) gets the 401 JSON.
128
+ if (gate && tunnelGate.wantsLoginPage(request)) {
129
+ const html = tunnelLoginPage.loginPageHtml({
130
+ brandName: options.brandName ?? "this app",
131
+ });
132
+ response.writeHead(401, { "content-type": "text/html; charset=utf-8" });
133
+ response.end(html);
134
+ } else {
135
+ sendJson(response, 401, tunnelGate.UNAUTHORIZED_BODY);
136
+ }
110
137
  return;
111
138
  }
112
139
  proxy.web(request, response);
@@ -115,12 +142,12 @@ export function startProxy(options: ProxyOptions): Promise<void> {
115
142
  if (!response.headersSent) sendJson(response, 502, { error: "bad gateway" });
116
143
  else response.end();
117
144
  });
118
- });
145
+ };
119
146
 
120
147
  // A websocket upgrade cannot be answered with a 401 body, so a denied one is
121
148
  // destroyed - the client sees the handshake fail, which is what a browser's
122
149
  // WebSocket error handler expects.
123
- server.on("upgrade", (request: IncomingMessage, socket: Socket, head: Buffer) => {
150
+ const onUpgrade = (request: IncomingMessage, socket: Socket, head: Buffer): void => {
124
151
  const upgradeSocket = socket as UpgradeSocket;
125
152
  upgradeSocket.destroySoon ??= () => upgradeSocket.end();
126
153
  void decide(request)
@@ -129,12 +156,28 @@ export function startProxy(options: ProxyOptions): Promise<void> {
129
156
  else proxy.ws(request, upgradeSocket, head);
130
157
  })
131
158
  .catch(() => upgradeSocket.destroy());
132
- });
159
+ };
133
160
 
134
- return new Promise((resolve) => {
135
- server.listen(options.publicPort, "0.0.0.0", () => {
136
- logger.info("proxy listening", { publicPort: options.publicPort, appPort: options.appPort });
137
- resolve();
138
- });
139
- });
161
+ // One net.Server binds one address, so listen each host on its own server that
162
+ // shares the same handlers. Binding specific interface IPs (rather than the
163
+ // default 0.0.0.0) is what lets the gate front an overlay/LAN address while
164
+ // loopback reaches the upstream ungated.
165
+ const hosts = options.bindHosts?.length ? options.bindHosts : ["0.0.0.0"];
166
+ await Promise.all(
167
+ hosts.map(
168
+ (host) =>
169
+ new Promise<void>((resolve) => {
170
+ const server = createServer(onRequest);
171
+ server.on("upgrade", onUpgrade);
172
+ server.listen(options.publicPort, host, () => {
173
+ logger.info("proxy listening", {
174
+ host,
175
+ publicPort: options.publicPort,
176
+ appPort: options.appPort,
177
+ });
178
+ resolve();
179
+ });
180
+ }),
181
+ ),
182
+ );
140
183
  }