@dbx-tools/cli-tunnel 0.6.46 → 0.6.48
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 +167 -1
- package/bin/dbx-tools-tunnel.ts +1 -1
- package/lib/bin/dbx-tools-tunnel.js +2 -2
- package/lib/src/allowlist.d.ts +3 -3
- package/lib/src/allowlist.js +4 -4
- package/lib/src/app.d.ts +8 -0
- package/lib/src/app.js +48 -5
- package/lib/src/cli.d.ts +6 -4
- package/lib/src/cli.js +9 -7
- package/lib/src/otp.d.ts +7 -4
- package/lib/src/otp.js +8 -5
- package/lib/src/plugin.d.ts +29 -3
- package/lib/src/plugin.js +19 -15
- package/lib/src/portr.d.ts +3 -2
- package/lib/src/portr.js +4 -3
- package/lib/src/proxy.d.ts +5 -3
- package/lib/src/proxy.js +14 -11
- package/package.json +6 -5
- package/src/allowlist.ts +3 -3
- package/src/app.ts +49 -4
- package/src/cli.ts +11 -6
- package/src/otp.ts +7 -4
- package/src/plugin.ts +52 -19
- package/src/portr.ts +3 -2
- package/src/proxy.ts +13 -10
package/README.md
CHANGED
|
@@ -1 +1,167 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @dbx-tools/cli-tunnel
|
|
2
|
+
|
|
3
|
+
Front an app with a public tunnel and an email one-time-code access gate.
|
|
4
|
+
|
|
5
|
+
Built on [portr](https://github.com/amalshaji/portr). Run this CLI when an app
|
|
6
|
+
needs to be reachable from outside its network - a stakeholder demo, a webhook
|
|
7
|
+
sender that has to reach a dev build, an OAuth redirect that cannot point at
|
|
8
|
+
`localhost` - without publishing the app to anyone who learns the URL. It is
|
|
9
|
+
shaped for Databricks Apps (it honours the `DATABRICKS_APP_PORT` contract and
|
|
10
|
+
lets the platform's own front door through ungated) but the gate itself is
|
|
11
|
+
platform-neutral. The CLI wraps the app's real start command: it
|
|
12
|
+
moves the app onto a private loopback port, binds the public port with a gate
|
|
13
|
+
proxy, and brings the tunnel up alongside it. Access is granted per email
|
|
14
|
+
address against an allow-list, verified by a code sent over
|
|
15
|
+
[`@dbx-tools/email`](../../node/email).
|
|
16
|
+
|
|
17
|
+
**Key features:**
|
|
18
|
+
|
|
19
|
+
- Wraps an unmodified start command - everything after `--` runs as-is, so the
|
|
20
|
+
app needs no tunnel-specific code:
|
|
21
|
+
`dbxt-tunnel --allow example.com -- bun src/server.ts`.
|
|
22
|
+
- Branded from the repo-wide brand context: the code email's accent colour, font,
|
|
23
|
+
logo, and display name come from the app's own `branding/brand.yaml` (via
|
|
24
|
+
`@dbx-tools/core`'s `loadBrandContext()`), falling back to the dbx-tools
|
|
25
|
+
default - so the sign-in email looks like the app it fronts with nothing to
|
|
26
|
+
configure. `--brand-name` overrides just the name.
|
|
27
|
+
- Conventional one-time-code copy, so platform autofill works: the email is
|
|
28
|
+
`Your verification code is: / <code> / This code expires in N minutes`, and the
|
|
29
|
+
code input carries `autocomplete="one-time-code"`. iOS, Gmail, Outlook, and
|
|
30
|
+
Android detect a code from that shape and offer it directly from the
|
|
31
|
+
notification; novel phrasing is what breaks the detection. Both MIME parts carry
|
|
32
|
+
the code as visible text, never an image.
|
|
33
|
+
- Email one-time-code gate: a 6-digit code stored as a SHA-256 hash with an
|
|
34
|
+
attempt counter, verified in constant time, in AppKit's `CacheManager` (memory
|
|
35
|
+
by default, Lakebase when the app configures persistent `CacheStorage`) so TTL
|
|
36
|
+
expiry and eviction are the cache's job.
|
|
37
|
+
- Short-lived HS256 session JWT (via `jose`) carrying only the email, signed with
|
|
38
|
+
`AUTH_JWT_SECRET`.
|
|
39
|
+
- Allow-list patterns in three shapes, matched in order: a domain shortcut
|
|
40
|
+
(`example.com`, `@example.com`), a shell-style glob (`*@example.com`), or a
|
|
41
|
+
regex literal (`/^ops-.*@example\.com$/`). An empty list allows nobody.
|
|
42
|
+
- Per-email and per-IP fixed-window rate limiting, plus anti-enumeration: a code
|
|
43
|
+
request always answers `{ ok: true }`, whether or not the address is allowed.
|
|
44
|
+
- Platform traffic passes through UNGATED. The gate distinguishes the portr
|
|
45
|
+
client (a loopback source address, same container) from the hosting platform's
|
|
46
|
+
front door (a non-loopback container-network address), so health checks and the
|
|
47
|
+
workspace UI keep working while public tunnel traffic is gated.
|
|
48
|
+
- SPA-aware gating: static assets and the login routes stay open so the browser
|
|
49
|
+
can load the client and render the login form; every other `/api/*` needs a
|
|
50
|
+
valid session cookie or gets `401`. WebSocket upgrades are gated the same way.
|
|
51
|
+
- Supervised teardown - the app child, the portr child, and this process are tied
|
|
52
|
+
together, so if any one exits the whole tunnel comes down.
|
|
53
|
+
- Fails fast when email is not configured for SMTP, because a gate that cannot
|
|
54
|
+
send codes locks everyone out. `--insecure` is the explicit opt-out.
|
|
55
|
+
|
|
56
|
+
## Why This Over An Ad-Hoc Tunnel
|
|
57
|
+
|
|
58
|
+
A bare tunnel (`ngrok`, `portr` on its own) makes the app reachable by anyone
|
|
59
|
+
with the URL. This package keeps the tunnel but puts a gate in front of it,
|
|
60
|
+
reusing what the app already has: AppKit's cache for code storage, the
|
|
61
|
+
`@dbx-tools/email` transport for delivery, and the app's own `From` policy. There
|
|
62
|
+
is nothing to add to the app itself - no route, no middleware, no auth library.
|
|
63
|
+
|
|
64
|
+
## Run It
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
dbxt-tunnel \
|
|
68
|
+
--allow "example.com, *@partner.example" \
|
|
69
|
+
--brand-name "Acme Ops" \
|
|
70
|
+
-- bun src/server.ts
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The package installs two equivalent commands, `dbx-tools-tunnel` and the shorter
|
|
74
|
+
`dbxt-tunnel`. Neither matches the package name, so a one-off run has to name the
|
|
75
|
+
command explicitly:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
npx --package @dbx-tools/cli-tunnel dbx-tools-tunnel --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Everything after `--` is the real start command. The CLI sets
|
|
82
|
+
`DATABRICKS_APP_PORT` to a random private port for that child and binds the
|
|
83
|
+
original public port itself.
|
|
84
|
+
|
|
85
|
+
## Options
|
|
86
|
+
|
|
87
|
+
Every flag has an environment fallback, so a deployment can configure the gate
|
|
88
|
+
with no change to its start command.
|
|
89
|
+
|
|
90
|
+
| Flag | Env | Default |
|
|
91
|
+
| ----------------- | ------------------ | ---------------------------- |
|
|
92
|
+
| `--allow` | `EMAIL_AUTH_ALLOW` | empty (allow nobody) |
|
|
93
|
+
| `--subject` | `AUTH_SUBJECT` | `Your verification code` |
|
|
94
|
+
| `--brand-name` | `AUTH_BRAND_NAME` | the brand context `name` |
|
|
95
|
+
| `--message` | `AUTH_MESSAGE` | `Your verification code is:` |
|
|
96
|
+
| `--session-ttl` | `AUTH_SESSION_TTL` | `43200` (12 hours) |
|
|
97
|
+
| `--code-ttl` | `AUTH_CODE_TTL` | `600` (10 minutes) |
|
|
98
|
+
| `--subdomain` | - | derived from `PUBLIC_DOMAIN` |
|
|
99
|
+
| `--public-domain` | `PUBLIC_DOMAIN` | - |
|
|
100
|
+
| `--insecure` | `TUNNEL_INSECURE` | off (the gate is required) |
|
|
101
|
+
|
|
102
|
+
`--allow` and `EMAIL_AUTH_ALLOW` are UNIONED rather than one overriding the
|
|
103
|
+
other, so a deployment-wide allow-list and a per-invocation addition both grant
|
|
104
|
+
access. Session signing reads `AUTH_JWT_SECRET`; when it is unset the gate mints
|
|
105
|
+
an ephemeral per-process key, so sessions simply do not survive a restart rather
|
|
106
|
+
than the gate refusing to serve.
|
|
107
|
+
|
|
108
|
+
## Use The Gate As A Plugin
|
|
109
|
+
|
|
110
|
+
The gate is an AppKit plugin, so an app that wants the OTP flow without the
|
|
111
|
+
tunnel can mount it directly. It registers no routes - it exposes handlers the
|
|
112
|
+
caller invokes - and it takes a `sendCode` callback because delivering mail is
|
|
113
|
+
the one thing it cannot resolve on its own:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { createApp } from "@dbx-tools/appkit";
|
|
117
|
+
import { authGate } from "@dbx-tools/cli-tunnel/plugin";
|
|
118
|
+
import { brand, email, sender, transport } from "@dbx-tools/email";
|
|
119
|
+
|
|
120
|
+
const handle = await createApp({
|
|
121
|
+
plugins: [
|
|
122
|
+
email({ brand: brand.defaultEmailBrand }),
|
|
123
|
+
authGate({
|
|
124
|
+
allow: ["example.com"],
|
|
125
|
+
sendCode: async (to, code, opts) => {
|
|
126
|
+
const runtime = transport.getEmailRuntime();
|
|
127
|
+
await transport.sendEmail(
|
|
128
|
+
{
|
|
129
|
+
to: [to],
|
|
130
|
+
subject: opts.subject,
|
|
131
|
+
body: `${opts.message}\n\n## ${code}`,
|
|
132
|
+
},
|
|
133
|
+
// The app's configured sender; a code email has no on-behalf-of user.
|
|
134
|
+
sender.resolveSenderAddress(runtime.config, undefined),
|
|
135
|
+
);
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// The gate exposes handlers rather than routes - call them from your own server.
|
|
142
|
+
const status = await handle.authGate.status(sessionCookieValue);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`sendCode` is the one thing the plugin cannot resolve on its own. When the tunnel
|
|
146
|
+
CLI boots the gate it wires this same callback, and derives the email styling from
|
|
147
|
+
the brand context, so mounting the plugin directly is the only case that needs it
|
|
148
|
+
by hand.
|
|
149
|
+
|
|
150
|
+
## Modules
|
|
151
|
+
|
|
152
|
+
- `cli` - argv parsing, the wrapped-command split at `--`, and process
|
|
153
|
+
supervision.
|
|
154
|
+
- `plugin` - `authGate()`, its config/env resolution, and the `AuthGateApi`
|
|
155
|
+
handlers the proxy calls in-process.
|
|
156
|
+
- `proxy` - the public-port reverse proxy: loopback-vs-platform classification,
|
|
157
|
+
open login routes, session enforcement, and WebSocket forwarding.
|
|
158
|
+
- `otp` - the `CacheManager`-backed code store and the session JWT.
|
|
159
|
+
- `allowlist` - domain / glob / regex matching and `looksLikeEmail`.
|
|
160
|
+
- `rate-limit` - the in-memory fixed-window limiter (single-instance only; not
|
|
161
|
+
distributed).
|
|
162
|
+
- `portr` - portr install, config rendering, and child launch.
|
|
163
|
+
- `app` - boots the minimal gate AppKit app and returns the `AuthGateApi`.
|
|
164
|
+
|
|
165
|
+
Browser-safe login wire schemas (the request/verify payloads and the session
|
|
166
|
+
cookie name) live in [`@dbx-tools/shared-email`](../../shared/email); the React
|
|
167
|
+
login surface is in [`@dbx-tools/ui-email`](../../ui/email).
|
package/bin/dbx-tools-tunnel.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* `dbx-tools-tunnel` / `dbxt-tunnel` entry: front
|
|
3
|
+
* `dbx-tools-tunnel` / `dbxt-tunnel` entry: front an app with a public
|
|
4
4
|
* portr tunnel + email-OTP gate, wrapping the start command after `--`.
|
|
5
5
|
* Delegates to the commander program in `../src/cli`.
|
|
6
6
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* `dbx-tools-tunnel` / `dbxt-tunnel` entry: front
|
|
3
|
+
* `dbx-tools-tunnel` / `dbxt-tunnel` entry: front an app with a public
|
|
4
4
|
* portr tunnel + email-OTP gate, wrapping the start command after `--`.
|
|
5
5
|
* Delegates to the commander program in `../src/cli`.
|
|
6
6
|
*/
|
|
@@ -11,4 +11,4 @@ runCli(process.argv).catch((err) => {
|
|
|
11
11
|
process.stderr.write(`${err instanceof Error ? (err.stack ?? err.message) : String(err)}\n`);
|
|
12
12
|
process.exit(1);
|
|
13
13
|
});
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGJ4LXRvb2xzLXR1bm5lbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2Jpbi9kYngtdG9vbHMtdHVubmVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFZLEVBQUUsRUFBRTtJQUMxQyxJQUFJLEdBQUcsWUFBWSxjQUFjO1FBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdGLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG4vKipcbiAqIGBkYngtdG9vbHMtdHVubmVsYCAvIGBkYnh0LXR1bm5lbGAgZW50cnk6IGZyb250IGFuIGFwcCB3aXRoIGEgcHVibGljXG4gKiBwb3J0ciB0dW5uZWwgKyBlbWFpbC1PVFAgZ2F0ZSwgd3JhcHBpbmcgdGhlIHN0YXJ0IGNvbW1hbmQgYWZ0ZXIgYC0tYC5cbiAqIERlbGVnYXRlcyB0byB0aGUgY29tbWFuZGVyIHByb2dyYW0gaW4gYC4uL3NyYy9jbGlgLlxuICovXG5pbXBvcnQgeyBDb21tYW5kZXJFcnJvciwgcnVuQ2xpIH0gZnJvbSBcIi4uL3NyYy9jbGkudHNcIjtcblxucnVuQ2xpKHByb2Nlc3MuYXJndikuY2F0Y2goKGVycjogdW5rbm93bikgPT4ge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgQ29tbWFuZGVyRXJyb3IpIHByb2Nlc3MuZXhpdChlcnIuZXhpdENvZGUpO1xuICBwcm9jZXNzLnN0ZGVyci53cml0ZShgJHtlcnIgaW5zdGFuY2VvZiBFcnJvciA/IChlcnIuc3RhY2sgPz8gZXJyLm1lc3NhZ2UpIDogU3RyaW5nKGVycil9XFxuYCk7XG4gIHByb2Nlc3MuZXhpdCgxKTtcbn0pO1xuIl19
|
package/lib/src/allowlist.d.ts
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each pattern in the configured list is one of three shapes, tried in order:
|
|
5
5
|
*
|
|
6
|
-
* - **domain shortcut** - `
|
|
6
|
+
* - **domain shortcut** - `example.com` or `@example.com`: matches any
|
|
7
7
|
* address whose domain equals it (case-insensitive). The leading `@` is
|
|
8
8
|
* optional and stripped.
|
|
9
|
-
* - **glob** - contains `*` or `?`, e.g. `*.
|
|
10
|
-
* `*@
|
|
9
|
+
* - **glob** - contains `*` or `?`, e.g. `*.example.com` or
|
|
10
|
+
* `*@example.com`: matched against the WHOLE address with shell-style
|
|
11
11
|
* wildcards (`*` = any run, `?` = one char).
|
|
12
12
|
* - **regex** - wrapped in slashes, `/.../ [flags]`: compiled and tested
|
|
13
13
|
* against the whole address. An invalid regex never matches (it is skipped
|
package/lib/src/allowlist.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each pattern in the configured list is one of three shapes, tried in order:
|
|
5
5
|
*
|
|
6
|
-
* - **domain shortcut** - `
|
|
6
|
+
* - **domain shortcut** - `example.com` or `@example.com`: matches any
|
|
7
7
|
* address whose domain equals it (case-insensitive). The leading `@` is
|
|
8
8
|
* optional and stripped.
|
|
9
|
-
* - **glob** - contains `*` or `?`, e.g. `*.
|
|
10
|
-
* `*@
|
|
9
|
+
* - **glob** - contains `*` or `?`, e.g. `*.example.com` or
|
|
10
|
+
* `*@example.com`: matched against the WHOLE address with shell-style
|
|
11
11
|
* wildcards (`*` = any run, `?` = one char).
|
|
12
12
|
* - **regex** - wrapped in slashes, `/.../ [flags]`: compiled and tested
|
|
13
13
|
* against the whole address. An invalid regex never matches (it is skipped
|
|
@@ -79,4 +79,4 @@ export function matchesAllowlist(email, patterns) {
|
|
|
79
79
|
export function looksLikeEmail(value) {
|
|
80
80
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
81
81
|
}
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsb3dsaXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FsbG93bGlzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUVILE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU3QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFOUMseURBQXlEO0FBQ3pELFNBQVMsWUFBWSxDQUFDLEtBQWE7SUFDakMsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRCx1RkFBdUY7QUFDdkYsU0FBUyxZQUFZLENBQUMsSUFBWTtJQUNoQyxNQUFNLElBQUksR0FBRyxJQUFJO1NBQ2QsS0FBSyxDQUFDLFFBQVEsQ0FBQztTQUNmLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDOUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ1osT0FBTyxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsU0FBUyxpQkFBaUIsQ0FBQyxPQUFlO0lBQ3hDLE1BQU0sS0FBSyxHQUFHLHNCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFFLEdBQUcsQ0FBQztRQUNwRSxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkNBQTJDLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQztBQUVELCtEQUErRDtBQUMvRCxTQUFTLGNBQWMsQ0FBQyxLQUFhLEVBQUUsT0FBZTtJQUNwRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDL0IsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzQixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFM0MsdUJBQXVCO0lBQ3ZCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVCLE1BQU0sRUFBRSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDdkMsQ0FBQztJQUVELDZCQUE2QjtJQUM3QixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ25ELE9BQU8sWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3ZELE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQztBQUNyRCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxRQUF1QztJQUNyRixJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQy9ELE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFhO0lBQzFDLE9BQU8sNEJBQTRCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVuaWZpZWQgYWNjZXNzIGFsbG93LWxpc3QgbWF0Y2hpbmcgZm9yIHRoZSBlbWFpbC1PVFAgZ2F0ZS5cbiAqXG4gKiBFYWNoIHBhdHRlcm4gaW4gdGhlIGNvbmZpZ3VyZWQgbGlzdCBpcyBvbmUgb2YgdGhyZWUgc2hhcGVzLCB0cmllZCBpbiBvcmRlcjpcbiAqXG4gKiAgIC0gKipkb21haW4gc2hvcnRjdXQqKiAtIGBleGFtcGxlLmNvbWAgb3IgYEBleGFtcGxlLmNvbWA6IG1hdGNoZXMgYW55XG4gKiAgICAgYWRkcmVzcyB3aG9zZSBkb21haW4gZXF1YWxzIGl0IChjYXNlLWluc2Vuc2l0aXZlKS4gVGhlIGxlYWRpbmcgYEBgIGlzXG4gKiAgICAgb3B0aW9uYWwgYW5kIHN0cmlwcGVkLlxuICogICAtICoqZ2xvYioqIC0gY29udGFpbnMgYCpgIG9yIGA/YCwgZS5nLiBgKi5leGFtcGxlLmNvbWAgb3JcbiAqICAgICBgKkBleGFtcGxlLmNvbWA6IG1hdGNoZWQgYWdhaW5zdCB0aGUgV0hPTEUgYWRkcmVzcyB3aXRoIHNoZWxsLXN0eWxlXG4gKiAgICAgd2lsZGNhcmRzIChgKmAgPSBhbnkgcnVuLCBgP2AgPSBvbmUgY2hhcikuXG4gKiAgIC0gKipyZWdleCoqIC0gd3JhcHBlZCBpbiBzbGFzaGVzLCBgLy4uLi8gW2ZsYWdzXWA6IGNvbXBpbGVkIGFuZCB0ZXN0ZWRcbiAqICAgICBhZ2FpbnN0IHRoZSB3aG9sZSBhZGRyZXNzLiBBbiBpbnZhbGlkIHJlZ2V4IG5ldmVyIG1hdGNoZXMgKGl0IGlzIHNraXBwZWRcbiAqICAgICB3aXRoIGEgd2FybmluZyByYXRoZXIgdGhhbiB0aHJvd2luZykuXG4gKlxuICogQW4gRU1QVFkgbGlzdCBtYXRjaGVzIG5vYm9keSAoZmFpbCBjbG9zZWQpOiBhbiBhcHAgdGhhdCBlbmFibGVzIHRoZSBnYXRlIGJ1dFxuICogY29uZmlndXJlcyBubyBwYXR0ZXJucyBsZXRzIG5vIG9uZSBpbiwgd2hpY2ggaXMgdGhlIHNhZmUgZGVmYXVsdC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDphbGxvd2xpc3RcIik7XG5cbi8qKiBFc2NhcGUgYSBzdHJpbmcgZm9yIGxpdGVyYWwgdXNlIGluc2lkZSBhIGBSZWdFeHBgLiAqL1xuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFwiXFxcXCQmXCIpO1xufVxuXG4vKiogQ29tcGlsZSBhIHNoZWxsLXN0eWxlIGdsb2IgKGAqYCwgYD9gKSBpbnRvIGFuIGFuY2hvcmVkLCBjYXNlLWluc2Vuc2l0aXZlIFJlZ0V4cC4gKi9cbmZ1bmN0aW9uIGdsb2JUb1JlZ0V4cChnbG9iOiBzdHJpbmcpOiBSZWdFeHAge1xuICBjb25zdCBib2R5ID0gZ2xvYlxuICAgIC5zcGxpdCgvKFsqP10pLylcbiAgICAubWFwKChwYXJ0KSA9PiAocGFydCA9PT0gXCIqXCIgPyBcIi4qXCIgOiBwYXJ0ID09PSBcIj9cIiA/IFwiLlwiIDogZXNjYXBlUmVnRXhwKHBhcnQpKSlcbiAgICAuam9pbihcIlwiKTtcbiAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke2JvZHl9JGAsIFwiaVwiKTtcbn1cblxuLyoqIFBhcnNlIGEgYC9wYXR0ZXJuL2ZsYWdzYCBzdHJpbmcgaW50byBhIFJlZ0V4cCwgb3IgYHVuZGVmaW5lZGAgaWYgbWFsZm9ybWVkLiAqL1xuZnVuY3Rpb24gcGFyc2VSZWdleExpdGVyYWwocGF0dGVybjogc3RyaW5nKTogUmVnRXhwIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWF0Y2ggPSAvXlxcLyguKylcXC8oW2Etel0qKSQvaXMuZXhlYyhwYXR0ZXJuKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgdHJ5IHtcbiAgICBjb25zdCBmbGFncyA9IG1hdGNoWzJdIS5pbmNsdWRlcyhcImlcIikgPyBtYXRjaFsyXSEgOiBgJHttYXRjaFsyXSF9aWA7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAobWF0Y2hbMV0hLCBmbGFncyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJpZ25vcmluZyBpbnZhbGlkIHJlZ2V4IGFsbG93LWxpc3QgcGF0dGVyblwiLCB7IHBhdHRlcm4sIGVycm9yIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqIFRydWUgd2hlbiBgZW1haWxgIG1hdGNoZXMgYSBzaW5nbGUgYWxsb3ctbGlzdCBgcGF0dGVybmAuICovXG5mdW5jdGlvbiBtYXRjaGVzUGF0dGVybihlbWFpbDogc3RyaW5nLCBwYXR0ZXJuOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgdHJpbW1lZCA9IHBhdHRlcm4udHJpbSgpO1xuICBpZiAoIXRyaW1tZWQpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgYWRkcmVzcyA9IGVtYWlsLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuXG4gIC8vIFJlZ2V4IGxpdGVyYWw6IC8uLi4vXG4gIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgY29uc3QgcmUgPSBwYXJzZVJlZ2V4TGl0ZXJhbCh0cmltbWVkKTtcbiAgICByZXR1cm4gcmUgPyByZS50ZXN0KGFkZHJlc3MpIDogZmFsc2U7XG4gIH1cblxuICAvLyBHbG9iOiBjb250YWlucyBhIHdpbGRjYXJkLlxuICBpZiAodHJpbW1lZC5pbmNsdWRlcyhcIipcIikgfHwgdHJpbW1lZC5pbmNsdWRlcyhcIj9cIikpIHtcbiAgICByZXR1cm4gZ2xvYlRvUmVnRXhwKHRyaW1tZWQpLnRlc3QoYWRkcmVzcyk7XG4gIH1cblxuICAvLyBEb21haW4gc2hvcnRjdXQ6IGBAZC5jb21gIG9yIGBkLmNvbWAgLT4gbWF0Y2ggdGhlIGFkZHJlc3MncyBkb21haW4uXG4gIGNvbnN0IGRvbWFpbiA9IHRyaW1tZWQucmVwbGFjZSgvXkAvLCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBhdCA9IGFkZHJlc3MubGFzdEluZGV4T2YoXCJAXCIpO1xuICByZXR1cm4gYXQgPj0gMCAmJiBhZGRyZXNzLnNsaWNlKGF0ICsgMSkgPT09IGRvbWFpbjtcbn1cblxuLyoqXG4gKiBUcnVlIHdoZW4gYGVtYWlsYCBpcyBhbGxvd2VkIGJ5IEFOWSBwYXR0ZXJuIGluIGBwYXR0ZXJuc2AuIEFuIGVtcHR5IChvclxuICogbWlzc2luZykgbGlzdCBhbGxvd3Mgbm9ib2R5IC0gdGhlIGdhdGUgZmFpbHMgY2xvc2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hlc0FsbG93bGlzdChlbWFpbDogc3RyaW5nLCBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKCFlbWFpbCB8fCAhcGF0dGVybnMgfHwgcGF0dGVybnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBwYXR0ZXJucy5zb21lKChwYXR0ZXJuKSA9PiBtYXRjaGVzUGF0dGVybihlbWFpbCwgcGF0dGVybikpO1xufVxuXG4vKiogUm91Z2ggc2hhcGUgY2hlY2sgc28gYSBjbGVhcmx5LWludmFsaWQgYWRkcmVzcyBpcyByZWplY3RlZCBiZWZvcmUgYW55IHdvcmsuICovXG5leHBvcnQgZnVuY3Rpb24gbG9va3NMaWtlRW1haWwodmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL15bXlxcc0BdK0BbXlxcc0BdK1xcLlteXFxzQF0rJC8udGVzdCh2YWx1ZS50cmltKCkpO1xufVxuIl19
|
package/lib/src/app.d.ts
CHANGED
|
@@ -22,6 +22,14 @@
|
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
|
24
24
|
import { type AuthGateApi, type AuthGateConfig } from "./plugin.ts";
|
|
25
|
+
/**
|
|
26
|
+
* A code TTL as the plain phrase the email states ("10 minutes", "45 seconds").
|
|
27
|
+
*
|
|
28
|
+
* Whole minutes read as minutes; anything else stays in seconds rather than
|
|
29
|
+
* rounding, so a 90-second TTL is not advertised as "1 minute" and a recipient is
|
|
30
|
+
* never told the code lives longer than it does.
|
|
31
|
+
*/
|
|
32
|
+
export declare function expiresIn(seconds: number): string;
|
|
25
33
|
/**
|
|
26
34
|
* Boot the gate app and return the API the proxy calls. Throws when email is not
|
|
27
35
|
* in SMTP mode (no way to deliver a code) so a misconfigured gate fails fast at
|
package/lib/src/app.js
CHANGED
|
@@ -22,13 +22,28 @@
|
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
|
24
24
|
import { createApp as createAppNs } from "@dbx-tools/appkit";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
25
|
+
import { brand as nodeBrand } from "@dbx-tools/core";
|
|
26
|
+
import { brand as emailBrand, email, sender, transport } from "@dbx-tools/email";
|
|
27
|
+
import { log, string } from "@dbx-tools/shared-core";
|
|
27
28
|
import { authGate } from "./plugin.js";
|
|
28
29
|
const logger = log.logger("tunnel:app");
|
|
30
|
+
/**
|
|
31
|
+
* A code TTL as the plain phrase the email states ("10 minutes", "45 seconds").
|
|
32
|
+
*
|
|
33
|
+
* Whole minutes read as minutes; anything else stays in seconds rather than
|
|
34
|
+
* rounding, so a 90-second TTL is not advertised as "1 minute" and a recipient is
|
|
35
|
+
* never told the code lives longer than it does.
|
|
36
|
+
*/
|
|
37
|
+
export function expiresIn(seconds) {
|
|
38
|
+
return seconds >= 60 && seconds % 60 === 0
|
|
39
|
+
? string.pluralize(seconds / 60, "minute")
|
|
40
|
+
: string.pluralize(seconds, "second");
|
|
41
|
+
}
|
|
29
42
|
const { createApp } = createAppNs;
|
|
30
43
|
const { resolveSenderAddress } = sender;
|
|
31
44
|
const { getEmailRuntime, sendEmail } = transport;
|
|
45
|
+
const { emailBrandFromContext } = emailBrand;
|
|
46
|
+
const { loadBrandContext } = nodeBrand;
|
|
32
47
|
/**
|
|
33
48
|
* Boot the gate app and return the API the proxy calls. Throws when email is not
|
|
34
49
|
* in SMTP mode (no way to deliver a code) so a misconfigured gate fails fast at
|
|
@@ -36,6 +51,12 @@ const { getEmailRuntime, sendEmail } = transport;
|
|
|
36
51
|
* fall back to insecure/open mode when the operator opted in.
|
|
37
52
|
*/
|
|
38
53
|
export async function startGateApp(config) {
|
|
54
|
+
// The host app's own brand (`branding/brand.yaml` discovered from cwd) or the
|
|
55
|
+
// dbx-tools default. This is the ONE brand source for the gate: it styles the
|
|
56
|
+
// code email (accent band, font, logo) via the email plugin AND supplies the
|
|
57
|
+
// display name the copy uses, so a deployment that themes its app themes its
|
|
58
|
+
// sign-in email with it. An explicit `brandName` still wins (see below).
|
|
59
|
+
const context = await loadBrandContext();
|
|
39
60
|
// `sendCode` delivers the OTP through the email plugin's SHARED transport, which
|
|
40
61
|
// the `email()` plugin primes during its `setup()` (awaited by `createApp`
|
|
41
62
|
// below). Using the module-level `sendEmail` avoids a circular dependency on the
|
|
@@ -46,18 +67,40 @@ export async function startGateApp(config) {
|
|
|
46
67
|
await sendEmail({
|
|
47
68
|
to: [to],
|
|
48
69
|
subject: opts.subject,
|
|
70
|
+
// Deliberately the conventional one-time-code layout: the prompt line,
|
|
71
|
+
// then the bare code ALONE on the next line, then the expiry. iOS, Gmail,
|
|
72
|
+
// Outlook, and Android all detect a code from this shape and offer to
|
|
73
|
+
// autofill it, and anything more decorative is what breaks that. The code
|
|
74
|
+
// stays visible TEXT in both MIME parts (the email plugin renders the
|
|
75
|
+
// HTML and plain-text alternatives from one React Email tree), never an
|
|
76
|
+
// image, so a client that scrapes the text part still finds it.
|
|
49
77
|
body: [
|
|
50
78
|
opts.message,
|
|
51
79
|
"",
|
|
52
80
|
`## ${code}`,
|
|
53
81
|
"",
|
|
54
|
-
|
|
82
|
+
`This code expires in ${expiresIn(opts.codeTtlSeconds)}.`,
|
|
83
|
+
"",
|
|
84
|
+
"If you did not request this code, you can ignore this email.",
|
|
55
85
|
].join("\n"),
|
|
56
86
|
}, from);
|
|
57
87
|
};
|
|
58
88
|
// `createApp` namespaces each plugin's exports on the handle by manifest name;
|
|
59
89
|
// `handle.authGate` is the in-process gate API the proxy drives.
|
|
60
|
-
const handle = await createApp({
|
|
90
|
+
const handle = await createApp({
|
|
91
|
+
plugins: [
|
|
92
|
+
// Brand the code email from the resolved context, the same bridge every
|
|
93
|
+
// other dbx-tools email surface uses (accent + font inlined, logo only when
|
|
94
|
+
// it is a fetchable URL - a package-export path cannot load in an inbox).
|
|
95
|
+
email({ brand: emailBrandFromContext(context) }),
|
|
96
|
+
// `brandName` falls back to the resolved context's display name, so the
|
|
97
|
+
// email copy names the app rather than a generic placeholder. Spelled as an
|
|
98
|
+
// explicit `??` rather than a key before `...config`: commander sets
|
|
99
|
+
// `brandName` on the options object whether or not the flag was passed, so
|
|
100
|
+
// spreading it would clobber the context name with `undefined`.
|
|
101
|
+
authGate({ ...config, brandName: config.brandName ?? context.name, sendCode }),
|
|
102
|
+
],
|
|
103
|
+
});
|
|
61
104
|
// Fail fast: the gate needs SMTP to email codes. `getEmailRuntime()` resolves to
|
|
62
105
|
// `mode: "file"` (outbox) or throws when no SMTP creds are configured - neither
|
|
63
106
|
// can deliver to a real inbox, so refuse to bring up a gate that lets nobody in.
|
|
@@ -68,4 +111,4 @@ export async function startGateApp(config) {
|
|
|
68
111
|
logger.info("gate app ready (no server; proxy-driven)");
|
|
69
112
|
return handle.authGate;
|
|
70
113
|
}
|
|
71
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDN0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxRQUFRLEVBQXlDLE1BQU0sYUFBYSxDQUFDO0FBRTlFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFeEMsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLFdBQVcsQ0FBQztBQUNsQyxNQUFNLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxNQUFNLENBQUM7QUFDeEMsTUFBTSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsR0FBRyxTQUFTLENBQUM7QUFFakQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FBQyxNQUFzQjtJQUN2RCxpRkFBaUY7SUFDakYsMkVBQTJFO0lBQzNFLGlGQUFpRjtJQUNqRixrRkFBa0Y7SUFDbEYsa0ZBQWtGO0lBQ2xGLE1BQU0sUUFBUSxHQUE0QyxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUNqRixNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdkUsTUFBTSxTQUFTLENBQ2I7WUFDRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDUixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsSUFBSSxFQUFFO2dCQUNKLElBQUksQ0FBQyxPQUFPO2dCQUNaLEVBQUU7Z0JBQ0YsTUFBTSxJQUFJLEVBQUU7Z0JBQ1osRUFBRTtnQkFDRixvRUFBb0U7YUFDckUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ2IsRUFDRCxJQUFJLENBQ0wsQ0FBQztJQUNKLENBQUMsQ0FBQztJQUVGLCtFQUErRTtJQUMvRSxpRUFBaUU7SUFDakUsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxRQUFRLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTFGLGlGQUFpRjtJQUNqRixnRkFBZ0Y7SUFDaEYsaUZBQWlGO0lBQ2pGLElBQUksZUFBZSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM3QyxNQUFNLElBQUksS0FBSyxDQUNiLDhFQUE4RTtZQUM1RSwwR0FBMEcsQ0FDN0csQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxNQUFNLENBQUMsUUFBdUIsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsIGdhdGUncyB0aW55IEFwcEtpdCBcImFwcFwiIC0gYGNyZWF0ZUFwcGAgV0lUSE9VVCBhIGBzZXJ2ZXIoKWAgcGx1Z2luLlxuICpcbiAqIFRoZXJlIGlzIG5vIEhUVFAgc2VydmVyIGhlcmU6IHRoZSB0dW5uZWwgcHJveHkgaXMgdGhlIHNlcnZlciwgYW5kIGl0IGNhbGxzIHRoZVxuICogZ2F0ZSBoYW5kbGVycyBpbi1wcm9jZXNzLiBgY3JlYXRlQXBwYCBpcyB1c2VkIG9ubHkgZm9yIHdoYXQgaXQgYXV0by13aXJlczpcbiAqICAgLSBgQ2FjaGVNYW5hZ2VyYCAobWVtb3J5LCBvciBMYWtlYmFzZSB3aGVuIHRoZSBkZXBsb3kgY29uZmlndXJlcyBwZXJzaXN0ZW50XG4gKiAgICAgY2FjaGUgc3RvcmFnZSkgLSB3aGljaCB0aGUgT1RQIGBDb2RlU3RvcmVgIHVzZXMgZm9yIHN0b3JhZ2UgKyBUVEwgZXZpY3Rpb247XG4gKiAgIC0gdGhlIGBlbWFpbCgpYCB0cmFuc3BvcnQgKFNNVFAgLyBvdXRib3gpLCBwcmltZWQgZnJvbSBlbnYsIHNvIGBzZW5kQ29kZWAgY2FuXG4gKiAgICAgZGVsaXZlciB0aGUgb25lLXRpbWUgY29kZTtcbiAqICAgLSBkYngtdG9vbHMgYXV0by1jb25maWd1cmF0aW9uICsgYnJhbmRpbmcgdmlhIGBAZGJ4LXRvb2xzL2FwcGtpdGAuXG4gKlxuICogSXQgcmV0dXJucyB0aGUge0BsaW5rIEF1dGhHYXRlQXBpfSB0aGUgcHJveHkgZHJpdmVzLiBgc2VuZENvZGVgIGlzIHdpcmVkIGhlcmVcbiAqICh0aGUgcGx1Z2luIGNhbid0IHJlc29sdmUgSE9XIHRvIHNlbmQgb24gaXRzIG93bikgdG8gdGhlIGVtYWlsIHBsdWdpbidzXG4gKiB0cmFuc3BvcnQsIHJlc29sdmluZyB0aGUgYEZyb21gIGZyb20gdGhlIGVtYWlsIHJ1bnRpbWUgY29uZmlnIChFTUFJTF9GUk9NIC9cbiAqIEVNQUlMX0RPTUFJTikgc2luY2UgYW4gT1RQIHJlcXVlc3QgaGFzIG5vIG9uLWJlaGFsZi1vZiB1c2VyLlxuICpcbiAqIEZBSUwgRkFTVDogYSBnYXRlIHRoYXQgY2FuJ3QgZW1haWwgYSBjb2RlIGlzIHVzZWxlc3MsIHNvIGlmIGVtYWlsIGRvZXMgbm90XG4gKiByZXNvbHZlIHRvIFNNVFAgbW9kZSAocmVhbCBkZWxpdmVyeSksIHRoaXMgdGhyb3dzIC0gdW5sZXNzIGBpbnNlY3VyZWAgaXMgc2V0XG4gKiAoYC0taW5zZWN1cmVgIC8gYFRVTk5FTF9JTlNFQ1VSRT10cnVlYCksIGluIHdoaWNoIGNhc2UgdGhlIGNhbGxlciBydW5zIHRoZVxuICogdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVBcHAgYXMgY3JlYXRlQXBwTnMgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGVtYWlsLCBzZW5kZXIsIHRyYW5zcG9ydCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgYXV0aEdhdGUsIHR5cGUgQXV0aEdhdGVBcGksIHR5cGUgQXV0aEdhdGVDb25maWcgfSBmcm9tIFwiLi9wbHVnaW4udHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDphcHBcIik7XG5cbmNvbnN0IHsgY3JlYXRlQXBwIH0gPSBjcmVhdGVBcHBOcztcbmNvbnN0IHsgcmVzb2x2ZVNlbmRlckFkZHJlc3MgfSA9IHNlbmRlcjtcbmNvbnN0IHsgZ2V0RW1haWxSdW50aW1lLCBzZW5kRW1haWwgfSA9IHRyYW5zcG9ydDtcblxuLyoqXG4gKiBCb290IHRoZSBnYXRlIGFwcCBhbmQgcmV0dXJuIHRoZSBBUEkgdGhlIHByb3h5IGNhbGxzLiBUaHJvd3Mgd2hlbiBlbWFpbCBpcyBub3RcbiAqIGluIFNNVFAgbW9kZSAobm8gd2F5IHRvIGRlbGl2ZXIgYSBjb2RlKSBzbyBhIG1pc2NvbmZpZ3VyZWQgZ2F0ZSBmYWlscyBmYXN0IGF0XG4gKiBzdGFydHVwIHJhdGhlciB0aGFuIHNpbGVudGx5IGFjY2VwdGluZyBub2JvZHk7IHRoZSBjYWxsZXIgbWF5IGNhdGNoIHRoaXMgYW5kXG4gKiBmYWxsIGJhY2sgdG8gaW5zZWN1cmUvb3BlbiBtb2RlIHdoZW4gdGhlIG9wZXJhdG9yIG9wdGVkIGluLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRHYXRlQXBwKGNvbmZpZzogQXV0aEdhdGVDb25maWcpOiBQcm9taXNlPEF1dGhHYXRlQXBpPiB7XG4gIC8vIGBzZW5kQ29kZWAgZGVsaXZlcnMgdGhlIE9UUCB0aHJvdWdoIHRoZSBlbWFpbCBwbHVnaW4ncyBTSEFSRUQgdHJhbnNwb3J0LCB3aGljaFxuICAvLyB0aGUgYGVtYWlsKClgIHBsdWdpbiBwcmltZXMgZHVyaW5nIGl0cyBgc2V0dXAoKWAgKGF3YWl0ZWQgYnkgYGNyZWF0ZUFwcGBcbiAgLy8gYmVsb3cpLiBVc2luZyB0aGUgbW9kdWxlLWxldmVsIGBzZW5kRW1haWxgIGF2b2lkcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgb24gdGhlXG4gIC8vIGFwcCBoYW5kbGUncyBpbmZlcnJlZCB0eXBlLiBgRnJvbWAgaXMgdGhlIGFwcCdzIGNvbmZpZ3VyZWQgc2VuZGVyIChFTUFJTF9GUk9NIC9cbiAgLy8gRU1BSUxfRE9NQUlOKTsgdGhlIGNvZGUgZW1haWwgaGFzIG5vIE9CTyB1c2VyLCBzbyBpdCByZXNvbHZlcyB3aXRoIGB1bmRlZmluZWRgLlxuICBjb25zdCBzZW5kQ29kZTogTm9uTnVsbGFibGU8QXV0aEdhdGVDb25maWdbXCJzZW5kQ29kZVwiXT4gPSBhc3luYyAodG8sIGNvZGUsIG9wdHMpID0+IHtcbiAgICBjb25zdCBmcm9tID0gcmVzb2x2ZVNlbmRlckFkZHJlc3MoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLCB1bmRlZmluZWQpO1xuICAgIGF3YWl0IHNlbmRFbWFpbChcbiAgICAgIHtcbiAgICAgICAgdG86IFt0b10sXG4gICAgICAgIHN1YmplY3Q6IG9wdHMuc3ViamVjdCxcbiAgICAgICAgYm9keTogW1xuICAgICAgICAgIG9wdHMubWVzc2FnZSxcbiAgICAgICAgICBcIlwiLFxuICAgICAgICAgIGAjIyAke2NvZGV9YCxcbiAgICAgICAgICBcIlwiLFxuICAgICAgICAgIFwiSXQgZXhwaXJlcyBzaG9ydGx5LiBJZiB5b3UgZGlkbid0IHJlcXVlc3QgdGhpcywgaWdub3JlIHRoaXMgZW1haWwuXCIsXG4gICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgIH0sXG4gICAgICBmcm9tLFxuICAgICk7XG4gIH07XG5cbiAgLy8gYGNyZWF0ZUFwcGAgbmFtZXNwYWNlcyBlYWNoIHBsdWdpbidzIGV4cG9ydHMgb24gdGhlIGhhbmRsZSBieSBtYW5pZmVzdCBuYW1lO1xuICAvLyBgaGFuZGxlLmF1dGhHYXRlYCBpcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSSB0aGUgcHJveHkgZHJpdmVzLlxuICBjb25zdCBoYW5kbGUgPSBhd2FpdCBjcmVhdGVBcHAoeyBwbHVnaW5zOiBbZW1haWwoKSwgYXV0aEdhdGUoeyAuLi5jb25maWcsIHNlbmRDb2RlIH0pXSB9KTtcblxuICAvLyBGYWlsIGZhc3Q6IHRoZSBnYXRlIG5lZWRzIFNNVFAgdG8gZW1haWwgY29kZXMuIGBnZXRFbWFpbFJ1bnRpbWUoKWAgcmVzb2x2ZXMgdG9cbiAgLy8gYG1vZGU6IFwiZmlsZVwiYCAob3V0Ym94KSBvciB0aHJvd3Mgd2hlbiBubyBTTVRQIGNyZWRzIGFyZSBjb25maWd1cmVkIC0gbmVpdGhlclxuICAvLyBjYW4gZGVsaXZlciB0byBhIHJlYWwgaW5ib3gsIHNvIHJlZnVzZSB0byBicmluZyB1cCBhIGdhdGUgdGhhdCBsZXRzIG5vYm9keSBpbi5cbiAgaWYgKGdldEVtYWlsUnVudGltZSgpLmNvbmZpZy5tb2RlICE9PSBcInNtdHBcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiZW1haWwgaXMgbm90IGNvbmZpZ3VyZWQgZm9yIFNNVFAgZGVsaXZlcnkgLSB0aGUgT1RQIGdhdGUgY2Fubm90IHNlbmQgY29kZXMuIFwiICtcbiAgICAgICAgXCJTZXQgU01UUF9IT1NUL1NNVFBfVVNFUi9TTVRQX1BBU1NXT1JELCBvciBwYXNzIC0taW5zZWN1cmUgLyBUVU5ORUxfSU5TRUNVUkU9dHJ1ZSB0byBydW4gdGhlIHR1bm5lbCBvcGVuLlwiLFxuICAgICk7XG4gIH1cblxuICBsb2dnZXIuaW5mbyhcImdhdGUgYXBwIHJlYWR5IChubyBzZXJ2ZXI7IHByb3h5LWRyaXZlbilcIik7XG4gIHJldHVybiBoYW5kbGUuYXV0aEdhdGUgYXMgQXV0aEdhdGVBcGk7XG59XG4iXX0=
|
|
114
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDN0QsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxJQUFJLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLFFBQVEsRUFBeUMsTUFBTSxhQUFhLENBQUM7QUFFOUUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUV4Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQWU7SUFDdkMsT0FBTyxPQUFPLElBQUksRUFBRSxJQUFJLE9BQU8sR0FBRyxFQUFFLEtBQUssQ0FBQztRQUN4QyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsRUFBRSxFQUFFLFFBQVEsQ0FBQztRQUMxQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQUVELE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxXQUFXLENBQUM7QUFDbEMsTUFBTSxFQUFFLG9CQUFvQixFQUFFLEdBQUcsTUFBTSxDQUFDO0FBQ3hDLE1BQU0sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLEdBQUcsU0FBUyxDQUFDO0FBQ2pELE1BQU0sRUFBRSxxQkFBcUIsRUFBRSxHQUFHLFVBQVUsQ0FBQztBQUM3QyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxTQUFTLENBQUM7QUFFdkM7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FBQyxNQUFzQjtJQUN2RCw4RUFBOEU7SUFDOUUsOEVBQThFO0lBQzlFLDZFQUE2RTtJQUM3RSw2RUFBNkU7SUFDN0UseUVBQXlFO0lBQ3pFLE1BQU0sT0FBTyxHQUFHLE1BQU0sZ0JBQWdCLEVBQUUsQ0FBQztJQUV6QyxpRkFBaUY7SUFDakYsMkVBQTJFO0lBQzNFLGlGQUFpRjtJQUNqRixrRkFBa0Y7SUFDbEYsa0ZBQWtGO0lBQ2xGLE1BQU0sUUFBUSxHQUE0QyxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUNqRixNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdkUsTUFBTSxTQUFTLENBQ2I7WUFDRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDUixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsdUVBQXVFO1lBQ3ZFLDBFQUEwRTtZQUMxRSxzRUFBc0U7WUFDdEUsMEVBQTBFO1lBQzFFLHNFQUFzRTtZQUN0RSx3RUFBd0U7WUFDeEUsZ0VBQWdFO1lBQ2hFLElBQUksRUFBRTtnQkFDSixJQUFJLENBQUMsT0FBTztnQkFDWixFQUFFO2dCQUNGLE1BQU0sSUFBSSxFQUFFO2dCQUNaLEVBQUU7Z0JBQ0Ysd0JBQXdCLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUc7Z0JBQ3pELEVBQUU7Z0JBQ0YsOERBQThEO2FBQy9ELENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNiLEVBQ0QsSUFBSSxDQUNMLENBQUM7SUFDSixDQUFDLENBQUM7SUFFRiwrRUFBK0U7SUFDL0UsaUVBQWlFO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLE1BQU0sU0FBUyxDQUFDO1FBQzdCLE9BQU8sRUFBRTtZQUNQLHdFQUF3RTtZQUN4RSw0RUFBNEU7WUFDNUUsMEVBQTBFO1lBQzFFLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2hELHdFQUF3RTtZQUN4RSw0RUFBNEU7WUFDNUUscUVBQXFFO1lBQ3JFLDJFQUEyRTtZQUMzRSxnRUFBZ0U7WUFDaEUsUUFBUSxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQztTQUMvRTtLQUNGLENBQUMsQ0FBQztJQUVILGlGQUFpRjtJQUNqRixnRkFBZ0Y7SUFDaEYsaUZBQWlGO0lBQ2pGLElBQUksZUFBZSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM3QyxNQUFNLElBQUksS0FBSyxDQUNiLDhFQUE4RTtZQUM1RSwwR0FBMEcsQ0FDN0csQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxNQUFNLENBQUMsUUFBdUIsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsIGdhdGUncyB0aW55IEFwcEtpdCBcImFwcFwiIC0gYGNyZWF0ZUFwcGAgV0lUSE9VVCBhIGBzZXJ2ZXIoKWAgcGx1Z2luLlxuICpcbiAqIFRoZXJlIGlzIG5vIEhUVFAgc2VydmVyIGhlcmU6IHRoZSB0dW5uZWwgcHJveHkgaXMgdGhlIHNlcnZlciwgYW5kIGl0IGNhbGxzIHRoZVxuICogZ2F0ZSBoYW5kbGVycyBpbi1wcm9jZXNzLiBgY3JlYXRlQXBwYCBpcyB1c2VkIG9ubHkgZm9yIHdoYXQgaXQgYXV0by13aXJlczpcbiAqICAgLSBgQ2FjaGVNYW5hZ2VyYCAobWVtb3J5LCBvciBMYWtlYmFzZSB3aGVuIHRoZSBkZXBsb3kgY29uZmlndXJlcyBwZXJzaXN0ZW50XG4gKiAgICAgY2FjaGUgc3RvcmFnZSkgLSB3aGljaCB0aGUgT1RQIGBDb2RlU3RvcmVgIHVzZXMgZm9yIHN0b3JhZ2UgKyBUVEwgZXZpY3Rpb247XG4gKiAgIC0gdGhlIGBlbWFpbCgpYCB0cmFuc3BvcnQgKFNNVFAgLyBvdXRib3gpLCBwcmltZWQgZnJvbSBlbnYsIHNvIGBzZW5kQ29kZWAgY2FuXG4gKiAgICAgZGVsaXZlciB0aGUgb25lLXRpbWUgY29kZTtcbiAqICAgLSBkYngtdG9vbHMgYXV0by1jb25maWd1cmF0aW9uICsgYnJhbmRpbmcgdmlhIGBAZGJ4LXRvb2xzL2FwcGtpdGAuXG4gKlxuICogSXQgcmV0dXJucyB0aGUge0BsaW5rIEF1dGhHYXRlQXBpfSB0aGUgcHJveHkgZHJpdmVzLiBgc2VuZENvZGVgIGlzIHdpcmVkIGhlcmVcbiAqICh0aGUgcGx1Z2luIGNhbid0IHJlc29sdmUgSE9XIHRvIHNlbmQgb24gaXRzIG93bikgdG8gdGhlIGVtYWlsIHBsdWdpbidzXG4gKiB0cmFuc3BvcnQsIHJlc29sdmluZyB0aGUgYEZyb21gIGZyb20gdGhlIGVtYWlsIHJ1bnRpbWUgY29uZmlnIChFTUFJTF9GUk9NIC9cbiAqIEVNQUlMX0RPTUFJTikgc2luY2UgYW4gT1RQIHJlcXVlc3QgaGFzIG5vIG9uLWJlaGFsZi1vZiB1c2VyLlxuICpcbiAqIEZBSUwgRkFTVDogYSBnYXRlIHRoYXQgY2FuJ3QgZW1haWwgYSBjb2RlIGlzIHVzZWxlc3MsIHNvIGlmIGVtYWlsIGRvZXMgbm90XG4gKiByZXNvbHZlIHRvIFNNVFAgbW9kZSAocmVhbCBkZWxpdmVyeSksIHRoaXMgdGhyb3dzIC0gdW5sZXNzIGBpbnNlY3VyZWAgaXMgc2V0XG4gKiAoYC0taW5zZWN1cmVgIC8gYFRVTk5FTF9JTlNFQ1VSRT10cnVlYCksIGluIHdoaWNoIGNhc2UgdGhlIGNhbGxlciBydW5zIHRoZVxuICogdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVBcHAgYXMgY3JlYXRlQXBwTnMgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGJyYW5kIGFzIG5vZGVCcmFuZCB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGJyYW5kIGFzIGVtYWlsQnJhbmQsIGVtYWlsLCBzZW5kZXIsIHRyYW5zcG9ydCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG5pbXBvcnQgeyBsb2csIHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBhdXRoR2F0ZSwgdHlwZSBBdXRoR2F0ZUFwaSwgdHlwZSBBdXRoR2F0ZUNvbmZpZyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsOmFwcFwiKTtcblxuLyoqXG4gKiBBIGNvZGUgVFRMIGFzIHRoZSBwbGFpbiBwaHJhc2UgdGhlIGVtYWlsIHN0YXRlcyAoXCIxMCBtaW51dGVzXCIsIFwiNDUgc2Vjb25kc1wiKS5cbiAqXG4gKiBXaG9sZSBtaW51dGVzIHJlYWQgYXMgbWludXRlczsgYW55dGhpbmcgZWxzZSBzdGF5cyBpbiBzZWNvbmRzIHJhdGhlciB0aGFuXG4gKiByb3VuZGluZywgc28gYSA5MC1zZWNvbmQgVFRMIGlzIG5vdCBhZHZlcnRpc2VkIGFzIFwiMSBtaW51dGVcIiBhbmQgYSByZWNpcGllbnQgaXNcbiAqIG5ldmVyIHRvbGQgdGhlIGNvZGUgbGl2ZXMgbG9uZ2VyIHRoYW4gaXQgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cGlyZXNJbihzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gc2Vjb25kcyA+PSA2MCAmJiBzZWNvbmRzICUgNjAgPT09IDBcbiAgICA/IHN0cmluZy5wbHVyYWxpemUoc2Vjb25kcyAvIDYwLCBcIm1pbnV0ZVwiKVxuICAgIDogc3RyaW5nLnBsdXJhbGl6ZShzZWNvbmRzLCBcInNlY29uZFwiKTtcbn1cblxuY29uc3QgeyBjcmVhdGVBcHAgfSA9IGNyZWF0ZUFwcE5zO1xuY29uc3QgeyByZXNvbHZlU2VuZGVyQWRkcmVzcyB9ID0gc2VuZGVyO1xuY29uc3QgeyBnZXRFbWFpbFJ1bnRpbWUsIHNlbmRFbWFpbCB9ID0gdHJhbnNwb3J0O1xuY29uc3QgeyBlbWFpbEJyYW5kRnJvbUNvbnRleHQgfSA9IGVtYWlsQnJhbmQ7XG5jb25zdCB7IGxvYWRCcmFuZENvbnRleHQgfSA9IG5vZGVCcmFuZDtcblxuLyoqXG4gKiBCb290IHRoZSBnYXRlIGFwcCBhbmQgcmV0dXJuIHRoZSBBUEkgdGhlIHByb3h5IGNhbGxzLiBUaHJvd3Mgd2hlbiBlbWFpbCBpcyBub3RcbiAqIGluIFNNVFAgbW9kZSAobm8gd2F5IHRvIGRlbGl2ZXIgYSBjb2RlKSBzbyBhIG1pc2NvbmZpZ3VyZWQgZ2F0ZSBmYWlscyBmYXN0IGF0XG4gKiBzdGFydHVwIHJhdGhlciB0aGFuIHNpbGVudGx5IGFjY2VwdGluZyBub2JvZHk7IHRoZSBjYWxsZXIgbWF5IGNhdGNoIHRoaXMgYW5kXG4gKiBmYWxsIGJhY2sgdG8gaW5zZWN1cmUvb3BlbiBtb2RlIHdoZW4gdGhlIG9wZXJhdG9yIG9wdGVkIGluLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRHYXRlQXBwKGNvbmZpZzogQXV0aEdhdGVDb25maWcpOiBQcm9taXNlPEF1dGhHYXRlQXBpPiB7XG4gIC8vIFRoZSBob3N0IGFwcCdzIG93biBicmFuZCAoYGJyYW5kaW5nL2JyYW5kLnlhbWxgIGRpc2NvdmVyZWQgZnJvbSBjd2QpIG9yIHRoZVxuICAvLyBkYngtdG9vbHMgZGVmYXVsdC4gVGhpcyBpcyB0aGUgT05FIGJyYW5kIHNvdXJjZSBmb3IgdGhlIGdhdGU6IGl0IHN0eWxlcyB0aGVcbiAgLy8gY29kZSBlbWFpbCAoYWNjZW50IGJhbmQsIGZvbnQsIGxvZ28pIHZpYSB0aGUgZW1haWwgcGx1Z2luIEFORCBzdXBwbGllcyB0aGVcbiAgLy8gZGlzcGxheSBuYW1lIHRoZSBjb3B5IHVzZXMsIHNvIGEgZGVwbG95bWVudCB0aGF0IHRoZW1lcyBpdHMgYXBwIHRoZW1lcyBpdHNcbiAgLy8gc2lnbi1pbiBlbWFpbCB3aXRoIGl0LiBBbiBleHBsaWNpdCBgYnJhbmROYW1lYCBzdGlsbCB3aW5zIChzZWUgYmVsb3cpLlxuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgbG9hZEJyYW5kQ29udGV4dCgpO1xuXG4gIC8vIGBzZW5kQ29kZWAgZGVsaXZlcnMgdGhlIE9UUCB0aHJvdWdoIHRoZSBlbWFpbCBwbHVnaW4ncyBTSEFSRUQgdHJhbnNwb3J0LCB3aGljaFxuICAvLyB0aGUgYGVtYWlsKClgIHBsdWdpbiBwcmltZXMgZHVyaW5nIGl0cyBgc2V0dXAoKWAgKGF3YWl0ZWQgYnkgYGNyZWF0ZUFwcGBcbiAgLy8gYmVsb3cpLiBVc2luZyB0aGUgbW9kdWxlLWxldmVsIGBzZW5kRW1haWxgIGF2b2lkcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgb24gdGhlXG4gIC8vIGFwcCBoYW5kbGUncyBpbmZlcnJlZCB0eXBlLiBgRnJvbWAgaXMgdGhlIGFwcCdzIGNvbmZpZ3VyZWQgc2VuZGVyIChFTUFJTF9GUk9NIC9cbiAgLy8gRU1BSUxfRE9NQUlOKTsgdGhlIGNvZGUgZW1haWwgaGFzIG5vIE9CTyB1c2VyLCBzbyBpdCByZXNvbHZlcyB3aXRoIGB1bmRlZmluZWRgLlxuICBjb25zdCBzZW5kQ29kZTogTm9uTnVsbGFibGU8QXV0aEdhdGVDb25maWdbXCJzZW5kQ29kZVwiXT4gPSBhc3luYyAodG8sIGNvZGUsIG9wdHMpID0+IHtcbiAgICBjb25zdCBmcm9tID0gcmVzb2x2ZVNlbmRlckFkZHJlc3MoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLCB1bmRlZmluZWQpO1xuICAgIGF3YWl0IHNlbmRFbWFpbChcbiAgICAgIHtcbiAgICAgICAgdG86IFt0b10sXG4gICAgICAgIHN1YmplY3Q6IG9wdHMuc3ViamVjdCxcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IHRoZSBjb252ZW50aW9uYWwgb25lLXRpbWUtY29kZSBsYXlvdXQ6IHRoZSBwcm9tcHQgbGluZSxcbiAgICAgICAgLy8gdGhlbiB0aGUgYmFyZSBjb2RlIEFMT05FIG9uIHRoZSBuZXh0IGxpbmUsIHRoZW4gdGhlIGV4cGlyeS4gaU9TLCBHbWFpbCxcbiAgICAgICAgLy8gT3V0bG9vaywgYW5kIEFuZHJvaWQgYWxsIGRldGVjdCBhIGNvZGUgZnJvbSB0aGlzIHNoYXBlIGFuZCBvZmZlciB0b1xuICAgICAgICAvLyBhdXRvZmlsbCBpdCwgYW5kIGFueXRoaW5nIG1vcmUgZGVjb3JhdGl2ZSBpcyB3aGF0IGJyZWFrcyB0aGF0LiBUaGUgY29kZVxuICAgICAgICAvLyBzdGF5cyB2aXNpYmxlIFRFWFQgaW4gYm90aCBNSU1FIHBhcnRzICh0aGUgZW1haWwgcGx1Z2luIHJlbmRlcnMgdGhlXG4gICAgICAgIC8vIEhUTUwgYW5kIHBsYWluLXRleHQgYWx0ZXJuYXRpdmVzIGZyb20gb25lIFJlYWN0IEVtYWlsIHRyZWUpLCBuZXZlciBhblxuICAgICAgICAvLyBpbWFnZSwgc28gYSBjbGllbnQgdGhhdCBzY3JhcGVzIHRoZSB0ZXh0IHBhcnQgc3RpbGwgZmluZHMgaXQuXG4gICAgICAgIGJvZHk6IFtcbiAgICAgICAgICBvcHRzLm1lc3NhZ2UsXG4gICAgICAgICAgXCJcIixcbiAgICAgICAgICBgIyMgJHtjb2RlfWAsXG4gICAgICAgICAgXCJcIixcbiAgICAgICAgICBgVGhpcyBjb2RlIGV4cGlyZXMgaW4gJHtleHBpcmVzSW4ob3B0cy5jb2RlVHRsU2Vjb25kcyl9LmAsXG4gICAgICAgICAgXCJcIixcbiAgICAgICAgICBcIklmIHlvdSBkaWQgbm90IHJlcXVlc3QgdGhpcyBjb2RlLCB5b3UgY2FuIGlnbm9yZSB0aGlzIGVtYWlsLlwiLFxuICAgICAgICBdLmpvaW4oXCJcXG5cIiksXG4gICAgICB9LFxuICAgICAgZnJvbSxcbiAgICApO1xuICB9O1xuXG4gIC8vIGBjcmVhdGVBcHBgIG5hbWVzcGFjZXMgZWFjaCBwbHVnaW4ncyBleHBvcnRzIG9uIHRoZSBoYW5kbGUgYnkgbWFuaWZlc3QgbmFtZTtcbiAgLy8gYGhhbmRsZS5hdXRoR2F0ZWAgaXMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBBUEkgdGhlIHByb3h5IGRyaXZlcy5cbiAgY29uc3QgaGFuZGxlID0gYXdhaXQgY3JlYXRlQXBwKHtcbiAgICBwbHVnaW5zOiBbXG4gICAgICAvLyBCcmFuZCB0aGUgY29kZSBlbWFpbCBmcm9tIHRoZSByZXNvbHZlZCBjb250ZXh0LCB0aGUgc2FtZSBicmlkZ2UgZXZlcnlcbiAgICAgIC8vIG90aGVyIGRieC10b29scyBlbWFpbCBzdXJmYWNlIHVzZXMgKGFjY2VudCArIGZvbnQgaW5saW5lZCwgbG9nbyBvbmx5IHdoZW5cbiAgICAgIC8vIGl0IGlzIGEgZmV0Y2hhYmxlIFVSTCAtIGEgcGFja2FnZS1leHBvcnQgcGF0aCBjYW5ub3QgbG9hZCBpbiBhbiBpbmJveCkuXG4gICAgICBlbWFpbCh7IGJyYW5kOiBlbWFpbEJyYW5kRnJvbUNvbnRleHQoY29udGV4dCkgfSksXG4gICAgICAvLyBgYnJhbmROYW1lYCBmYWxscyBiYWNrIHRvIHRoZSByZXNvbHZlZCBjb250ZXh0J3MgZGlzcGxheSBuYW1lLCBzbyB0aGVcbiAgICAgIC8vIGVtYWlsIGNvcHkgbmFtZXMgdGhlIGFwcCByYXRoZXIgdGhhbiBhIGdlbmVyaWMgcGxhY2Vob2xkZXIuIFNwZWxsZWQgYXMgYW5cbiAgICAgIC8vIGV4cGxpY2l0IGA/P2AgcmF0aGVyIHRoYW4gYSBrZXkgYmVmb3JlIGAuLi5jb25maWdgOiBjb21tYW5kZXIgc2V0c1xuICAgICAgLy8gYGJyYW5kTmFtZWAgb24gdGhlIG9wdGlvbnMgb2JqZWN0IHdoZXRoZXIgb3Igbm90IHRoZSBmbGFnIHdhcyBwYXNzZWQsIHNvXG4gICAgICAvLyBzcHJlYWRpbmcgaXQgd291bGQgY2xvYmJlciB0aGUgY29udGV4dCBuYW1lIHdpdGggYHVuZGVmaW5lZGAuXG4gICAgICBhdXRoR2F0ZSh7IC4uLmNvbmZpZywgYnJhbmROYW1lOiBjb25maWcuYnJhbmROYW1lID8/IGNvbnRleHQubmFtZSwgc2VuZENvZGUgfSksXG4gICAgXSxcbiAgfSk7XG5cbiAgLy8gRmFpbCBmYXN0OiB0aGUgZ2F0ZSBuZWVkcyBTTVRQIHRvIGVtYWlsIGNvZGVzLiBgZ2V0RW1haWxSdW50aW1lKClgIHJlc29sdmVzIHRvXG4gIC8vIGBtb2RlOiBcImZpbGVcImAgKG91dGJveCkgb3IgdGhyb3dzIHdoZW4gbm8gU01UUCBjcmVkcyBhcmUgY29uZmlndXJlZCAtIG5laXRoZXJcbiAgLy8gY2FuIGRlbGl2ZXIgdG8gYSByZWFsIGluYm94LCBzbyByZWZ1c2UgdG8gYnJpbmcgdXAgYSBnYXRlIHRoYXQgbGV0cyBub2JvZHkgaW4uXG4gIGlmIChnZXRFbWFpbFJ1bnRpbWUoKS5jb25maWcubW9kZSAhPT0gXCJzbXRwXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcImVtYWlsIGlzIG5vdCBjb25maWd1cmVkIGZvciBTTVRQIGRlbGl2ZXJ5IC0gdGhlIE9UUCBnYXRlIGNhbm5vdCBzZW5kIGNvZGVzLiBcIiArXG4gICAgICAgIFwiU2V0IFNNVFBfSE9TVC9TTVRQX1VTRVIvU01UUF9QQVNTV09SRCwgb3IgcGFzcyAtLWluc2VjdXJlIC8gVFVOTkVMX0lOU0VDVVJFPXRydWUgdG8gcnVuIHRoZSB0dW5uZWwgb3Blbi5cIixcbiAgICApO1xuICB9XG5cbiAgbG9nZ2VyLmluZm8oXCJnYXRlIGFwcCByZWFkeSAobm8gc2VydmVyOyBwcm94eS1kcml2ZW4pXCIpO1xuICByZXR1cm4gaGFuZGxlLmF1dGhHYXRlIGFzIEF1dGhHYXRlQXBpO1xufVxuIl19
|
package/lib/src/cli.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `dbx-tools-tunnel` / `dbxt-tunnel` CLI.
|
|
3
3
|
*
|
|
4
|
-
* Wraps
|
|
5
|
-
*
|
|
4
|
+
* Wraps an app's start command with a public portr tunnel and an email-OTP
|
|
5
|
+
* access gate. Everything after `--` is the REAL app start command:
|
|
6
6
|
*
|
|
7
|
-
* dbxt-tunnel --subject "Here's your OTP" --allow
|
|
7
|
+
* dbxt-tunnel --subject "Here's your OTP" --allow example.com -- bun src/server.ts
|
|
8
8
|
*
|
|
9
9
|
* Boot sequence:
|
|
10
10
|
* 1. Pick a random PRIVATE port and spawn the app command with
|
|
11
|
-
* `DATABRICKS_APP_PORT` set to it (so the app binds loopback-private).
|
|
11
|
+
* `DATABRICKS_APP_PORT` set to it (so the app binds loopback-private). That
|
|
12
|
+
* variable name is the Databricks Apps runtime contract; the gate itself is
|
|
13
|
+
* platform-neutral and honours whatever port it finds there.
|
|
12
14
|
* 2. Boot the tiny gate AppKit app (no server): inits `CacheManager` + the
|
|
13
15
|
* email transport, yields the in-process gate API.
|
|
14
16
|
* 3. Start the gate PROXY on the ORIGINAL public port, forwarding to the app.
|
package/lib/src/cli.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `dbx-tools-tunnel` / `dbxt-tunnel` CLI.
|
|
3
3
|
*
|
|
4
|
-
* Wraps
|
|
5
|
-
*
|
|
4
|
+
* Wraps an app's start command with a public portr tunnel and an email-OTP
|
|
5
|
+
* access gate. Everything after `--` is the REAL app start command:
|
|
6
6
|
*
|
|
7
|
-
* dbxt-tunnel --subject "Here's your OTP" --allow
|
|
7
|
+
* dbxt-tunnel --subject "Here's your OTP" --allow example.com -- bun src/server.ts
|
|
8
8
|
*
|
|
9
9
|
* Boot sequence:
|
|
10
10
|
* 1. Pick a random PRIVATE port and spawn the app command with
|
|
11
|
-
* `DATABRICKS_APP_PORT` set to it (so the app binds loopback-private).
|
|
11
|
+
* `DATABRICKS_APP_PORT` set to it (so the app binds loopback-private). That
|
|
12
|
+
* variable name is the Databricks Apps runtime contract; the gate itself is
|
|
13
|
+
* platform-neutral and honours whatever port it finds there.
|
|
12
14
|
* 2. Boot the tiny gate AppKit app (no server): inits `CacheManager` + the
|
|
13
15
|
* email transport, yields the in-process gate API.
|
|
14
16
|
* 3. Start the gate PROXY on the ORIGINAL public port, forwarding to the app.
|
|
@@ -38,12 +40,12 @@ function randomPort() {
|
|
|
38
40
|
function program() {
|
|
39
41
|
return new Command()
|
|
40
42
|
.name("dbx-tools-tunnel")
|
|
41
|
-
.description("Front
|
|
43
|
+
.description("Front an app with a public portr tunnel + email-OTP gate")
|
|
42
44
|
.option("--subject <text>", "Subject line for the code email (env AUTH_SUBJECT)")
|
|
43
45
|
.option("--allow <patterns>", "Comma/space-separated allow-list: domain / glob / /regex/ (env EMAIL_AUTH_ALLOW)")
|
|
44
46
|
.option("--subdomain <name>", "portr subdomain (else derived from PUBLIC_DOMAIN)")
|
|
45
47
|
.option("--public-domain <host>", "portr <subdomain>.<server> (env PUBLIC_DOMAIN)")
|
|
46
|
-
.option("--brand-name <name>", "
|
|
48
|
+
.option("--brand-name <name>", "Display name in the code email copy (env AUTH_BRAND_NAME; defaults to the brand context name)")
|
|
47
49
|
.option("--message <text>", "Line shown above the code in the email (env AUTH_MESSAGE)")
|
|
48
50
|
.option("--session-ttl <seconds>", "Session lifetime (env AUTH_SESSION_TTL)")
|
|
49
51
|
.option("--code-ttl <seconds>", "One-time-code lifetime (env AUTH_CODE_TTL)")
|
|
@@ -144,4 +146,4 @@ export async function runCli(argv) {
|
|
|
144
146
|
// Any child exit (or a signal) tears the whole thing down.
|
|
145
147
|
superviseExit(children);
|
|
146
148
|
}
|
|
147
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFFSCxPQUFPLEVBQXFCLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFeEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDO0FBRTFCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFcEMscUZBQXFGO0FBQ3JGLFNBQVMsVUFBVTtJQUNqQixPQUFPLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBY0Qsb0ZBQW9GO0FBQ3BGLFNBQVMsT0FBTztJQUNkLE9BQU8sSUFBSSxPQUFPLEVBQUU7U0FDakIsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1NBQ3hCLFdBQVcsQ0FBQyxvRUFBb0UsQ0FBQztTQUNqRixNQUFNLENBQUMsa0JBQWtCLEVBQUUsb0RBQW9ELENBQUM7U0FDaEYsTUFBTSxDQUNMLG9CQUFvQixFQUNwQixrRkFBa0YsQ0FDbkY7U0FDQSxNQUFNLENBQUMsb0JBQW9CLEVBQUUsbURBQW1ELENBQUM7U0FDakYsTUFBTSxDQUFDLHdCQUF3QixFQUFFLGdEQUFnRCxD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bnQiOlsiLyoqXG4gKiBgZGJ4LXRvb2xzLXR1bm5lbGAgLyBgZGJ4dC10dW5uZWxgIENMSS5cbiAqXG4gKiBXcmFwcyBhIERhdGFicmlja3MgQXBwIHN0YXJ0IGNvbW1hbmQgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgYW5kIGFuXG4gKiBlbWFpbC1PVFAgYWNjZXNzIGdhdGUuIEV2ZXJ5dGhpbmcgYWZ0ZXIgYC0tYCBpcyB0aGUgUkVBTCBhcHAgc3RhcnQgY29tbWFuZDpcbiAqXG4gKiAgIGRieHQtdHVubmVsIC0tc3ViamVjdCBcIkhlcmUncyB5b3VyIE9UUFwiIC0tYWxsb3cgZGF0YWJyaWNrcy5jb20gLS0gYnVuIHNyYy9zZXJ2ZXIudHNcbiAqXG4gKiBCb290IHNlcXVlbmNlOlxuICogICAxLiBQaWNrIGEgcmFuZG9tIFBSSVZBVEUgcG9ydCBhbmQgc3Bhd24gdGhlIGFwcCBjb21tYW5kIHdpdGhcbiAqICAgICAgYERBVEFCUklDS1NfQVBQX1BPUlRgIHNldCB0byBpdCAoc28gdGhlIGFwcCBiaW5kcyBsb29wYmFjay1wcml2YXRlKS5cbiAqICAgMi4gQm9vdCB0aGUgdGlueSBnYXRlIEFwcEtpdCBhcHAgKG5vIHNlcnZlcik6IGluaXRzIGBDYWNoZU1hbmFnZXJgICsgdGhlXG4gKiAgICAgIGVtYWlsIHRyYW5zcG9ydCwgeWllbGRzIHRoZSBpbi1wcm9jZXNzIGdhdGUgQVBJLlxuICogICAzLiBTdGFydCB0aGUgZ2F0ZSBQUk9YWSBvbiB0aGUgT1JJR0lOQUwgcHVibGljIHBvcnQsIGZvcndhcmRpbmcgdG8gdGhlIGFwcC5cbiAqICAgNC4gSW5zdGFsbCArIHJ1biBwb3J0ciBwb2ludGVkIGF0IHRoZSBwdWJsaWMgcG9ydCAod2hlbiBhIHR1bm5lbCBpc1xuICogICAgICBjb25maWd1cmVkOyBvdGhlcndpc2UgdGhlIHByb3h5IHN0aWxsIGdhdGVzIG5vdGhpbmcgYW5kIGZvcndhcmRzKS5cbiAqXG4gKiBTdXBlcnZpc2lvbjogdGhlIGFwcCBjaGlsZCwgcG9ydHIgY2hpbGQsIGFuZCB0aGlzIHByb2Nlc3MgYXJlIHRpZWQgdG9nZXRoZXIgLVxuICogaWYgQU5ZIGV4aXRzLCBldmVyeXRoaW5nIGNvbWVzIGRvd24gKGNvbmN1cnJlbnRseS1zdHlsZSBga2lsbE90aGVyc2ApLlxuICpcbiAqIE9wdGlvbnMgY29tZSBmcm9tIGZsYWdzIE9SIGVudjsgc2VlIHRoZSBvcHRpb24gZGVmaW5pdGlvbnMgYmVsb3cuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHR5cGUgQ2hpbGRQcm9jZXNzLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBDb21tYW5kLCBDb21tYW5kZXJFcnJvciB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCB7IHN0YXJ0R2F0ZUFwcCB9IGZyb20gXCIuL2FwcC50c1wiO1xuaW1wb3J0IHR5cGUgeyBBdXRoR2F0ZUNvbmZpZyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuaW1wb3J0IHsgaW5zdGFsbFBvcnRyLCByZXNvbHZlUG9ydHJDb25maWcsIHN0YXJ0UG9ydHIsIHdyaXRlUG9ydHJDb25maWcgfSBmcm9tIFwiLi9wb3J0ci50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBBIHJhbmRvbSBlcGhlbWVyYWwgcG9ydCBmb3IgdGhlIGFwcCB0byBiaW5kICh0aGUgcHJveHkgZnJvbnRzIHRoZSBwdWJsaWMgb25lKS4gKi9cbmZ1bmN0aW9uIHJhbmRvbVBvcnQoKTogbnVtYmVyIHtcbiAgcmV0dXJuIDIwMDAwICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjAwMDApO1xufVxuXG5pbnRlcmZhY2UgVHVubmVsT3B0cyB7XG4gIHN1YmplY3Q/OiBzdHJpbmc7XG4gIGFsbG93Pzogc3RyaW5nO1xuICBzdWJkb21haW4/OiBzdHJpbmc7XG4gIHB1YmxpY0RvbWFpbj86IHN0cmluZztcbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBzZXNzaW9uVHRsPzogc3RyaW5nO1xuICBjb2RlVHRsPzogc3RyaW5nO1xuICBpbnNlY3VyZT86IGJvb2xlYW47XG59XG5cbi8qKiBCdWlsZCB0aGUgY29tbWFuZGVyIHByb2dyYW0uIGAtLWAgc2VwYXJhdGVzIGZsYWdzIGZyb20gdGhlIGFwcCBzdGFydCBjb21tYW5kLiAqL1xuZnVuY3Rpb24gcHJvZ3JhbSgpOiBDb21tYW5kIHtcbiAgcmV0dXJuIG5ldyBDb21tYW5kKClcbiAgICAubmFtZShcImRieC10b29scy10dW5uZWxcIilcbiAgICAuZGVzY3JpcHRpb24oXCJGcm9udCBhIERhdGFicmlja3MgQXBwIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsICsgZW1haWwtT1RQIGdhdGVcIilcbiAgICAub3B0aW9uKFwiLS1zdWJqZWN0IDx0ZXh0PlwiLCBcIlN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwgKGVudiBBVVRIX1NVQkpFQ1QpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1hbGxvdyA8cGF0dGVybnM+XCIsXG4gICAgICBcIkNvbW1hL3NwYWNlLXNlcGFyYXRlZCBhbGxvdy1saXN0OiBkb21haW4gLyBnbG9iIC8gL3JlZ2V4LyAoZW52IEVNQUlMX0FVVEhfQUxMT1cpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXCItLXN1YmRvbWFpbiA8bmFtZT5cIiwgXCJwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcIi0tcHVibGljLWRvbWFpbiA8aG9zdD5cIiwgXCJwb3J0ciA8c3ViZG9tYWluPi48c2VydmVyPiAoZW52IFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcIi0tYnJhbmQtbmFtZSA8bmFtZT5cIiwgXCJQcm9kdWN0IG5hbWUgaW4gdGhlIGVtYWlsICsgbG9naW4gY29weSAoZW52IEFVVEhfQlJBTkRfTkFNRSlcIilcbiAgICAub3B0aW9uKFwiLS1tZXNzYWdlIDx0ZXh0PlwiLCBcIkxpbmUgc2hvd24gYWJvdmUgdGhlIGNvZGUgaW4gdGhlIGVtYWlsIChlbnYgQVVUSF9NRVNTQUdFKVwiKVxuICAgIC5vcHRpb24oXCItLXNlc3Npb24tdHRsIDxzZWNvbmRzPlwiLCBcIlNlc3Npb24gbGlmZXRpbWUgKGVudiBBVVRIX1NFU1NJT05fVFRMKVwiKVxuICAgIC5vcHRpb24oXCItLWNvZGUtdHRsIDxzZWNvbmRzPlwiLCBcIk9uZS10aW1lLWNvZGUgbGlmZXRpbWUgKGVudiBBVVRIX0NPREVfVFRMKVwiKVxuICAgIC5vcHRpb24oXG4gICAgICBcIi0taW5zZWN1cmVcIixcbiAgICAgIFwiUnVuIHRoZSB0dW5uZWwgT1BFTiB3aXRoIG5vIGdhdGUgKGVudiBUVU5ORUxfSU5TRUNVUkU9dHJ1ZSkuIE90aGVyd2lzZSB0aGUgQ0xJIGZhaWxzIGZhc3Qgd2hlbiBlbWFpbCBTTVRQIGlzIG5vdCBjb25maWd1cmVkLlwiLFxuICAgIClcbiAgICAuYWxsb3dFeGNlc3NBcmd1bWVudHModHJ1ZSlcbiAgICAuaGVscE9wdGlvbihcIi1oLCAtLWhlbHBcIiwgXCJTaG93IGhlbHBcIik7XG59XG5cbi8qKiBUaWUgYSBjaGlsZCdzIGV4aXQgdG8gZnVsbCB0ZWFyZG93bjogYW55IGV4aXQgYnJpbmdzIHRoZSB3aG9sZSB0dW5uZWwgZG93bi4gKi9cbmZ1bmN0aW9uIHN1cGVydmlzZUV4aXQoY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdKTogdm9pZCB7XG4gIGxldCBzaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgY29uc3Qgc2h1dGRvd24gPSAoY29kZTogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgaWYgKHNodXR0aW5nRG93bikgcmV0dXJuO1xuICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIH1cbiAgICAvLyBHaXZlIGNoaWxkcmVuIGEgbW9tZW50LCB0aGVuIGV4aXQgd2l0aCB0aGUgZmlyc3Qgbm9uLXplcm8gY29kZSBzZWVuLlxuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCAzMDAwKS51bnJlZigpO1xuICB9O1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihgY2hpbGQgZXhpdGVkICgke2NvZGUgPz8gXCJzaWduYWxcIn0pOyBicmluZ2luZyB0dW5uZWwgZG93bmApO1xuICAgICAgc2h1dGRvd24oY29kZSA/PyAxKTtcbiAgICB9KTtcbiAgfVxuICBmb3IgKGNvbnN0IHNpZyBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWcsICgpID0+IHNodXRkb3duKDApKTtcbiAgfVxufVxuXG4vKiogUGFyc2UgYXJndiBhbmQgcnVuIHRoZSB0dW5uZWwuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ2xpKGFyZ3Y6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIFNwbGl0IGZsYWdzIGZyb20gdGhlIHdyYXBwZWQgY29tbWFuZCBhdCB0aGUgZmlyc3QgYC0tYC5cbiAgY29uc3Qgc2VwID0gYXJndi5pbmRleE9mKFwiLS1cIik7XG4gIGNvbnN0IGZsYWdzID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKDAsIHNlcCkgOiBhcmd2O1xuICBjb25zdCBjb21tYW5kID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKHNlcCArIDEpIDogW107XG5cbiAgY29uc3QgcHJvZyA9IHByb2dyYW0oKTtcbiAgcHJvZy5wYXJzZShmbGFncyk7XG4gIGNvbnN0IG9wdHMgPSBwcm9nLm9wdHM8VHVubmVsT3B0cz4oKTtcblxuICBpZiAoY29tbWFuZC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgQ29tbWFuZGVyRXJyb3IoMSwgXCJ0dW5uZWwubm8tY29tbWFuZFwiLCBcIm5vIHN0YXJ0IGNvbW1hbmQgZ2l2ZW4gYWZ0ZXIgYC0tYFwiKTtcbiAgfVxuXG4gIGNvbnN0IHB1YmxpY1BvcnQgPSBOdW1iZXIocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19BUFBfUE9SVCA/PyA4MDAwKTtcbiAgY29uc3QgYXBwUG9ydCA9IHJhbmRvbVBvcnQoKTtcblxuICBjb25zdCBnYXRlQ29uZmlnOiBBdXRoR2F0ZUNvbmZpZyA9IHtcbiAgICBhbGxvdzogb3B0cy5hbGxvdyxcbiAgICBzdWJqZWN0OiBvcHRzLnN1YmplY3QsXG4gICAgYnJhbmROYW1lOiBvcHRzLmJyYW5kTmFtZSxcbiAgICBtZXNzYWdlOiBvcHRzLm1lc3NhZ2UsXG4gICAgc2Vzc2lvblR0bFNlY29uZHM6IG9wdHMuc2Vzc2lvblR0bCA/IE51bWJlcihvcHRzLnNlc3Npb25UdGwpIDogdW5kZWZpbmVkLFxuICAgIGNvZGVUdGxTZWNvbmRzOiBvcHRzLmNvZGVUdGwgPyBOdW1iZXIob3B0cy5jb2RlVHRsKSA6IHVuZGVmaW5lZCxcbiAgfTtcblxuICAvLyAxLiBTcGF3biB0aGUgd3JhcHBlZCBhcHAgd2l0aCB0aGUgUFJJVkFURSBwb3J0LiBJdCBiaW5kcyBsb29wYmFjazsgb25seSB0aGVcbiAgLy8gICAgcHJveHkgcmVhY2hlcyBpdC5cbiAgbG9nZ2VyLmluZm8oYHNwYXduaW5nIGFwcCBvbiBwcml2YXRlIHBvcnQgJHthcHBQb3J0fTogJHtjb21tYW5kLmpvaW4oXCIgXCIpfWApO1xuICBjb25zdCBbY21kLCAuLi5hcmdzXSA9IGNvbW1hbmQ7XG4gIGNvbnN0IGFwcCA9IHNwYXduKGNtZCEsIGFyZ3MsIHtcbiAgICBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIERBVEFCUklDS1NfQVBQX1BPUlQ6IFN0cmluZyhhcHBQb3J0KSwgSE9TVDogXCIxMjcuMC4wLjFcIiB9LFxuICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgfSk7XG5cbiAgLy8gMi4gQm9vdCB0aGUgZ2F0ZSBhcHAgKGNhY2hlICsgZW1haWwgdHJhbnNwb3J0ICsgZ2F0ZSBBUEkpLiBgc3RhcnRHYXRlQXBwYFxuICAvLyAgICBGQUlMUyBGQVNUIHdoZW4gZW1haWwgY2FuJ3Qgc2VuZCBjb2RlcyAobm8gU01UUCkuIEluc2VjdXJlIG1vZGVcbiAgLy8gICAgKGAtLWluc2VjdXJlYCAvIFRVTk5FTF9JTlNFQ1VSRSkgc2tpcHMgdGhlIGdhdGUgYW5kIHJ1bnMgdGhlIHR1bm5lbCBvcGVuLlxuICBjb25zdCBpbnNlY3VyZSA9IG9wdHMuaW5zZWN1cmUgfHwgL14oMXx0cnVlfHllc3xvbikkL2kudGVzdChwcm9jZXNzLmVudi5UVU5ORUxfSU5TRUNVUkUgPz8gXCJcIik7XG4gIGxldCBnYXRlOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHN0YXJ0R2F0ZUFwcD4+IHwgdW5kZWZpbmVkO1xuICBpZiAoaW5zZWN1cmUpIHtcbiAgICBsb2dnZXIud2FybihcImluc2VjdXJlIG1vZGUgLSB0dW5uZWwgcnVucyBPUEVOIHdpdGggbm8gZW1haWwtT1RQIGdhdGVcIik7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIGdhdGUgPSBhd2FpdCBzdGFydEdhdGVBcHAoZ2F0ZUNvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhaWwgZmFzdDogZG9uJ3Qgc2lsZW50bHkgZXhwb3NlIGFuIHVuZ2F0ZWQgdHVubmVsLiBUaGUgb3BlcmF0b3IgbXVzdCBmaXhcbiAgICAgIC8vIFNNVFAgb3IgZXhwbGljaXRseSBvcHQgaW50byBgLS1pbnNlY3VyZWAuXG4gICAgICBsb2dnZXIuZXJyb3IoXCJjYW5ub3Qgc3RhcnQgdGhlIE9UUCBnYXRlXCIsIHsgZXJyb3I6IChlcnJvciBhcyBFcnJvcikubWVzc2FnZSB9KTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIDMuIFN0YXJ0IHRoZSBnYXRlIHByb3h5IG9uIHRoZSBwdWJsaWMgcG9ydCAob3BlbiB3aGVuIGBnYXRlYCBpcyB1bmRlZmluZWQpLlxuICBhd2FpdCBzdGFydFByb3h5KHsgcHVibGljUG9ydCwgYXBwUG9ydCwgZ2F0ZSB9KTtcblxuICAvLyA0LiBJbnN0YWxsICsgcnVuIHBvcnRyIHdoZW4gYSB0dW5uZWwgaXMgY29uZmlndXJlZC5cbiAgY29uc3QgcG9ydHJDb25maWcgPSByZXNvbHZlUG9ydHJDb25maWcoe1xuICAgIHB1YmxpY0RvbWFpbjogb3B0cy5wdWJsaWNEb21haW4sXG4gICAgc3ViZG9tYWluOiBvcHRzLnN1YmRvbWFpbixcbiAgICBwb3J0OiBwdWJsaWNQb3J0LFxuICB9KTtcbiAgY29uc3QgY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdID0gW2FwcF07XG4gIGlmIChwb3J0ckNvbmZpZykge1xuICAgIGNvbnN0IGVudiA9IGluc3RhbGxQb3J0cigpO1xuICAgIHdyaXRlUG9ydHJDb25maWcocG9ydHJDb25maWcsIGVudik7XG4gICAgY2hpbGRyZW4ucHVzaChzdGFydFBvcnRyKHBvcnRyQ29uZmlnLCBlbnYpKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuaW5mbyhcIm5vIFBPUlRSX1RPS0VOL1BVQkxJQ19ET01BSU4gLSBzZXJ2aW5nIHRoZSBnYXRlIHByb3h5IHdpdGhvdXQgYSBwdWJsaWMgdHVubmVsXCIpO1xuICB9XG5cbiAgLy8gQW55IGNoaWxkIGV4aXQgKG9yIGEgc2lnbmFsKSB0ZWFycyB0aGUgd2hvbGUgdGhpbmcgZG93bi5cbiAgc3VwZXJ2aXNlRXhpdChjaGlsZHJlbik7XG59XG4iXX0=
|
|
149
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFeEMsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxxRkFBcUY7QUFDckYsU0FBUyxVQUFVO0lBQ2pCLE9BQU8sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFjRCxvRkFBb0Y7QUFDcEYsU0FBUyxPQUFPO0lBQ2QsT0FBTyxJQUFJLE9BQU8sRUFBRTtTQUNqQixJQUFJLENBQUMsa0JBQWtCLENBQUM7U0FDeEIsV0FBVyxDQUFDLDBEQUEwRCxDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxvREFBb0QsQ0FBQztTQUNoRixNQUFNLENBQ0wsb0JBQW9CLEVBQ3BCLGtGQUFrRixDQUNuRjtTQUNBLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxtREFBbUQsQ0FBQztTQUNqRixNQUFNLENBQUMsd0JBQXdCLEVBQUUsZ0RBQWdELENBQUM7U0FDbEYsTUFBTSxDQUNMLHFCQUFxQixFQUNyQiwrRkFBK0YsQ0FDaEc7U0FDQSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsMkRBQTJELENBQUM7U0FDdkYsTUFBTSxDQUFDLHlCQUF5QixFQUFFLHlDQUF5QyxDQUFDO1NBQzVFLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSw0Q0FBNEMsQ0FBQztTQUM1RSxNQUFNLENBQ0wsWUFBWSxFQUNaLDhIQUE4SCxDQUMvSDtTQUNBLG9CQUFvQixDQUFDLElBQUksQ0FBQztTQUMxQixVQUFVLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsU0FBUyxhQUFhLENBQUMsUUFBd0I7SUFDN0MsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBWSxFQUFRLEVBQUU7UUFDdEMsSUFBSSxZQUFZO1lBQUUsT0FBTztRQUN6QixZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO2dCQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUNELHVFQUF1RTtRQUN2RSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNyRCxDQUFDLENBQUM7SUFDRixLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzdCLEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLFFBQVEseUJBQXlCLENBQUMsQ0FBQztZQUN4RSxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELEtBQUssTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBVSxFQUFFLENBQUM7UUFDM0QsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDckMsQ0FBQztBQUNILENBQUM7QUFFRCxxQ0FBcUM7QUFDckMsTUFBTSxDQUFDLEtBQUssVUFBVSxNQUFNLENBQUMsSUFBYztJQUN6QywwREFBMEQ7SUFDMUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixNQUFNLEtBQUssR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ25ELE1BQU0sT0FBTyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFcEQsTUFBTSxJQUFJLEdBQUcsT0FBTyxFQUFFLENBQUM7SUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFjLENBQUM7SUFFckMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxjQUFjLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLG1DQUFtQyxDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLElBQUksQ0FBQyxDQUFDO0lBQ25FLE1BQU0sT0FBTyxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBRTdCLE1BQU0sVUFBVSxHQUFtQjtRQUNqQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7UUFDakIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1FBQ3JCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztRQUN6QixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87UUFDckIsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUN4RSxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztLQUNoRSxDQUFDO0lBRUYsOEVBQThFO0lBQzlFLHVCQUF1QjtJQUN2QixNQUFNLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxPQUFPLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0UsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQztJQUMvQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBSSxFQUFFLElBQUksRUFBRTtRQUM1QixHQUFHLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUU7UUFDaEYsS0FBSyxFQUFFLFNBQVM7S0FDakIsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLHFFQUFxRTtJQUNyRSwrRUFBK0U7SUFDL0UsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0YsSUFBSSxJQUEwRCxDQUFDO0lBQy9ELElBQUksUUFBUSxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLHlEQUF5RCxDQUFDLENBQUM7SUFDekUsQ0FBQztTQUFNLENBQUM7UUFDTixJQUFJLENBQUM7WUFDSCxJQUFJLEdBQUcsTUFBTSxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZiw0RUFBNEU7WUFDNUUsNENBQTRDO1lBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsRUFBRSxLQUFLLEVBQUcsS0FBZSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDL0UsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxNQUFNLFVBQVUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUVoRCxzREFBc0Q7SUFDdEQsTUFBTSxXQUFXLEdBQUcsa0JBQWtCLENBQUM7UUFDckMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1FBQy9CLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztRQUN6QixJQUFJLEVBQUUsVUFBVTtLQUNqQixDQUFDLENBQUM7SUFDSCxNQUFNLFFBQVEsR0FBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sR0FBRyxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQzNCLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNuQyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsK0VBQStFLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQsMkRBQTJEO0lBQzNELGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgZGJ4LXRvb2xzLXR1bm5lbGAgLyBgZGJ4dC10dW5uZWxgIENMSS5cbiAqXG4gKiBXcmFwcyBhbiBhcHAncyBzdGFydCBjb21tYW5kIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsIGFuZCBhbiBlbWFpbC1PVFBcbiAqIGFjY2VzcyBnYXRlLiBFdmVyeXRoaW5nIGFmdGVyIGAtLWAgaXMgdGhlIFJFQUwgYXBwIHN0YXJ0IGNvbW1hbmQ6XG4gKlxuICogICBkYnh0LXR1bm5lbCAtLXN1YmplY3QgXCJIZXJlJ3MgeW91ciBPVFBcIiAtLWFsbG93IGV4YW1wbGUuY29tIC0tIGJ1biBzcmMvc2VydmVyLnRzXG4gKlxuICogQm9vdCBzZXF1ZW5jZTpcbiAqICAgMS4gUGljayBhIHJhbmRvbSBQUklWQVRFIHBvcnQgYW5kIHNwYXduIHRoZSBhcHAgY29tbWFuZCB3aXRoXG4gKiAgICAgIGBEQVRBQlJJQ0tTX0FQUF9QT1JUYCBzZXQgdG8gaXQgKHNvIHRoZSBhcHAgYmluZHMgbG9vcGJhY2stcHJpdmF0ZSkuIFRoYXRcbiAqICAgICAgdmFyaWFibGUgbmFtZSBpcyB0aGUgRGF0YWJyaWNrcyBBcHBzIHJ1bnRpbWUgY29udHJhY3Q7IHRoZSBnYXRlIGl0c2VsZiBpc1xuICogICAgICBwbGF0Zm9ybS1uZXV0cmFsIGFuZCBob25vdXJzIHdoYXRldmVyIHBvcnQgaXQgZmluZHMgdGhlcmUuXG4gKiAgIDIuIEJvb3QgdGhlIHRpbnkgZ2F0ZSBBcHBLaXQgYXBwIChubyBzZXJ2ZXIpOiBpbml0cyBgQ2FjaGVNYW5hZ2VyYCArIHRoZVxuICogICAgICBlbWFpbCB0cmFuc3BvcnQsIHlpZWxkcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSS5cbiAqICAgMy4gU3RhcnQgdGhlIGdhdGUgUFJPWFkgb24gdGhlIE9SSUdJTkFMIHB1YmxpYyBwb3J0LCBmb3J3YXJkaW5nIHRvIHRoZSBhcHAuXG4gKiAgIDQuIEluc3RhbGwgKyBydW4gcG9ydHIgcG9pbnRlZCBhdCB0aGUgcHVibGljIHBvcnQgKHdoZW4gYSB0dW5uZWwgaXNcbiAqICAgICAgY29uZmlndXJlZDsgb3RoZXJ3aXNlIHRoZSBwcm94eSBzdGlsbCBnYXRlcyBub3RoaW5nIGFuZCBmb3J3YXJkcykuXG4gKlxuICogU3VwZXJ2aXNpb246IHRoZSBhcHAgY2hpbGQsIHBvcnRyIGNoaWxkLCBhbmQgdGhpcyBwcm9jZXNzIGFyZSB0aWVkIHRvZ2V0aGVyIC1cbiAqIGlmIEFOWSBleGl0cywgZXZlcnl0aGluZyBjb21lcyBkb3duIChjb25jdXJyZW50bHktc3R5bGUgYGtpbGxPdGhlcnNgKS5cbiAqXG4gKiBPcHRpb25zIGNvbWUgZnJvbSBmbGFncyBPUiBlbnY7IHNlZSB0aGUgb3B0aW9uIGRlZmluaXRpb25zIGJlbG93LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyBzdGFydEdhdGVBcHAgfSBmcm9tIFwiLi9hcHAudHNcIjtcbmltcG9ydCB0eXBlIHsgQXV0aEdhdGVDb25maWcgfSBmcm9tIFwiLi9wbHVnaW4udHNcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdGFydFBvcnRyLCB3cml0ZVBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vcG9ydHIudHNcIjtcbmltcG9ydCB7IHN0YXJ0UHJveHkgfSBmcm9tIFwiLi9wcm94eS50c1wiO1xuXG5leHBvcnQgeyBDb21tYW5kZXJFcnJvciB9O1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsXCIpO1xuXG4vKiogQSByYW5kb20gZXBoZW1lcmFsIHBvcnQgZm9yIHRoZSBhcHAgdG8gYmluZCAodGhlIHByb3h5IGZyb250cyB0aGUgcHVibGljIG9uZSkuICovXG5mdW5jdGlvbiByYW5kb21Qb3J0KCk6IG51bWJlciB7XG4gIHJldHVybiAyMDAwMCArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDIwMDAwKTtcbn1cblxuaW50ZXJmYWNlIFR1bm5lbE9wdHMge1xuICBzdWJqZWN0Pzogc3RyaW5nO1xuICBhbGxvdz86IHN0cmluZztcbiAgc3ViZG9tYWluPzogc3RyaW5nO1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIGJyYW5kTmFtZT86IHN0cmluZztcbiAgbWVzc2FnZT86IHN0cmluZztcbiAgc2Vzc2lvblR0bD86IHN0cmluZztcbiAgY29kZVR0bD86IHN0cmluZztcbiAgaW5zZWN1cmU/OiBib29sZWFuO1xufVxuXG4vKiogQnVpbGQgdGhlIGNvbW1hbmRlciBwcm9ncmFtLiBgLS1gIHNlcGFyYXRlcyBmbGFncyBmcm9tIHRoZSBhcHAgc3RhcnQgY29tbWFuZC4gKi9cbmZ1bmN0aW9uIHByb2dyYW0oKTogQ29tbWFuZCB7XG4gIHJldHVybiBuZXcgQ29tbWFuZCgpXG4gICAgLm5hbWUoXCJkYngtdG9vbHMtdHVubmVsXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiRnJvbnQgYW4gYXBwIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsICsgZW1haWwtT1RQIGdhdGVcIilcbiAgICAub3B0aW9uKFwiLS1zdWJqZWN0IDx0ZXh0PlwiLCBcIlN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwgKGVudiBBVVRIX1NVQkpFQ1QpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1hbGxvdyA8cGF0dGVybnM+XCIsXG4gICAgICBcIkNvbW1hL3NwYWNlLXNlcGFyYXRlZCBhbGxvdy1saXN0OiBkb21haW4gLyBnbG9iIC8gL3JlZ2V4LyAoZW52IEVNQUlMX0FVVEhfQUxMT1cpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXCItLXN1YmRvbWFpbiA8bmFtZT5cIiwgXCJwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcIi0tcHVibGljLWRvbWFpbiA8aG9zdD5cIiwgXCJwb3J0ciA8c3ViZG9tYWluPi48c2VydmVyPiAoZW52IFBVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1icmFuZC1uYW1lIDxuYW1lPlwiLFxuICAgICAgXCJEaXNwbGF5IG5hbWUgaW4gdGhlIGNvZGUgZW1haWwgY29weSAoZW52IEFVVEhfQlJBTkRfTkFNRTsgZGVmYXVsdHMgdG8gdGhlIGJyYW5kIGNvbnRleHQgbmFtZSlcIixcbiAgICApXG4gICAgLm9wdGlvbihcIi0tbWVzc2FnZSA8dGV4dD5cIiwgXCJMaW5lIHNob3duIGFib3ZlIHRoZSBjb2RlIGluIHRoZSBlbWFpbCAoZW52IEFVVEhfTUVTU0FHRSlcIilcbiAgICAub3B0aW9uKFwiLS1zZXNzaW9uLXR0bCA8c2Vjb25kcz5cIiwgXCJTZXNzaW9uIGxpZmV0aW1lIChlbnYgQVVUSF9TRVNTSU9OX1RUTClcIilcbiAgICAub3B0aW9uKFwiLS1jb2RlLXR0bCA8c2Vjb25kcz5cIiwgXCJPbmUtdGltZS1jb2RlIGxpZmV0aW1lIChlbnYgQVVUSF9DT0RFX1RUTClcIilcbiAgICAub3B0aW9uKFxuICAgICAgXCItLWluc2VjdXJlXCIsXG4gICAgICBcIlJ1biB0aGUgdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlIChlbnYgVFVOTkVMX0lOU0VDVVJFPXRydWUpLiBPdGhlcndpc2UgdGhlIENMSSBmYWlscyBmYXN0IHdoZW4gZW1haWwgU01UUCBpcyBub3QgY29uZmlndXJlZC5cIixcbiAgICApXG4gICAgLmFsbG93RXhjZXNzQXJndW1lbnRzKHRydWUpXG4gICAgLmhlbHBPcHRpb24oXCItaCwgLS1oZWxwXCIsIFwiU2hvdyBoZWxwXCIpO1xufVxuXG4vKiogVGllIGEgY2hpbGQncyBleGl0IHRvIGZ1bGwgdGVhcmRvd246IGFueSBleGl0IGJyaW5ncyB0aGUgd2hvbGUgdHVubmVsIGRvd24uICovXG5mdW5jdGlvbiBzdXBlcnZpc2VFeGl0KGNoaWxkcmVuOiBDaGlsZFByb2Nlc3NbXSk6IHZvaWQge1xuICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gIGNvbnN0IHNodXRkb3duID0gKGNvZGU6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGlmIChzaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICAgIGlmICghY2hpbGQua2lsbGVkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9XG4gICAgLy8gR2l2ZSBjaGlsZHJlbiBhIG1vbWVudCwgdGhlbiBleGl0IHdpdGggdGhlIGZpcnN0IG5vbi16ZXJvIGNvZGUgc2Vlbi5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHByb2Nlc3MuZXhpdChjb2RlKSwgMzAwMCkudW5yZWYoKTtcbiAgfTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgIGNoaWxkLm9uKFwiZXhpdFwiLCAoY29kZSkgPT4ge1xuICAgICAgbG9nZ2VyLndhcm4oYGNoaWxkIGV4aXRlZCAoJHtjb2RlID8/IFwic2lnbmFsXCJ9KTsgYnJpbmdpbmcgdHVubmVsIGRvd25gKTtcbiAgICAgIHNodXRkb3duKGNvZGUgPz8gMSk7XG4gICAgfSk7XG4gIH1cbiAgZm9yIChjb25zdCBzaWcgb2YgW1wiU0lHVEVSTVwiLCBcIlNJR0lOVFwiLCBcIlNJR0hVUFwiXSBhcyBjb25zdCkge1xuICAgIHByb2Nlc3Mub24oc2lnLCAoKSA9PiBzaHV0ZG93bigwKSk7XG4gIH1cbn1cblxuLyoqIFBhcnNlIGFyZ3YgYW5kIHJ1biB0aGUgdHVubmVsLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkNsaShhcmd2OiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAvLyBTcGxpdCBmbGFncyBmcm9tIHRoZSB3cmFwcGVkIGNvbW1hbmQgYXQgdGhlIGZpcnN0IGAtLWAuXG4gIGNvbnN0IHNlcCA9IGFyZ3YuaW5kZXhPZihcIi0tXCIpO1xuICBjb25zdCBmbGFncyA9IHNlcCA+PSAwID8gYXJndi5zbGljZSgwLCBzZXApIDogYXJndjtcbiAgY29uc3QgY29tbWFuZCA9IHNlcCA+PSAwID8gYXJndi5zbGljZShzZXAgKyAxKSA6IFtdO1xuXG4gIGNvbnN0IHByb2cgPSBwcm9ncmFtKCk7XG4gIHByb2cucGFyc2UoZmxhZ3MpO1xuICBjb25zdCBvcHRzID0gcHJvZy5vcHRzPFR1bm5lbE9wdHM+KCk7XG5cbiAgaWYgKGNvbW1hbmQubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IENvbW1hbmRlckVycm9yKDEsIFwidHVubmVsLm5vLWNvbW1hbmRcIiwgXCJubyBzdGFydCBjb21tYW5kIGdpdmVuIGFmdGVyIGAtLWBcIik7XG4gIH1cblxuICBjb25zdCBwdWJsaWNQb3J0ID0gTnVtYmVyKHByb2Nlc3MuZW52LkRBVEFCUklDS1NfQVBQX1BPUlQgPz8gODAwMCk7XG4gIGNvbnN0IGFwcFBvcnQgPSByYW5kb21Qb3J0KCk7XG5cbiAgY29uc3QgZ2F0ZUNvbmZpZzogQXV0aEdhdGVDb25maWcgPSB7XG4gICAgYWxsb3c6IG9wdHMuYWxsb3csXG4gICAgc3ViamVjdDogb3B0cy5zdWJqZWN0LFxuICAgIGJyYW5kTmFtZTogb3B0cy5icmFuZE5hbWUsXG4gICAgbWVzc2FnZTogb3B0cy5tZXNzYWdlLFxuICAgIHNlc3Npb25UdGxTZWNvbmRzOiBvcHRzLnNlc3Npb25UdGwgPyBOdW1iZXIob3B0cy5zZXNzaW9uVHRsKSA6IHVuZGVmaW5lZCxcbiAgICBjb2RlVHRsU2Vjb25kczogb3B0cy5jb2RlVHRsID8gTnVtYmVyKG9wdHMuY29kZVR0bCkgOiB1bmRlZmluZWQsXG4gIH07XG5cbiAgLy8gMS4gU3Bhd24gdGhlIHdyYXBwZWQgYXBwIHdpdGggdGhlIFBSSVZBVEUgcG9ydC4gSXQgYmluZHMgbG9vcGJhY2s7IG9ubHkgdGhlXG4gIC8vICAgIHByb3h5IHJlYWNoZXMgaXQuXG4gIGxvZ2dlci5pbmZvKGBzcGF3bmluZyBhcHAgb24gcHJpdmF0ZSBwb3J0ICR7YXBwUG9ydH06ICR7Y29tbWFuZC5qb2luKFwiIFwiKX1gKTtcbiAgY29uc3QgW2NtZCwgLi4uYXJnc10gPSBjb21tYW5kO1xuICBjb25zdCBhcHAgPSBzcGF3bihjbWQhLCBhcmdzLCB7XG4gICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBEQVRBQlJJQ0tTX0FQUF9QT1JUOiBTdHJpbmcoYXBwUG9ydCksIEhPU1Q6IFwiMTI3LjAuMC4xXCIgfSxcbiAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gIH0pO1xuXG4gIC8vIDIuIEJvb3QgdGhlIGdhdGUgYXBwIChjYWNoZSArIGVtYWlsIHRyYW5zcG9ydCArIGdhdGUgQVBJKS4gYHN0YXJ0R2F0ZUFwcGBcbiAgLy8gICAgRkFJTFMgRkFTVCB3aGVuIGVtYWlsIGNhbid0IHNlbmQgY29kZXMgKG5vIFNNVFApLiBJbnNlY3VyZSBtb2RlXG4gIC8vICAgIChgLS1pbnNlY3VyZWAgLyBUVU5ORUxfSU5TRUNVUkUpIHNraXBzIHRoZSBnYXRlIGFuZCBydW5zIHRoZSB0dW5uZWwgb3Blbi5cbiAgY29uc3QgaW5zZWN1cmUgPSBvcHRzLmluc2VjdXJlIHx8IC9eKDF8dHJ1ZXx5ZXN8b24pJC9pLnRlc3QocHJvY2Vzcy5lbnYuVFVOTkVMX0lOU0VDVVJFID8/IFwiXCIpO1xuICBsZXQgZ2F0ZTogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBzdGFydEdhdGVBcHA+PiB8IHVuZGVmaW5lZDtcbiAgaWYgKGluc2VjdXJlKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJpbnNlY3VyZSBtb2RlIC0gdHVubmVsIHJ1bnMgT1BFTiB3aXRoIG5vIGVtYWlsLU9UUCBnYXRlXCIpO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICBnYXRlID0gYXdhaXQgc3RhcnRHYXRlQXBwKGdhdGVDb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBGYWlsIGZhc3Q6IGRvbid0IHNpbGVudGx5IGV4cG9zZSBhbiB1bmdhdGVkIHR1bm5lbC4gVGhlIG9wZXJhdG9yIG11c3QgZml4XG4gICAgICAvLyBTTVRQIG9yIGV4cGxpY2l0bHkgb3B0IGludG8gYC0taW5zZWN1cmVgLlxuICAgICAgbG9nZ2VyLmVycm9yKFwiY2Fubm90IHN0YXJ0IHRoZSBPVFAgZ2F0ZVwiLCB7IGVycm9yOiAoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2UgfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvLyAzLiBTdGFydCB0aGUgZ2F0ZSBwcm94eSBvbiB0aGUgcHVibGljIHBvcnQgKG9wZW4gd2hlbiBgZ2F0ZWAgaXMgdW5kZWZpbmVkKS5cbiAgYXdhaXQgc3RhcnRQcm94eSh7IHB1YmxpY1BvcnQsIGFwcFBvcnQsIGdhdGUgfSk7XG5cbiAgLy8gNC4gSW5zdGFsbCArIHJ1biBwb3J0ciB3aGVuIGEgdHVubmVsIGlzIGNvbmZpZ3VyZWQuXG4gIGNvbnN0IHBvcnRyQ29uZmlnID0gcmVzb2x2ZVBvcnRyQ29uZmlnKHtcbiAgICBwdWJsaWNEb21haW46IG9wdHMucHVibGljRG9tYWluLFxuICAgIHN1YmRvbWFpbjogb3B0cy5zdWJkb21haW4sXG4gICAgcG9ydDogcHVibGljUG9ydCxcbiAgfSk7XG4gIGNvbnN0IGNoaWxkcmVuOiBDaGlsZFByb2Nlc3NbXSA9IFthcHBdO1xuICBpZiAocG9ydHJDb25maWcpIHtcbiAgICBjb25zdCBlbnYgPSBpbnN0YWxsUG9ydHIoKTtcbiAgICB3cml0ZVBvcnRyQ29uZmlnKHBvcnRyQ29uZmlnLCBlbnYpO1xuICAgIGNoaWxkcmVuLnB1c2goc3RhcnRQb3J0cihwb3J0ckNvbmZpZywgZW52KSk7XG4gIH0gZWxzZSB7XG4gICAgbG9nZ2VyLmluZm8oXCJubyBQT1JUUl9UT0tFTi9QVUJMSUNfRE9NQUlOIC0gc2VydmluZyB0aGUgZ2F0ZSBwcm94eSB3aXRob3V0IGEgcHVibGljIHR1bm5lbFwiKTtcbiAgfVxuXG4gIC8vIEFueSBjaGlsZCBleGl0IChvciBhIHNpZ25hbCkgdGVhcnMgdGhlIHdob2xlIHRoaW5nIGRvd24uXG4gIHN1cGVydmlzZUV4aXQoY2hpbGRyZW4pO1xufVxuIl19
|
package/lib/src/otp.d.ts
CHANGED
|
@@ -9,10 +9,13 @@
|
|
|
9
9
|
* the hash, and the entry is deleted on success or once attempts are exhausted.
|
|
10
10
|
*
|
|
11
11
|
* The session JWT is a short-lived HS256 token (via `jose`) carrying only the
|
|
12
|
-
* email. Its signing key comes from `AUTH_JWT_SECRET`; when unset the gate
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* email. Its signing key comes from `AUTH_JWT_SECRET`; when unset the gate uses an
|
|
13
|
+
* ephemeral per-process key rather than refusing service, so an unset secret
|
|
14
|
+
* degrades to "sessions don't survive a restart", not "nobody can log in". Note
|
|
15
|
+
* what this does NOT weaken: a caller still needs a code delivered to an
|
|
16
|
+
* allow-listed address, because the signing key only validates an ALREADY-issued
|
|
17
|
+
* session. Set it in any deployment running more than one instance, or sessions
|
|
18
|
+
* minted by one will not verify on another.
|
|
16
19
|
*
|
|
17
20
|
* @module
|
|
18
21
|
*/
|