@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.
- package/README.md +93 -17
- package/index.ts +5 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -1
- package/lib/src/allowlist.d.ts +14 -9
- package/lib/src/allowlist.js +28 -53
- package/lib/src/cli.js +24 -16
- package/lib/src/env.d.ts +51 -0
- package/lib/src/env.js +51 -0
- package/lib/src/headers.d.ts +108 -0
- package/lib/src/headers.js +140 -0
- package/lib/src/otp.d.ts +1 -1
- package/lib/src/otp.js +7 -6
- package/lib/src/plugin.d.ts +6 -6
- package/lib/src/plugin.js +11 -8
- package/lib/src/portr.d.ts +3 -3
- package/lib/src/portr.js +10 -8
- package/lib/src/proxy.d.ts +8 -1
- package/lib/src/proxy.js +59 -19
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -6
- package/src/allowlist.ts +27 -55
- package/src/cli.ts +29 -15
- package/src/env.ts +62 -0
- package/src/headers.ts +155 -0
- package/src/otp.ts +6 -5
- package/src/plugin.ts +23 -17
- package/src/portr.ts +9 -7
- package/src/proxy.ts +71 -18
package/README.md
CHANGED
|
@@ -41,6 +41,11 @@ address against an allow-list, verified by a code sent over
|
|
|
41
41
|
regex literal (`/^ops-.*@example\.com$/`). An empty list allows nobody.
|
|
42
42
|
- Per-email and per-IP fixed-window rate limiting, plus anti-enumeration: a code
|
|
43
43
|
request always answers `{ ok: true }`, whether or not the address is allowed.
|
|
44
|
+
- Inbound `x-` headers are stripped by default and re-allowed by pattern, so a
|
|
45
|
+
public caller cannot spoof the headers the app trusts - above all
|
|
46
|
+
`x-forwarded-access-token`, which would otherwise let anyone drive the app's
|
|
47
|
+
workspace calls with a pasted token. Add an app's own headers with
|
|
48
|
+
`--forward-headers`.
|
|
44
49
|
- Platform traffic passes through UNGATED. The gate distinguishes the portr
|
|
45
50
|
client (a loopback source address, same container) from the hosting platform's
|
|
46
51
|
front door (a non-loopback container-network address), so health checks and the
|
|
@@ -87,23 +92,91 @@ original public port itself.
|
|
|
87
92
|
Every flag has an environment fallback, so a deployment can configure the gate
|
|
88
93
|
with no change to its start command.
|
|
89
94
|
|
|
90
|
-
| Flag
|
|
91
|
-
|
|
|
92
|
-
| `--allow`
|
|
93
|
-
| `--subject`
|
|
94
|
-
| `--brand-name`
|
|
95
|
-
| `--message`
|
|
96
|
-
| `--session-ttl`
|
|
97
|
-
| `--code-ttl`
|
|
98
|
-
| `--subdomain`
|
|
99
|
-
| `--public-domain`
|
|
100
|
-
| `--
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
| Flag | Env | Default |
|
|
96
|
+
| ------------------- | ------------------------- | ------------------------------ |
|
|
97
|
+
| `--allow` | `TUNNEL_AUTH_ALLOW` | empty (allow nobody) |
|
|
98
|
+
| `--subject` | `TUNNEL_AUTH_SUBJECT` | `Your verification code` |
|
|
99
|
+
| `--brand-name` | `TUNNEL_AUTH_BRAND_NAME` | the brand context `name` |
|
|
100
|
+
| `--message` | `TUNNEL_AUTH_MESSAGE` | `Your verification code is:` |
|
|
101
|
+
| `--session-ttl` | `TUNNEL_AUTH_SESSION_TTL` | `43200` (12 hours) |
|
|
102
|
+
| `--code-ttl` | `TUNNEL_AUTH_CODE_TTL` | `600` (10 minutes) |
|
|
103
|
+
| `--subdomain` | - | derived from the public domain |
|
|
104
|
+
| `--public-domain` | `TUNNEL_PUBLIC_DOMAIN` | - |
|
|
105
|
+
| `--forward-headers` | `TUNNEL_FORWARD_HEADERS` | the built-in `x-` allow-list |
|
|
106
|
+
| `--insecure` | `TUNNEL_INSECURE` | off (the gate is required) |
|
|
107
|
+
| - | `TUNNEL_AUTH_JWT_SECRET` | an ephemeral per-process key |
|
|
108
|
+
|
|
109
|
+
Every variable is `TUNNEL_`-prefixed because the gate runs as a WRAPPER: it and
|
|
110
|
+
the app it wraps share one environment, so a generic name is one the app may
|
|
111
|
+
already be using. The earlier unprefixed spellings - `AUTH_SUBJECT`,
|
|
112
|
+
`AUTH_BRAND_NAME`, `AUTH_MESSAGE`, `AUTH_SESSION_TTL`, `AUTH_CODE_TTL`,
|
|
113
|
+
`AUTH_JWT_SECRET`, `EMAIL_AUTH_ALLOW`, `PUBLIC_DOMAIN` - are still read as
|
|
114
|
+
deprecated aliases, with the `TUNNEL_` name winning when both are set, so an
|
|
115
|
+
existing deployment needs no coordinated rename. `PORTR_TOKEN` / `PORTR_SERVER`
|
|
116
|
+
keep their names: that namespace belongs to portr itself, as does
|
|
117
|
+
`DATABRICKS_APP_PORT`, which the platform sets and the gate honours.
|
|
118
|
+
|
|
119
|
+
`--allow` and `TUNNEL_AUTH_ALLOW` are UNIONED rather than one overriding the
|
|
103
120
|
other, so a deployment-wide allow-list and a per-invocation addition both grant
|
|
104
|
-
access. Session signing reads `
|
|
105
|
-
an ephemeral per-process key, so sessions simply do not survive a restart
|
|
106
|
-
than the gate refusing to serve.
|
|
121
|
+
access. Session signing reads `TUNNEL_AUTH_JWT_SECRET`; when it is unset the gate
|
|
122
|
+
mints an ephemeral per-process key, so sessions simply do not survive a restart
|
|
123
|
+
rather than the gate refusing to serve. Set it in any deployment running more than
|
|
124
|
+
one instance, or a session minted by one will not verify on another.
|
|
125
|
+
|
|
126
|
+
## Inbound Header Policy
|
|
127
|
+
|
|
128
|
+
Tunnel traffic arrives from the public internet, so every header on it is
|
|
129
|
+
attacker-controlled - and the headers an app trusts are exactly the ones a caller
|
|
130
|
+
must not be able to write, because the app cannot tell a header the Databricks
|
|
131
|
+
front door set from one a browser typed.
|
|
132
|
+
|
|
133
|
+
Enumerating headers to remove is a losing game (a deny-list is only correct until
|
|
134
|
+
the platform adds a header), so the policy is inverted: **every `x-`-prefixed
|
|
135
|
+
request header is stripped from tunnel traffic unless a pattern allows it.** A
|
|
136
|
+
header nobody thought about is removed rather than trusted. Non-`x-` headers -
|
|
137
|
+
`content-type`, `accept`, `authorization`, `cookie` - are the app's normal input
|
|
138
|
+
and pass through untouched.
|
|
139
|
+
|
|
140
|
+
The default allow-list covers the `x-` namespaces this repo's own client sends
|
|
141
|
+
and its own server reads, so a dbx-tools app works behind the tunnel with no
|
|
142
|
+
configuration:
|
|
143
|
+
|
|
144
|
+
| Pattern | Why |
|
|
145
|
+
| ------------------ | --------------------------------------------------- |
|
|
146
|
+
| `x-mastra-*` | thread and model routing for `@dbx-tools/ui-mastra` |
|
|
147
|
+
| `x-mlflow-*` | MLflow trace correlation for feedback |
|
|
148
|
+
| `x-requested-with` | the conventional AJAX marker |
|
|
149
|
+
|
|
150
|
+
Add an app's own headers with `--forward-headers` /`TUNNEL_FORWARD_HEADERS`. Each
|
|
151
|
+
entry is a literal name, a shell-style glob, or a `/regex/` - the same three
|
|
152
|
+
shapes the email allow-list takes - and the configured list is UNIONED with the
|
|
153
|
+
defaults, so extending it never silently breaks the built-in surfaces:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
dbxt-tunnel --forward-headers "x-acme-*, /^x-trace-/, x-tenant" -- bun src/server.ts
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Some headers no pattern can forward. These decide who a request is and where it
|
|
160
|
+
came from, and on tunnel traffic only the gate may answer that:
|
|
161
|
+
|
|
162
|
+
| Header | Why it is never forwarded |
|
|
163
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| `x-forwarded-access-token` | OBO auth. A pasted workspace token would make every call in the app run as its owner; a verified email proves nothing about who a credential belongs to. |
|
|
165
|
+
| `x-forwarded-user`, `-email` | Caller identity. The gate sets these itself, from a verified session. |
|
|
166
|
+
| `x-forwarded-preferred-username` | Display identity from the IdP. |
|
|
167
|
+
| `x-forwarded-host`, `-proto`, `-port` | Original host/scheme/port. Spoofing them poisons absolute URLs the app builds, or makes a plaintext request look like TLS. |
|
|
168
|
+
| `x-forwarded-for`, `x-real-ip` | Client IP. Spoofing forges the audit trail and gives a caller a fresh rate-limit bucket per request. |
|
|
169
|
+
| `x-request-id` | Request correlation UUID. Forged or colliding ids make logs unreliable. |
|
|
170
|
+
|
|
171
|
+
The identity headers are AppKit's OBO contract; the rest are the
|
|
172
|
+
[`X-Forwarded-*` set Databricks Apps documents passing to an
|
|
173
|
+
app](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/http-headers),
|
|
174
|
+
plus the conventional `x-forwarded-proto`/`-port`/`x-real-ip` a library may read
|
|
175
|
+
anyway. Dropping the transport headers costs nothing: the proxy re-adds them from
|
|
176
|
+
the real socket after the policy runs, so the app sees the honest values instead
|
|
177
|
+
of the caller's claim. Rate limiting reads the client IP before stripping, and
|
|
178
|
+
takes the **rightmost** `x-forwarded-for` entry - the only one a proxy appended
|
|
179
|
+
rather than a client supplied.
|
|
107
180
|
|
|
108
181
|
## Use The Gate As A Plugin
|
|
109
182
|
|
|
@@ -156,10 +229,13 @@ by hand.
|
|
|
156
229
|
- `proxy` - the public-port reverse proxy: loopback-vs-platform classification,
|
|
157
230
|
open login routes, session enforcement, and WebSocket forwarding.
|
|
158
231
|
- `otp` - the `CacheManager`-backed code store and the session JWT.
|
|
159
|
-
- `allowlist` - domain / glob / regex matching and `looksLikeEmail`.
|
|
232
|
+
- `allowlist` - email domain / glob / regex matching and `looksLikeEmail`.
|
|
233
|
+
- `headers` - the inbound-header allow-list: `toHeaderPolicy()`,
|
|
234
|
+
`DEFAULT_FORWARD_HEADERS`, and the `PROTECTED_HEADERS` no pattern can forward.
|
|
160
235
|
- `rate-limit` - the in-memory fixed-window limiter (single-instance only; not
|
|
161
236
|
distributed).
|
|
162
237
|
- `portr` - portr install, config rendering, and child launch.
|
|
238
|
+
- `env` - the environment-variable names, each with its deprecated aliases.
|
|
163
239
|
- `app` - boots the minimal gate AppKit app and returns the `AuthGateApi`.
|
|
164
240
|
|
|
165
241
|
Browser-safe login wire schemas (the request/verify payloads and the session
|
package/index.ts
CHANGED
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
export * as allowlist from "./src/allowlist.ts";
|
|
6
6
|
export * as app from "./src/app.ts";
|
|
7
7
|
export * as cli from "./src/cli.ts";
|
|
8
|
+
export * as env from "./src/env.ts";
|
|
9
|
+
export * as headers from "./src/headers.ts";
|
|
8
10
|
export * as otp from "./src/otp.ts";
|
|
9
11
|
export * as plugin from "./src/plugin.ts";
|
|
10
12
|
export * as portr from "./src/portr.ts";
|
|
11
13
|
export * as proxy from "./src/proxy.ts";
|
|
12
14
|
export * as rateLimit from "./src/rate-limit.ts";
|
|
13
15
|
export { CommanderError } from "./src/cli.ts";
|
|
16
|
+
export { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.ts";
|
|
17
|
+
export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.ts";
|
|
18
|
+
export type { HeaderPolicy } from "./src/headers.ts";
|
|
14
19
|
export { CodeStore } from "./src/otp.ts";
|
|
15
20
|
export type { VerifyOutcome } from "./src/otp.ts";
|
|
16
21
|
export { AuthGatePlugin, authGate } from "./src/plugin.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
export * as allowlist from "./src/allowlist.ts";
|
|
2
2
|
export * as app from "./src/app.ts";
|
|
3
3
|
export * as cli from "./src/cli.ts";
|
|
4
|
+
export * as env from "./src/env.ts";
|
|
5
|
+
export * as headers from "./src/headers.ts";
|
|
4
6
|
export * as otp from "./src/otp.ts";
|
|
5
7
|
export * as plugin from "./src/plugin.ts";
|
|
6
8
|
export * as portr from "./src/portr.ts";
|
|
7
9
|
export * as proxy from "./src/proxy.ts";
|
|
8
10
|
export * as rateLimit from "./src/rate-limit.ts";
|
|
9
11
|
export { CommanderError } from "./src/cli.ts";
|
|
12
|
+
export { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.ts";
|
|
13
|
+
export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.ts";
|
|
14
|
+
export type { HeaderPolicy } from "./src/headers.ts";
|
|
10
15
|
export { CodeStore } from "./src/otp.ts";
|
|
11
16
|
export type { VerifyOutcome } from "./src/otp.ts";
|
|
12
17
|
export { AuthGatePlugin, authGate } from "./src/plugin.ts";
|
package/lib/index.js
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
export * as allowlist from "./src/allowlist.js";
|
|
5
5
|
export * as app from "./src/app.js";
|
|
6
6
|
export * as cli from "./src/cli.js";
|
|
7
|
+
export * as env from "./src/env.js";
|
|
8
|
+
export * as headers from "./src/headers.js";
|
|
7
9
|
export * as otp from "./src/otp.js";
|
|
8
10
|
export * as plugin from "./src/plugin.js";
|
|
9
11
|
export * as portr from "./src/portr.js";
|
|
10
12
|
export * as proxy from "./src/proxy.js";
|
|
11
13
|
export * as rateLimit from "./src/rate-limit.js";
|
|
12
14
|
export { CommanderError } from "./src/cli.js";
|
|
15
|
+
export { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.js";
|
|
16
|
+
export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.js";
|
|
13
17
|
export { CodeStore } from "./src/otp.js";
|
|
14
18
|
export { AuthGatePlugin, authGate } from "./src/plugin.js";
|
|
15
19
|
export { RateLimiter } from "./src/rate-limit.js";
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3hMLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFekMsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUkzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBhbGxvd2xpc3QgZnJvbSBcIi4vc3JjL2FsbG93bGlzdC50c1wiO1xuZXhwb3J0ICogYXMgYXBwIGZyb20gXCIuL3NyYy9hcHAudHNcIjtcbmV4cG9ydCAqIGFzIGNsaSBmcm9tIFwiLi9zcmMvY2xpLnRzXCI7XG5leHBvcnQgKiBhcyBlbnYgZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0ICogYXMgaGVhZGVycyBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0ICogYXMgb3RwIGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCAqIGFzIHBsdWdpbiBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgKiBhcyBwb3J0ciBmcm9tIFwiLi9zcmMvcG9ydHIudHNcIjtcbmV4cG9ydCAqIGFzIHByb3h5IGZyb20gXCIuL3NyYy9wcm94eS50c1wiO1xuZXhwb3J0ICogYXMgcmF0ZUxpbWl0IGZyb20gXCIuL3NyYy9yYXRlLWxpbWl0LnRzXCI7XG5leHBvcnQgeyBDb21tYW5kZXJFcnJvciB9IGZyb20gXCIuL3NyYy9jbGkudHNcIjtcbmV4cG9ydCB7IEFMTE9XX0VOViwgU1VCSkVDVF9FTlYsIEJSQU5EX05BTUVfRU5WLCBNRVNTQUdFX0VOViwgU0VTU0lPTl9UVExfRU5WLCBDT0RFX1RUTF9FTlYsIEpXVF9TRUNSRVRfRU5WLCBQVUJMSUNfRE9NQUlOX0VOViwgSU5TRUNVUkVfRU5WLCBGT1JXQVJEX0hFQURFUlNfRU5WIH0gZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0IHsgUFJPVEVDVEVEX0hFQURFUlMsIERFRkFVTFRfRk9SV0FSRF9IRUFERVJTIH0gZnJvbSBcIi4vc3JjL2hlYWRlcnMudHNcIjtcbmV4cG9ydCB0eXBlIHsgSGVhZGVyUG9saWN5IH0gZnJvbSBcIi4vc3JjL2hlYWRlcnMudHNcIjtcbmV4cG9ydCB7IENvZGVTdG9yZSB9IGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCB0eXBlIHsgVmVyaWZ5T3V0Y29tZSB9IGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCB7IEF1dGhHYXRlUGx1Z2luLCBhdXRoR2F0ZSB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgQXV0aEdhdGVDb25maWcsIFNlbmRDb2RlT3B0aW9ucywgUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZywgQXV0aEdhdGVBcGkgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgdHlwZSB7IFBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vc3JjL3BvcnRyLnRzXCI7XG5leHBvcnQgdHlwZSB7IFByb3h5T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9wcm94eS50c1wiO1xuZXhwb3J0IHsgUmF0ZUxpbWl0ZXIgfSBmcm9tIFwiLi9zcmMvcmF0ZS1saW1pdC50c1wiO1xuIl19
|
package/lib/src/allowlist.d.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
|
|
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
|
|
8
|
-
*
|
|
9
|
-
* - **glob** - contains `*` or `?`, e.g.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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.
|
package/lib/src/allowlist.js
CHANGED
|
@@ -1,70 +1,45 @@
|
|
|
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
|
|
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
|
|
8
|
-
*
|
|
9
|
-
* - **glob** - contains `*` or `?`, e.g.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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.
|
|
18
23
|
*
|
|
19
24
|
* @module
|
|
20
25
|
*/
|
|
21
|
-
import {
|
|
22
|
-
const logger = log.logger("tunnel:allowlist");
|
|
23
|
-
/** Escape a string for literal use inside a `RegExp`. */
|
|
24
|
-
function escapeRegExp(value) {
|
|
25
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26
|
-
}
|
|
27
|
-
/** Compile a shell-style glob (`*`, `?`) into an anchored, case-insensitive RegExp. */
|
|
28
|
-
function globToRegExp(glob) {
|
|
29
|
-
const body = glob
|
|
30
|
-
.split(/([*?])/)
|
|
31
|
-
.map((part) => (part === "*" ? ".*" : part === "?" ? "." : escapeRegExp(part)))
|
|
32
|
-
.join("");
|
|
33
|
-
return new RegExp(`^${body}$`, "i");
|
|
34
|
-
}
|
|
35
|
-
/** Parse a `/pattern/flags` string into a RegExp, or `undefined` if malformed. */
|
|
36
|
-
function parseRegexLiteral(pattern) {
|
|
37
|
-
const match = /^\/(.+)\/([a-z]*)$/is.exec(pattern);
|
|
38
|
-
if (!match)
|
|
39
|
-
return undefined;
|
|
40
|
-
try {
|
|
41
|
-
const flags = match[2].includes("i") ? match[2] : `${match[2]}i`;
|
|
42
|
-
return new RegExp(match[1], flags);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
logger.warn("ignoring invalid regex allow-list pattern", { pattern, error });
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
26
|
+
import { pattern } from "@dbx-tools/shared-core";
|
|
49
27
|
/** True when `email` matches a single allow-list `pattern`. */
|
|
50
|
-
function matchesPattern(email,
|
|
51
|
-
const trimmed =
|
|
28
|
+
function matchesPattern(email, entry) {
|
|
29
|
+
const trimmed = entry.trim();
|
|
52
30
|
if (!trimmed)
|
|
53
31
|
return false;
|
|
54
32
|
const address = email.trim().toLowerCase();
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return
|
|
33
|
+
// A bare value with no wildcard and no regex delimiters is a DOMAIN shortcut,
|
|
34
|
+
// the one shape shared-core cannot infer: there it would mean whole-string
|
|
35
|
+
// equality against the address, which is never what an operator writing
|
|
36
|
+
// `example.com` in an access list intends.
|
|
37
|
+
if (!trimmed.startsWith("/") && !trimmed.includes("*") && !trimmed.includes("?")) {
|
|
38
|
+
const domain = trimmed.replace(/^@/, "").toLowerCase();
|
|
39
|
+
const at = address.lastIndexOf("@");
|
|
40
|
+
return at >= 0 && address.slice(at + 1) === domain;
|
|
63
41
|
}
|
|
64
|
-
|
|
65
|
-
const domain = trimmed.replace(/^@/, "").toLowerCase();
|
|
66
|
-
const at = address.lastIndexOf("@");
|
|
67
|
-
return at >= 0 && address.slice(at + 1) === domain;
|
|
42
|
+
return pattern.toPattern(trimmed)?.(address) ?? false;
|
|
68
43
|
}
|
|
69
44
|
/**
|
|
70
45
|
* True when `email` is allowed by ANY pattern in `patterns`. An empty (or
|
|
@@ -73,10 +48,10 @@ function matchesPattern(email, pattern) {
|
|
|
73
48
|
export function matchesAllowlist(email, patterns) {
|
|
74
49
|
if (!email || !patterns || patterns.length === 0)
|
|
75
50
|
return false;
|
|
76
|
-
return patterns.some((
|
|
51
|
+
return patterns.some((entry) => matchesPattern(email, entry));
|
|
77
52
|
}
|
|
78
53
|
/** Rough shape check so a clearly-invalid address is rejected before any work. */
|
|
79
54
|
export function looksLikeEmail(value) {
|
|
80
55
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
81
56
|
}
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsb3dsaXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FsbG93bGlzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRWpELCtEQUErRDtBQUMvRCxTQUFTLGNBQWMsQ0FBQyxLQUFhLEVBQUUsS0FBYTtJQUNsRCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0IsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzQixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFM0MsOEVBQThFO0lBQzlFLDJFQUEyRTtJQUMzRSx3RUFBd0U7SUFDeEUsMkNBQTJDO0lBQzNDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNqRixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2RCxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUM7SUFDckQsQ0FBQztJQUVELE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQztBQUN4RCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxRQUF1QztJQUNyRixJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQy9ELE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFhO0lBQzFDLE9BQU8sNEJBQTRCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVuaWZpZWQgYWNjZXNzIGFsbG93LWxpc3QgbWF0Y2hpbmcgZm9yIHRoZSBlbWFpbC1PVFAgZ2F0ZS5cbiAqXG4gKiBFYWNoIHBhdHRlcm4gaW4gdGhlIGNvbmZpZ3VyZWQgbGlzdCBpcyBvbmUgb2YgdGhyZWUgc2hhcGVzOlxuICpcbiAqICAgLSAqKmRvbWFpbiBzaG9ydGN1dCoqIC0gYGV4YW1wbGUuY29tYCBvciBgQGV4YW1wbGUuY29tYDogbWF0Y2hlcyBhbnlcbiAqICAgICBhZGRyZXNzIHdob3NlIGRvbWFpbiBlcXVhbHMgaXQuIFRoaXMgaXMgdGhlIGdhdGUncyBPV04gc2VtYW50aWMgKGEgYmFyZVxuICogICAgIHZhbHVlIG1lYW5zIFwidGhlIGRvbWFpblwiLCBub3QgXCJ0aGUgd2hvbGUgYWRkcmVzc1wiKSwgc28gaXQgaXMgaGFuZGxlZCBoZXJlLlxuICogICAtICoqZ2xvYioqIC0gY29udGFpbnMgYCpgIG9yIGA/YCwgZS5nLiBgKkBleGFtcGxlLmNvbWA6IG1hdGNoZWQgYWdhaW5zdCB0aGVcbiAqICAgICBXSE9MRSBhZGRyZXNzIHdpdGggc2hlbGwtc3R5bGUgd2lsZGNhcmRzLlxuICogICAtICoqcmVnZXgqKiAtIHdyYXBwZWQgaW4gc2xhc2hlcywgYC8uLi4vIFtmbGFnc11gOiB0ZXN0ZWQgYWdhaW5zdCB0aGUgd2hvbGVcbiAqICAgICBhZGRyZXNzLiBBbiBpbnZhbGlkIHJlZ2V4IG5ldmVyIG1hdGNoZXMgKGl0IGlzIHNraXBwZWQgd2l0aCBhIHdhcm5pbmdcbiAqICAgICByYXRoZXIgdGhhbiB0aHJvd2luZykuXG4gKlxuICogT25seSB0aGUgZmlyc3Qgc2hhcGUgaXMgdGhpcyBtb2R1bGUncyBidXNpbmVzczogdGhlIGdsb2IgYW5kIHJlZ2V4IHNoYXBlcyBhcmVcbiAqIGRlbGVnYXRlZCB0byBgQGRieC10b29scy9zaGFyZWQtY29yZWAncyB7QGxpbmsgcGF0dGVybi50b1BhdHRlcm59LCB3aGljaCBpc1xuICogd2hlcmUgdGhhdCBjb21waWxhdGlvbiBsaXZlcyBmb3IgZXZlcnkgYWxsb3ctbGlzdCBpbiB0aGUgcmVwbyAodGhlIHR1bm5lbCdzXG4gKiBpbmJvdW5kLWhlYWRlciBwb2xpY3kgdXNlcyB0aGUgc2FtZSBvbmUpLiBNYXRjaGluZyBpcyBjYXNlLWluc2Vuc2l0aXZlXG4gKiB0aHJvdWdob3V0LlxuICpcbiAqIEFuIEVNUFRZIGxpc3QgbWF0Y2hlcyBub2JvZHkgKGZhaWwgY2xvc2VkKTogYW4gYXBwIHRoYXQgZW5hYmxlcyB0aGUgZ2F0ZSBidXRcbiAqIGNvbmZpZ3VyZXMgbm8gcGF0dGVybnMgbGV0cyBubyBvbmUgaW4sIHdoaWNoIGlzIHRoZSBzYWZlIGRlZmF1bHQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHBhdHRlcm4gfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuXG4vKiogVHJ1ZSB3aGVuIGBlbWFpbGAgbWF0Y2hlcyBhIHNpbmdsZSBhbGxvdy1saXN0IGBwYXR0ZXJuYC4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNQYXR0ZXJuKGVtYWlsOiBzdHJpbmcsIGVudHJ5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgdHJpbW1lZCA9IGVudHJ5LnRyaW0oKTtcbiAgaWYgKCF0cmltbWVkKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IGFkZHJlc3MgPSBlbWFpbC50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICAvLyBBIGJhcmUgdmFsdWUgd2l0aCBubyB3aWxkY2FyZCBhbmQgbm8gcmVnZXggZGVsaW1pdGVycyBpcyBhIERPTUFJTiBzaG9ydGN1dCxcbiAgLy8gdGhlIG9uZSBzaGFwZSBzaGFyZWQtY29yZSBjYW5ub3QgaW5mZXI6IHRoZXJlIGl0IHdvdWxkIG1lYW4gd2hvbGUtc3RyaW5nXG4gIC8vIGVxdWFsaXR5IGFnYWluc3QgdGhlIGFkZHJlc3MsIHdoaWNoIGlzIG5ldmVyIHdoYXQgYW4gb3BlcmF0b3Igd3JpdGluZ1xuICAvLyBgZXhhbXBsZS5jb21gIGluIGFuIGFjY2VzcyBsaXN0IGludGVuZHMuXG4gIGlmICghdHJpbW1lZC5zdGFydHNXaXRoKFwiL1wiKSAmJiAhdHJpbW1lZC5pbmNsdWRlcyhcIipcIikgJiYgIXRyaW1tZWQuaW5jbHVkZXMoXCI/XCIpKSB7XG4gICAgY29uc3QgZG9tYWluID0gdHJpbW1lZC5yZXBsYWNlKC9eQC8sIFwiXCIpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgYXQgPSBhZGRyZXNzLmxhc3RJbmRleE9mKFwiQFwiKTtcbiAgICByZXR1cm4gYXQgPj0gMCAmJiBhZGRyZXNzLnNsaWNlKGF0ICsgMSkgPT09IGRvbWFpbjtcbiAgfVxuXG4gIHJldHVybiBwYXR0ZXJuLnRvUGF0dGVybih0cmltbWVkKT8uKGFkZHJlc3MpID8/IGZhbHNlO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiBgZW1haWxgIGlzIGFsbG93ZWQgYnkgQU5ZIHBhdHRlcm4gaW4gYHBhdHRlcm5zYC4gQW4gZW1wdHkgKG9yXG4gKiBtaXNzaW5nKSBsaXN0IGFsbG93cyBub2JvZHkgLSB0aGUgZ2F0ZSBmYWlscyBjbG9zZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaGVzQWxsb3dsaXN0KGVtYWlsOiBzdHJpbmcsIHBhdHRlcm5zOiByZWFkb25seSBzdHJpbmdbXSB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICBpZiAoIWVtYWlsIHx8ICFwYXR0ZXJucyB8fCBwYXR0ZXJucy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHBhdHRlcm5zLnNvbWUoKGVudHJ5KSA9PiBtYXRjaGVzUGF0dGVybihlbWFpbCwgZW50cnkpKTtcbn1cblxuLyoqIFJvdWdoIHNoYXBlIGNoZWNrIHNvIGEgY2xlYXJseS1pbnZhbGlkIGFkZHJlc3MgaXMgcmVqZWN0ZWQgYmVmb3JlIGFueSB3b3JrLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvb2tzTGlrZUVtYWlsKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eW15cXHNAXStAW15cXHNAXStcXC5bXlxcc0BdKyQvLnRlc3QodmFsdWUudHJpbSgpKTtcbn1cbiJdfQ==
|
package/lib/src/cli.js
CHANGED
|
@@ -25,9 +25,10 @@
|
|
|
25
25
|
* @module
|
|
26
26
|
*/
|
|
27
27
|
import { spawn } from "node:child_process";
|
|
28
|
-
import { log } from "@dbx-tools/shared-core";
|
|
28
|
+
import { env, log } from "@dbx-tools/shared-core";
|
|
29
29
|
import { Command, CommanderError } from "commander";
|
|
30
30
|
import { startGateApp } from "./app.js";
|
|
31
|
+
import { FORWARD_HEADERS_ENV, INSECURE_ENV } from "./env.js";
|
|
31
32
|
import { installPortr, resolvePortrConfig, startPortr, writePortrConfig } from "./portr.js";
|
|
32
33
|
import { startProxy } from "./proxy.js";
|
|
33
34
|
export { CommanderError };
|
|
@@ -41,14 +42,15 @@ function program() {
|
|
|
41
42
|
return new Command()
|
|
42
43
|
.name("dbx-tools-tunnel")
|
|
43
44
|
.description("Front an app with a public portr tunnel + email-OTP gate")
|
|
44
|
-
.option("--subject <text>", "Subject line for the code email (env
|
|
45
|
-
.option("--allow <patterns>", "Comma/space-separated allow-list: domain / glob / /regex/ (env
|
|
46
|
-
.option("--subdomain <name>", "portr subdomain (else derived from
|
|
47
|
-
.option("--public-domain <host>", "portr <subdomain>.<server> (env
|
|
48
|
-
.option("--brand-name <name>", "Display name in the code email copy (env
|
|
49
|
-
.option("--message <text>", "Line shown above the code in the email (env
|
|
50
|
-
.option("--session-ttl <seconds>", "Session lifetime (env
|
|
51
|
-
.option("--code-ttl <seconds>", "One-time-code lifetime (env
|
|
45
|
+
.option("--subject <text>", "Subject line for the code email (env TUNNEL_AUTH_SUBJECT)")
|
|
46
|
+
.option("--allow <patterns>", "Comma/space-separated allow-list: domain / glob / /regex/ (env TUNNEL_AUTH_ALLOW)")
|
|
47
|
+
.option("--subdomain <name>", "portr subdomain (else derived from TUNNEL_PUBLIC_DOMAIN)")
|
|
48
|
+
.option("--public-domain <host>", "portr <subdomain>.<server> (env TUNNEL_PUBLIC_DOMAIN)")
|
|
49
|
+
.option("--brand-name <name>", "Display name in the code email copy (env TUNNEL_AUTH_BRAND_NAME; defaults to the brand context name)")
|
|
50
|
+
.option("--message <text>", "Line shown above the code in the email (env TUNNEL_AUTH_MESSAGE)")
|
|
51
|
+
.option("--session-ttl <seconds>", "Session lifetime (env TUNNEL_AUTH_SESSION_TTL)")
|
|
52
|
+
.option("--code-ttl <seconds>", "One-time-code lifetime (env TUNNEL_AUTH_CODE_TTL)")
|
|
53
|
+
.option("--forward-headers <patterns>", "Extra x- request headers tunnel traffic may forward: literal / glob / /regex/ (env TUNNEL_FORWARD_HEADERS)")
|
|
52
54
|
.option("--insecure", "Run the tunnel OPEN with no gate (env TUNNEL_INSECURE=true). Otherwise the CLI fails fast when email SMTP is not configured.")
|
|
53
55
|
.allowExcessArguments(true)
|
|
54
56
|
.helpOption("-h, --help", "Show help");
|
|
@@ -110,7 +112,7 @@ export async function runCli(argv) {
|
|
|
110
112
|
// 2. Boot the gate app (cache + email transport + gate API). `startGateApp`
|
|
111
113
|
// FAILS FAST when email can't send codes (no SMTP). Insecure mode
|
|
112
114
|
// (`--insecure` / TUNNEL_INSECURE) skips the gate and runs the tunnel open.
|
|
113
|
-
const insecure = opts.insecure
|
|
115
|
+
const insecure = env.boolean(opts.insecure, INSECURE_ENV) ?? false;
|
|
114
116
|
let gate;
|
|
115
117
|
if (insecure) {
|
|
116
118
|
logger.warn("insecure mode - tunnel runs OPEN with no email-OTP gate");
|
|
@@ -127,7 +129,13 @@ export async function runCli(argv) {
|
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
// 3. Start the gate proxy on the public port (open when `gate` is undefined).
|
|
130
|
-
|
|
132
|
+
// `forwardHeaders` only ADDS to the built-in allow-list; see `./headers.ts`.
|
|
133
|
+
await startProxy({
|
|
134
|
+
publicPort,
|
|
135
|
+
appPort,
|
|
136
|
+
gate,
|
|
137
|
+
forwardHeaders: env.list(opts.forwardHeaders, FORWARD_HEADERS_ENV),
|
|
138
|
+
});
|
|
131
139
|
// 4. Install + run portr when a tunnel is configured.
|
|
132
140
|
const portrConfig = resolvePortrConfig({
|
|
133
141
|
publicDomain: opts.publicDomain,
|
|
@@ -136,14 +144,14 @@ export async function runCli(argv) {
|
|
|
136
144
|
});
|
|
137
145
|
const children = [app];
|
|
138
146
|
if (portrConfig) {
|
|
139
|
-
const
|
|
140
|
-
writePortrConfig(portrConfig,
|
|
141
|
-
children.push(startPortr(portrConfig,
|
|
147
|
+
const portrEnv = installPortr();
|
|
148
|
+
writePortrConfig(portrConfig, portrEnv);
|
|
149
|
+
children.push(startPortr(portrConfig, portrEnv));
|
|
142
150
|
}
|
|
143
151
|
else {
|
|
144
|
-
logger.info("no PORTR_TOKEN/
|
|
152
|
+
logger.info("no PORTR_TOKEN/TUNNEL_PUBLIC_DOMAIN - serving the gate proxy without a public tunnel");
|
|
145
153
|
}
|
|
146
154
|
// Any child exit (or a signal) tears the whole thing down.
|
|
147
155
|
superviseExit(children);
|
|
148
156
|
}
|
|
149
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFeEMsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxxRkFBcUY7QUFDckYsU0FBUyxVQUFVO0lBQ2pCLE9BQU8sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFjRCxvRkFBb0Y7QUFDcEYsU0FBUyxPQUFPO0lBQ2QsT0FBTyxJQUFJLE9BQU8sRUFBRTtTQUNqQixJQUFJLENBQUMsa0JBQWtCLENBQUM7U0FDeEIsV0FBVyxDQUFDLDBEQUEwRCxDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxvREFBb0QsQ0FBQztTQUNoRixNQUFNLENBQ0wsb0JBQW9CLEVBQ3BCLGtGQUFrRixDQUNuRjtTQUNBLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxtREFBbUQsQ0FBQztTQUNqRixNQUFNLENBQUMsd0JBQXdCLEVBQUUsZ0RBQWdE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bnRlbnQiOlsiLyoqXG4gKiBgZGJ4LXRvb2xzLXR1bm5lbGAgLyBgZGJ4dC10dW5uZWxgIENMSS5cbiAqXG4gKiBXcmFwcyBhbiBhcHAncyBzdGFydCBjb21tYW5kIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsIGFuZCBhbiBlbWFpbC1PVFBcbiAqIGFjY2VzcyBnYXRlLiBFdmVyeXRoaW5nIGFmdGVyIGAtLWAgaXMgdGhlIFJFQUwgYXBwIHN0YXJ0IGNvbW1hbmQ6XG4gKlxuICogICBkYnh0LXR1bm5lbCAtLXN1YmplY3QgXCJIZXJlJ3MgeW91ciBPVFBcIiAtLWFsbG93IGV4YW1wbGUuY29tIC0tIGJ1biBzcmMvc2VydmVyLnRzXG4gKlxuICogQm9vdCBzZXF1ZW5jZTpcbiAqICAgMS4gUGljayBhIHJhbmRvbSBQUklWQVRFIHBvcnQgYW5kIHNwYXduIHRoZSBhcHAgY29tbWFuZCB3aXRoXG4gKiAgICAgIGBEQVRBQlJJQ0tTX0FQUF9QT1JUYCBzZXQgdG8gaXQgKHNvIHRoZSBhcHAgYmluZHMgbG9vcGJhY2stcHJpdmF0ZSkuIFRoYXRcbiAqICAgICAgdmFyaWFibGUgbmFtZSBpcyB0aGUgRGF0YWJyaWNrcyBBcHBzIHJ1bnRpbWUgY29udHJhY3Q7IHRoZSBnYXRlIGl0c2VsZiBpc1xuICogICAgICBwbGF0Zm9ybS1uZXV0cmFsIGFuZCBob25vdXJzIHdoYXRldmVyIHBvcnQgaXQgZmluZHMgdGhlcmUuXG4gKiAgIDIuIEJvb3QgdGhlIHRpbnkgZ2F0ZSBBcHBLaXQgYXBwIChubyBzZXJ2ZXIpOiBpbml0cyBgQ2FjaGVNYW5hZ2VyYCArIHRoZVxuICogICAgICBlbWFpbCB0cmFuc3BvcnQsIHlpZWxkcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSS5cbiAqICAgMy4gU3RhcnQgdGhlIGdhdGUgUFJPWFkgb24gdGhlIE9SSUdJTkFMIHB1YmxpYyBwb3J0LCBmb3J3YXJkaW5nIHRvIHRoZSBhcHAuXG4gKiAgIDQuIEluc3RhbGwgKyBydW4gcG9ydHIgcG9pbnRlZCBhdCB0aGUgcHVibGljIHBvcnQgKHdoZW4gYSB0dW5uZWwgaXNcbiAqICAgICAgY29uZmlndXJlZDsgb3RoZXJ3aXNlIHRoZSBwcm94eSBzdGlsbCBnYXRlcyBub3RoaW5nIGFuZCBmb3J3YXJkcykuXG4gKlxuICogU3VwZXJ2aXNpb246IHRoZSBhcHAgY2hpbGQsIHBvcnRyIGNoaWxkLCBhbmQgdGhpcyBwcm9jZXNzIGFyZSB0aWVkIHRvZ2V0aGVyIC1cbiAqIGlmIEFOWSBleGl0cywgZXZlcnl0aGluZyBjb21lcyBkb3duIChjb25jdXJyZW50bHktc3R5bGUgYGtpbGxPdGhlcnNgKS5cbiAqXG4gKiBPcHRpb25zIGNvbWUgZnJvbSBmbGFncyBPUiBlbnY7IHNlZSB0aGUgb3B0aW9uIGRlZmluaXRpb25zIGJlbG93LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyBzdGFydEdhdGVBcHAgfSBmcm9tIFwiLi9hcHAudHNcIjtcbmltcG9ydCB0eXBlIHsgQXV0aEdhdGVDb25maWcgfSBmcm9tIFwiLi9wbHVnaW4udHNcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdGFydFBvcnRyLCB3cml0ZVBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vcG9ydHIudHNcIjtcbmltcG9ydCB7IHN0YXJ0UHJveHkgfSBmcm9tIFwiLi9wcm94eS50c1wiO1xuXG5leHBvcnQgeyBDb21tYW5kZXJFcnJvciB9O1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsXCIpO1xuXG4vKiogQSByYW5kb20gZXBoZW1lcmFsIHBvcnQgZm9yIHRoZSBhcHAgdG8gYmluZCAodGhlIHByb3h5IGZyb250cyB0aGUgcHVibGljIG9uZSkuICovXG5mdW5jdGlvbiByYW5kb21Qb3J0KCk6IG51bWJlciB7XG4gIHJldHVybiAyMDAwMCArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDIwMDAwKTtcbn1cblxuaW50ZXJmYWNlIFR1bm5lbE9wdHMge1xuICBzdWJqZWN0Pzogc3RyaW5nO1xuICBhbGxvdz86IHN0cmluZztcbiAgc3ViZG9tYWluPzogc3RyaW5nO1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIGJyYW5kTmFtZT86IHN0cmluZztcbiAgbWVzc2FnZT86IHN0cmluZztcbiAgc2Vzc2lvblR0bD86IHN0cmluZztcbiAgY29kZVR0bD86IHN0cmluZztcbiAgaW5zZWN1cmU/OiBib29sZWFuO1xufVxuXG4vKiogQnVpbGQgdGhlIGNvbW1hbmRlciBwcm9ncmFtLiBgLS1gIHNlcGFyYXRlcyBmbGFncyBmcm9tIHRoZSBhcHAgc3RhcnQgY29tbWFuZC4gKi9cbmZ1bmN0aW9uIHByb2dyYW0oKTogQ29tbWFuZCB7XG4gIHJldHVybiBuZXcgQ29tbWFuZCgpXG4gICAgLm5hbWUoXCJkYngtdG9vbHMtdHVubmVsXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiRnJvbnQgYW4gYXBwIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsICsgZW1haWwtT1RQIGdhdGVcIilcbiAgICAub3B0aW9uKFwiLS1zdWJqZWN0IDx0ZXh0PlwiLCBcIlN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwgKGVudiBBVVRIX1NVQkpFQ1QpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1hbGxvdyA8cGF0dGVybnM+XCIsXG4gICAgICBcIkNvbW1hL3NwYWNlLXNlcGFyYXRlZCBhbGxvdy1saXN0OiBkb21haW4gLyBnbG9iIC8gL3JlZ2V4LyAoZW52IEVNQUlMX0FVVEhfQUxMT1cpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXCItLXN1YmRvbWFpbiA8bmFtZT5cIiwgXCJwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcIi0tcHVibGljLWRvbWFpbiA8aG9zdD5cIiwgXCJwb3J0ciA8c3ViZG9tYWluPi48c2VydmVyPiAoZW52IFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1icmFuZC1uYW1lIDxuYW1lPlwiLFxuICAgICAgXCJEaXNwbGF5IG5hbWUgaW4gdGhlIGNvZGUgZW1haWwgY29weSAoZW52IEFVVEhfQlJBTkRfTkFNRTsgZGVmYXVsdHMgdG8gdGhlIGJyYW5kIGNvbnRleHQgbmFtZSlcIixcbiAgICApXG4gICAgLm9wdGlvbihcIi0tbWVzc2FnZSA8dGV4dD5cIiwgXCJMaW5lIHNob3duIGFib3ZlIHRoZSBjb2RlIGluIHRoZSBlbWFpbCAoZW52IEFVVEhfTUVTU0FHRSlcIilcbiAgICAub3B0aW9uKFwiLS1zZXNzaW9uLXR0bCA8c2Vjb25kcz5cIiwgXCJTZXNzaW9uIGxpZmV0aW1lIChlbnYgQVVUSF9TRVNTSU9OX1RUTClcIilcbiAgICAub3B0aW9uKFwiLS1jb2RlLXR0bCA8c2Vjb25kcz5cIiwgXCJPbmUtdGltZS1jb2RlIGxpZmV0aW1lIChlbnYgQVVUSF9DT0RFX1RUTClcIilcbiAgICAub3B0aW9uKFxuICAgICAgXCItLWluc2VjdXJlXCIsXG4gICAgICBcIlJ1biB0aGUgdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlIChlbnYgVFVOTkVMX0lOU0VDVVJFPXRydWUpLiBPdGhlcndpc2UgdGhlIENMSSBmYWlscyBmYXN0IHdoZW4gZW1haWwgU01UUCBpcyBub3QgY29uZmlndXJlZC5cIixcbiAgICApXG4gICAgLmFsbG93RXhjZXNzQXJndW1lbnRzKHRydWUpXG4gICAgLmhlbHBPcHRpb24oXCItaCwgLS1oZWxwXCIsIFwiU2hvdyBoZWxwXCIpO1xufVxuXG4vKiogVGllIGEgY2hpbGQncyBleGl0IHRvIGZ1bGwgdGVhcmRvd246IGFueSBleGl0IGJyaW5ncyB0aGUgd2hvbGUgdHVubmVsIGRvd24uICovXG5mdW5jdGlvbiBzdXBlcnZpc2VFeGl0KGNoaWxkcmVuOiBDaGlsZFByb2Nlc3NbXSk6IHZvaWQge1xuICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gIGNvbnN0IHNodXRkb3duID0gKGNvZGU6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGlmIChzaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICAgIGlmICghY2hpbGQua2lsbGVkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9XG4gICAgLy8gR2l2ZSBjaGlsZHJlbiBhIG1vbWVudCwgdGhlbiBleGl0IHdpdGggdGhlIGZpcnN0IG5vbi16ZXJvIGNvZGUgc2Vlbi5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHByb2Nlc3MuZXhpdChjb2RlKSwgMzAwMCkudW5yZWYoKTtcbiAgfTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgIGNoaWxkLm9uKFwiZXhpdFwiLCAoY29kZSkgPT4ge1xuICAgICAgbG9nZ2VyLndhcm4oYGNoaWxkIGV4aXRlZCAoJHtjb2RlID8/IFwic2lnbmFsXCJ9KTsgYnJpbmdpbmcgdHVubmVsIGRvd25gKTtcbiAgICAgIHNodXRkb3duKGNvZGUgPz8gMSk7XG4gICAgfSk7XG4gIH1cbiAgZm9yIChjb25zdCBzaWcgb2YgW1wiU0lHVEVSTVwiLCBcIlNJR0lOVFwiLCBcIlNJR0hVUFwiXSBhcyBjb25zdCkge1xuICAgIHByb2Nlc3Mub24oc2lnLCAoKSA9PiBzaHV0ZG93bigwKSk7XG4gIH1cbn1cblxuLyoqIFBhcnNlIGFyZ3YgYW5kIHJ1biB0aGUgdHVubmVsLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkNsaShhcmd2OiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAvLyBTcGxpdCBmbGFncyBmcm9tIHRoZSB3cmFwcGVkIGNvbW1hbmQgYXQgdGhlIGZpcnN0IGAtLWAuXG4gIGNvbnN0IHNlcCA9IGFyZ3YuaW5kZXhPZihcIi0tXCIpO1xuICBjb25zdCBmbGFncyA9IHNlcCA+PSAwID8gYXJndi5zbGljZSgwLCBzZXApIDogYXJndjtcbiAgY29uc3QgY29tbWFuZCA9IHNlcCA+PSAwID8gYXJndi5zbGljZShzZXAgKyAxKSA6IFtdO1xuXG4gIGNvbnN0IHByb2cgPSBwcm9ncmFtKCk7XG4gIHByb2cucGFyc2UoZmxhZ3MpO1xuICBjb25zdCBvcHRzID0gcHJvZy5vcHRzPFR1bm5lbE9wdHM+KCk7XG5cbiAgaWYgKGNvbW1hbmQubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IENvbW1hbmRlckVycm9yKDEsIFwidHVubmVsLm5vLWNvbW1hbmRcIiwgXCJubyBzdGFydCBjb21tYW5kIGdpdmVuIGFmdGVyIGAtLWBcIik7XG4gIH1cblxuICBjb25zdCBwdWJsaWNQb3J0ID0gTnVtYmVyKHByb2Nlc3MuZW52LkRBVEFCUklDS1NfQVBQX1BPUlQgPz8gODAwMCk7XG4gIGNvbnN0IGFwcFBvcnQgPSByYW5kb21Qb3J0KCk7XG5cbiAgY29uc3QgZ2F0ZUNvbmZpZzogQXV0aEdhdGVDb25maWcgPSB7XG4gICAgYWxsb3c6IG9wdHMuYWxsb3csXG4gICAgc3ViamVjdDogb3B0cy5zdWJqZWN0LFxuICAgIGJyYW5kTmFtZTogb3B0cy5icmFuZE5hbWUsXG4gICAgbWVzc2FnZTogb3B0cy5tZXNzYWdlLFxuICAgIHNlc3Npb25UdGxTZWNvbmRzOiBvcHRzLnNlc3Npb25UdGwgPyBOdW1iZXIob3B0cy5zZXNzaW9uVHRsKSA6IHVuZGVmaW5lZCxcbiAgICBjb2RlVHRsU2Vjb25kczogb3B0cy5jb2RlVHRsID8gTnVtYmVyKG9wdHMuY29kZVR0bCkgOiB1bmRlZmluZWQsXG4gIH07XG5cbiAgLy8gMS4gU3Bhd24gdGhlIHdyYXBwZWQgYXBwIHdpdGggdGhlIFBSSVZBVEUgcG9ydC4gSXQgYmluZHMgbG9vcGJhY2s7IG9ubHkgdGhlXG4gIC8vICAgIHByb3h5IHJlYWNoZXMgaXQuXG4gIGxvZ2dlci5pbmZvKGBzcGF3bmluZyBhcHAgb24gcHJpdmF0ZSBwb3J0ICR7YXBwUG9ydH06ICR7Y29tbWFuZC5qb2luKFwiIFwiKX1gKTtcbiAgY29uc3QgW2NtZCwgLi4uYXJnc10gPSBjb21tYW5kO1xuICBjb25zdCBhcHAgPSBzcGF3bihjbWQhLCBhcmdzLCB7XG4gICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBEQVRBQlJJQ0tTX0FQUF9QT1JUOiBTdHJpbmcoYXBwUG9ydCksIEhPU1Q6IFwiMTI3LjAuMC4xXCIgfSxcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuXG4gIC8vIDIuIEJvb3QgdGhlIGdhdGUgYXBwIChjYWNoZSArIGVtYWlsIHRyYW5zcG9ydCArIGdhdGUgQVBJKS4gYHN0YXJ0R2F0ZUFwcGBcbiAgLy8gICAgRkFJTFMgRkFTVCB3aGVuIGVtYWlsIGNhbid0IHNlbmQgY29kZXMgKG5vIFNNVFApLiBJbnNlY3VyZSBtb2RlXG4gIC8vICAgIChgLS1pbnNlY3VyZWAgLyBUVU5ORUxfSU5TRUNVUkUpIHNraXBzIHRoZSBnYXRlIGFuZCBydW5zIHRoZSB0dW5uZWwgb3Blbi5cbiAgY29uc3QgaW5zZWN1cmUgPSBvcHRzLmluc2VjdXJlIHx8IC9eKDF8dHJ1ZXx5ZXN8b24pJC9pLnRlc3QocHJvY2Vzcy5lbnYuVFVOTkVMX0lOU0VDVVJFID8/IFwiXCIpO1xuICBsZXQgZ2F0ZTogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBzdGFydEdhdGVBcHA+PiB8IHVuZGVmaW5lZDtcbiAgaWYgKGluc2VjdXJlKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJpbnNlY3VyZSBtb2RlIC0gdHVubmVsIHJ1bnMgT1BFTiB3aXRoIG5vIGVtYWlsLU9UUCBnYXRlXCIpO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICBnYXRlID0gYXdhaXQgc3RhcnRHYXRlQXBwKGdhdGVDb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBGYWlsIGZhc3Q6IGRvbid0IHNpbGVudGx5IGV4cG9zZSBhbiB1bmdhdGVkIHR1bm5lbC4gVGhlIG9wZXJhdG9yIG11c3QgZml4XG4gICAgICAvLyBTTVRQIG9yIGV4cGxpY2l0bHkgb3B0IGludG8gYC0taW5zZWN1cmVgLlxuICAgICAgbG9nZ2VyLmVycm9yKFwiY2Fubm90IHN0YXJ0IHRoZSBPVFAgZ2F0ZVwiLCB7IGVycm9yOiAoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2UgfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvLyAzLiBTdGFydCB0aGUgZ2F0ZSBwcm94eSBvbiB0aGUgcHVibGljIHBvcnQgKG9wZW4gd2hlbiBgZ2F0ZWAgaXMgdW5kZWZpbmVkKS5cbiAgYXdhaXQgc3RhcnRQcm94eSh7IHB1YmxpY1BvcnQsIGFwcFBvcnQsIGdhdGUgfSk7XG5cbiAgLy8gNC4gSW5zdGFsbCArIHJ1biBwb3J0ciB3aGVuIGEgdHVubmVsIGlzIGNvbmZpZ3VyZWQuXG4gIGNvbnN0IHBvcnRyQ29uZmlnID0gcmVzb2x2ZVBvcnRyQ29uZmlnKHtcbiAgICBwdWJsaWNEb21haW46IG9wdHMucHVibGljRG9tYWluLFxuICAgIHN1YmRvbWFpbjogb3B0cy5zdWJkb21haW4sXG4gICAgcG9ydDogcHVibGljUG9ydCxcbiAgfSk7XG4gIGNvbnN0IGNoaWxkcmVuOiBDaGlsZFByb2Nlc3NbXSA9IFthcHBdO1xuICBpZiAocG9ydHJDb25maWcpIHtcbiAgICBjb25zdCBlbnYgPSBpbnN0YWxsUG9ydHIoKTtcbiAgICB3cml0ZVBvcnRyQ29uZmlnKHBvcnRyQ29uZmlnLCBlbnYpO1xuICAgIGNoaWxkcmVuLnB1c2goc3RhcnRQb3J0cihwb3J0ckNvbmZpZywgZW52KSk7XG4gIH0gZWxzZSB7XG4gICAgbG9nZ2VyLmluZm8oXCJubyBQT1JUUl9UT0tFTi9QVUJMSUNfRE9NQUlOIC0gc2VydmluZyB0aGUgZ2F0ZSBwcm94eSB3aXRob3V0IGEgcHVibGljIHR1bm5lbFwiKTtcbiAgfVxuXG4gIC8vIEFueSBjaGlsZCBleGl0IChvciBhIHNpZ25hbCkgdGVhcnMgdGhlIHdob2xlIHRoaW5nIGRvd24uXG4gIHN1cGVydmlzZUV4aXQoY2hpbGRyZW4pO1xufVxuIl19
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxxRkFBcUY7QUFDckYsU0FBUyxVQUFVO0lBQ2pCLE9BQU8sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFlRCxvRkFBb0Y7QUFDcEYsU0FBUyxPQUFPO0lBQ2QsT0FBTyxJQUFJLE9BQU8sRUFBRTtTQUNqQixJQUFJLENBQUMsa0JBQWtCLENBQUM7U0FDeEIsV0FBVyxDQUFDLDBEQUEwRCxDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSwyREFBMkQsQ0FBQztTQUN2RixNQUFNLENBQ0wsb0JBQW9CLEVBQ3BCLG1GQUFtRixDQUNwRjtTQUNBLE1BQU0s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QUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNuRCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sQ0FBQyxJQUFJLENBQ1Qsc0ZBQXNGLENBQ3ZGLENBQUM7SUFDSixDQUFDO0lBRUQsMkRBQTJEO0lBQzNELGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgZGJ4LXRvb2xzLXR1bm5lbGAgLyBgZGJ4dC10dW5uZWxgIENMSS5cbiAqXG4gKiBXcmFwcyBhbiBhcHAncyBzdGFydCBjb21tYW5kIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsIGFuZCBhbiBlbWFpbC1PVFBcbiAqIGFjY2VzcyBnYXRlLiBFdmVyeXRoaW5nIGFmdGVyIGAtLWAgaXMgdGhlIFJFQUwgYXBwIHN0YXJ0IGNvbW1hbmQ6XG4gKlxuICogICBkYnh0LXR1bm5lbCAtLXN1YmplY3QgXCJIZXJlJ3MgeW91ciBPVFBcIiAtLWFsbG93IGV4YW1wbGUuY29tIC0tIGJ1biBzcmMvc2VydmVyLnRzXG4gKlxuICogQm9vdCBzZXF1ZW5jZTpcbiAqICAgMS4gUGljayBhIHJhbmRvbSBQUklWQVRFIHBvcnQgYW5kIHNwYXduIHRoZSBhcHAgY29tbWFuZCB3aXRoXG4gKiAgICAgIGBEQVRBQlJJQ0tTX0FQUF9QT1JUYCBzZXQgdG8gaXQgKHNvIHRoZSBhcHAgYmluZHMgbG9vcGJhY2stcHJpdmF0ZSkuIFRoYXRcbiAqICAgICAgdmFyaWFibGUgbmFtZSBpcyB0aGUgRGF0YWJyaWNrcyBBcHBzIHJ1bnRpbWUgY29udHJhY3Q7IHRoZSBnYXRlIGl0c2VsZiBpc1xuICogICAgICBwbGF0Zm9ybS1uZXV0cmFsIGFuZCBob25vdXJzIHdoYXRldmVyIHBvcnQgaXQgZmluZHMgdGhlcmUuXG4gKiAgIDIuIEJvb3QgdGhlIHRpbnkgZ2F0ZSBBcHBLaXQgYXBwIChubyBzZXJ2ZXIpOiBpbml0cyBgQ2FjaGVNYW5hZ2VyYCArIHRoZVxuICogICAgICBlbWFpbCB0cmFuc3BvcnQsIHlpZWxkcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSS5cbiAqICAgMy4gU3RhcnQgdGhlIGdhdGUgUFJPWFkgb24gdGhlIE9SSUdJTkFMIHB1YmxpYyBwb3J0LCBmb3J3YXJkaW5nIHRvIHRoZSBhcHAuXG4gKiAgIDQuIEluc3RhbGwgKyBydW4gcG9ydHIgcG9pbnRlZCBhdCB0aGUgcHVibGljIHBvcnQgKHdoZW4gYSB0dW5uZWwgaXNcbiAqICAgICAgY29uZmlndXJlZDsgb3RoZXJ3aXNlIHRoZSBwcm94eSBzdGlsbCBnYXRlcyBub3RoaW5nIGFuZCBmb3J3YXJkcykuXG4gKlxuICogU3VwZXJ2aXNpb246IHRoZSBhcHAgY2hpbGQsIHBvcnRyIGNoaWxkLCBhbmQgdGhpcyBwcm9jZXNzIGFyZSB0aWVkIHRvZ2V0aGVyIC1cbiAqIGlmIEFOWSBleGl0cywgZXZlcnl0aGluZyBjb21lcyBkb3duIChjb25jdXJyZW50bHktc3R5bGUgYGtpbGxPdGhlcnNgKS5cbiAqXG4gKiBPcHRpb25zIGNvbWUgZnJvbSBmbGFncyBPUiBlbnY7IHNlZSB0aGUgb3B0aW9uIGRlZmluaXRpb25zIGJlbG93LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBlbnYsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBDb21tYW5kLCBDb21tYW5kZXJFcnJvciB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCB7IHN0YXJ0R2F0ZUFwcCB9IGZyb20gXCIuL2FwcC50c1wiO1xuaW1wb3J0IHsgRk9SV0FSRF9IRUFERVJTX0VOViwgSU5TRUNVUkVfRU5WIH0gZnJvbSBcIi4vZW52LnRzXCI7XG5pbXBvcnQgdHlwZSB7IEF1dGhHYXRlQ29uZmlnIH0gZnJvbSBcIi4vcGx1Z2luLnRzXCI7XG5pbXBvcnQgeyBpbnN0YWxsUG9ydHIsIHJlc29sdmVQb3J0ckNvbmZpZywgc3RhcnRQb3J0ciwgd3JpdGVQb3J0ckNvbmZpZyB9IGZyb20gXCIuL3BvcnRyLnRzXCI7XG5pbXBvcnQgeyBzdGFydFByb3h5IH0gZnJvbSBcIi4vcHJveHkudHNcIjtcblxuZXhwb3J0IHsgQ29tbWFuZGVyRXJyb3IgfTtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbFwiKTtcblxuLyoqIEEgcmFuZG9tIGVwaGVtZXJhbCBwb3J0IGZvciB0aGUgYXBwIHRvIGJpbmQgKHRoZSBwcm94eSBmcm9udHMgdGhlIHB1YmxpYyBvbmUpLiAqL1xuZnVuY3Rpb24gcmFuZG9tUG9ydCgpOiBudW1iZXIge1xuICByZXR1cm4gMjAwMDAgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyMDAwMCk7XG59XG5cbmludGVyZmFjZSBUdW5uZWxPcHRzIHtcbiAgc3ViamVjdD86IHN0cmluZztcbiAgYWxsb3c/OiBzdHJpbmc7XG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICBicmFuZE5hbWU/OiBzdHJpbmc7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIHNlc3Npb25UdGw/OiBzdHJpbmc7XG4gIGNvZGVUdGw/OiBzdHJpbmc7XG4gIGluc2VjdXJlPzogYm9vbGVhbjtcbiAgZm9yd2FyZEhlYWRlcnM/OiBzdHJpbmc7XG59XG5cbi8qKiBCdWlsZCB0aGUgY29tbWFuZGVyIHByb2dyYW0uIGAtLWAgc2VwYXJhdGVzIGZsYWdzIGZyb20gdGhlIGFwcCBzdGFydCBjb21tYW5kLiAqL1xuZnVuY3Rpb24gcHJvZ3JhbSgpOiBDb21tYW5kIHtcbiAgcmV0dXJuIG5ldyBDb21tYW5kKClcbiAgICAubmFtZShcImRieC10b29scy10dW5uZWxcIilcbiAgICAuZGVzY3JpcHRpb24oXCJGcm9udCBhbiBhcHAgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgKyBlbWFpbC1PVFAgZ2F0ZVwiKVxuICAgIC5vcHRpb24oXCItLXN1YmplY3QgPHRleHQ+XCIsIFwiU3ViamVjdCBsaW5lIGZvciB0aGUgY29kZSBlbWFpbCAoZW52IFRVTk5FTF9BVVRIX1NVQkpFQ1QpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1hbGxvdyA8cGF0dGVybnM+XCIsXG4gICAgICBcIkNvbW1hL3NwYWNlLXNlcGFyYXRlZCBhbGxvdy1saXN0OiBkb21haW4gLyBnbG9iIC8gL3JlZ2V4LyAoZW52IFRVTk5FTF9BVVRIX0FMTE9XKVwiLFxuICAgIClcbiAgICAub3B0aW9uKFwiLS1zdWJkb21haW4gPG5hbWU+XCIsIFwicG9ydHIgc3ViZG9tYWluIChlbHNlIGRlcml2ZWQgZnJvbSBUVU5ORUxfUFVCTElDX0RPTUFJTilcIilcbiAgICAub3B0aW9uKFwiLS1wdWJsaWMtZG9tYWluIDxob3N0PlwiLCBcInBvcnRyIDxzdWJkb21haW4+LjxzZXJ2ZXI+IChlbnYgVFVOTkVMX1BVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1icmFuZC1uYW1lIDxuYW1lPlwiLFxuICAgICAgXCJEaXNwbGF5IG5hbWUgaW4gdGhlIGNvZGUgZW1haWwgY29weSAoZW52IFRVTk5FTF9BVVRIX0JSQU5EX05BTUU7IGRlZmF1bHRzIHRvIHRoZSBicmFuZCBjb250ZXh0IG5hbWUpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXCItLW1lc3NhZ2UgPHRleHQ+XCIsIFwiTGluZSBzaG93biBhYm92ZSB0aGUgY29kZSBpbiB0aGUgZW1haWwgKGVudiBUVU5ORUxfQVVUSF9NRVNTQUdFKVwiKVxuICAgIC5vcHRpb24oXCItLXNlc3Npb24tdHRsIDxzZWNvbmRzPlwiLCBcIlNlc3Npb24gbGlmZXRpbWUgKGVudiBUVU5ORUxfQVVUSF9TRVNTSU9OX1RUTClcIilcbiAgICAub3B0aW9uKFwiLS1jb2RlLXR0bCA8c2Vjb25kcz5cIiwgXCJPbmUtdGltZS1jb2RlIGxpZmV0aW1lIChlbnYgVFVOTkVMX0FVVEhfQ09ERV9UVEwpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1mb3J3YXJkLWhlYWRlcnMgPHBhdHRlcm5zPlwiLFxuICAgICAgXCJFeHRyYSB4LSByZXF1ZXN0IGhlYWRlcnMgdHVubmVsIHRyYWZmaWMgbWF5IGZvcndhcmQ6IGxpdGVyYWwgLyBnbG9iIC8gL3JlZ2V4LyAoZW52IFRVTk5FTF9GT1JXQVJEX0hFQURFUlMpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXG4gICAgICBcIi0taW5zZWN1cmVcIixcbiAgICAgIFwiUnVuIHRoZSB0dW5uZWwgT1BFTiB3aXRoIG5vIGdhdGUgKGVudiBUVU5ORUxfSU5TRUNVUkU9dHJ1ZSkuIE90aGVyd2lzZSB0aGUgQ0xJIGZhaWxzIGZhc3Qgd2hlbiBlbWFpbCBTTVRQIGlzIG5vdCBjb25maWd1cmVkLlwiLFxuICAgIClcbiAgICAuYWxsb3dFeGNlc3NBcmd1bWVudHModHJ1ZSlcbiAgICAuaGVscE9wdGlvbihcIi1oLCAtLWhlbHBcIiwgXCJTaG93IGhlbHBcIik7XG59XG5cbi8qKiBUaWUgYSBjaGlsZCdzIGV4aXQgdG8gZnVsbCB0ZWFyZG93bjogYW55IGV4aXQgYnJpbmdzIHRoZSB3aG9sZSB0dW5uZWwgZG93bi4gKi9cbmZ1bmN0aW9uIHN1cGVydmlzZUV4aXQoY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdKTogdm9pZCB7XG4gIGxldCBzaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgY29uc3Qgc2h1dGRvd24gPSAoY29kZTogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgaWYgKHNodXR0aW5nRG93bikgcmV0dXJuO1xuICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIH1cbiAgICAvLyBHaXZlIGNoaWxkcmVuIGEgbW9tZW50LCB0aGVuIGV4aXQgd2l0aCB0aGUgZmlyc3Qgbm9uLXplcm8gY29kZSBzZWVuLlxuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCAzMDAwKS51bnJlZigpO1xuICB9O1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihgY2hpbGQgZXhpdGVkICgke2NvZGUgPz8gXCJzaWduYWxcIn0pOyBicmluZ2luZyB0dW5uZWwgZG93bmApO1xuICAgICAgc2h1dGRvd24oY29kZSA/PyAxKTtcbiAgICB9KTtcbiAgfVxuICBmb3IgKGNvbnN0IHNpZyBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWcsICgpID0+IHNodXRkb3duKDApKTtcbiAgfVxufVxuXG4vKiogUGFyc2UgYXJndiBhbmQgcnVuIHRoZSB0dW5uZWwuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ2xpKGFyZ3Y6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIFNwbGl0IGZsYWdzIGZyb20gdGhlIHdyYXBwZWQgY29tbWFuZCBhdCB0aGUgZmlyc3QgYC0tYC5cbiAgY29uc3Qgc2VwID0gYXJndi5pbmRleE9mKFwiLS1cIik7XG4gIGNvbnN0IGZsYWdzID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKDAsIHNlcCkgOiBhcmd2O1xuICBjb25zdCBjb21tYW5kID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKHNlcCArIDEpIDogW107XG5cbiAgY29uc3QgcHJvZyA9IHByb2dyYW0oKTtcbiAgcHJvZy5wYXJzZShmbGFncyk7XG4gIGNvbnN0IG9wdHMgPSBwcm9nLm9wdHM8VHVubmVsT3B0cz4oKTtcblxuICBpZiAoY29tbWFuZC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgQ29tbWFuZGVyRXJyb3IoMSwgXCJ0dW5uZWwubm8tY29tbWFuZFwiLCBcIm5vIHN0YXJ0IGNvbW1hbmQgZ2l2ZW4gYWZ0ZXIgYC0tYFwiKTtcbiAgfVxuXG4gIGNvbnN0IHB1YmxpY1BvcnQgPSBOdW1iZXIocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19BUFBfUE9SVCA/PyA4MDAwKTtcbiAgY29uc3QgYXBwUG9ydCA9IHJhbmRvbVBvcnQoKTtcblxuICBjb25zdCBnYXRlQ29uZmlnOiBBdXRoR2F0ZUNvbmZpZyA9IHtcbiAgICBhbGxvdzogb3B0cy5hbGxvdyxcbiAgICBzdWJqZWN0OiBvcHRzLnN1YmplY3QsXG4gICAgYnJhbmROYW1lOiBvcHRzLmJyYW5kTmFtZSxcbiAgICBtZXNzYWdlOiBvcHRzLm1lc3NhZ2UsXG4gICAgc2Vzc2lvblR0bFNlY29uZHM6IG9wdHMuc2Vzc2lvblR0bCA/IE51bWJlcihvcHRzLnNlc3Npb25UdGwpIDogdW5kZWZpbmVkLFxuICAgIGNvZGVUdGxTZWNvbmRzOiBvcHRzLmNvZGVUdGwgPyBOdW1iZXIob3B0cy5jb2RlVHRsKSA6IHVuZGVmaW5lZCxcbiAgfTtcblxuICAvLyAxLiBTcGF3biB0aGUgd3JhcHBlZCBhcHAgd2l0aCB0aGUgUFJJVkFURSBwb3J0LiBJdCBiaW5kcyBsb29wYmFjazsgb25seSB0aGVcbiAgLy8gICAgcHJveHkgcmVhY2hlcyBpdC5cbiAgbG9nZ2VyLmluZm8oYHNwYXduaW5nIGFwcCBvbiBwcml2YXRlIHBvcnQgJHthcHBQb3J0fTogJHtjb21tYW5kLmpvaW4oXCIgXCIpfWApO1xuICBjb25zdCBbY21kLCAuLi5hcmdzXSA9IGNvbW1hbmQ7XG4gIGNvbnN0IGFwcCA9IHNwYXduKGNtZCEsIGFyZ3MsIHtcbiAgICBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIERBVEFCUklDS1NfQVBQX1BPUlQ6IFN0cmluZyhhcHBQb3J0KSwgSE9TVDogXCIxMjcuMC4wLjFcIiB9LFxuICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgfSk7XG5cbiAgLy8gMi4gQm9vdCB0aGUgZ2F0ZSBhcHAgKGNhY2hlICsgZW1haWwgdHJhbnNwb3J0ICsgZ2F0ZSBBUEkpLiBgc3RhcnRHYXRlQXBwYFxuICAvLyAgICBGQUlMUyBGQVNUIHdoZW4gZW1haWwgY2FuJ3Qgc2VuZCBjb2RlcyAobm8gU01UUCkuIEluc2VjdXJlIG1vZGVcbiAgLy8gICAgKGAtLWluc2VjdXJlYCAvIFRVTk5FTF9JTlNFQ1VSRSkgc2tpcHMgdGhlIGdhdGUgYW5kIHJ1bnMgdGhlIHR1bm5lbCBvcGVuLlxuICBjb25zdCBpbnNlY3VyZSA9IGVudi5ib29sZWFuKG9wdHMuaW5zZWN1cmUsIElOU0VDVVJFX0VOVikgPz8gZmFsc2U7XG4gIGxldCBnYXRlOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHN0YXJ0R2F0ZUFwcD4+IHwgdW5kZWZpbmVkO1xuICBpZiAoaW5zZWN1cmUpIHtcbiAgICBsb2dnZXIud2FybihcImluc2VjdXJlIG1vZGUgLSB0dW5uZWwgcnVucyBPUEVOIHdpdGggbm8gZW1haWwtT1RQIGdhdGVcIik7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIGdhdGUgPSBhd2FpdCBzdGFydEdhdGVBcHAoZ2F0ZUNvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhaWwgZmFzdDogZG9uJ3Qgc2lsZW50bHkgZXhwb3NlIGFuIHVuZ2F0ZWQgdHVubmVsLiBUaGUgb3BlcmF0b3IgbXVzdCBmaXhcbiAgICAgIC8vIFNNVFAgb3IgZXhwbGljaXRseSBvcHQgaW50byBgLS1pbnNlY3VyZWAuXG4gICAgICBsb2dnZXIuZXJyb3IoXCJjYW5ub3Qgc3RhcnQgdGhlIE9UUCBnYXRlXCIsIHsgZXJyb3I6IChlcnJvciBhcyBFcnJvcikubWVzc2FnZSB9KTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIDMuIFN0YXJ0IHRoZSBnYXRlIHByb3h5IG9uIHRoZSBwdWJsaWMgcG9ydCAob3BlbiB3aGVuIGBnYXRlYCBpcyB1bmRlZmluZWQpLlxuICAvLyAgICBgZm9yd2FyZEhlYWRlcnNgIG9ubHkgQUREUyB0byB0aGUgYnVpbHQtaW4gYWxsb3ctbGlzdDsgc2VlIGAuL2hlYWRlcnMudHNgLlxuICBhd2FpdCBzdGFydFByb3h5KHtcbiAgICBwdWJsaWNQb3J0LFxuICAgIGFwcFBvcnQsXG4gICAgZ2F0ZSxcbiAgICBmb3J3YXJkSGVhZGVyczogZW52Lmxpc3Qob3B0cy5mb3J3YXJkSGVhZGVycywgRk9SV0FSRF9IRUFERVJTX0VOViksXG4gIH0pO1xuXG4gIC8vIDQuIEluc3RhbGwgKyBydW4gcG9ydHIgd2hlbiBhIHR1bm5lbCBpcyBjb25maWd1cmVkLlxuICBjb25zdCBwb3J0ckNvbmZpZyA9IHJlc29sdmVQb3J0ckNvbmZpZyh7XG4gICAgcHVibGljRG9tYWluOiBvcHRzLnB1YmxpY0RvbWFpbixcbiAgICBzdWJkb21haW46IG9wdHMuc3ViZG9tYWluLFxuICAgIHBvcnQ6IHB1YmxpY1BvcnQsXG4gIH0pO1xuICBjb25zdCBjaGlsZHJlbjogQ2hpbGRQcm9jZXNzW10gPSBbYXBwXTtcbiAgaWYgKHBvcnRyQ29uZmlnKSB7XG4gICAgY29uc3QgcG9ydHJFbnYgPSBpbnN0YWxsUG9ydHIoKTtcbiAgICB3cml0ZVBvcnRyQ29uZmlnKHBvcnRyQ29uZmlnLCBwb3J0ckVudik7XG4gICAgY2hpbGRyZW4ucHVzaChzdGFydFBvcnRyKHBvcnRyQ29uZmlnLCBwb3J0ckVudikpO1xuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5pbmZvKFxuICAgICAgXCJubyBQT1JUUl9UT0tFTi9UVU5ORUxfUFVCTElDX0RPTUFJTiAtIHNlcnZpbmcgdGhlIGdhdGUgcHJveHkgd2l0aG91dCBhIHB1YmxpYyB0dW5uZWxcIixcbiAgICApO1xuICB9XG5cbiAgLy8gQW55IGNoaWxkIGV4aXQgKG9yIGEgc2lnbmFsKSB0ZWFycyB0aGUgd2hvbGUgdGhpbmcgZG93bi5cbiAgc3VwZXJ2aXNlRXhpdChjaGlsZHJlbik7XG59XG4iXX0=
|
package/lib/src/env.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment-variable names the tunnel reads.
|
|
3
|
+
*
|
|
4
|
+
* Every setting is `TUNNEL_`-prefixed, matching the repo convention of naming a
|
|
5
|
+
* variable after the package that owns it (`MASTRA_*`, `TEAMS_*`,
|
|
6
|
+
* `WEB_SEARCH_*`). The gate's original names were unprefixed (`AUTH_SUBJECT`,
|
|
7
|
+
* `PUBLIC_DOMAIN`, ...), which is a real hazard for a package that runs as a
|
|
8
|
+
* WRAPPER: the tunnel and the app it wraps share one environment, so a generic
|
|
9
|
+
* name is one the wrapped app may already use for something else, and
|
|
10
|
+
* `PUBLIC_DOMAIN` in particular reads like an app-wide setting rather than a
|
|
11
|
+
* portr detail. `EMAIL_AUTH_ALLOW` was worse than generic - it sat in
|
|
12
|
+
* `@dbx-tools/email`'s `EMAIL_*` namespace while configuring the gate, not email.
|
|
13
|
+
*
|
|
14
|
+
* Each entry is an {@link EnvKey} list, EARLIEST-WINS, whose first element is the
|
|
15
|
+
* current name and whose remaining elements are the deprecated originals. A
|
|
16
|
+
* deployment set up against the old names keeps working; nothing needs a
|
|
17
|
+
* coordinated rename. Read them through `env.string` / `env.positiveInt` /
|
|
18
|
+
* `env.list`, which accept the list directly.
|
|
19
|
+
*
|
|
20
|
+
* Not renamed:
|
|
21
|
+
*
|
|
22
|
+
* - `DATABRICKS_APP_PORT` - the Databricks Apps runtime contract. The platform
|
|
23
|
+
* sets it; the gate honours it.
|
|
24
|
+
* - `PORTR_TOKEN` / `PORTR_SERVER` / `PORTR_AUTO_ADD_PATH` - upstream
|
|
25
|
+
* [portr](https://github.com/amalshaji/portr)'s own namespace, and
|
|
26
|
+
* `PORTR_AUTO_ADD_PATH` is passed straight to that binary. Renaming these
|
|
27
|
+
* would rename someone else's contract.
|
|
28
|
+
*
|
|
29
|
+
* @module
|
|
30
|
+
*/
|
|
31
|
+
import type { EnvKey } from "@dbx-tools/shared-core";
|
|
32
|
+
/** Access allow-list patterns (domain / glob / `/regex/`). */
|
|
33
|
+
export declare const ALLOW_ENV: EnvKey;
|
|
34
|
+
/** Subject line for the code email. */
|
|
35
|
+
export declare const SUBJECT_ENV: EnvKey;
|
|
36
|
+
/** Display name used in the code email copy. */
|
|
37
|
+
export declare const BRAND_NAME_ENV: EnvKey;
|
|
38
|
+
/** Line shown immediately above the code in the email. */
|
|
39
|
+
export declare const MESSAGE_ENV: EnvKey;
|
|
40
|
+
/** Session lifetime, in seconds. */
|
|
41
|
+
export declare const SESSION_TTL_ENV: EnvKey;
|
|
42
|
+
/** One-time-code lifetime, in seconds. */
|
|
43
|
+
export declare const CODE_TTL_ENV: EnvKey;
|
|
44
|
+
/** HS256 signing secret for the session JWT. */
|
|
45
|
+
export declare const JWT_SECRET_ENV: EnvKey;
|
|
46
|
+
/** The public `<subdomain>.<server>` portr should serve on. */
|
|
47
|
+
export declare const PUBLIC_DOMAIN_ENV: EnvKey;
|
|
48
|
+
/** Run the tunnel OPEN, with no gate. Ignored unless truthy. */
|
|
49
|
+
export declare const INSECURE_ENV: EnvKey;
|
|
50
|
+
/** Extra `x-` request headers tunnel traffic may forward. */
|
|
51
|
+
export declare const FORWARD_HEADERS_ENV: EnvKey;
|