@dbx-tools/cli-tunnel 0.6.50 → 0.6.51

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 CHANGED
@@ -34,8 +34,11 @@ address against an allow-list, verified by a code sent over
34
34
  attempt counter, verified in constant time, in AppKit's `CacheManager` (memory
35
35
  by default, Lakebase when the app configures persistent `CacheStorage`) so TTL
36
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`.
37
+ - HS256 session JWT (via `jose`) carrying only the email, signed with a key that
38
+ is PERSISTED in AppKit's cache for 30 days - so a signed-in browser stays signed
39
+ in across the restarts a tunnel sees whenever the app it wraps reloads. An
40
+ operator-held `TUNNEL_AUTH_JWT_SECRET` still wins. `TUNNEL_AUTH_SESSION_EPOCH`
41
+ is the log-everyone-out switch.
39
42
  - Allow-list patterns in three shapes, matched in order: a domain shortcut
40
43
  (`example.com`, `@example.com`), a shell-style glob (`*@example.com`), or a
41
44
  regex literal (`/^ops-.*@example\.com$/`). An empty list allows nobody.
@@ -92,19 +95,20 @@ original public port itself.
92
95
  Every flag has an environment fallback, so a deployment can configure the gate
93
96
  with no change to its start command.
94
97
 
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 |
98
+ | Flag | Env | Default |
99
+ | ------------------- | --------------------------- | ------------------------------ |
100
+ | `--allow` | `TUNNEL_AUTH_ALLOW` | empty (allow nobody) |
101
+ | `--subject` | `TUNNEL_AUTH_SUBJECT` | `Your verification code` |
102
+ | `--brand-name` | `TUNNEL_AUTH_BRAND_NAME` | the brand context `name` |
103
+ | `--message` | `TUNNEL_AUTH_MESSAGE` | `Your verification code is:` |
104
+ | `--session-ttl` | `TUNNEL_AUTH_SESSION_TTL` | `2592000` (30 days) |
105
+ | `--code-ttl` | `TUNNEL_AUTH_CODE_TTL` | `600` (10 minutes) |
106
+ | `--session-epoch` | `TUNNEL_AUTH_SESSION_EPOCH` | unset (no cutoff) |
107
+ | `--subdomain` | - | derived from the public domain |
108
+ | `--public-domain` | `TUNNEL_PUBLIC_DOMAIN` | - |
109
+ | `--forward-headers` | `TUNNEL_FORWARD_HEADERS` | the built-in `x-` allow-list |
110
+ | `--insecure` | `TUNNEL_INSECURE` | off (the gate is required) |
111
+ | - | `TUNNEL_AUTH_JWT_SECRET` | an ephemeral per-process key |
108
112
 
109
113
  Every variable is `TUNNEL_`-prefixed because the gate runs as a WRAPPER: it and
110
114
  the app it wraps share one environment, so a generic name is one the app may
@@ -118,10 +122,55 @@ keep their names: that namespace belongs to portr itself, as does
118
122
 
119
123
  `--allow` and `TUNNEL_AUTH_ALLOW` are UNIONED rather than one overriding the
120
124
  other, so a deployment-wide allow-list and a per-invocation addition both grant
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
+ access.
126
+
127
+ ## Sessions That Survive A Restart
128
+
129
+ The signing key decides whether an already-issued session COOKIE still verifies,
130
+ so where that key comes from is what decides whether a restart signs everyone out.
131
+ Resolution order:
132
+
133
+ 1. **`TUNNEL_AUTH_JWT_SECRET`**, when set. The right answer for a fleet: an
134
+ operator-held secret needs no shared cache, and it survives a cache flush.
135
+ 2. **A key persisted in AppKit's cache for 30 days.** With a persistent
136
+ `CacheStorage` (Lakebase) the key outlives the process, so cookies stay valid
137
+ across restarts - which a tunnel does often, since it restarts whenever the app
138
+ it wraps reloads. On the default in-memory cache the key is per-process, the
139
+ same as having no secret at all.
140
+ 3. **An ephemeral per-process key**, when there is no secret and no reachable
141
+ cache. Sessions do not survive a restart, but the gate still serves: the key
142
+ only validates an ALREADY-issued session, so losing it costs sessions, never
143
+ admission. A caller still needs a code delivered to an allow-listed address.
144
+
145
+ The cached key is read, generated-and-stored, then **re-read**. Two instances
146
+ booting together both miss the cache, so both generate; adopting whatever is
147
+ STORED afterwards is what makes them converge on one key instead of each trusting
148
+ the one it minted. Set `TUNNEL_AUTH_JWT_SECRET` to remove the race entirely.
149
+
150
+ `TUNNEL_AUTH_SESSION_TTL` defaults to the same 30 days the key is stored for, on
151
+ purpose - a key that expired before the cookies it signed would sign everyone out
152
+ for no reason.
153
+
154
+ ### Signing everyone out
155
+
156
+ `--session-epoch` / `TUNNEL_AUTH_SESSION_EPOCH` invalidates every session issued
157
+ before a given moment:
158
+
159
+ ```sh
160
+ dbxt-tunnel --session-epoch 2026-08-02 -- bun src/server.ts
161
+ TUNNEL_AUTH_SESSION_EPOCH=$(date +%s) dbxt-tunnel -- bun src/server.ts
162
+ ```
163
+
164
+ Accepts a date, an ISO timestamp, or bare epoch seconds / millis. It works two
165
+ ways at once, so it holds however the key was resolved: the epoch is part of the
166
+ key's CACHE KEY (moving it orphans the previous key), and it is also checked
167
+ against each token's `iat` (which is what makes it bite when
168
+ `TUNNEL_AUTH_JWT_SECRET` is set and there is no key to rotate).
169
+
170
+ A FUTURE date is clamped to now, because an unclamped one would refuse the
171
+ sessions it is about to mint as well as the old ones - an app nobody can sign in
172
+ to, from a mistyped year. An unparseable value is ignored with a warning rather
173
+ than failing startup: this is the switch that gets a fleet back in.
125
174
 
126
175
  ## Inbound Header Policy
127
176
 
@@ -229,6 +278,8 @@ by hand.
229
278
  - `proxy` - the public-port reverse proxy: loopback-vs-platform classification,
230
279
  open login routes, session enforcement, and WebSocket forwarding.
231
280
  - `otp` - the `CacheManager`-backed code store and the session JWT.
281
+ - `signingKey` - the cache-persisted HS256 session key (30-day TTL, get/generate/
282
+ re-read convergence) and the `TUNNEL_AUTH_SESSION_EPOCH` force-clear cutoff.
232
283
  - `allowlist` - email domain / glob / regex matching and `looksLikeEmail`.
233
284
  - `headers` - the inbound-header allow-list: `toHeaderPolicy()`,
234
285
  `DEFAULT_FORWARD_HEADERS`, and the `PROTECTED_HEADERS` no pattern can forward.
package/index.ts CHANGED
@@ -12,8 +12,9 @@ export * as plugin from "./src/plugin.ts";
12
12
  export * as portr from "./src/portr.ts";
13
13
  export * as proxy from "./src/proxy.ts";
14
14
  export * as rateLimit from "./src/rate-limit.ts";
15
+ export * as signingKey from "./src/signing-key.ts";
15
16
  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 { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, SESSION_EPOCH_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.ts";
17
18
  export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.ts";
18
19
  export type { HeaderPolicy } from "./src/headers.ts";
19
20
  export { CodeStore } from "./src/otp.ts";
@@ -23,3 +24,5 @@ export type { AuthGateConfig, SendCodeOptions, ResolvedAuthGateConfig, AuthGateA
23
24
  export type { PortrConfig } from "./src/portr.ts";
24
25
  export type { ProxyOptions } from "./src/proxy.ts";
25
26
  export { RateLimiter } from "./src/rate-limit.ts";
27
+ export { KEY_TTL_SECONDS } from "./src/signing-key.ts";
28
+ export type { SigningKey } from "./src/signing-key.ts";
package/lib/index.d.ts CHANGED
@@ -8,8 +8,9 @@ export * as plugin from "./src/plugin.ts";
8
8
  export * as portr from "./src/portr.ts";
9
9
  export * as proxy from "./src/proxy.ts";
10
10
  export * as rateLimit from "./src/rate-limit.ts";
11
+ export * as signingKey from "./src/signing-key.ts";
11
12
  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 { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, SESSION_EPOCH_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.ts";
13
14
  export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.ts";
14
15
  export type { HeaderPolicy } from "./src/headers.ts";
15
16
  export { CodeStore } from "./src/otp.ts";
@@ -19,3 +20,5 @@ export type { AuthGateConfig, SendCodeOptions, ResolvedAuthGateConfig, AuthGateA
19
20
  export type { PortrConfig } from "./src/portr.ts";
20
21
  export type { ProxyOptions } from "./src/proxy.ts";
21
22
  export { RateLimiter } from "./src/rate-limit.ts";
23
+ export { KEY_TTL_SECONDS } from "./src/signing-key.ts";
24
+ export type { SigningKey } from "./src/signing-key.ts";
package/lib/index.js CHANGED
@@ -11,10 +11,12 @@ export * as plugin from "./src/plugin.js";
11
11
  export * as portr from "./src/portr.js";
12
12
  export * as proxy from "./src/proxy.js";
13
13
  export * as rateLimit from "./src/rate-limit.js";
14
+ export * as signingKey from "./src/signing-key.js";
14
15
  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 { ALLOW_ENV, SUBJECT_ENV, BRAND_NAME_ENV, MESSAGE_ENV, SESSION_TTL_ENV, CODE_TTL_ENV, JWT_SECRET_ENV, SESSION_EPOCH_ENV, PUBLIC_DOMAIN_ENV, INSECURE_ENV, FORWARD_HEADERS_ENV } from "./src/env.js";
16
17
  export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.js";
17
18
  export { CodeStore } from "./src/otp.js";
18
19
  export { AuthGatePlugin, authGate } from "./src/plugin.js";
19
20
  export { RateLimiter } from "./src/rate-limit.js";
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3hMLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFekMsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUkzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBhbGxvd2xpc3QgZnJvbSBcIi4vc3JjL2FsbG93bGlzdC50c1wiO1xuZXhwb3J0ICogYXMgYXBwIGZyb20gXCIuL3NyYy9hcHAudHNcIjtcbmV4cG9ydCAqIGFzIGNsaSBmcm9tIFwiLi9zcmMvY2xpLnRzXCI7XG5leHBvcnQgKiBhcyBlbnYgZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0ICogYXMgaGVhZGVycyBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0ICogYXMgb3RwIGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCAqIGFzIHBsdWdpbiBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgKiBhcyBwb3J0ciBmcm9tIFwiLi9zcmMvcG9ydHIudHNcIjtcbmV4cG9ydCAqIGFzIHByb3h5IGZyb20gXCIuL3NyYy9wcm94eS50c1wiO1xuZXhwb3J0ICogYXMgcmF0ZUxpbWl0IGZyb20gXCIuL3NyYy9yYXRlLWxpbWl0LnRzXCI7XG5leHBvcnQgeyBDb21tYW5kZXJFcnJvciB9IGZyb20gXCIuL3NyYy9jbGkudHNcIjtcbmV4cG9ydCB7IEFMTE9XX0VOViwgU1VCSkVDVF9FTlYsIEJSQU5EX05BTUVfRU5WLCBNRVNTQUdFX0VOViwgU0VTU0lPTl9UVExfRU5WLCBDT0RFX1RUTF9FTlYsIEpXVF9TRUNSRVRfRU5WLCBQVUJMSUNfRE9NQUlOX0VOViwgSU5TRUNVUkVfRU5WLCBGT1JXQVJEX0hFQURFUlNfRU5WIH0gZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0IHsgUFJPVEVDVEVEX0hFQURFUlMsIERFRkFVTFRfRk9SV0FSRF9IRUFERVJTIH0gZnJvbSBcIi4vc3JjL2hlYWRlcnMudHNcIjtcbmV4cG9ydCB0eXBlIHsgSGVhZGVyUG9saWN5IH0gZnJvbSBcIi4vc3JjL2hlYWRlcnMudHNcIjtcbmV4cG9ydCB7IENvZGVTdG9yZSB9IGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCB0eXBlIHsgVmVyaWZ5T3V0Y29tZSB9IGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCB7IEF1dGhHYXRlUGx1Z2luLCBhdXRoR2F0ZSB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgQXV0aEdhdGVDb25maWcsIFNlbmRDb2RlT3B0aW9ucywgUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZywgQXV0aEdhdGVBcGkgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgdHlwZSB7IFBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vc3JjL3BvcnRyLnRzXCI7XG5leHBvcnQgdHlwZSB7IFByb3h5T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9wcm94eS50c1wiO1xuZXhwb3J0IHsgUmF0ZUxpbWl0ZXIgfSBmcm9tIFwiLi9zcmMvcmF0ZS1saW1pdC50c1wiO1xuIl19
21
+ export { KEY_TTL_SECONDS } from "./src/signing-key.js";
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEtBQUssVUFBVSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDM00sT0FBTyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFOUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSTNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBhbGxvd2xpc3QgZnJvbSBcIi4vc3JjL2FsbG93bGlzdC50c1wiO1xuZXhwb3J0ICogYXMgYXBwIGZyb20gXCIuL3NyYy9hcHAudHNcIjtcbmV4cG9ydCAqIGFzIGNsaSBmcm9tIFwiLi9zcmMvY2xpLnRzXCI7XG5leHBvcnQgKiBhcyBlbnYgZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0ICogYXMgaGVhZGVycyBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0ICogYXMgb3RwIGZyb20gXCIuL3NyYy9vdHAudHNcIjtcbmV4cG9ydCAqIGFzIHBsdWdpbiBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgKiBhcyBwb3J0ciBmcm9tIFwiLi9zcmMvcG9ydHIudHNcIjtcbmV4cG9ydCAqIGFzIHByb3h5IGZyb20gXCIuL3NyYy9wcm94eS50c1wiO1xuZXhwb3J0ICogYXMgcmF0ZUxpbWl0IGZyb20gXCIuL3NyYy9yYXRlLWxpbWl0LnRzXCI7XG5leHBvcnQgKiBhcyBzaWduaW5nS2V5IGZyb20gXCIuL3NyYy9zaWduaW5nLWtleS50c1wiO1xuZXhwb3J0IHsgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiLi9zcmMvY2xpLnRzXCI7XG5leHBvcnQgeyBBTExPV19FTlYsIFNVQkpFQ1RfRU5WLCBCUkFORF9OQU1FX0VOViwgTUVTU0FHRV9FTlYsIFNFU1NJT05fVFRMX0VOViwgQ09ERV9UVExfRU5WLCBKV1RfU0VDUkVUX0VOViwgU0VTU0lPTl9FUE9DSF9FTlYsIFBVQkxJQ19ET01BSU5fRU5WLCBJTlNFQ1VSRV9FTlYsIEZPUldBUkRfSEVBREVSU19FTlYgfSBmcm9tIFwiLi9zcmMvZW52LnRzXCI7XG5leHBvcnQgeyBQUk9URUNURURfSEVBREVSUywgREVGQVVMVF9GT1JXQVJEX0hFQURFUlMgfSBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0IHR5cGUgeyBIZWFkZXJQb2xpY3kgfSBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0IHsgQ29kZVN0b3JlIH0gZnJvbSBcIi4vc3JjL290cC50c1wiO1xuZXhwb3J0IHR5cGUgeyBWZXJpZnlPdXRjb21lIH0gZnJvbSBcIi4vc3JjL290cC50c1wiO1xuZXhwb3J0IHsgQXV0aEdhdGVQbHVnaW4sIGF1dGhHYXRlIH0gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBBdXRoR2F0ZUNvbmZpZywgU2VuZENvZGVPcHRpb25zLCBSZXNvbHZlZEF1dGhHYXRlQ29uZmlnLCBBdXRoR2F0ZUFwaSB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgUG9ydHJDb25maWcgfSBmcm9tIFwiLi9zcmMvcG9ydHIudHNcIjtcbmV4cG9ydCB0eXBlIHsgUHJveHlPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3Byb3h5LnRzXCI7XG5leHBvcnQgeyBSYXRlTGltaXRlciB9IGZyb20gXCIuL3NyYy9yYXRlLWxpbWl0LnRzXCI7XG5leHBvcnQgeyBLRVlfVFRMX1NFQ09ORFMgfSBmcm9tIFwiLi9zcmMvc2lnbmluZy1rZXkudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2lnbmluZ0tleSB9IGZyb20gXCIuL3NyYy9zaWduaW5nLWtleS50c1wiO1xuIl19
package/lib/src/cli.js CHANGED
@@ -50,6 +50,7 @@ function program() {
50
50
  .option("--message <text>", "Line shown above the code in the email (env TUNNEL_AUTH_MESSAGE)")
51
51
  .option("--session-ttl <seconds>", "Session lifetime (env TUNNEL_AUTH_SESSION_TTL)")
52
52
  .option("--code-ttl <seconds>", "One-time-code lifetime (env TUNNEL_AUTH_CODE_TTL)")
53
+ .option("--session-epoch <date>", "Invalidate sessions issued before this date, signing everyone out: a date, ISO timestamp, or epoch seconds (env TUNNEL_AUTH_SESSION_EPOCH)")
53
54
  .option("--forward-headers <patterns>", "Extra x- request headers tunnel traffic may forward: literal / glob / /regex/ (env TUNNEL_FORWARD_HEADERS)")
54
55
  .option("--insecure", "Run the tunnel OPEN with no gate (env TUNNEL_INSECURE=true). Otherwise the CLI fails fast when email SMTP is not configured.")
55
56
  .allowExcessArguments(true)
@@ -100,6 +101,7 @@ export async function runCli(argv) {
100
101
  message: opts.message,
101
102
  sessionTtlSeconds: opts.sessionTtl ? Number(opts.sessionTtl) : undefined,
102
103
  codeTtlSeconds: opts.codeTtl ? Number(opts.codeTtl) : undefined,
104
+ sessionEpoch: opts.sessionEpoch,
103
105
  };
104
106
  // 1. Spawn the wrapped app with the PRIVATE port. It binds loopback; only the
105
107
  // proxy reaches it.
@@ -154,4 +156,4 @@ export async function runCli(argv) {
154
156
  // Any child exit (or a signal) tears the whole thing down.
155
157
  superviseExit(children);
156
158
  }
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=
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxxRkFBcUY7QUFDckYsU0FBUyxVQUFVO0lBQ2pCLE9BQU8sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFnQkQsb0ZBQW9GO0FBQ3BGLFNBQVMsT0FBTztJQUNkLE9BQU8sSUFBSSxPQUFPLEVBQUU7U0FDakIsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1NBQ3hCLFdBQVcsQ0FBQywwREFBMEQsQ0FBQztTQUN2RSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsMkRBQTJELENBQUM7U0FDdkYsTUFBTSxDQUNMLG9CQUFvQixFQUNwQixtRkFBbUYsQ0FDcEY7U0FDQSxNQUFN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Q0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDeEMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLENBQUMsSUFBSSxDQUNULHNGQUFzRixDQUN2RixDQUFDO0lBQ0osQ0FBQztJQUVELDJEQUEyRDtJQUMzRCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYGRieC10b29scy10dW5uZWxgIC8gYGRieHQtdHVubmVsYCBDTEkuXG4gKlxuICogV3JhcHMgYW4gYXBwJ3Mgc3RhcnQgY29tbWFuZCB3aXRoIGEgcHVibGljIHBvcnRyIHR1bm5lbCBhbmQgYW4gZW1haWwtT1RQXG4gKiBhY2Nlc3MgZ2F0ZS4gRXZlcnl0aGluZyBhZnRlciBgLS1gIGlzIHRoZSBSRUFMIGFwcCBzdGFydCBjb21tYW5kOlxuICpcbiAqICAgZGJ4dC10dW5uZWwgLS1zdWJqZWN0IFwiSGVyZSdzIHlvdXIgT1RQXCIgLS1hbGxvdyBleGFtcGxlLmNvbSAtLSBidW4gc3JjL3NlcnZlci50c1xuICpcbiAqIEJvb3Qgc2VxdWVuY2U6XG4gKiAgIDEuIFBpY2sgYSByYW5kb20gUFJJVkFURSBwb3J0IGFuZCBzcGF3biB0aGUgYXBwIGNvbW1hbmQgd2l0aFxuICogICAgICBgREFUQUJSSUNLU19BUFBfUE9SVGAgc2V0IHRvIGl0IChzbyB0aGUgYXBwIGJpbmRzIGxvb3BiYWNrLXByaXZhdGUpLiBUaGF0XG4gKiAgICAgIHZhcmlhYmxlIG5hbWUgaXMgdGhlIERhdGFicmlja3MgQXBwcyBydW50aW1lIGNvbnRyYWN0OyB0aGUgZ2F0ZSBpdHNlbGYgaXNcbiAqICAgICAgcGxhdGZvcm0tbmV1dHJhbCBhbmQgaG9ub3VycyB3aGF0ZXZlciBwb3J0IGl0IGZpbmRzIHRoZXJlLlxuICogICAyLiBCb290IHRoZSB0aW55IGdhdGUgQXBwS2l0IGFwcCAobm8gc2VydmVyKTogaW5pdHMgYENhY2hlTWFuYWdlcmAgKyB0aGVcbiAqICAgICAgZW1haWwgdHJhbnNwb3J0LCB5aWVsZHMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBBUEkuXG4gKiAgIDMuIFN0YXJ0IHRoZSBnYXRlIFBST1hZIG9uIHRoZSBPUklHSU5BTCBwdWJsaWMgcG9ydCwgZm9yd2FyZGluZyB0byB0aGUgYXBwLlxuICogICA0LiBJbnN0YWxsICsgcnVuIHBvcnRyIHBvaW50ZWQgYXQgdGhlIHB1YmxpYyBwb3J0ICh3aGVuIGEgdHVubmVsIGlzXG4gKiAgICAgIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSB0aGUgcHJveHkgc3RpbGwgZ2F0ZXMgbm90aGluZyBhbmQgZm9yd2FyZHMpLlxuICpcbiAqIFN1cGVydmlzaW9uOiB0aGUgYXBwIGNoaWxkLCBwb3J0ciBjaGlsZCwgYW5kIHRoaXMgcHJvY2VzcyBhcmUgdGllZCB0b2dldGhlciAtXG4gKiBpZiBBTlkgZXhpdHMsIGV2ZXJ5dGhpbmcgY29tZXMgZG93biAoY29uY3VycmVudGx5LXN0eWxlIGBraWxsT3RoZXJzYCkuXG4gKlxuICogT3B0aW9ucyBjb21lIGZyb20gZmxhZ3MgT1IgZW52OyBzZWUgdGhlIG9wdGlvbiBkZWZpbml0aW9ucyBiZWxvdy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgdHlwZSBDaGlsZFByb2Nlc3MsIHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgZW52LCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyBzdGFydEdhdGVBcHAgfSBmcm9tIFwiLi9hcHAudHNcIjtcbmltcG9ydCB7IEZPUldBUkRfSEVBREVSU19FTlYsIElOU0VDVVJFX0VOViB9IGZyb20gXCIuL2Vudi50c1wiO1xuaW1wb3J0IHR5cGUgeyBBdXRoR2F0ZUNvbmZpZyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuaW1wb3J0IHsgaW5zdGFsbFBvcnRyLCByZXNvbHZlUG9ydHJDb25maWcsIHN0YXJ0UG9ydHIsIHdyaXRlUG9ydHJDb25maWcgfSBmcm9tIFwiLi9wb3J0ci50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBBIHJhbmRvbSBlcGhlbWVyYWwgcG9ydCBmb3IgdGhlIGFwcCB0byBiaW5kICh0aGUgcHJveHkgZnJvbnRzIHRoZSBwdWJsaWMgb25lKS4gKi9cbmZ1bmN0aW9uIHJhbmRvbVBvcnQoKTogbnVtYmVyIHtcbiAgcmV0dXJuIDIwMDAwICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjAwMDApO1xufVxuXG5pbnRlcmZhY2UgVHVubmVsT3B0cyB7XG4gIHN1YmplY3Q/OiBzdHJpbmc7XG4gIGFsbG93Pzogc3RyaW5nO1xuICBzdWJkb21haW4/OiBzdHJpbmc7XG4gIHB1YmxpY0RvbWFpbj86IHN0cmluZztcbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBzZXNzaW9uVHRsPzogc3RyaW5nO1xuICBjb2RlVHRsPzogc3RyaW5nO1xuICBzZXNzaW9uRXBvY2g/OiBzdHJpbmc7XG4gIGluc2VjdXJlPzogYm9vbGVhbjtcbiAgZm9yd2FyZEhlYWRlcnM/OiBzdHJpbmc7XG59XG5cbi8qKiBCdWlsZCB0aGUgY29tbWFuZGVyIHByb2dyYW0uIGAtLWAgc2VwYXJhdGVzIGZsYWdzIGZyb20gdGhlIGFwcCBzdGFydCBjb21tYW5kLiAqL1xuZnVuY3Rpb24gcHJvZ3JhbSgpOiBDb21tYW5kIHtcbiAgcmV0dXJuIG5ldyBDb21tYW5kKClcbiAgICAubmFtZShcImRieC10b29scy10dW5uZWxcIilcbiAgICAuZGVzY3JpcHRpb24oXCJGcm9udCBhbiBhcHAgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgKyBlbWFpbC1PVFAgZ2F0ZVwiKVxuICAgIC5vcHRpb24oXCItLXN1YmplY3QgPHRleHQ+XCIsIFwiU3ViamVjdCBsaW5lIGZvciB0aGUgY29kZSBlbWFpbCAoZW52IFRVTk5FTF9BVVRIX1NVQkpFQ1QpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1hbGxvdyA8cGF0dGVybnM+XCIsXG4gICAgICBcIkNvbW1hL3NwYWNlLXNlcGFyYXRlZCBhbGxvdy1saXN0OiBkb21haW4gLyBnbG9iIC8gL3JlZ2V4LyAoZW52IFRVTk5FTF9BVVRIX0FMTE9XKVwiLFxuICAgIClcbiAgICAub3B0aW9uKFwiLS1zdWJkb21haW4gPG5hbWU+XCIsIFwicG9ydHIgc3ViZG9tYWluIChlbHNlIGRlcml2ZWQgZnJvbSBUVU5ORUxfUFVCTElDX0RPTUFJTilcIilcbiAgICAub3B0aW9uKFwiLS1wdWJsaWMtZG9tYWluIDxob3N0PlwiLCBcInBvcnRyIDxzdWJkb21haW4+LjxzZXJ2ZXI+IChlbnYgVFVOTkVMX1BVQkxJQ19ET01BSU4pXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1icmFuZC1uYW1lIDxuYW1lPlwiLFxuICAgICAgXCJEaXNwbGF5IG5hbWUgaW4gdGhlIGNvZGUgZW1haWwgY29weSAoZW52IFRVTk5FTF9BVVRIX0JSQU5EX05BTUU7IGRlZmF1bHRzIHRvIHRoZSBicmFuZCBjb250ZXh0IG5hbWUpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXCItLW1lc3NhZ2UgPHRleHQ+XCIsIFwiTGluZSBzaG93biBhYm92ZSB0aGUgY29kZSBpbiB0aGUgZW1haWwgKGVudiBUVU5ORUxfQVVUSF9NRVNTQUdFKVwiKVxuICAgIC5vcHRpb24oXCItLXNlc3Npb24tdHRsIDxzZWNvbmRzPlwiLCBcIlNlc3Npb24gbGlmZXRpbWUgKGVudiBUVU5ORUxfQVVUSF9TRVNTSU9OX1RUTClcIilcbiAgICAub3B0aW9uKFwiLS1jb2RlLXR0bCA8c2Vjb25kcz5cIiwgXCJPbmUtdGltZS1jb2RlIGxpZmV0aW1lIChlbnYgVFVOTkVMX0FVVEhfQ09ERV9UVEwpXCIpXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1zZXNzaW9uLWVwb2NoIDxkYXRlPlwiLFxuICAgICAgXCJJbnZhbGlkYXRlIHNlc3Npb25zIGlzc3VlZCBiZWZvcmUgdGhpcyBkYXRlLCBzaWduaW5nIGV2ZXJ5b25lIG91dDogYSBkYXRlLCBJU08gdGltZXN0YW1wLCBvciBlcG9jaCBzZWNvbmRzIChlbnYgVFVOTkVMX0FVVEhfU0VTU0lPTl9FUE9DSClcIixcbiAgICApXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLS1mb3J3YXJkLWhlYWRlcnMgPHBhdHRlcm5zPlwiLFxuICAgICAgXCJFeHRyYSB4LSByZXF1ZXN0IGhlYWRlcnMgdHVubmVsIHRyYWZmaWMgbWF5IGZvcndhcmQ6IGxpdGVyYWwgLyBnbG9iIC8gL3JlZ2V4LyAoZW52IFRVTk5FTF9GT1JXQVJEX0hFQURFUlMpXCIsXG4gICAgKVxuICAgIC5vcHRpb24oXG4gICAgICBcIi0taW5zZWN1cmVcIixcbiAgICAgIFwiUnVuIHRoZSB0dW5uZWwgT1BFTiB3aXRoIG5vIGdhdGUgKGVudiBUVU5ORUxfSU5TRUNVUkU9dHJ1ZSkuIE90aGVyd2lzZSB0aGUgQ0xJIGZhaWxzIGZhc3Qgd2hlbiBlbWFpbCBTTVRQIGlzIG5vdCBjb25maWd1cmVkLlwiLFxuICAgIClcbiAgICAuYWxsb3dFeGNlc3NBcmd1bWVudHModHJ1ZSlcbiAgICAuaGVscE9wdGlvbihcIi1oLCAtLWhlbHBcIiwgXCJTaG93IGhlbHBcIik7XG59XG5cbi8qKiBUaWUgYSBjaGlsZCdzIGV4aXQgdG8gZnVsbCB0ZWFyZG93bjogYW55IGV4aXQgYnJpbmdzIHRoZSB3aG9sZSB0dW5uZWwgZG93bi4gKi9cbmZ1bmN0aW9uIHN1cGVydmlzZUV4aXQoY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdKTogdm9pZCB7XG4gIGxldCBzaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgY29uc3Qgc2h1dGRvd24gPSAoY29kZTogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgaWYgKHNodXR0aW5nRG93bikgcmV0dXJuO1xuICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIH1cbiAgICAvLyBHaXZlIGNoaWxkcmVuIGEgbW9tZW50LCB0aGVuIGV4aXQgd2l0aCB0aGUgZmlyc3Qgbm9uLXplcm8gY29kZSBzZWVuLlxuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCAzMDAwKS51bnJlZigpO1xuICB9O1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihgY2hpbGQgZXhpdGVkICgke2NvZGUgPz8gXCJzaWduYWxcIn0pOyBicmluZ2luZyB0dW5uZWwgZG93bmApO1xuICAgICAgc2h1dGRvd24oY29kZSA/PyAxKTtcbiAgICB9KTtcbiAgfVxuICBmb3IgKGNvbnN0IHNpZyBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWcsICgpID0+IHNodXRkb3duKDApKTtcbiAgfVxufVxuXG4vKiogUGFyc2UgYXJndiBhbmQgcnVuIHRoZSB0dW5uZWwuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ2xpKGFyZ3Y6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIFNwbGl0IGZsYWdzIGZyb20gdGhlIHdyYXBwZWQgY29tbWFuZCBhdCB0aGUgZmlyc3QgYC0tYC5cbiAgY29uc3Qgc2VwID0gYXJndi5pbmRleE9mKFwiLS1cIik7XG4gIGNvbnN0IGZsYWdzID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKDAsIHNlcCkgOiBhcmd2O1xuICBjb25zdCBjb21tYW5kID0gc2VwID49IDAgPyBhcmd2LnNsaWNlKHNlcCArIDEpIDogW107XG5cbiAgY29uc3QgcHJvZyA9IHByb2dyYW0oKTtcbiAgcHJvZy5wYXJzZShmbGFncyk7XG4gIGNvbnN0IG9wdHMgPSBwcm9nLm9wdHM8VHVubmVsT3B0cz4oKTtcblxuICBpZiAoY29tbWFuZC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgQ29tbWFuZGVyRXJyb3IoMSwgXCJ0dW5uZWwubm8tY29tbWFuZFwiLCBcIm5vIHN0YXJ0IGNvbW1hbmQgZ2l2ZW4gYWZ0ZXIgYC0tYFwiKTtcbiAgfVxuXG4gIGNvbnN0IHB1YmxpY1BvcnQgPSBOdW1iZXIocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19BUFBfUE9SVCA/PyA4MDAwKTtcbiAgY29uc3QgYXBwUG9ydCA9IHJhbmRvbVBvcnQoKTtcblxuICBjb25zdCBnYXRlQ29uZmlnOiBBdXRoR2F0ZUNvbmZpZyA9IHtcbiAgICBhbGxvdzogb3B0cy5hbGxvdyxcbiAgICBzdWJqZWN0OiBvcHRzLnN1YmplY3QsXG4gICAgYnJhbmROYW1lOiBvcHRzLmJyYW5kTmFtZSxcbiAgICBtZXNzYWdlOiBvcHRzLm1lc3NhZ2UsXG4gICAgc2Vzc2lvblR0bFNlY29uZHM6IG9wdHMuc2Vzc2lvblR0bCA/IE51bWJlcihvcHRzLnNlc3Npb25UdGwpIDogdW5kZWZpbmVkLFxuICAgIGNvZGVUdGxTZWNvbmRzOiBvcHRzLmNvZGVUdGwgPyBOdW1iZXIob3B0cy5jb2RlVHRsKSA6IHVuZGVmaW5lZCxcbiAgICBzZXNzaW9uRXBvY2g6IG9wdHMuc2Vzc2lvbkVwb2NoLFxuICB9O1xuXG4gIC8vIDEuIFNwYXduIHRoZSB3cmFwcGVkIGFwcCB3aXRoIHRoZSBQUklWQVRFIHBvcnQuIEl0IGJpbmRzIGxvb3BiYWNrOyBvbmx5IHRoZVxuICAvLyAgICBwcm94eSByZWFjaGVzIGl0LlxuICBsb2dnZXIuaW5mbyhgc3Bhd25pbmcgYXBwIG9uIHByaXZhdGUgcG9ydCAke2FwcFBvcnR9OiAke2NvbW1hbmQuam9pbihcIiBcIil9YCk7XG4gIGNvbnN0IFtjbWQsIC4uLmFyZ3NdID0gY29tbWFuZDtcbiAgY29uc3QgYXBwID0gc3Bhd24oY21kISwgYXJncywge1xuICAgIGVudjogeyAuLi5wcm9jZXNzLmVudiwgREFUQUJSSUNLU19BUFBfUE9SVDogU3RyaW5nKGFwcFBvcnQpLCBIT1NUOiBcIjEyNy4wLjAuMVwiIH0sXG4gICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICB9KTtcblxuICAvLyAyLiBCb290IHRoZSBnYXRlIGFwcCAoY2FjaGUgKyBlbWFpbCB0cmFuc3BvcnQgKyBnYXRlIEFQSSkuIGBzdGFydEdhdGVBcHBgXG4gIC8vICAgIEZBSUxTIEZBU1Qgd2hlbiBlbWFpbCBjYW4ndCBzZW5kIGNvZGVzIChubyBTTVRQKS4gSW5zZWN1cmUgbW9kZVxuICAvLyAgICAoYC0taW5zZWN1cmVgIC8gVFVOTkVMX0lOU0VDVVJFKSBza2lwcyB0aGUgZ2F0ZSBhbmQgcnVucyB0aGUgdHVubmVsIG9wZW4uXG4gIGNvbnN0IGluc2VjdXJlID0gZW52LmJvb2xlYW4ob3B0cy5pbnNlY3VyZSwgSU5TRUNVUkVfRU5WKSA/PyBmYWxzZTtcbiAgbGV0IGdhdGU6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2Ygc3RhcnRHYXRlQXBwPj4gfCB1bmRlZmluZWQ7XG4gIGlmIChpbnNlY3VyZSkge1xuICAgIGxvZ2dlci53YXJuKFwiaW5zZWN1cmUgbW9kZSAtIHR1bm5lbCBydW5zIE9QRU4gd2l0aCBubyBlbWFpbC1PVFAgZ2F0ZVwiKTtcbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgZ2F0ZSA9IGF3YWl0IHN0YXJ0R2F0ZUFwcChnYXRlQ29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gRmFpbCBmYXN0OiBkb24ndCBzaWxlbnRseSBleHBvc2UgYW4gdW5nYXRlZCB0dW5uZWwuIFRoZSBvcGVyYXRvciBtdXN0IGZpeFxuICAgICAgLy8gU01UUCBvciBleHBsaWNpdGx5IG9wdCBpbnRvIGAtLWluc2VjdXJlYC5cbiAgICAgIGxvZ2dlci5lcnJvcihcImNhbm5vdCBzdGFydCB0aGUgT1RQIGdhdGVcIiwgeyBlcnJvcjogKGVycm9yIGFzIEVycm9yKS5tZXNzYWdlIH0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLy8gMy4gU3RhcnQgdGhlIGdhdGUgcHJveHkgb24gdGhlIHB1YmxpYyBwb3J0IChvcGVuIHdoZW4gYGdhdGVgIGlzIHVuZGVmaW5lZCkuXG4gIC8vICAgIGBmb3J3YXJkSGVhZGVyc2Agb25seSBBRERTIHRvIHRoZSBidWlsdC1pbiBhbGxvdy1saXN0OyBzZWUgYC4vaGVhZGVycy50c2AuXG4gIGF3YWl0IHN0YXJ0UHJveHkoe1xuICAgIHB1YmxpY1BvcnQsXG4gICAgYXBwUG9ydCxcbiAgICBnYXRlLFxuICAgIGZvcndhcmRIZWFkZXJzOiBlbnYubGlzdChvcHRzLmZvcndhcmRIZWFkZXJzLCBGT1JXQVJEX0hFQURFUlNfRU5WKSxcbiAgfSk7XG5cbiAgLy8gNC4gSW5zdGFsbCArIHJ1biBwb3J0ciB3aGVuIGEgdHVubmVsIGlzIGNvbmZpZ3VyZWQuXG4gIGNvbnN0IHBvcnRyQ29uZmlnID0gcmVzb2x2ZVBvcnRyQ29uZmlnKHtcbiAgICBwdWJsaWNEb21haW46IG9wdHMucHVibGljRG9tYWluLFxuICAgIHN1YmRvbWFpbjogb3B0cy5zdWJkb21haW4sXG4gICAgcG9ydDogcHVibGljUG9ydCxcbiAgfSk7XG4gIGNvbnN0IGNoaWxkcmVuOiBDaGlsZFByb2Nlc3NbXSA9IFthcHBdO1xuICBpZiAocG9ydHJDb25maWcpIHtcbiAgICBjb25zdCBwb3J0ckVudiA9IGluc3RhbGxQb3J0cigpO1xuICAgIHdyaXRlUG9ydHJDb25maWcocG9ydHJDb25maWcsIHBvcnRyRW52KTtcbiAgICBjaGlsZHJlbi5wdXNoKHN0YXJ0UG9ydHIocG9ydHJDb25maWcsIHBvcnRyRW52KSk7XG4gIH0gZWxzZSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBcIm5vIFBPUlRSX1RPS0VOL1RVTk5FTF9QVUJMSUNfRE9NQUlOIC0gc2VydmluZyB0aGUgZ2F0ZSBwcm94eSB3aXRob3V0IGEgcHVibGljIHR1bm5lbFwiLFxuICAgICk7XG4gIH1cblxuICAvLyBBbnkgY2hpbGQgZXhpdCAob3IgYSBzaWduYWwpIHRlYXJzIHRoZSB3aG9sZSB0aGluZyBkb3duLlxuICBzdXBlcnZpc2VFeGl0KGNoaWxkcmVuKTtcbn1cbiJdfQ==
package/lib/src/env.d.ts CHANGED
@@ -43,6 +43,11 @@ export declare const SESSION_TTL_ENV: EnvKey;
43
43
  export declare const CODE_TTL_ENV: EnvKey;
44
44
  /** HS256 signing secret for the session JWT. */
45
45
  export declare const JWT_SECRET_ENV: EnvKey;
46
+ /**
47
+ * Force-clear date for sessions issued before it: every earlier cookie stops
48
+ * verifying. Any `Date`-parseable value, or bare epoch seconds / millis.
49
+ */
50
+ export declare const SESSION_EPOCH_ENV: EnvKey;
46
51
  /** The public `<subdomain>.<server>` portr should serve on. */
47
52
  export declare const PUBLIC_DOMAIN_ENV: EnvKey;
48
53
  /** Run the tunnel OPEN, with no gate. Ignored unless truthy. */
package/lib/src/env.js CHANGED
@@ -42,10 +42,15 @@ export const SESSION_TTL_ENV = ["TUNNEL_AUTH_SESSION_TTL", "AUTH_SESSION_TTL"];
42
42
  export const CODE_TTL_ENV = ["TUNNEL_AUTH_CODE_TTL", "AUTH_CODE_TTL"];
43
43
  /** HS256 signing secret for the session JWT. */
44
44
  export const JWT_SECRET_ENV = ["TUNNEL_AUTH_JWT_SECRET", "AUTH_JWT_SECRET"];
45
+ /**
46
+ * Force-clear date for sessions issued before it: every earlier cookie stops
47
+ * verifying. Any `Date`-parseable value, or bare epoch seconds / millis.
48
+ */
49
+ export const SESSION_EPOCH_ENV = "TUNNEL_AUTH_SESSION_EPOCH";
45
50
  /** The public `<subdomain>.<server>` portr should serve on. */
46
51
  export const PUBLIC_DOMAIN_ENV = ["TUNNEL_PUBLIC_DOMAIN", "PUBLIC_DOMAIN"];
47
52
  /** Run the tunnel OPEN, with no gate. Ignored unless truthy. */
48
53
  export const INSECURE_ENV = "TUNNEL_INSECURE";
49
54
  /** Extra `x-` request headers tunnel traffic may forward. */
50
55
  export const FORWARD_HEADERS_ENV = "TUNNEL_FORWARD_HEADERS";
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Vudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFJSCw4REFBOEQ7QUFDOUQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFXLENBQUMsbUJBQW1CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUUzRSx1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFXLENBQUMscUJBQXFCLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFFM0UsZ0RBQWdEO0FBQ2hELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBVyxDQUFDLHdCQUF3QixFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFFcEYsMERBQTBEO0FBQzFELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBVyxDQUFDLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBRTNFLG9DQUFvQztBQUNwQyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQVcsQ0FBQyx5QkFBeUIsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0FBRXZGLDBDQUEwQztBQUMxQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUU5RSxnREFBZ0Q7QUFDaEQsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFXLENBQUMsd0JBQXdCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUVwRiwrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUVuRixnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFXLGlCQUFpQixDQUFDO0FBRXRELDZEQUE2RDtBQUM3RCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBVyx3QkFBd0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRW52aXJvbm1lbnQtdmFyaWFibGUgbmFtZXMgdGhlIHR1bm5lbCByZWFkcy5cbiAqXG4gKiBFdmVyeSBzZXR0aW5nIGlzIGBUVU5ORUxfYC1wcmVmaXhlZCwgbWF0Y2hpbmcgdGhlIHJlcG8gY29udmVudGlvbiBvZiBuYW1pbmcgYVxuICogdmFyaWFibGUgYWZ0ZXIgdGhlIHBhY2thZ2UgdGhhdCBvd25zIGl0IChgTUFTVFJBXypgLCBgVEVBTVNfKmAsXG4gKiBgV0VCX1NFQVJDSF8qYCkuIFRoZSBnYXRlJ3Mgb3JpZ2luYWwgbmFtZXMgd2VyZSB1bnByZWZpeGVkIChgQVVUSF9TVUJKRUNUYCxcbiAqIGBQVUJMSUNfRE9NQUlOYCwgLi4uKSwgd2hpY2ggaXMgYSByZWFsIGhhemFyZCBmb3IgYSBwYWNrYWdlIHRoYXQgcnVucyBhcyBhXG4gKiBXUkFQUEVSOiB0aGUgdHVubmVsIGFuZCB0aGUgYXBwIGl0IHdyYXBzIHNoYXJlIG9uZSBlbnZpcm9ubWVudCwgc28gYSBnZW5lcmljXG4gKiBuYW1lIGlzIG9uZSB0aGUgd3JhcHBlZCBhcHAgbWF5IGFscmVhZHkgdXNlIGZvciBzb21ldGhpbmcgZWxzZSwgYW5kXG4gKiBgUFVCTElDX0RPTUFJTmAgaW4gcGFydGljdWxhciByZWFkcyBsaWtlIGFuIGFwcC13aWRlIHNldHRpbmcgcmF0aGVyIHRoYW4gYVxuICogcG9ydHIgZGV0YWlsLiBgRU1BSUxfQVVUSF9BTExPV2Agd2FzIHdvcnNlIHRoYW4gZ2VuZXJpYyAtIGl0IHNhdCBpblxuICogYEBkYngtdG9vbHMvZW1haWxgJ3MgYEVNQUlMXypgIG5hbWVzcGFjZSB3aGlsZSBjb25maWd1cmluZyB0aGUgZ2F0ZSwgbm90IGVtYWlsLlxuICpcbiAqIEVhY2ggZW50cnkgaXMgYW4ge0BsaW5rIEVudktleX0gbGlzdCwgRUFSTElFU1QtV0lOUywgd2hvc2UgZmlyc3QgZWxlbWVudCBpcyB0aGVcbiAqIGN1cnJlbnQgbmFtZSBhbmQgd2hvc2UgcmVtYWluaW5nIGVsZW1lbnRzIGFyZSB0aGUgZGVwcmVjYXRlZCBvcmlnaW5hbHMuIEFcbiAqIGRlcGxveW1lbnQgc2V0IHVwIGFnYWluc3QgdGhlIG9sZCBuYW1lcyBrZWVwcyB3b3JraW5nOyBub3RoaW5nIG5lZWRzIGFcbiAqIGNvb3JkaW5hdGVkIHJlbmFtZS4gUmVhZCB0aGVtIHRocm91Z2ggYGVudi5zdHJpbmdgIC8gYGVudi5wb3NpdGl2ZUludGAgL1xuICogYGVudi5saXN0YCwgd2hpY2ggYWNjZXB0IHRoZSBsaXN0IGRpcmVjdGx5LlxuICpcbiAqIE5vdCByZW5hbWVkOlxuICpcbiAqICAgLSBgREFUQUJSSUNLU19BUFBfUE9SVGAgLSB0aGUgRGF0YWJyaWNrcyBBcHBzIHJ1bnRpbWUgY29udHJhY3QuIFRoZSBwbGF0Zm9ybVxuICogICAgIHNldHMgaXQ7IHRoZSBnYXRlIGhvbm91cnMgaXQuXG4gKiAgIC0gYFBPUlRSX1RPS0VOYCAvIGBQT1JUUl9TRVJWRVJgIC8gYFBPUlRSX0FVVE9fQUREX1BBVEhgIC0gdXBzdHJlYW1cbiAqICAgICBbcG9ydHJdKGh0dHBzOi8vZ2l0aHViLmNvbS9hbWFsc2hhamkvcG9ydHIpJ3Mgb3duIG5hbWVzcGFjZSwgYW5kXG4gKiAgICAgYFBPUlRSX0FVVE9fQUREX1BBVEhgIGlzIHBhc3NlZCBzdHJhaWdodCB0byB0aGF0IGJpbmFyeS4gUmVuYW1pbmcgdGhlc2VcbiAqICAgICB3b3VsZCByZW5hbWUgc29tZW9uZSBlbHNlJ3MgY29udHJhY3QuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRW52S2V5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuLyoqIEFjY2VzcyBhbGxvdy1saXN0IHBhdHRlcm5zIChkb21haW4gLyBnbG9iIC8gYC9yZWdleC9gKS4gKi9cbmV4cG9ydCBjb25zdCBBTExPV19FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0FMTE9XXCIsIFwiRU1BSUxfQVVUSF9BTExPV1wiXTtcblxuLyoqIFN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwuICovXG5leHBvcnQgY29uc3QgU1VCSkVDVF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX1NVQkpFQ1RcIiwgXCJBVVRIX1NVQkpFQ1RcIl07XG5cbi8qKiBEaXNwbGF5IG5hbWUgdXNlZCBpbiB0aGUgY29kZSBlbWFpbCBjb3B5LiAqL1xuZXhwb3J0IGNvbnN0IEJSQU5EX05BTUVfRU5WOiBFbnZLZXkgPSBbXCJUVU5ORUxfQVVUSF9CUkFORF9OQU1FXCIsIFwiQVVUSF9CUkFORF9OQU1FXCJdO1xuXG4vKiogTGluZSBzaG93biBpbW1lZGlhdGVseSBhYm92ZSB0aGUgY29kZSBpbiB0aGUgZW1haWwuICovXG5leHBvcnQgY29uc3QgTUVTU0FHRV9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX01FU1NBR0VcIiwgXCJBVVRIX01FU1NBR0VcIl07XG5cbi8qKiBTZXNzaW9uIGxpZmV0aW1lLCBpbiBzZWNvbmRzLiAqL1xuZXhwb3J0IGNvbnN0IFNFU1NJT05fVFRMX0VOVjogRW52S2V5ID0gW1wiVFVOTkVMX0FVVEhfU0VTU0lPTl9UVExcIiwgXCJBVVRIX1NFU1NJT05fVFRMXCJdO1xuXG4vKiogT25lLXRpbWUtY29kZSBsaWZldGltZSwgaW4gc2Vjb25kcy4gKi9cbmV4cG9ydCBjb25zdCBDT0RFX1RUTF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0NPREVfVFRMXCIsIFwiQVVUSF9DT0RFX1RUTFwiXTtcblxuLyoqIEhTMjU2IHNpZ25pbmcgc2VjcmV0IGZvciB0aGUgc2Vzc2lvbiBKV1QuICovXG5leHBvcnQgY29uc3QgSldUX1NFQ1JFVF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0pXVF9TRUNSRVRcIiwgXCJBVVRIX0pXVF9TRUNSRVRcIl07XG5cbi8qKiBUaGUgcHVibGljIGA8c3ViZG9tYWluPi48c2VydmVyPmAgcG9ydHIgc2hvdWxkIHNlcnZlIG9uLiAqL1xuZXhwb3J0IGNvbnN0IFBVQkxJQ19ET01BSU5fRU5WOiBFbnZLZXkgPSBbXCJUVU5ORUxfUFVCTElDX0RPTUFJTlwiLCBcIlBVQkxJQ19ET01BSU5cIl07XG5cbi8qKiBSdW4gdGhlIHR1bm5lbCBPUEVOLCB3aXRoIG5vIGdhdGUuIElnbm9yZWQgdW5sZXNzIHRydXRoeS4gKi9cbmV4cG9ydCBjb25zdCBJTlNFQ1VSRV9FTlY6IEVudktleSA9IFwiVFVOTkVMX0lOU0VDVVJFXCI7XG5cbi8qKiBFeHRyYSBgeC1gIHJlcXVlc3QgaGVhZGVycyB0dW5uZWwgdHJhZmZpYyBtYXkgZm9yd2FyZC4gKi9cbmV4cG9ydCBjb25zdCBGT1JXQVJEX0hFQURFUlNfRU5WOiBFbnZLZXkgPSBcIlRVTk5FTF9GT1JXQVJEX0hFQURFUlNcIjtcbiJdfQ==
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Vudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFJSCw4REFBOEQ7QUFDOUQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFXLENBQUMsbUJBQW1CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUUzRSx1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFXLENBQUMscUJBQXFCLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFFM0UsZ0RBQWdEO0FBQ2hELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBVyxDQUFDLHdCQUF3QixFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFFcEYsMERBQTBEO0FBQzFELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBVyxDQUFDLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBRTNFLG9DQUFvQztBQUNwQyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQVcsQ0FBQyx5QkFBeUIsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0FBRXZGLDBDQUEwQztBQUMxQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUU5RSxnREFBZ0Q7QUFDaEQsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFXLENBQUMsd0JBQXdCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUVwRjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBVywyQkFBMkIsQ0FBQztBQUVyRSwrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUVuRixnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFXLGlCQUFpQixDQUFDO0FBRXRELDZEQUE2RDtBQUM3RCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBVyx3QkFBd0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRW52aXJvbm1lbnQtdmFyaWFibGUgbmFtZXMgdGhlIHR1bm5lbCByZWFkcy5cbiAqXG4gKiBFdmVyeSBzZXR0aW5nIGlzIGBUVU5ORUxfYC1wcmVmaXhlZCwgbWF0Y2hpbmcgdGhlIHJlcG8gY29udmVudGlvbiBvZiBuYW1pbmcgYVxuICogdmFyaWFibGUgYWZ0ZXIgdGhlIHBhY2thZ2UgdGhhdCBvd25zIGl0IChgTUFTVFJBXypgLCBgVEVBTVNfKmAsXG4gKiBgV0VCX1NFQVJDSF8qYCkuIFRoZSBnYXRlJ3Mgb3JpZ2luYWwgbmFtZXMgd2VyZSB1bnByZWZpeGVkIChgQVVUSF9TVUJKRUNUYCxcbiAqIGBQVUJMSUNfRE9NQUlOYCwgLi4uKSwgd2hpY2ggaXMgYSByZWFsIGhhemFyZCBmb3IgYSBwYWNrYWdlIHRoYXQgcnVucyBhcyBhXG4gKiBXUkFQUEVSOiB0aGUgdHVubmVsIGFuZCB0aGUgYXBwIGl0IHdyYXBzIHNoYXJlIG9uZSBlbnZpcm9ubWVudCwgc28gYSBnZW5lcmljXG4gKiBuYW1lIGlzIG9uZSB0aGUgd3JhcHBlZCBhcHAgbWF5IGFscmVhZHkgdXNlIGZvciBzb21ldGhpbmcgZWxzZSwgYW5kXG4gKiBgUFVCTElDX0RPTUFJTmAgaW4gcGFydGljdWxhciByZWFkcyBsaWtlIGFuIGFwcC13aWRlIHNldHRpbmcgcmF0aGVyIHRoYW4gYVxuICogcG9ydHIgZGV0YWlsLiBgRU1BSUxfQVVUSF9BTExPV2Agd2FzIHdvcnNlIHRoYW4gZ2VuZXJpYyAtIGl0IHNhdCBpblxuICogYEBkYngtdG9vbHMvZW1haWxgJ3MgYEVNQUlMXypgIG5hbWVzcGFjZSB3aGlsZSBjb25maWd1cmluZyB0aGUgZ2F0ZSwgbm90IGVtYWlsLlxuICpcbiAqIEVhY2ggZW50cnkgaXMgYW4ge0BsaW5rIEVudktleX0gbGlzdCwgRUFSTElFU1QtV0lOUywgd2hvc2UgZmlyc3QgZWxlbWVudCBpcyB0aGVcbiAqIGN1cnJlbnQgbmFtZSBhbmQgd2hvc2UgcmVtYWluaW5nIGVsZW1lbnRzIGFyZSB0aGUgZGVwcmVjYXRlZCBvcmlnaW5hbHMuIEFcbiAqIGRlcGxveW1lbnQgc2V0IHVwIGFnYWluc3QgdGhlIG9sZCBuYW1lcyBrZWVwcyB3b3JraW5nOyBub3RoaW5nIG5lZWRzIGFcbiAqIGNvb3JkaW5hdGVkIHJlbmFtZS4gUmVhZCB0aGVtIHRocm91Z2ggYGVudi5zdHJpbmdgIC8gYGVudi5wb3NpdGl2ZUludGAgL1xuICogYGVudi5saXN0YCwgd2hpY2ggYWNjZXB0IHRoZSBsaXN0IGRpcmVjdGx5LlxuICpcbiAqIE5vdCByZW5hbWVkOlxuICpcbiAqICAgLSBgREFUQUJSSUNLU19BUFBfUE9SVGAgLSB0aGUgRGF0YWJyaWNrcyBBcHBzIHJ1bnRpbWUgY29udHJhY3QuIFRoZSBwbGF0Zm9ybVxuICogICAgIHNldHMgaXQ7IHRoZSBnYXRlIGhvbm91cnMgaXQuXG4gKiAgIC0gYFBPUlRSX1RPS0VOYCAvIGBQT1JUUl9TRVJWRVJgIC8gYFBPUlRSX0FVVE9fQUREX1BBVEhgIC0gdXBzdHJlYW1cbiAqICAgICBbcG9ydHJdKGh0dHBzOi8vZ2l0aHViLmNvbS9hbWFsc2hhamkvcG9ydHIpJ3Mgb3duIG5hbWVzcGFjZSwgYW5kXG4gKiAgICAgYFBPUlRSX0FVVE9fQUREX1BBVEhgIGlzIHBhc3NlZCBzdHJhaWdodCB0byB0aGF0IGJpbmFyeS4gUmVuYW1pbmcgdGhlc2VcbiAqICAgICB3b3VsZCByZW5hbWUgc29tZW9uZSBlbHNlJ3MgY29udHJhY3QuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgRW52S2V5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuLyoqIEFjY2VzcyBhbGxvdy1saXN0IHBhdHRlcm5zIChkb21haW4gLyBnbG9iIC8gYC9yZWdleC9gKS4gKi9cbmV4cG9ydCBjb25zdCBBTExPV19FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0FMTE9XXCIsIFwiRU1BSUxfQVVUSF9BTExPV1wiXTtcblxuLyoqIFN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwuICovXG5leHBvcnQgY29uc3QgU1VCSkVDVF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX1NVQkpFQ1RcIiwgXCJBVVRIX1NVQkpFQ1RcIl07XG5cbi8qKiBEaXNwbGF5IG5hbWUgdXNlZCBpbiB0aGUgY29kZSBlbWFpbCBjb3B5LiAqL1xuZXhwb3J0IGNvbnN0IEJSQU5EX05BTUVfRU5WOiBFbnZLZXkgPSBbXCJUVU5ORUxfQVVUSF9CUkFORF9OQU1FXCIsIFwiQVVUSF9CUkFORF9OQU1FXCJdO1xuXG4vKiogTGluZSBzaG93biBpbW1lZGlhdGVseSBhYm92ZSB0aGUgY29kZSBpbiB0aGUgZW1haWwuICovXG5leHBvcnQgY29uc3QgTUVTU0FHRV9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX01FU1NBR0VcIiwgXCJBVVRIX01FU1NBR0VcIl07XG5cbi8qKiBTZXNzaW9uIGxpZmV0aW1lLCBpbiBzZWNvbmRzLiAqL1xuZXhwb3J0IGNvbnN0IFNFU1NJT05fVFRMX0VOVjogRW52S2V5ID0gW1wiVFVOTkVMX0FVVEhfU0VTU0lPTl9UVExcIiwgXCJBVVRIX1NFU1NJT05fVFRMXCJdO1xuXG4vKiogT25lLXRpbWUtY29kZSBsaWZldGltZSwgaW4gc2Vjb25kcy4gKi9cbmV4cG9ydCBjb25zdCBDT0RFX1RUTF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0NPREVfVFRMXCIsIFwiQVVUSF9DT0RFX1RUTFwiXTtcblxuLyoqIEhTMjU2IHNpZ25pbmcgc2VjcmV0IGZvciB0aGUgc2Vzc2lvbiBKV1QuICovXG5leHBvcnQgY29uc3QgSldUX1NFQ1JFVF9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9BVVRIX0pXVF9TRUNSRVRcIiwgXCJBVVRIX0pXVF9TRUNSRVRcIl07XG5cbi8qKlxuICogRm9yY2UtY2xlYXIgZGF0ZSBmb3Igc2Vzc2lvbnMgaXNzdWVkIGJlZm9yZSBpdDogZXZlcnkgZWFybGllciBjb29raWUgc3RvcHNcbiAqIHZlcmlmeWluZy4gQW55IGBEYXRlYC1wYXJzZWFibGUgdmFsdWUsIG9yIGJhcmUgZXBvY2ggc2Vjb25kcyAvIG1pbGxpcy5cbiAqL1xuZXhwb3J0IGNvbnN0IFNFU1NJT05fRVBPQ0hfRU5WOiBFbnZLZXkgPSBcIlRVTk5FTF9BVVRIX1NFU1NJT05fRVBPQ0hcIjtcblxuLyoqIFRoZSBwdWJsaWMgYDxzdWJkb21haW4+LjxzZXJ2ZXI+YCBwb3J0ciBzaG91bGQgc2VydmUgb24uICovXG5leHBvcnQgY29uc3QgUFVCTElDX0RPTUFJTl9FTlY6IEVudktleSA9IFtcIlRVTk5FTF9QVUJMSUNfRE9NQUlOXCIsIFwiUFVCTElDX0RPTUFJTlwiXTtcblxuLyoqIFJ1biB0aGUgdHVubmVsIE9QRU4sIHdpdGggbm8gZ2F0ZS4gSWdub3JlZCB1bmxlc3MgdHJ1dGh5LiAqL1xuZXhwb3J0IGNvbnN0IElOU0VDVVJFX0VOVjogRW52S2V5ID0gXCJUVU5ORUxfSU5TRUNVUkVcIjtcblxuLyoqIEV4dHJhIGB4LWAgcmVxdWVzdCBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkLiAqL1xuZXhwb3J0IGNvbnN0IEZPUldBUkRfSEVBREVSU19FTlY6IEVudktleSA9IFwiVFVOTkVMX0ZPUldBUkRfSEVBREVSU1wiO1xuIl19
package/lib/src/otp.d.ts CHANGED
@@ -8,14 +8,12 @@
8
8
  * counter (never the plaintext, never in the JWT); `verify` is constant-time on
9
9
  * the hash, and the entry is deleted on success or once attempts are exhausted.
10
10
  *
11
- * The session JWT is a short-lived HS256 token (via `jose`) carrying only the
12
- * email. Its signing key comes from `TUNNEL_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.
11
+ * The session JWT is an HS256 token (via `jose`) carrying only the email. Its
12
+ * signing key is resolved by `./signing-key.ts`: `TUNNEL_AUTH_JWT_SECRET` when
13
+ * set, else a key persisted in the cache for 30 days so cookies survive the
14
+ * restarts a tunnel sees whenever the app it wraps reloads. A cookie signed
15
+ * before `TUNNEL_AUTH_SESSION_EPOCH` is refused here as well as being orphaned by
16
+ * the cache key, so the force-clear switch holds even for a still-current key.
19
17
  *
20
18
  * @module
21
19
  */
@@ -45,9 +43,7 @@ export declare class CodeStore {
45
43
  */
46
44
  verify(email: string, code: string): Promise<VerifyOutcome>;
47
45
  }
48
- /** Reset the memoized key (tests, or after changing the env in-process). */
49
- export declare function resetSigningKey(): void;
50
- /** Mint a short-lived session JWT for `email`, expiring in `ttlSeconds`. */
46
+ /** Mint a session JWT for `email`, expiring in `ttlSeconds`. */
51
47
  export declare function signSession(email: string, ttlSeconds: number): Promise<string>;
52
48
  /** Validate a session JWT, returning the email it was minted for, or `undefined`. */
53
49
  export declare function verifySession(token: string | undefined): Promise<string | undefined>;
package/lib/src/otp.js CHANGED
@@ -8,23 +8,19 @@
8
8
  * counter (never the plaintext, never in the JWT); `verify` is constant-time on
9
9
  * the hash, and the entry is deleted on success or once attempts are exhausted.
10
10
  *
11
- * The session JWT is a short-lived HS256 token (via `jose`) carrying only the
12
- * email. Its signing key comes from `TUNNEL_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.
11
+ * The session JWT is an HS256 token (via `jose`) carrying only the email. Its
12
+ * signing key is resolved by `./signing-key.ts`: `TUNNEL_AUTH_JWT_SECRET` when
13
+ * set, else a key persisted in the cache for 30 days so cookies survive the
14
+ * restarts a tunnel sees whenever the app it wraps reloads. A cookie signed
15
+ * before `TUNNEL_AUTH_SESSION_EPOCH` is refused here as well as being orphaned by
16
+ * the cache key, so the force-clear switch holds even for a still-current key.
19
17
  *
20
18
  * @module
21
19
  */
22
- import { createHash, randomBytes, randomInt, timingSafeEqual } from "node:crypto";
20
+ import { createHash, randomInt, timingSafeEqual } from "node:crypto";
23
21
  import { CacheManager } from "@databricks/appkit";
24
- import { env, log } from "@dbx-tools/shared-core";
25
22
  import { jwtVerify, SignJWT } from "jose";
26
- import { JWT_SECRET_ENV } from "./env.js";
27
- const logger = log.logger("tunnel:otp");
23
+ import { signingKey } from "./signing-key.js";
28
24
  /** JWT issuer/audience so a token minted for this gate isn't accepted elsewhere. */
29
25
  const JWT_AUD = "dbx-tools-tunnel-auth";
30
26
  /** Cache-key prefix for pending codes, namespaced away from any other cache use. */
@@ -91,48 +87,38 @@ export class CodeStore {
91
87
  return "invalid";
92
88
  }
93
89
  }
94
- /**
95
- * Resolve the HS256 signing key. Prefers `TUNNEL_AUTH_JWT_SECRET`; when unset, mints an
96
- * ephemeral per-process key (fail-open) and warns once. Memoized.
97
- */
98
- let cachedKey;
99
- function signingKey() {
100
- if (cachedKey)
101
- return cachedKey;
102
- const secret = env.text(JWT_SECRET_ENV);
103
- if (secret) {
104
- cachedKey = new TextEncoder().encode(secret);
105
- }
106
- else {
107
- logger.warn(`${JWT_SECRET_ENV[0]} is not set - using an ephemeral per-process key; sessions will not survive a restart`);
108
- cachedKey = randomBytes(32);
109
- }
110
- return cachedKey;
111
- }
112
- /** Reset the memoized key (tests, or after changing the env in-process). */
113
- export function resetSigningKey() {
114
- cachedKey = undefined;
115
- }
116
- /** Mint a short-lived session JWT for `email`, expiring in `ttlSeconds`. */
90
+ /** Mint a session JWT for `email`, expiring in `ttlSeconds`. */
117
91
  export async function signSession(email, ttlSeconds) {
92
+ const { key } = await signingKey();
118
93
  return new SignJWT({ email })
119
94
  .setProtectedHeader({ alg: "HS256" })
120
95
  .setSubject(email)
121
96
  .setAudience(JWT_AUD)
122
97
  .setIssuedAt()
123
98
  .setExpirationTime(`${ttlSeconds}s`)
124
- .sign(signingKey());
99
+ .sign(key);
125
100
  }
126
101
  /** Validate a session JWT, returning the email it was minted for, or `undefined`. */
127
102
  export async function verifySession(token) {
128
103
  if (!token)
129
104
  return undefined;
130
105
  try {
131
- const { payload } = await jwtVerify(token, signingKey(), { audience: JWT_AUD });
106
+ const { key, epochMs } = await signingKey();
107
+ const { payload } = await jwtVerify(token, key, { audience: JWT_AUD });
108
+ // Belt and braces with the epoch-scoped cache key: that alone already
109
+ // orphans older keys, but an operator who moved the epoch while
110
+ // TUNNEL_AUTH_JWT_SECRET is set has no key rotation to rely on, and this
111
+ // check is what makes the switch work in that case too.
112
+ // Compared in whole SECONDS because `iat` has no finer resolution: against a
113
+ // millisecond epoch, a cookie minted in the same second as the cutoff would
114
+ // be refused depending on sub-second rounding.
115
+ if (epochMs > 0 && (payload.iat === undefined || payload.iat < Math.floor(epochMs / 1000))) {
116
+ return undefined;
117
+ }
132
118
  return typeof payload.email === "string" ? payload.email : undefined;
133
119
  }
134
120
  catch {
135
121
  return undefined;
136
122
  }
137
123
  }
138
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL290cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFMUMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUV4QyxvRkFBb0Y7QUFDcEYsTUFBTSxPQUFPLEdBQUcsdUJBQXVCLENBQUM7QUFFeEMsb0ZBQW9GO0FBQ3BGLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUVsQyw4QkFBOEI7QUFDOUIsU0FBUyxNQUFNLENBQUMsS0FBYTtJQUMzQixPQUFPLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsU0FBUyxZQUFZLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDeEMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxNQUFNO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDeEMsT0FBTyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztB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Q0FBQztJQUM5QixDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSxNQUFNLFVBQVUsZUFBZTtJQUM3QixTQUFTLEdBQUcsU0FBUyxDQUFDO0FBQ3hCLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBYSxFQUFFLFVBQWtCO0lBQ2pFLE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQztTQUMxQixrQkFBa0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQztTQUNwQyxVQUFVLENBQUMsS0FBSyxDQUFDO1NBQ2pCLFdBQVcsQ0FBQyxPQUFPLENBQUM7U0FDcEIsV0FBVyxFQUFFO1NBQ2IsaUJBQWlCLENBQUMsR0FBRyxVQUFVLEdBQUcsQ0FBQztTQUNuQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztBQUN4QixDQUFDO0FBRUQscUZBQXFGO0FBQ3JGLE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLEtBQXlCO0lBQzNELElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDN0IsSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3ZFLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT25lLXRpbWUtY29kZSBzdG9yZSArIHNlc3Npb24gSldUIGZvciB0aGUgZW1haWwtT1RQIHR1bm5lbCBnYXRlLlxuICpcbiAqIFRoZSBjb2RlIHN0b3JlIGlzIGJhY2tlZCBieSBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYCAoYXV0by1jb25maWd1cmVkIHRvIG1lbW9yeSxcbiAqIG9yIExha2ViYXNlIHdoZW4gdGhlIGFwcCB3aXJlcyBhIHBlcnNpc3RlbnQgYENhY2hlU3RvcmFnZWApLCBzbyBUVEwgRVhQSVJZIGFuZFxuICogZXZpY3Rpb24gYXJlIHRoZSBjYWNoZSdzIGpvYiAtIG5vIGhhbmQtcm9sbGVkIE1hcCBvciB0aW1lcnMuIEEgNi1kaWdpdCBjb2RlIGlzXG4gKiBnZW5lcmF0ZWQgd2l0aCBgY3J5cHRvLnJhbmRvbUludGAgYW5kIHN0b3JlZCBhcyBhIFNIQS0yNTYgaGFzaCB3aXRoIGFuIGF0dGVtcHRcbiAqIGNvdW50ZXIgKG5ldmVyIHRoZSBwbGFpbnRleHQsIG5ldmVyIGluIHRoZSBKV1QpOyBgdmVyaWZ5YCBpcyBjb25zdGFudC10aW1lIG9uXG4gKiB0aGUgaGFzaCwgYW5kIHRoZSBlbnRyeSBpcyBkZWxldGVkIG9uIHN1Y2Nlc3Mgb3Igb25jZSBhdHRlbXB0cyBhcmUgZXhoYXVzdGVkLlxuICpcbiAqIFRoZSBzZXNzaW9uIEpXVCBpcyBhIHNob3J0LWxpdmVkIEhTMjU2IHRva2VuICh2aWEgYGpvc2VgKSBjYXJyeWluZyBvbmx5IHRoZVxuICogZW1haWwuIEl0cyBzaWduaW5nIGtleSBjb21lcyBmcm9tIGBUVU5ORUxfQVVUSF9KV1RfU0VDUkVUYDsgd2hlbiB1bnNldCB0aGUgZ2F0ZSB1c2VzIGFuXG4gKiBlcGhlbWVyYWwgcGVyLXByb2Nlc3Mga2V5IHJhdGhlciB0aGFuIHJlZnVzaW5nIHNlcnZpY2UsIHNvIGFuIHVuc2V0IHNlY3JldFxuICogZGVncmFkZXMgdG8gXCJzZXNzaW9ucyBkb24ndCBzdXJ2aXZlIGEgcmVzdGFydFwiLCBub3QgXCJub2JvZHkgY2FuIGxvZyBpblwiLiBOb3RlXG4gKiB3aGF0IHRoaXMgZG9lcyBOT1Qgd2Vha2VuOiBhIGNhbGxlciBzdGlsbCBuZWVkcyBhIGNvZGUgZGVsaXZlcmVkIHRvIGFuXG4gKiBhbGxvdy1saXN0ZWQgYWRkcmVzcywgYmVjYXVzZSB0aGUgc2lnbmluZyBrZXkgb25seSB2YWxpZGF0ZXMgYW4gQUxSRUFEWS1pc3N1ZWRcbiAqIHNlc3Npb24uIFNldCBpdCBpbiBhbnkgZGVwbG95bWVudCBydW5uaW5nIG1vcmUgdGhhbiBvbmUgaW5zdGFuY2UsIG9yIHNlc3Npb25zXG4gKiBtaW50ZWQgYnkgb25lIHdpbGwgbm90IHZlcmlmeSBvbiBhbm90aGVyLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoLCByYW5kb21CeXRlcywgcmFuZG9tSW50LCB0aW1pbmdTYWZlRXF1YWwgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IENhY2hlTWFuYWdlciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGVudiwgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGp3dFZlcmlmeSwgU2lnbkpXVCB9IGZyb20gXCJqb3NlXCI7XG5pbXBvcnQgeyBKV1RfU0VDUkVUX0VOViB9IGZyb20gXCIuL2Vudi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsOm90cFwiKTtcblxuLyoqIEpXVCBpc3N1ZXIvYXVkaWVuY2Ugc28gYSB0b2tlbiBtaW50ZWQgZm9yIHRoaXMgZ2F0ZSBpc24ndCBhY2NlcHRlZCBlbHNld2hlcmUuICovXG5jb25zdCBKV1RfQVVEID0gXCJkYngtdG9vbHMtdHVubmVsLWF1dGhcIjtcblxuLyoqIENhY2hlLWtleSBwcmVmaXggZm9yIHBlbmRpbmcgY29kZXMsIG5hbWVzcGFjZWQgYXdheSBmcm9tIGFueSBvdGhlciBjYWNoZSB1c2UuICovXG5jb25zdCBDT0RFX1BSRUZJWCA9IFwidHVubmVsOm90cDpcIjtcblxuLyoqIFNIQS0yNTYgaGV4IG9mIGEgdmFsdWUuICovXG5mdW5jdGlvbiBzaGEyNTYodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZSh2YWx1ZSkuZGlnZXN0KFwiaGV4XCIpO1xufVxuXG4vKiogQ29uc3RhbnQtdGltZSBjb21wYXJlIG9mIHR3byBlcXVhbC1sZW5ndGggaGV4IGRpZ2VzdHMuICovXG5mdW5jdGlvbiBzYWZlRXF1YWxIZXgoYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdGltaW5nU2FmZUVxdWFsKEJ1ZmZlci5mcm9tKGEsIFwiaGV4XCIpLCBCdWZmZXIuZnJvbShiLCBcImhleFwiKSk7XG59XG5cbmludGVyZmFjZSBDb2RlRW50cnkge1xuICBoYXNoOiBzdHJpbmc7XG4gIGF0dGVtcHRzOiBudW1iZXI7XG59XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIENvZGVTdG9yZS52ZXJpZnl9LiAqL1xuZXhwb3J0IHR5cGUgVmVyaWZ5T3V0Y29tZSA9IFwib2tcIiB8IFwiaW52YWxpZFwiIHwgXCJleHBpcmVkXCIgfCBcInRvby1tYW55LWF0dGVtcHRzXCI7XG5cbi8qKlxuICogUGVuZGluZyBvbmUtdGltZSBjb2Rlcywgc3RvcmVkIGluIEFwcEtpdCdzIGNhY2hlIGtleWVkIGJ5IGxvd2VyY2FzZWQgZW1haWwuXG4gKiBFeHBpcnkgaXMgdGhlIGNhY2hlJ3MgVFRMIChubyBtYW51YWwgY2xvY2spOyBhIG1pc3MgbWVhbnMgZXhwaXJlZC1vci1uZXZlci5cbiAqL1xuZXhwb3J0IGNsYXNzIENvZGVTdG9yZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdHRsU2Vjb25kczogbnVtYmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF4QXR0ZW1wdHM6IG51bWJlcixcbiAgKSB7fVxuXG4gIHByaXZhdGUgY2FjaGUoKTogQ2FjaGVNYW5hZ2VyIHtcbiAgICByZXR1cm4gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpO1xuICB9XG5cbiAgcHJpdmF0ZSBrZXkoZW1haWw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke0NPREVfUFJFRklYfSR7ZW1haWwudG9Mb3dlckNhc2UoKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlLCBzdG9yZSAoaGFzaGVkLCB3aXRoIHRoZSBjYWNoZSBUVEwpLCBhbmQgUkVUVVJOIGEgZnJlc2ggNi1kaWdpdFxuICAgKiBjb2RlLiBUaGUgY2FsbGVyIGVtYWlscyB0aGUgcmV0dXJuZWQgcGxhaW50ZXh0OyBvbmx5IHRoZSBoYXNoIGlzIHJldGFpbmVkLlxuICAgKiBSZXBsYWNlcyBhbnkgcGVuZGluZyBjb2RlIGZvciB0aGUgYWRkcmVzcy5cbiAgICovXG4gIGFzeW5jIGlzc3VlKGVtYWlsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGNvZGUgPSBTdHJpbmcocmFuZG9tSW50KDAsIDFfMDAwXzAwMCkpLnBhZFN0YXJ0KDYsIFwiMFwiKTtcbiAgICBjb25zdCBlbnRyeTogQ29kZUVudHJ5ID0geyBoYXNoOiBzaGEyNTYoY29kZSksIGF0dGVtcHRzOiAwIH07XG4gICAgYXdhaXQgdGhpcy5jYWNoZSgpLnNldCh0aGlzLmtleShlbWFpbCksIGVudHJ5LCB7IHR0bDogdGhpcy50dGxTZWNvbmRzIH0pO1xuICAgIHJldHVybiBjb2RlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGBjb2RlYCBmb3IgYGVtYWlsYC4gQSBjYWNoZSBtaXNzIGlzIGBleHBpcmVkYCAoVFRMIGVsYXBzZWQgb3IgbmV2ZXJcbiAgICogaXNzdWVkKS4gRGVsZXRlcyB0aGUgZW50cnkgb24gc3VjY2VzcyBvciB3aGVuIGF0dGVtcHRzIGFyZSBleGhhdXN0ZWQsIHNvIGFcbiAgICogY29kZSBpcyBzaW5nbGUtdXNlIGFuZCBjYW4ndCBiZSBicnV0ZS1mb3JjZWQgcGFzdCB0aGUgY2FwLiBBbiBhdHRlbXB0XG4gICAqIGluY3JlbWVudHMgdGhlIHN0b3JlZCBjb3VudGVyIChyZS1wZXJzaXN0ZWQgd2l0aCBhIGZyZXNoIFRUTCB3aW5kb3cpLlxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5KGVtYWlsOiBzdHJpbmcsIGNvZGU6IHN0cmluZyk6IFByb21pc2U8VmVyaWZ5T3V0Y29tZT4ge1xuICAgIGNvbnN0IGtleSA9IHRoaXMua2V5KGVtYWlsKTtcbiAgICBjb25zdCBlbnRyeSA9IGF3YWl0IHRoaXMuY2FjaGUoKS5nZXQ8Q29kZUVudHJ5PihrZXkpO1xuICAgIGlmICghZW50cnkpIHJldHVybiBcImV4cGlyZWRcIjtcbiAgICBjb25zdCBhdHRlbXB0cyA9IGVudHJ5LmF0dGVtcHRzICsgMTtcbiAgICBpZiAoc2FmZUVxdWFsSGV4KGVudHJ5Lmhhc2gsIHNoYTI1Nihjb2RlKSkpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2FjaGUoKS5kZWxldGUoa2V5KTtcbiAgICAgIHJldHVybiBcIm9rXCI7XG4gICAgfVxuICAgIGlmIChhdHRlbXB0cyA+PSB0aGlzLm1heEF0dGVtcHRzKSB7XG4gICAgICBhd2FpdCB0aGlzLmNhY2hlKCkuZGVsZXRlKGtleSk7XG4gICAgICByZXR1cm4gXCJ0b28tbWFueS1hdHRlbXB0c1wiO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLmNhY2hlKCkuc2V0KGtleSwgeyAuLi5lbnRyeSwgYXR0ZW1wdHMgfSwgeyB0dGw6IHRoaXMudHRsU2Vjb25kcyB9KTtcbiAgICByZXR1cm4gXCJpbnZhbGlkXCI7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBIUzI1NiBzaWduaW5nIGtleS4gUHJlZmVycyBgVFVOTkVMX0FVVEhfSldUX1NFQ1JFVGA7IHdoZW4gdW5zZXQsIG1pbnRzIGFuXG4gKiBlcGhlbWVyYWwgcGVyLXByb2Nlc3Mga2V5IChmYWlsLW9wZW4pIGFuZCB3YXJucyBvbmNlLiBNZW1vaXplZC5cbiAqL1xubGV0IGNhY2hlZEtleTogVWludDhBcnJheSB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIHNpZ25pbmdLZXkoKTogVWludDhBcnJheSB7XG4gIGlmIChjYWNoZWRLZXkpIHJldHVybiBjYWNoZWRLZXk7XG4gIGNvbnN0IHNlY3JldCA9IGVudi50ZXh0KEpXVF9TRUNSRVRfRU5WKTtcbiAgaWYgKHNlY3JldCkge1xuICAgIGNhY2hlZEtleSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWNyZXQpO1xuICB9IGVsc2Uge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgYCR7SldUX1NFQ1JFVF9FTlZbMF19IGlzIG5vdCBzZXQgLSB1c2luZyBhbiBlcGhlbWVyYWwgcGVyLXByb2Nlc3Mga2V5OyBzZXNzaW9ucyB3aWxsIG5vdCBzdXJ2aXZlIGEgcmVzdGFydGAsXG4gICAgKTtcbiAgICBjYWNoZWRLZXkgPSByYW5kb21CeXRlcygzMik7XG4gIH1cbiAgcmV0dXJuIGNhY2hlZEtleTtcbn1cblxuLyoqIFJlc2V0IHRoZSBtZW1vaXplZCBrZXkgKHRlc3RzLCBvciBhZnRlciBjaGFuZ2luZyB0aGUgZW52IGluLXByb2Nlc3MpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0U2lnbmluZ0tleSgpOiB2b2lkIHtcbiAgY2FjaGVkS2V5ID0gdW5kZWZpbmVkO1xufVxuXG4vKiogTWludCBhIHNob3J0LWxpdmVkIHNlc3Npb24gSldUIGZvciBgZW1haWxgLCBleHBpcmluZyBpbiBgdHRsU2Vjb25kc2AuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2lnblNlc3Npb24oZW1haWw6IHN0cmluZywgdHRsU2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBTaWduSldUKHsgZW1haWwgfSlcbiAgICAuc2V0UHJvdGVjdGVkSGVhZGVyKHsgYWxnOiBcIkhTMjU2XCIgfSlcbiAgICAuc2V0U3ViamVjdChlbWFpbClcbiAgICAuc2V0QXVkaWVuY2UoSldUX0FVRClcbiAgICAuc2V0SXNzdWVkQXQoKVxuICAgIC5zZXRFeHBpcmF0aW9uVGltZShgJHt0dGxTZWNvbmRzfXNgKVxuICAgIC5zaWduKHNpZ25pbmdLZXkoKSk7XG59XG5cbi8qKiBWYWxpZGF0ZSBhIHNlc3Npb24gSldULCByZXR1cm5pbmcgdGhlIGVtYWlsIGl0IHdhcyBtaW50ZWQgZm9yLCBvciBgdW5kZWZpbmVkYC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2ZXJpZnlTZXNzaW9uKHRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIXRva2VuKSByZXR1cm4gdW5kZWZpbmVkO1xuICB0cnkge1xuICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgand0VmVyaWZ5KHRva2VuLCBzaWduaW5nS2V5KCksIHsgYXVkaWVuY2U6IEpXVF9BVUQgfSk7XG4gICAgcmV0dXJuIHR5cGVvZiBwYXlsb2FkLmVtYWlsID09PSBcInN0cmluZ1wiID8gcGF5bG9hZC5lbWFpbCA6IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL290cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFOUMsb0ZBQW9GO0FBQ3BGLE1BQU0sT0FBTyxHQUFHLHVCQUF1QixDQUFDO0FBRXhDLG9GQUFvRjtBQUNwRixNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUM7QUFFbEMsOEJBQThCO0FBQzlCLFNBQVMsTUFBTSxDQUFDLEtBQWE7SUFDM0IsT0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQsNkRBQTZEO0FBQzdELFNBQVMsWUFBWSxDQUFDLENBQVMsRUFBRSxDQUFTO0lBQ3hDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hDLE9BQU8sZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQVVEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBRUQ7SUFDQTtJQUZuQixZQUNtQixVQUFrQixFQUNsQixXQUFtQjtRQURuQixlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2xCLGdCQUFX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LE1BQU0sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQztRQUM1QyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLHNFQUFzRTtRQUN0RSxnRUFBZ0U7UUFDaEUseUVBQXlFO1FBQ3pFLHdEQUF3RDtRQUN4RCw2RUFBNkU7UUFDN0UsNEVBQTRFO1FBQzVFLCtDQUErQztRQUMvQyxJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMzRixPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQ0QsT0FBTyxPQUFPLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDdkUsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBPbmUtdGltZS1jb2RlIHN0b3JlICsgc2Vzc2lvbiBKV1QgZm9yIHRoZSBlbWFpbC1PVFAgdHVubmVsIGdhdGUuXG4gKlxuICogVGhlIGNvZGUgc3RvcmUgaXMgYmFja2VkIGJ5IEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgIChhdXRvLWNvbmZpZ3VyZWQgdG8gbWVtb3J5LFxuICogb3IgTGFrZWJhc2Ugd2hlbiB0aGUgYXBwIHdpcmVzIGEgcGVyc2lzdGVudCBgQ2FjaGVTdG9yYWdlYCksIHNvIFRUTCBFWFBJUlkgYW5kXG4gKiBldmljdGlvbiBhcmUgdGhlIGNhY2hlJ3Mgam9iIC0gbm8gaGFuZC1yb2xsZWQgTWFwIG9yIHRpbWVycy4gQSA2LWRpZ2l0IGNvZGUgaXNcbiAqIGdlbmVyYXRlZCB3aXRoIGBjcnlwdG8ucmFuZG9tSW50YCBhbmQgc3RvcmVkIGFzIGEgU0hBLTI1NiBoYXNoIHdpdGggYW4gYXR0ZW1wdFxuICogY291bnRlciAobmV2ZXIgdGhlIHBsYWludGV4dCwgbmV2ZXIgaW4gdGhlIEpXVCk7IGB2ZXJpZnlgIGlzIGNvbnN0YW50LXRpbWUgb25cbiAqIHRoZSBoYXNoLCBhbmQgdGhlIGVudHJ5IGlzIGRlbGV0ZWQgb24gc3VjY2VzcyBvciBvbmNlIGF0dGVtcHRzIGFyZSBleGhhdXN0ZWQuXG4gKlxuICogVGhlIHNlc3Npb24gSldUIGlzIGFuIEhTMjU2IHRva2VuICh2aWEgYGpvc2VgKSBjYXJyeWluZyBvbmx5IHRoZSBlbWFpbC4gSXRzXG4gKiBzaWduaW5nIGtleSBpcyByZXNvbHZlZCBieSBgLi9zaWduaW5nLWtleS50c2A6IGBUVU5ORUxfQVVUSF9KV1RfU0VDUkVUYCB3aGVuXG4gKiBzZXQsIGVsc2UgYSBrZXkgcGVyc2lzdGVkIGluIHRoZSBjYWNoZSBmb3IgMzAgZGF5cyBzbyBjb29raWVzIHN1cnZpdmUgdGhlXG4gKiByZXN0YXJ0cyBhIHR1bm5lbCBzZWVzIHdoZW5ldmVyIHRoZSBhcHAgaXQgd3JhcHMgcmVsb2Fkcy4gQSBjb29raWUgc2lnbmVkXG4gKiBiZWZvcmUgYFRVTk5FTF9BVVRIX1NFU1NJT05fRVBPQ0hgIGlzIHJlZnVzZWQgaGVyZSBhcyB3ZWxsIGFzIGJlaW5nIG9ycGhhbmVkIGJ5XG4gKiB0aGUgY2FjaGUga2V5LCBzbyB0aGUgZm9yY2UtY2xlYXIgc3dpdGNoIGhvbGRzIGV2ZW4gZm9yIGEgc3RpbGwtY3VycmVudCBrZXkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUhhc2gsIHJhbmRvbUludCwgdGltaW5nU2FmZUVxdWFsIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBqd3RWZXJpZnksIFNpZ25KV1QgfSBmcm9tIFwiam9zZVwiO1xuaW1wb3J0IHsgc2lnbmluZ0tleSB9IGZyb20gXCIuL3NpZ25pbmcta2V5LnRzXCI7XG5cbi8qKiBKV1QgaXNzdWVyL2F1ZGllbmNlIHNvIGEgdG9rZW4gbWludGVkIGZvciB0aGlzIGdhdGUgaXNuJ3QgYWNjZXB0ZWQgZWxzZXdoZXJlLiAqL1xuY29uc3QgSldUX0FVRCA9IFwiZGJ4LXRvb2xzLXR1bm5lbC1hdXRoXCI7XG5cbi8qKiBDYWNoZS1rZXkgcHJlZml4IGZvciBwZW5kaW5nIGNvZGVzLCBuYW1lc3BhY2VkIGF3YXkgZnJvbSBhbnkgb3RoZXIgY2FjaGUgdXNlLiAqL1xuY29uc3QgQ09ERV9QUkVGSVggPSBcInR1bm5lbDpvdHA6XCI7XG5cbi8qKiBTSEEtMjU2IGhleCBvZiBhIHZhbHVlLiAqL1xuZnVuY3Rpb24gc2hhMjU2KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUodmFsdWUpLmRpZ2VzdChcImhleFwiKTtcbn1cblxuLyoqIENvbnN0YW50LXRpbWUgY29tcGFyZSBvZiB0d28gZXF1YWwtbGVuZ3RoIGhleCBkaWdlc3RzLiAqL1xuZnVuY3Rpb24gc2FmZUVxdWFsSGV4KGE6IHN0cmluZywgYjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRpbWluZ1NhZmVFcXVhbChCdWZmZXIuZnJvbShhLCBcImhleFwiKSwgQnVmZmVyLmZyb20oYiwgXCJoZXhcIikpO1xufVxuXG5pbnRlcmZhY2UgQ29kZUVudHJ5IHtcbiAgaGFzaDogc3RyaW5nO1xuICBhdHRlbXB0czogbnVtYmVyO1xufVxuXG4vKiogUmVzdWx0IG9mIHtAbGluayBDb2RlU3RvcmUudmVyaWZ5fS4gKi9cbmV4cG9ydCB0eXBlIFZlcmlmeU91dGNvbWUgPSBcIm9rXCIgfCBcImludmFsaWRcIiB8IFwiZXhwaXJlZFwiIHwgXCJ0b28tbWFueS1hdHRlbXB0c1wiO1xuXG4vKipcbiAqIFBlbmRpbmcgb25lLXRpbWUgY29kZXMsIHN0b3JlZCBpbiBBcHBLaXQncyBjYWNoZSBrZXllZCBieSBsb3dlcmNhc2VkIGVtYWlsLlxuICogRXhwaXJ5IGlzIHRoZSBjYWNoZSdzIFRUTCAobm8gbWFudWFsIGNsb2NrKTsgYSBtaXNzIG1lYW5zIGV4cGlyZWQtb3ItbmV2ZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb2RlU3RvcmUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHR0bFNlY29uZHM6IG51bWJlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1heEF0dGVtcHRzOiBudW1iZXIsXG4gICkge31cblxuICBwcml2YXRlIGNhY2hlKCk6IENhY2hlTWFuYWdlciB7XG4gICAgcmV0dXJuIENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5KGVtYWlsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtDT0RFX1BSRUZJWH0ke2VtYWlsLnRvTG93ZXJDYXNlKCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSwgc3RvcmUgKGhhc2hlZCwgd2l0aCB0aGUgY2FjaGUgVFRMKSwgYW5kIFJFVFVSTiBhIGZyZXNoIDYtZGlnaXRcbiAgICogY29kZS4gVGhlIGNhbGxlciBlbWFpbHMgdGhlIHJldHVybmVkIHBsYWludGV4dDsgb25seSB0aGUgaGFzaCBpcyByZXRhaW5lZC5cbiAgICogUmVwbGFjZXMgYW55IHBlbmRpbmcgY29kZSBmb3IgdGhlIGFkZHJlc3MuXG4gICAqL1xuICBhc3luYyBpc3N1ZShlbWFpbDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBjb2RlID0gU3RyaW5nKHJhbmRvbUludCgwLCAxXzAwMF8wMDApKS5wYWRTdGFydCg2LCBcIjBcIik7XG4gICAgY29uc3QgZW50cnk6IENvZGVFbnRyeSA9IHsgaGFzaDogc2hhMjU2KGNvZGUpLCBhdHRlbXB0czogMCB9O1xuICAgIGF3YWl0IHRoaXMuY2FjaGUoKS5zZXQodGhpcy5rZXkoZW1haWwpLCBlbnRyeSwgeyB0dGw6IHRoaXMudHRsU2Vjb25kcyB9KTtcbiAgICByZXR1cm4gY29kZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBgY29kZWAgZm9yIGBlbWFpbGAuIEEgY2FjaGUgbWlzcyBpcyBgZXhwaXJlZGAgKFRUTCBlbGFwc2VkIG9yIG5ldmVyXG4gICAqIGlzc3VlZCkuIERlbGV0ZXMgdGhlIGVudHJ5IG9uIHN1Y2Nlc3Mgb3Igd2hlbiBhdHRlbXB0cyBhcmUgZXhoYXVzdGVkLCBzbyBhXG4gICAqIGNvZGUgaXMgc2luZ2xlLXVzZSBhbmQgY2FuJ3QgYmUgYnJ1dGUtZm9yY2VkIHBhc3QgdGhlIGNhcC4gQW4gYXR0ZW1wdFxuICAgKiBpbmNyZW1lbnRzIHRoZSBzdG9yZWQgY291bnRlciAocmUtcGVyc2lzdGVkIHdpdGggYSBmcmVzaCBUVEwgd2luZG93KS5cbiAgICovXG4gIGFzeW5jIHZlcmlmeShlbWFpbDogc3RyaW5nLCBjb2RlOiBzdHJpbmcpOiBQcm9taXNlPFZlcmlmeU91dGNvbWU+IHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmtleShlbWFpbCk7XG4gICAgY29uc3QgZW50cnkgPSBhd2FpdCB0aGlzLmNhY2hlKCkuZ2V0PENvZGVFbnRyeT4oa2V5KTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm4gXCJleHBpcmVkXCI7XG4gICAgY29uc3QgYXR0ZW1wdHMgPSBlbnRyeS5hdHRlbXB0cyArIDE7XG4gICAgaWYgKHNhZmVFcXVhbEhleChlbnRyeS5oYXNoLCBzaGEyNTYoY29kZSkpKSB7XG4gICAgICBhd2FpdCB0aGlzLmNhY2hlKCkuZGVsZXRlKGtleSk7XG4gICAgICByZXR1cm4gXCJva1wiO1xuICAgIH1cbiAgICBpZiAoYXR0ZW1wdHMgPj0gdGhpcy5tYXhBdHRlbXB0cykge1xuICAgICAgYXdhaXQgdGhpcy5jYWNoZSgpLmRlbGV0ZShrZXkpO1xuICAgICAgcmV0dXJuIFwidG9vLW1hbnktYXR0ZW1wdHNcIjtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5jYWNoZSgpLnNldChrZXksIHsgLi4uZW50cnksIGF0dGVtcHRzIH0sIHsgdHRsOiB0aGlzLnR0bFNlY29uZHMgfSk7XG4gICAgcmV0dXJuIFwiaW52YWxpZFwiO1xuICB9XG59XG5cbi8qKiBNaW50IGEgc2Vzc2lvbiBKV1QgZm9yIGBlbWFpbGAsIGV4cGlyaW5nIGluIGB0dGxTZWNvbmRzYC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaWduU2Vzc2lvbihlbWFpbDogc3RyaW5nLCB0dGxTZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB7IGtleSB9ID0gYXdhaXQgc2lnbmluZ0tleSgpO1xuICByZXR1cm4gbmV3IFNpZ25KV1QoeyBlbWFpbCB9KVxuICAgIC5zZXRQcm90ZWN0ZWRIZWFkZXIoeyBhbGc6IFwiSFMyNTZcIiB9KVxuICAgIC5zZXRTdWJqZWN0KGVtYWlsKVxuICAgIC5zZXRBdWRpZW5jZShKV1RfQVVEKVxuICAgIC5zZXRJc3N1ZWRBdCgpXG4gICAgLnNldEV4cGlyYXRpb25UaW1lKGAke3R0bFNlY29uZHN9c2ApXG4gICAgLnNpZ24oa2V5KTtcbn1cblxuLyoqIFZhbGlkYXRlIGEgc2Vzc2lvbiBKV1QsIHJldHVybmluZyB0aGUgZW1haWwgaXQgd2FzIG1pbnRlZCBmb3IsIG9yIGB1bmRlZmluZWRgLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeVNlc3Npb24odG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGlmICghdG9rZW4pIHJldHVybiB1bmRlZmluZWQ7XG4gIHRyeSB7XG4gICAgY29uc3QgeyBrZXksIGVwb2NoTXMgfSA9IGF3YWl0IHNpZ25pbmdLZXkoKTtcbiAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IGp3dFZlcmlmeSh0b2tlbiwga2V5LCB7IGF1ZGllbmNlOiBKV1RfQVVEIH0pO1xuICAgIC8vIEJlbHQgYW5kIGJyYWNlcyB3aXRoIHRoZSBlcG9jaC1zY29wZWQgY2FjaGUga2V5OiB0aGF0IGFsb25lIGFscmVhZHlcbiAgICAvLyBvcnBoYW5zIG9sZGVyIGtleXMsIGJ1dCBhbiBvcGVyYXRvciB3aG8gbW92ZWQgdGhlIGVwb2NoIHdoaWxlXG4gICAgLy8gVFVOTkVMX0FVVEhfSldUX1NFQ1JFVCBpcyBzZXQgaGFzIG5vIGtleSByb3RhdGlvbiB0byByZWx5IG9uLCBhbmQgdGhpc1xuICAgIC8vIGNoZWNrIGlzIHdoYXQgbWFrZXMgdGhlIHN3aXRjaCB3b3JrIGluIHRoYXQgY2FzZSB0b28uXG4gICAgLy8gQ29tcGFyZWQgaW4gd2hvbGUgU0VDT05EUyBiZWNhdXNlIGBpYXRgIGhhcyBubyBmaW5lciByZXNvbHV0aW9uOiBhZ2FpbnN0IGFcbiAgICAvLyBtaWxsaXNlY29uZCBlcG9jaCwgYSBjb29raWUgbWludGVkIGluIHRoZSBzYW1lIHNlY29uZCBhcyB0aGUgY3V0b2ZmIHdvdWxkXG4gICAgLy8gYmUgcmVmdXNlZCBkZXBlbmRpbmcgb24gc3ViLXNlY29uZCByb3VuZGluZy5cbiAgICBpZiAoZXBvY2hNcyA+IDAgJiYgKHBheWxvYWQuaWF0ID09PSB1bmRlZmluZWQgfHwgcGF5bG9hZC5pYXQgPCBNYXRoLmZsb29yKGVwb2NoTXMgLyAxMDAwKSkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB0eXBlb2YgcGF5bG9hZC5lbWFpbCA9PT0gXCJzdHJpbmdcIiA/IHBheWxvYWQuZW1haWwgOiB1bmRlZmluZWQ7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
@@ -46,12 +46,26 @@ export interface AuthGateConfig extends BasePluginConfig {
46
46
  * what the platform code-detection heuristics key on.
47
47
  */
48
48
  message?: string;
49
- /** Session lifetime (seconds). Env TUNNEL_AUTH_SESSION_TTL. Default 43200 (12h). */
49
+ /**
50
+ * Session lifetime (seconds). Env TUNNEL_AUTH_SESSION_TTL. Default 2592000 (30d).
51
+ *
52
+ * Matched to the cache-backed signing key's own 30-day TTL (see
53
+ * `./signing-key.ts`): the cookie and the key that validates it should expire
54
+ * together, or one silently outlives the other.
55
+ */
50
56
  sessionTtlSeconds?: number;
51
57
  /** One-time-code lifetime (seconds). Env TUNNEL_AUTH_CODE_TTL. Default 600 (10m). */
52
58
  codeTtlSeconds?: number;
53
59
  /** Max verify attempts per issued code. Default 5. */
54
60
  maxAttempts?: number;
61
+ /**
62
+ * Force-clear date: every session issued BEFORE it stops verifying, so moving
63
+ * it forward signs everyone out. Env TUNNEL_AUTH_SESSION_EPOCH.
64
+ *
65
+ * Any `Date`-parseable value (`2026-08-02`, an ISO timestamp) or bare epoch
66
+ * seconds / millis. Unset means no cutoff.
67
+ */
68
+ sessionEpoch?: string | number | Date;
55
69
  /** Deliver a code to an address. Wired by the app to the email plugin. */
56
70
  sendCode?: (email: string, code: string, opts: SendCodeOptions) => Promise<void>;
57
71
  }
@@ -77,6 +91,8 @@ export interface ResolvedAuthGateConfig {
77
91
  sessionTtlSeconds: number;
78
92
  codeTtlSeconds: number;
79
93
  maxAttempts: number;
94
+ /** Force-clear cutoff in epoch ms; `0` when unset. */
95
+ sessionEpochMs: number;
80
96
  }
81
97
  /** Merge {@link AuthGateConfig} over env over defaults into a resolved config. */
82
98
  export declare function resolveAuthGateConfig(config: AuthGateConfig): ResolvedAuthGateConfig;