@dbx-tools/email 0.6.44 → 0.6.45
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/index.ts +1 -10
- package/lib/index.d.ts +1 -10
- package/lib/index.js +1 -8
- package/lib/src/config.d.ts +0 -40
- package/lib/src/config.js +2 -54
- package/lib/src/plugin.d.ts +0 -23
- package/lib/src/plugin.js +2 -143
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/src/config.ts +1 -90
- package/src/plugin.ts +1 -163
- package/lib/src/auth/allowlist.d.ts +0 -27
- package/lib/src/auth/allowlist.js +0 -82
- package/lib/src/auth/gate.d.ts +0 -91
- package/lib/src/auth/gate.js +0 -143
- package/lib/src/auth/otp.d.ts +0 -49
- package/lib/src/auth/otp.js +0 -135
- package/lib/src/auth/rate-limit.d.ts +0 -35
- package/lib/src/auth/rate-limit.js +0 -53
- package/src/auth/allowlist.ts +0 -88
- package/src/auth/gate.ts +0 -172
- package/src/auth/otp.ts +0 -151
- package/src/auth/rate-limit.ts +0 -59
package/lib/src/plugin.js
CHANGED
|
@@ -26,9 +26,7 @@ import { AuthenticationError, ConfigurationError, ConnectionError, ExecutionErro
|
|
|
26
26
|
import { defineTool, executeFromRegistry, toolsFromRegistry, } from "@databricks/appkit/beta";
|
|
27
27
|
import { log } from "@dbx-tools/shared-core";
|
|
28
28
|
import { email as emailWire, } from "@dbx-tools/shared-email";
|
|
29
|
-
import {
|
|
30
|
-
import { EMAIL_CONFIG_SCHEMA, resolveAuthConfig } from "./config.js";
|
|
31
|
-
import { AuthGate, SESSION_COOKIE } from "./auth/gate.js";
|
|
29
|
+
import { EMAIL_CONFIG_SCHEMA } from "./config.js";
|
|
32
30
|
import { EMAIL_SENDERS_SETTINGS, EMAIL_VERIFY_SETTINGS } from "./defaults.js";
|
|
33
31
|
import { isSenderAllowed, listSenderOptions, resolveSenderAddress } from "./sender.js";
|
|
34
32
|
import { SEND_EMAIL_DESCRIPTION } from "./tool.js";
|
|
@@ -59,8 +57,6 @@ const logger = log.logger("email");
|
|
|
59
57
|
* ```
|
|
60
58
|
*/
|
|
61
59
|
export class EmailPlugin extends Plugin {
|
|
62
|
-
/** The email-OTP access gate, constructed in {@link setup} when `auth.enabled`. */
|
|
63
|
-
authGate;
|
|
64
60
|
static manifest = {
|
|
65
61
|
name: "email",
|
|
66
62
|
displayName: "Email",
|
|
@@ -107,7 +103,6 @@ export class EmailPlugin extends Plugin {
|
|
|
107
103
|
async setup() {
|
|
108
104
|
const { transporter, config } = getEmailRuntime(this.config);
|
|
109
105
|
setEmailExecutor((fn, settings) => this.execute(fn, settings));
|
|
110
|
-
this.setupAuthGate();
|
|
111
106
|
const policy = {
|
|
112
107
|
mode: config.mode,
|
|
113
108
|
senderPolicy: config.senderPolicy,
|
|
@@ -174,75 +169,6 @@ export class EmailPlugin extends Plugin {
|
|
|
174
169
|
res.json(result.data);
|
|
175
170
|
},
|
|
176
171
|
});
|
|
177
|
-
this.injectAuthRoutes(router);
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Mount the email-OTP login flow under `/api/email/auth/*` when the gate is
|
|
181
|
-
* enabled. These routes are the ONLY ones the gate middleware leaves open (see
|
|
182
|
-
* {@link AuthGate.middleware}); everything else requires the session cookie
|
|
183
|
-
* they establish. No-op when auth is off.
|
|
184
|
-
*/
|
|
185
|
-
injectAuthRoutes(router) {
|
|
186
|
-
const gate = this.authGate;
|
|
187
|
-
if (!gate)
|
|
188
|
-
return;
|
|
189
|
-
// `request` and `verify` take a raw email/code, not an OBO user, so they are
|
|
190
|
-
// NOT wrapped in `asUser` - the caller is anonymous until verified.
|
|
191
|
-
this.route(router, {
|
|
192
|
-
name: "authRequest",
|
|
193
|
-
method: "post",
|
|
194
|
-
path: "/auth/request",
|
|
195
|
-
handler: async (req, res) => {
|
|
196
|
-
const parsed = authRequestSchema.safeParse(req.body);
|
|
197
|
-
if (!parsed.success) {
|
|
198
|
-
// Even a malformed body reports success (anti-enumeration).
|
|
199
|
-
res.json({ ok: true });
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
const result = await gate.handleRequest(parsed.data.email, this.clientIp(req));
|
|
203
|
-
res.json(result);
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
this.route(router, {
|
|
207
|
-
name: "authVerify",
|
|
208
|
-
method: "post",
|
|
209
|
-
path: "/auth/verify",
|
|
210
|
-
handler: async (req, res) => {
|
|
211
|
-
const parsed = authVerifySchema.safeParse(req.body);
|
|
212
|
-
if (!parsed.success) {
|
|
213
|
-
res.json({ ok: false });
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
const result = await gate.handleVerify(parsed.data.email, parsed.data.code, this.clientIp(req), req.secure);
|
|
217
|
-
if (result.ok && result.token && result.cookieOptions) {
|
|
218
|
-
res.cookie(SESSION_COOKIE, result.token, result.cookieOptions);
|
|
219
|
-
}
|
|
220
|
-
res.json({ ok: result.ok, ...(result.retryAfter ? { retryAfter: result.retryAfter } : {}) });
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
this.route(router, {
|
|
224
|
-
name: "authLogout",
|
|
225
|
-
method: "post",
|
|
226
|
-
path: "/auth/logout",
|
|
227
|
-
handler: async (_req, res) => {
|
|
228
|
-
res.clearCookie(SESSION_COOKIE, { path: "/" });
|
|
229
|
-
res.json({ ok: true });
|
|
230
|
-
},
|
|
231
|
-
});
|
|
232
|
-
this.route(router, {
|
|
233
|
-
name: "authStatus",
|
|
234
|
-
method: "get",
|
|
235
|
-
path: "/auth/status",
|
|
236
|
-
handler: async (req, res) => {
|
|
237
|
-
res.json(await gate.status(req));
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
/** Client IP for rate-limiting, honoring the Apps ingress `x-forwarded-for`. */
|
|
242
|
-
clientIp(req) {
|
|
243
|
-
const fwd = req.headers["x-forwarded-for"];
|
|
244
|
-
const first = Array.isArray(fwd) ? fwd[0] : fwd?.split(",")[0];
|
|
245
|
-
return (first ?? req.ip ?? "unknown").trim();
|
|
246
172
|
}
|
|
247
173
|
exports() {
|
|
248
174
|
return {
|
|
@@ -280,73 +206,6 @@ export class EmailPlugin extends Plugin {
|
|
|
280
206
|
async send(message, from, signal) {
|
|
281
207
|
return sendEmail(message, from ?? this.resolveSender(), signal);
|
|
282
208
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Build the email-OTP access gate when `auth.enabled`, wiring its code
|
|
285
|
-
* delivery through this plugin's own transport. Called from {@link setup}; a
|
|
286
|
-
* no-op (leaves {@link authGate} undefined) when the gate is off.
|
|
287
|
-
*/
|
|
288
|
-
setupAuthGate() {
|
|
289
|
-
const auth = resolveAuthConfig(this.config.auth);
|
|
290
|
-
if (!auth)
|
|
291
|
-
return;
|
|
292
|
-
const gate = new AuthGate({
|
|
293
|
-
allow: auth.allow,
|
|
294
|
-
sessionTtlSeconds: auth.sessionTtlSeconds,
|
|
295
|
-
codeTtlSeconds: auth.codeTtlSeconds,
|
|
296
|
-
maxAttempts: auth.maxAttempts,
|
|
297
|
-
secureCookies: process.env.NODE_ENV === "production",
|
|
298
|
-
sendCode: (email, code) => this.sendOtpEmail(email, code),
|
|
299
|
-
});
|
|
300
|
-
this.authGate = gate;
|
|
301
|
-
// The gate must protect the WHOLE app, but a plugin's own `injectRoutes`
|
|
302
|
-
// router only covers `/api/email/*`. AppKit's `server` plugin exposes
|
|
303
|
-
// `addExtension(fn)` for exactly this: an app-level middleware applied before
|
|
304
|
-
// the server listens. The lookup is deferred to the `setup:complete`
|
|
305
|
-
// lifecycle event because sibling plugins (including `server`) are not all
|
|
306
|
-
// registered during this plugin's own `setup()` - the same coordination
|
|
307
|
-
// `appkit-mastra` uses to wait for `lakebase`. The login routes are exempted
|
|
308
|
-
// by the middleware's open-prefix (`/api/email/auth`).
|
|
309
|
-
const registerGate = () => {
|
|
310
|
-
const server = this.context?.getPlugins().get("server");
|
|
311
|
-
if (server?.addExtension) {
|
|
312
|
-
server.addExtension((app) => app.use(gate.middleware(`/api/${EmailPlugin.manifest.name}`)));
|
|
313
|
-
logger.info("auth:enabled", {
|
|
314
|
-
patterns: auth.allow.length,
|
|
315
|
-
sessionTtlSeconds: auth.sessionTtlSeconds,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
// No server plugin to gate through - the login routes still work, but the
|
|
320
|
-
// rest of the app would be ungated, so disable rather than half-enable.
|
|
321
|
-
this.authGate = undefined;
|
|
322
|
-
logger.warn("auth:disabled - the `server` plugin is required to gate the app; add server() to your plugins");
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
if (this.context?.onLifecycle) {
|
|
326
|
-
this.context.onLifecycle("setup:complete", registerGate);
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
registerGate();
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Deliver a one-time code to `email` through this plugin's transport. Throws
|
|
334
|
-
* on failure (the gate swallows it, so a delivery error never leaks whether
|
|
335
|
-
* the address was allow-listed).
|
|
336
|
-
*/
|
|
337
|
-
async sendOtpEmail(email, code) {
|
|
338
|
-
await this.send({
|
|
339
|
-
to: [email],
|
|
340
|
-
subject: `Your sign-in code: ${code}`,
|
|
341
|
-
body: [
|
|
342
|
-
`Your one-time sign-in code is:`,
|
|
343
|
-
``,
|
|
344
|
-
`## ${code}`,
|
|
345
|
-
``,
|
|
346
|
-
`It expires shortly. If you didn't request this, you can ignore this email.`,
|
|
347
|
-
].join("\n"),
|
|
348
|
-
}, undefined);
|
|
349
|
-
}
|
|
350
209
|
/** Run the sender-options lookup through the plugin's interceptor chain. */
|
|
351
210
|
async executeListSenders() {
|
|
352
211
|
return this.execute(async () => this.listSenders(), EMAIL_SENDERS_SETTINGS);
|
|
@@ -432,4 +291,4 @@ function unwrap(result) {
|
|
|
432
291
|
* ```
|
|
433
292
|
*/
|
|
434
293
|
export const email = toPlugin(EmailPlugin);
|
|
435
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFFSCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsY0FBYyxFQUNkLG1CQUFtQixFQUNuQixNQUFNLEVBQ04sUUFBUSxFQUNSLGVBQWUsR0FLaEIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0wsVUFBVSxFQUNWLG1CQUFtQixFQUNuQixpQkFBaUIsR0FJbEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUNMLEtBQUssSUFBSSxTQUFTLEdBSW5CLE1BQU0seUJBQXlCLENBQUM7QUFFakMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUEwQixNQUFNLGFBQWEsQ0FBQztBQUM3RixPQUFPLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RSxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLG9CQUFvQixHQUNyQixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLCtFQUErRTtBQUMvRSxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUM7QUFFakMsNEVB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QUksTUFBTSxDQUFDLEVBQUU7UUFBRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDbEMsTUFBTSxhQUFhLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IHBsdWdpbiAocmVnaXN0ZXJlZCBuYW1lOiBgZW1haWxgKSB0aGF0IG93bnMgdGhlIFNNVFAgcnVudGltZVxuICogZm9yIG91dGJvdW5kIG1haWwuIFJlZ2lzdGVyaW5nIGl0IHZhbGlkYXRlcyB0aGUgU01UUCBjb25maWd1cmF0aW9uXG4gKiBhbmQgdmVyaWZpZXMgY29ubmVjdGl2aXR5IGF0IHN0YXJ0dXAsIHNvIGEgYmFkIGhvc3QgLyBjcmVkZW50aWFsXG4gKiBzdXJmYWNlcyBpbiB0aGUgYm9vdCBsb2dzIGluc3RlYWQgb2Ygb24gdGhlIGZpcnN0IGFwcHJvdmVkIHNlbmQsIGFuZFxuICogaW5zdGFsbHMgdGhpcyBwbHVnaW4ncyBgZXhlY3V0ZSgpYCBhcyB0aGUgcnVudGltZSdzIGV4ZWN1dG9yIHNvIGV2ZXJ5XG4gKiBzZW5kIHBpY2tzIHVwIEFwcEtpdCdzIHJldHJ5IC8gdGltZW91dCAvIHRlbGVtZXRyeSBjaGFpbi5cbiAqXG4gKiBUaGUgcGx1Z2luIGlzIGFsc28gYSBgVG9vbFByb3ZpZGVyYCwgc28gYW4gQXBwS2l0IGFnZW50IGNhbiByZWFjaCBhblxuICogYGVtYWlsLnNlbmRgIHRvb2wgZGlyZWN0bHk7IHRoZSB7QGxpbmsgZW1haWxUb29sfSBleHBvcnQgaXMgdGhlIHNhbWVcbiAqIGNhcGFiaWxpdHkgZm9yIGEgTWFzdHJhIGFnZW50LiBCb3RoIHNoYXJlIHRoZSB0cmFuc3BvcnQgcHJpbWVkIGhlcmUsXG4gKiBhbmQge0BsaW5rIHNlbmRFbWFpbH0gaXMgYXZhaWxhYmxlIHRvIG5vbi1hZ2VudCBjYWxsZXJzLlxuICpcbiAqIENvbmZpZ3VyYXRpb24gaXMgdGhlIG1hbmlmZXN0LXB1Ymxpc2hlZCB7QGxpbmsgRW1haWxQbHVnaW5Db25maWd9XG4gKiAoU01UUCBob3N0L3BvcnQvY3JlZGVudGlhbHMsIHNlbmRlciBkb21haW4gb3IgZXhwbGljaXQgYGZyb21gLCB0aGVcbiAqIHNlbmRlciBwb2xpY3ksIGFuZCBhbiBvcHRpb25hbCBgYWxsb3dlZFNlbmRlcnNgIHJlc3RyaWN0aW9uKSwgd2l0aFxuICogdW5wcmVmaXhlZCBgU01UUF8qYCAvIGBFTUFJTF8qYCBlbnZpcm9ubWVudCBmYWxsYmFja3MuXG4gKlxuICogVGhlIHBsdWdpbiBtb3VudHMgb25lIHJvdXRlIHVuZGVyIGl0cyBiYXNlIHBhdGggKGAvYXBpL2VtYWlsYCk6XG4gKiBgR0VUIC9zZW5kZXJzYCByZXR1cm5zIHRoZSBwZXJtaXR0ZWQgYEZyb21gIG9wdGlvbnMgZm9yIHRoZSBjYWxsaW5nXG4gKiB1c2VyLCBzbyBhIGNvbXBvc2UgVUkgY2FuIG9mZmVyIHRoZW0gaW4gYSBkcm9wZG93bi5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHtcbiAgQXV0aGVudGljYXRpb25FcnJvcixcbiAgQ29uZmlndXJhdGlvbkVycm9yLFxuICBDb25uZWN0aW9uRXJyb3IsXG4gIEV4ZWN1dGlvbkVycm9yLFxuICBnZXRFeGVjdXRpb25Db250ZXh0LFxuICBQbHVnaW4sXG4gIHRvUGx1Z2luLFxuICBWYWxpZGF0aW9uRXJyb3IsXG4gIHR5cGUgQXBwS2l0RXJyb3IsXG4gIHR5cGUgRXhlY3V0aW9uUmVzdWx0LFxuICB0eXBlIElBcHBSb3V0ZXIsXG4gIHR5cGUgUGx1Z2luTWFuaWZlc3QsXG59IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7XG4gIGRlZmluZVRvb2wsXG4gIGV4ZWN1dGVGcm9tUmVnaXN0cnksXG4gIHRvb2xzRnJvbVJlZ2lzdHJ5LFxuICB0eXBlIEFnZW50VG9vbERlZmluaXRpb24sXG4gIHR5cGUgVG9vbFByb3ZpZGVyLFxuICB0eXBlIFRvb2xSZWdpc3RyeSxcbn0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdC9iZXRhXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgZW1haWwgYXMgZW1haWxXaXJlLFxuICB0eXBlIEVtYWlsTWVzc2FnZSxcbiAgdHlwZSBFbWFpbFJlc3VsdCxcbiAgdHlwZSBFbWFpbFNlbmRlcnMsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHR5cGUgZXhwcmVzcyBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHsgYXV0aFJlcXVlc3RTY2hlbWEsIGF1dGhWZXJpZnlTY2hlbWEgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtZW1haWxcIjtcbmltcG9ydCB7IEVNQUlMX0NPTkZJR19TQ0hFTUEsIHJlc29sdmVBdXRoQ29uZmlnLCB0eXBlIEVtYWlsUGx1Z2luQ29uZmlnIH0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBBdXRoR2F0ZSwgU0VTU0lPTl9DT09LSUUgfSBmcm9tIFwiLi9hdXRoL2dhdGUudHNcIjtcbmltcG9ydCB7IEVNQUlMX1NFTkRFUlNfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUyB9IGZyb20gXCIuL2RlZmF1bHRzLnRzXCI7XG5pbXBvcnQgeyBpc1NlbmRlckFsbG93ZWQsIGxpc3RTZW5kZXJPcHRpb25zLCByZXNvbHZlU2VuZGVyQWRkcmVzcyB9IGZyb20gXCIuL3NlbmRlci50c1wiO1xuaW1wb3J0IHsgU0VORF9FTUFJTF9ERVNDUklQVElPTiB9IGZyb20gXCIuL3Rvb2wudHNcIjtcbmltcG9ydCB7XG4gIGdldEVtYWlsUnVudGltZSxcbiAgcmVzZXRFbWFpbFJ1bnRpbWUsXG4gIHNlbmRFbWFpbCxcbiAgc2V0RW1haWxFeGVjdXRvcixcbiAgdmVyaWZ5RW1haWxUcmFuc3BvcnQsXG59IGZyb20gXCIuL3RyYW5zcG9ydC50c1wiO1xuXG4vKiogTW91bnQtcmVsYXRpdmUgcm91dGUgKHVuZGVyIGAvYXBpL2VtYWlsYCkgZm9yIHRoZSBzZW5kZXItb3B0aW9ucyBsb29rdXAuICovXG5jb25zdCBTRU5ERVJTX1JPVVRFID0gXCIvc2VuZGVyc1wiO1xuXG4vKiogUmVnaXN0cnkga2V5IG9mIHRoZSBhZ2VudCB0b29sLCB3aGljaCBhZ2VudHMgYWRkcmVzcyBhcyBgZW1haWwuc2VuZGAuICovXG5jb25zdCBTRU5EX1RPT0wgPSBcInNlbmRcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcImVtYWlsXCIpO1xuXG4vKipcbiAqIEFwcEtpdCBwbHVnaW4gdGhhdCBjb25maWd1cmVzIGFuZCB2ZXJpZmllcyB0aGUgU01UUCB0cmFuc3BvcnQgdXNlZCBieVxuICogdGhlIGBzZW5kX2VtYWlsYCB0b29sLCBhbmQgZXhwb3NlcyBzZW5kaW5nIGFzIGFuIEFwcEtpdCBhZ2VudCB0b29sLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY3JlYXRlQXBwLCBzZXJ2ZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG4gKiBpbXBvcnQgeyBwbHVnaW4gYXMgZW1haWxQbHVnaW4gfSBmcm9tIFwiQGRieC10b29scy9lbWFpbFwiO1xuICpcbiAqIGF3YWl0IGNyZWF0ZUFwcCh7XG4gKiAgIHBsdWdpbnM6IFtcbiAqICAgICBzZXJ2ZXIoKSxcbiAqICAgICBlbWFpbFBsdWdpbi5lbWFpbCh7XG4gKiAgICAgICBzbXRwOiB7IGhvc3Q6IFwic210cC5leGFtcGxlLmNvbVwiLCB1c2VyOiBcImFwaWtleVwiLCBwYXNzd29yZDogcHJvY2Vzcy5lbnYuU01UUF9LRVkgfSxcbiAqICAgICAgIGRvbWFpbjogXCJtYWlsLmV4YW1wbGUuY29tXCIsXG4gKiAgICAgfSksXG4gKiAgIF0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgRW1haWxQbHVnaW4gZXh0ZW5kcyBQbHVnaW48RW1haWxQbHVnaW5Db25maWc+IGltcGxlbWVudHMgVG9vbFByb3ZpZGVyIHtcbiAgLyoqIFRoZSBlbWFpbC1PVFAgYWNjZXNzIGdhdGUsIGNvbnN0cnVjdGVkIGluIHtAbGluayBzZXR1cH0gd2hlbiBgYXV0aC5lbmFibGVkYC4gKi9cbiAgcHJpdmF0ZSBhdXRoR2F0ZT86IEF1dGhHYXRlO1xuXG4gIHN0YXRpYyBtYW5pZmVzdCA9IHtcbiAgICBuYW1lOiBcImVtYWlsXCIsXG4gICAgZGlzcGxheU5hbWU6IFwiRW1haWxcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiU2VuZHMgYXBwcm92YWwtZ2F0ZWQgZW1haWwgb3ZlciBTTVRQLCB3aXRoIHRoZSBzZW5kZXIgZGVyaXZlZCBmcm9tIFwiICtcbiAgICAgIFwidGhlIG9uLWJlaGFsZi1vZiB1c2VyJ3MgYWRkcmVzcyBvbiBhIGNvbmZpZ3VyZWQgZG9tYWluLlwiLFxuICAgIHN0YWJpbGl0eTogXCJiZXRhXCIsXG4gICAgcmVzb3VyY2VzOiB7XG4gICAgICByZXF1aXJlZDogW10sXG4gICAgICBvcHRpb25hbDogW10sXG4gICAgfSxcbiAgICBjb25maWc6IHsgc2NoZW1hOiBFTUFJTF9DT05GSUdfU0NIRU1BIH0sXG4gIH0gc2F0aXNmaWVzIFBsdWdpbk1hbmlmZXN0PFwiZW1haWxcIj47XG5cbiAgLyoqXG4gICAqIFRoZSB0b29sIHRoaXMgcGx1Z2luIG9mZmVycyB0byBhbiBBcHBLaXQgYWdlbnQuXG4gICAqXG4gICAqIE5vdCBgYXV0b0luaGVyaXRhYmxlYDogYSBzZW5kIGlzIGlycmV2ZXJzaWJsZSBhbmQgbGVhdmVzIHRoZSB3b3Jrc3BhY2UsXG4gICAqIHNvIGl0IG11c3Qgb25seSBhcHBlYXIgaW4gYW4gYWdlbnQgdGhhdCBhc2tlZCBmb3IgaXQgYW5kIGFjY2VwdGVkIHRoZVxuICAgKiBzZW5kZXIgcG9saWN5IHRoYXQgY29tZXMgd2l0aCBpdC5cbiAgICpcbiAgICogYGV4ZWN1dGVgIHJlLXBhcnNlcyBpdHMgYXJndW1lbnRzIHdpdGggdGhlIGxvY2FsIHNjaGVtYTogQXBwS2l0IHZhbGlkYXRlc1xuICAgKiBhZ2FpbnN0IHRoZSBzYW1lIHNjaGVtYSBmaXJzdCwgYnV0IHJlLXBhcnNpbmcgaXMgd2hhdCBnaXZlcyB0aGUgYm9keSB0eXBlZFxuICAgKiBhcmd1bWVudHMgaW5zdGVhZCBvZiBgdW5rbm93bmAuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRvb2xzOiBUb29sUmVnaXN0cnkgPSB7XG4gICAgW1NFTkRfVE9PTF06IGRlZmluZVRvb2woe1xuICAgICAgZGVzY3JpcHRpb246IFNFTkRfRU1BSUxfREVTQ1JJUFRJT04sXG4gICAgICBzY2hlbWE6IGVtYWlsV2lyZS5lbWFpbE1lc3NhZ2VTY2hlbWEsXG4gICAgICBhbm5vdGF0aW9uczogeyBlZmZlY3Q6IFwid3JpdGVcIiwgcmVxdWlyZXNVc2VyQ29udGV4dDogdHJ1ZSB9LFxuICAgICAgYXV0b0luaGVyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzLCBzaWduYWwpID0+XG4gICAgICAgIHRoaXMuc2VuZChlbWFpbFdpcmUuZW1haWxNZXNzYWdlU2NoZW1hLnBhcnNlKGFyZ3MpLCB1bmRlZmluZWQsIHNpZ25hbCksXG4gICAgfSksXG4gIH07XG5cbiAgLyoqXG4gICAqIFByaW1lIHRoZSBzaGFyZWQgcnVudGltZSBmcm9tIHRoaXMgcGx1Z2luJ3MgY29uZmlnIChvdmVyIGVudiksIHJvdXRlIHRoZVxuICAgKiB0b29scycgc2VuZHMgdGhyb3VnaCB0aGlzIHBsdWdpbidzIGludGVyY2VwdG9yIGNoYWluLCBhbmQgbG9nIHRoZVxuICAgKiBlZmZlY3RpdmUgc2VuZGVyIHBvbGljeSBzbyBhbiBhY3RpdmUgcmVzdHJpY3Rpb24gaXMgb2J2aW91cyBhdCBib290LiBJblxuICAgKiBTTVRQIG1vZGUsIGZhaWwgc2V0dXAgd2hlbiB0aGUgdHJhbnNwb3J0IGNhbm5vdCBiZSB2ZXJpZmllZDogYSBiYWQgaG9zdFxuICAgKiBvciBjcmVkZW50aWFsIGlzIGEgZGVwbG95LXRpbWUgbWlzdGFrZSBhbmQgc2hvdWxkIHN0b3AgdGhlIGFwcCByYXRoZXJcbiAgICogdGhhbiB3YWl0IGZvciBhIHVzZXIgdG8gYXBwcm92ZSBhIHNlbmQgdGhhdCBjYW5ub3Qgd29yay4gV2l0aCBubyBTTVRQXG4gICAqIGNyZWRlbnRpYWxzIHRoZSBydW50aW1lIGlzIGluIGZpbGUvb3V0Ym94IG1vZGUgKG9ubHkgd2hlblxuICAgKiBgRU1BSUxfT1VUQk9YX01PREVgIGlzIHNldCksIGxvZ2dlZCBsb3VkbHkgaGVyZSBzbyBpdCBpcyBvYnZpb3VzIG1haWxcbiAgICogaXMgYmVpbmcgd3JpdHRlbiB0byBkaXNrIHJhdGhlciB0aGFuIHNlbnQuXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBzZXR1cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHRyYW5zcG9ydGVyLCBjb25maWcgfSA9IGdldEVtYWlsUnVudGltZSh0aGlzLmNvbmZpZyk7XG4gICAgc2V0RW1haWxFeGVjdXRvcigoZm4sIHNldHRpbmdzKSA9PiB0aGlzLmV4ZWN1dGUoZm4sIHNldHRpbmdzKSk7XG4gICAgdGhpcy5zZXR1cEF1dGhHYXRlKCk7XG4gICAgY29uc3QgcG9saWN5ID0ge1xuICAgICAgbW9kZTogY29uZmlnLm1vZGUsXG4gICAgICBzZW5kZXJQb2xpY3k6IGNvbmZpZy5zZW5kZXJQb2xpY3ksXG4gICAgICByZXN0cmljdGVkOiBjb25maWcuYWxsb3dlZFNlbmRlcnMubGVuZ3RoID4gMCxcbiAgICAgIC4uLihjb25maWcuYWxsb3dlZFNlbmRlcnMubGVuZ3RoID4gMCA/IHsgYWxsb3dlZFNlbmRlcnM6IGNvbmZpZy5hbGxvd2VkU2VuZGVycyB9IDoge30pLFxuICAgIH07XG4gICAgaWYgKGNvbmZpZy5tb2RlID09PSBcImZpbGVcIikge1xuICAgICAgbG9nZ2VyLndhcm4oXCJvdXRib3g6ZW5hYmxlZFwiLCB7XG4gICAgICAgIGRpcjogY29uZmlnLm91dERpcixcbiAgICAgICAgcmVhc29uOiBcIm5vIFNNVFAgY3JlZGVudGlhbHMgY29uZmlndXJlZDsgZW1haWxzIGFyZSB3cml0dGVuIHRvIGRpc2sgaW5zdGVhZCBvZiBzZW50XCIsXG4gICAgICB9KTtcbiAgICAgIGxvZ2dlci5pbmZvKFwicmVhZHlcIiwgcG9saWN5KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdmVyaWZpZWQgPSBhd2FpdCB0aGlzLmV4ZWN1dGUoXG4gICAgICBhc3luYyAoc2lnbmFsKSA9PiB2ZXJpZnlFbWFpbFRyYW5zcG9ydCh0cmFuc3BvcnRlciwgc2lnbmFsKSxcbiAgICAgIEVNQUlMX1ZFUklGWV9TRVRUSU5HUyxcbiAgICApO1xuICAgIGlmICghdmVyaWZpZWQub2spIHtcbiAgICAgIGxvZ2dlci5lcnJvcihcInNtdHA6dW52ZXJpZmllZFwiLCB7XG4gICAgICAgIGhvc3Q6IGNvbmZpZy5ob3N0LFxuICAgICAgICBwb3J0OiBjb25maWcucG9ydCxcbiAgICAgICAgc3RhdHVzOiB2ZXJpZmllZC5zdGF0dXMsXG4gICAgICAgIGVycm9yOiB2ZXJpZmllZC5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IuaW52YWxpZENvbm5lY3Rpb24oXG4gICAgICAgIFwiU01UUFwiLFxuICAgICAgICBgQ291bGQgbm90IHZlcmlmeSAke2NvbmZpZy5ob3N0fToke2NvbmZpZy5wb3J0fS4gQ2hlY2sgU01UUF9IT1NULCBTTVRQX1BPUlQsIFNNVFBfU0VDVVJFLCBhbmQgdGhlIGNyZWRlbnRpYWxzLCBvciBzZXQgRU1BSUxfT1VUQk9YX01PREU9MSBmb3IgbG9jYWwgb3V0Ym94IHRlc3RpbmcuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGxvZ2dlci5pbmZvKFwicmVhZHlcIiwge1xuICAgICAgLi4ucG9saWN5LFxuICAgICAgaG9zdDogY29uZmlnLmhvc3QsXG4gICAgICBwb3J0OiBjb25maWcucG9ydCxcbiAgICAgIHNlY3VyZTogY29uZmlnLnNlY3VyZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBDbG9zZSB0aGUgU01UUCBjb25uZWN0aW9uIHBvb2wuIElkZW1wb3RlbnQuICovXG4gIGFzeW5jIHNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJlc2V0RW1haWxSdW50aW1lKCk7XG4gIH1cblxuICAvKipcbiAgICogQWJvcnQgaW4tZmxpZ2h0IHdvcmsuIEFwcEtpdCdzIGdyYWNlZnVsIHNodXRkb3duIG9ubHkgaW52b2tlcyB0aGlzIGhvb2sgLVxuICAgKiBpdCBuZXZlciBjYWxscyB7QGxpbmsgc2h1dGRvd259IC0gc28gdGhlIFNNVFAgcG9vbCBpcyBjbG9zZWQgZnJvbSBoZXJlIG9yXG4gICAqIGl0IGxlYWtzIGF0IFNJR1RFUk0uIFRoZSB0ZWFyZG93biBpcyBzeW5jaHJvbm91cyBhbmQgaWRlbXBvdGVudCwgc28gdGhlXG4gICAqIHVuLWF3YWl0ZWQgY2FsbCBjb3N0cyBub3RoaW5nLlxuICAgKi9cbiAgb3ZlcnJpZGUgYWJvcnRBY3RpdmVPcGVyYXRpb25zKCk6IHZvaWQge1xuICAgIHN1cGVyLmFib3J0QWN0aXZlT3BlcmF0aW9ucygpO1xuICAgIHZvaWQgdGhpcy5zaHV0ZG93bigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9zZSB0aGUgc2VuZGVyLW9wdGlvbnMgbG9va3VwIHNvIFVJIGNvbXBvc2Ugdmlld3MgY2FuIHBvcHVsYXRlIGFcbiAgICogYEZyb21gIGRyb3Bkb3duIGZyb20gdGhlIGNvbmZpZ3VyZWQgYWxsb3ctbGlzdC4gTW91bnRlZCB1bmRlciB0aGVcbiAgICogcGx1Z2luIGJhc2UgcGF0aCwgaS5lLiBgR0VUIC9hcGkvZW1haWwvc2VuZGVyc2AuIFJ1bnMgaW4gdGhlIE9CT1xuICAgKiB1c2VyIHNjb3BlIHNvIGRvbWFpbiB3aWxkY2FyZHMgcmVzb2x2ZSBhZ2FpbnN0IHRoZSBjYWxsZXIncyBvd25cbiAgICogbG9jYWwgcGFydC5cbiAgICovXG4gIG92ZXJyaWRlIGluamVjdFJvdXRlcyhyb3V0ZXI6IElBcHBSb3V0ZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJvdXRlKHJvdXRlciwge1xuICAgICAgbmFtZTogXCJsaXN0U2VuZGVyc1wiLFxuICAgICAgbWV0aG9kOiBcImdldFwiLFxuICAgICAgcGF0aDogU0VOREVSU19ST1VURSxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmFzVXNlcihyZXEpLmV4ZWN1dGVMaXN0U2VuZGVycygpO1xuICAgICAgICBpZiAoIXJlc3VsdC5vaykge1xuICAgICAgICAgIHJlcy5zdGF0dXMocmVzdWx0LnN0YXR1cykuanNvbih7IGVycm9yOiByZXN1bHQubWVzc2FnZSB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmVzLmpzb24ocmVzdWx0LmRhdGEpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmluamVjdEF1dGhSb3V0ZXMocm91dGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3VudCB0aGUgZW1haWwtT1RQIGxvZ2luIGZsb3cgdW5kZXIgYC9hcGkvZW1haWwvYXV0aC8qYCB3aGVuIHRoZSBnYXRlIGlzXG4gICAqIGVuYWJsZWQuIFRoZXNlIHJvdXRlcyBhcmUgdGhlIE9OTFkgb25lcyB0aGUgZ2F0ZSBtaWRkbGV3YXJlIGxlYXZlcyBvcGVuIChzZWVcbiAgICoge0BsaW5rIEF1dGhHYXRlLm1pZGRsZXdhcmV9KTsgZXZlcnl0aGluZyBlbHNlIHJlcXVpcmVzIHRoZSBzZXNzaW9uIGNvb2tpZVxuICAgKiB0aGV5IGVzdGFibGlzaC4gTm8tb3Agd2hlbiBhdXRoIGlzIG9mZi5cbiAgICovXG4gIHByaXZhdGUgaW5qZWN0QXV0aFJvdXRlcyhyb3V0ZXI6IElBcHBSb3V0ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnYXRlID0gdGhpcy5hdXRoR2F0ZTtcbiAgICBpZiAoIWdhdGUpIHJldHVybjtcblxuICAgIC8vIGByZXF1ZXN0YCBhbmQgYHZlcmlmeWAgdGFrZSBhIHJhdyBlbWFpbC9jb2RlLCBub3QgYW4gT0JPIHVzZXIsIHNvIHRoZXkgYXJlXG4gICAgLy8gTk9UIHdyYXBwZWQgaW4gYGFzVXNlcmAgLSB0aGUgY2FsbGVyIGlzIGFub255bW91cyB1bnRpbCB2ZXJpZmllZC5cbiAgICB0aGlzLnJvdXRlKHJvdXRlciwge1xuICAgICAgbmFtZTogXCJhdXRoUmVxdWVzdFwiLFxuICAgICAgbWV0aG9kOiBcInBvc3RcIixcbiAgICAgIHBhdGg6IFwiL2F1dGgvcmVxdWVzdFwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IGF1dGhSZXF1ZXN0U2NoZW1hLnNhZmVQYXJzZShyZXEuYm9keSk7XG4gICAgICAgIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAvLyBFdmVuIGEgbWFsZm9ybWVkIGJvZHkgcmVwb3J0cyBzdWNjZXNzIChhbnRpLWVudW1lcmF0aW9uKS5cbiAgICAgICAgICByZXMuanNvbih7IG9rOiB0cnVlIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnYXRlLmhhbmRsZVJlcXVlc3QocGFyc2VkLmRhdGEuZW1haWwsIHRoaXMuY2xpZW50SXAocmVxKSk7XG4gICAgICAgIHJlcy5qc29uKHJlc3VsdCk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgIG5hbWU6IFwiYXV0aFZlcmlmeVwiLFxuICAgICAgbWV0aG9kOiBcInBvc3RcIixcbiAgICAgIHBhdGg6IFwiL2F1dGgvdmVyaWZ5XCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gYXV0aFZlcmlmeVNjaGVtYS5zYWZlUGFyc2UocmVxLmJvZHkpO1xuICAgICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB7XG4gICAgICAgICAgcmVzLmpzb24oeyBvazogZmFsc2UgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdhdGUuaGFuZGxlVmVyaWZ5KFxuICAgICAgICAgIHBhcnNlZC5kYXRhLmVtYWlsLFxuICAgICAgICAgIHBhcnNlZC5kYXRhLmNvZGUsXG4gICAgICAgICAgdGhpcy5jbGllbnRJcChyZXEpLFxuICAgICAgICAgIHJlcS5zZWN1cmUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChyZXN1bHQub2sgJiYgcmVzdWx0LnRva2VuICYmIHJlc3VsdC5jb29raWVPcHRpb25zKSB7XG4gICAgICAgICAgcmVzLmNvb2tpZShTRVNTSU9OX0NPT0tJRSwgcmVzdWx0LnRva2VuLCByZXN1bHQuY29va2llT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLmpzb24oeyBvazogcmVzdWx0Lm9rLCAuLi4ocmVzdWx0LnJldHJ5QWZ0ZXIgPyB7IHJldHJ5QWZ0ZXI6IHJlc3VsdC5yZXRyeUFmdGVyIH0gOiB7fSkgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgIG5hbWU6IFwiYXV0aExvZ291dFwiLFxuICAgICAgbWV0aG9kOiBcInBvc3RcIixcbiAgICAgIHBhdGg6IFwiL2F1dGgvbG9nb3V0XCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAoX3JlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5jbGVhckNvb2tpZShTRVNTSU9OX0NPT0tJRSwgeyBwYXRoOiBcIi9cIiB9KTtcbiAgICAgICAgcmVzLmpzb24oeyBvazogdHJ1ZSB9KTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlKHJvdXRlciwge1xuICAgICAgbmFtZTogXCJhdXRoU3RhdHVzXCIsXG4gICAgICBtZXRob2Q6IFwiZ2V0XCIsXG4gICAgICBwYXRoOiBcIi9hdXRoL3N0YXR1c1wiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIHJlcy5qc29uKGF3YWl0IGdhdGUuc3RhdHVzKHJlcSkpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBDbGllbnQgSVAgZm9yIHJhdGUtbGltaXRpbmcsIGhvbm9yaW5nIHRoZSBBcHBzIGluZ3Jlc3MgYHgtZm9yd2FyZGVkLWZvcmAuICovXG4gIHByaXZhdGUgY2xpZW50SXAocmVxOiBleHByZXNzLlJlcXVlc3QpOiBzdHJpbmcge1xuICAgIGNvbnN0IGZ3ZCA9IHJlcS5oZWFkZXJzW1wieC1mb3J3YXJkZWQtZm9yXCJdO1xuICAgIGNvbnN0IGZpcnN0ID0gQXJyYXkuaXNBcnJheShmd2QpID8gZndkWzBdIDogZndkPy5zcGxpdChcIixcIilbMF07XG4gICAgcmV0dXJuIChmaXJzdCA/PyByZXEuaXAgPz8gXCJ1bmtub3duXCIpLnRyaW0oKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGV4cG9ydHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogU2VuZCBhIG1lc3NhZ2UgaW1tZWRpYXRlbHkgZnJvbSBgZnJvbWAgdGhyb3VnaCB0aGUgc2hhcmVkXG4gICAgICAgKiB0cmFuc3BvcnQsIGJ5cGFzc2luZyB0aGUgYXBwcm92YWwgZmxvdy4gRm9yIGFnZW50LWRyaXZlbiBzZW5kc1xuICAgICAgICogdXNlIHtAbGluayBlbWFpbFRvb2x9IGluc3RlYWQuXG4gICAgICAgKi9cbiAgICAgIHNlbmRFbWFpbDogKFxuICAgICAgICBtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsXG4gICAgICAgIGZyb206IHN0cmluZyxcbiAgICAgICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICAgICApOiBQcm9taXNlPEVtYWlsUmVzdWx0PiA9PiB0aGlzLnNlbmQobWVzc2FnZSwgZnJvbSwgc2lnbmFsKSxcbiAgICAgIC8qKlxuICAgICAgICogU2VuZGVyIG9wdGlvbnMgZm9yIHRoZSBjdXJyZW50IHVzZXIgKHRoZSBgR0VUIC9zZW5kZXJzYCBwYXlsb2FkKS5cbiAgICAgICAqIEFwcEtpdCB3cmFwcyB0aGlzIHdpdGggYGFzVXNlcihyZXEpYCBmb3IgT0JPIHNjb3BpbmcuXG4gICAgICAgKi9cbiAgICAgIGxpc3RTZW5kZXJzOiBhc3luYyAoKTogUHJvbWlzZTxFbWFpbFNlbmRlcnM+ID0+IHVud3JhcChhd2FpdCB0aGlzLmV4ZWN1dGVMaXN0U2VuZGVycygpKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEFwcEtpdCBgVG9vbFByb3ZpZGVyYDogdGhlIHRvb2wgZGVmaW5pdGlvbnMgb2ZmZXJlZCB0byBhbiBhZ2VudC4gKi9cbiAgZ2V0QWdlbnRUb29scygpOiBBZ2VudFRvb2xEZWZpbml0aW9uW10ge1xuICAgIHJldHVybiB0b29sc0Zyb21SZWdpc3RyeSh0aGlzLnRvb2xzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBLaXQgYFRvb2xQcm92aWRlcmA6IHJ1biBvbmUgdG9vbCBjYWxsLiBBcmd1bWVudHMgYXJlIHZhbGlkYXRlZCBhZ2FpbnN0XG4gICAqIHRoZSB0b29sJ3Mgc2NoZW1hIGZpcnN0LCBhbmQgYSB2YWxpZGF0aW9uIGZhaWx1cmUgY29tZXMgYmFjayBhcyBhblxuICAgKiBMTE0tZnJpZW5kbHkgc3RyaW5nIHNvIHRoZSBtb2RlbCBjYW4gY29ycmVjdCBpdHNlbGYgb24gdGhlIG5leHQgdHVybi5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVBZ2VudFRvb2wobmFtZTogc3RyaW5nLCBhcmdzOiB1bmtub3duLCBzaWduYWw/OiBBYm9ydFNpZ25hbCk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIHJldHVybiBleGVjdXRlRnJvbVJlZ2lzdHJ5KHRoaXMudG9vbHMsIG5hbWUsIGFyZ3MsIHNpZ25hbCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBvbmUgbWVzc2FnZSwgcmVzb2x2aW5nIHRoZSBzZW5kZXIgZm9yIHRoZSBjYWxsZXIgaW4gc2NvcGUgd2hlblxuICAgKiBgZnJvbWAgaXMgbm90IHBpbm5lZC4gVGhlIGludGVyY2VwdG9yIGNoYWluIGlzIGFwcGxpZWQgaW5zaWRlXG4gICAqIHtAbGluayBzZW5kRW1haWx9IHRocm91Z2ggdGhlIGV4ZWN1dG9yIGluc3RhbGxlZCBhdCBzZXR1cCwgc28gdGhpcyBtdXN0XG4gICAqIG5vdCB3cmFwIGl0IGFnYWluLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZW5kKFxuICAgIG1lc3NhZ2U6IEVtYWlsTWVzc2FnZSxcbiAgICBmcm9tOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8RW1haWxSZXN1bHQ+IHtcbiAgICByZXR1cm4gc2VuZEVtYWlsKG1lc3NhZ2UsIGZyb20gPz8gdGhpcy5yZXNvbHZlU2VuZGVyKCksIHNpZ25hbCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgdGhlIGVtYWlsLU9UUCBhY2Nlc3MgZ2F0ZSB3aGVuIGBhdXRoLmVuYWJsZWRgLCB3aXJpbmcgaXRzIGNvZGVcbiAgICogZGVsaXZlcnkgdGhyb3VnaCB0aGlzIHBsdWdpbidzIG93biB0cmFuc3BvcnQuIENhbGxlZCBmcm9tIHtAbGluayBzZXR1cH07IGFcbiAgICogbm8tb3AgKGxlYXZlcyB7QGxpbmsgYXV0aEdhdGV9IHVuZGVmaW5lZCkgd2hlbiB0aGUgZ2F0ZSBpcyBvZmYuXG4gICAqL1xuICBwcml2YXRlIHNldHVwQXV0aEdhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgYXV0aCA9IHJlc29sdmVBdXRoQ29uZmlnKHRoaXMuY29uZmlnLmF1dGgpO1xuICAgIGlmICghYXV0aCkgcmV0dXJuO1xuICAgIGNvbnN0IGdhdGUgPSBuZXcgQXV0aEdhdGUoe1xuICAgICAgYWxsb3c6IGF1dGguYWxsb3csXG4gICAgICBzZXNzaW9uVHRsU2Vjb25kczogYXV0aC5zZXNzaW9uVHRsU2Vjb25kcyxcbiAgICAgIGNvZGVUdGxTZWNvbmRzOiBhdXRoLmNvZGVUdGxTZWNvbmRzLFxuICAgICAgbWF4QXR0ZW1wdHM6IGF1dGgubWF4QXR0ZW1wdHMsXG4gICAgICBzZWN1cmVDb29raWVzOiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCIsXG4gICAgICBzZW5kQ29kZTogKGVtYWlsLCBjb2RlKSA9PiB0aGlzLnNlbmRPdHBFbWFpbChlbWFpbCwgY29kZSksXG4gICAgfSk7XG4gICAgdGhpcy5hdXRoR2F0ZSA9IGdhdGU7XG5cbiAgICAvLyBUaGUgZ2F0ZSBtdXN0IHByb3RlY3QgdGhlIFdIT0xFIGFwcCwgYnV0IGEgcGx1Z2luJ3Mgb3duIGBpbmplY3RSb3V0ZXNgXG4gICAgLy8gcm91dGVyIG9ubHkgY292ZXJzIGAvYXBpL2VtYWlsLypgLiBBcHBLaXQncyBgc2VydmVyYCBwbHVnaW4gZXhwb3Nlc1xuICAgIC8vIGBhZGRFeHRlbnNpb24oZm4pYCBmb3IgZXhhY3RseSB0aGlzOiBhbiBhcHAtbGV2ZWwgbWlkZGxld2FyZSBhcHBsaWVkIGJlZm9yZVxuICAgIC8vIHRoZSBzZXJ2ZXIgbGlzdGVucy4gVGhlIGxvb2t1cCBpcyBkZWZlcnJlZCB0byB0aGUgYHNldHVwOmNvbXBsZXRlYFxuICAgIC8vIGxpZmVjeWNsZSBldmVudCBiZWNhdXNlIHNpYmxpbmcgcGx1Z2lucyAoaW5jbHVkaW5nIGBzZXJ2ZXJgKSBhcmUgbm90IGFsbFxuICAgIC8vIHJlZ2lzdGVyZWQgZHVyaW5nIHRoaXMgcGx1Z2luJ3Mgb3duIGBzZXR1cCgpYCAtIHRoZSBzYW1lIGNvb3JkaW5hdGlvblxuICAgIC8vIGBhcHBraXQtbWFzdHJhYCB1c2VzIHRvIHdhaXQgZm9yIGBsYWtlYmFzZWAuIFRoZSBsb2dpbiByb3V0ZXMgYXJlIGV4ZW1wdGVkXG4gICAgLy8gYnkgdGhlIG1pZGRsZXdhcmUncyBvcGVuLXByZWZpeCAoYC9hcGkvZW1haWwvYXV0aGApLlxuICAgIGNvbnN0IHJlZ2lzdGVyR2F0ZSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IHRoaXMuY29udGV4dD8uZ2V0UGx1Z2lucygpLmdldChcInNlcnZlclwiKSBhc1xuICAgICAgICB8IHsgYWRkRXh0ZW5zaW9uPzogKGZuOiAoYXBwOiBleHByZXNzLkFwcGxpY2F0aW9uKSA9PiB2b2lkKSA9PiB2b2lkIH1cbiAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoc2VydmVyPy5hZGRFeHRlbnNpb24pIHtcbiAgICAgICAgc2VydmVyLmFkZEV4dGVuc2lvbigoYXBwKSA9PlxuICAgICAgICAgIGFwcC51c2UoZ2F0ZS5taWRkbGV3YXJlKGAvYXBpLyR7RW1haWxQbHVnaW4ubWFuaWZlc3QubmFtZX1gKSksXG4gICAgICAgICk7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiYXV0aDplbmFibGVkXCIsIHtcbiAgICAgICAgICBwYXR0ZXJuczogYXV0aC5hbGxvdy5sZW5ndGgsXG4gICAgICAgICAgc2Vzc2lvblR0bFNlY29uZHM6IGF1dGguc2Vzc2lvblR0bFNlY29uZHMsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTm8gc2VydmVyIHBsdWdpbiB0byBnYXRlIHRocm91Z2ggLSB0aGUgbG9naW4gcm91dGVzIHN0aWxsIHdvcmssIGJ1dCB0aGVcbiAgICAgICAgLy8gcmVzdCBvZiB0aGUgYXBwIHdvdWxkIGJlIHVuZ2F0ZWQsIHNvIGRpc2FibGUgcmF0aGVyIHRoYW4gaGFsZi1lbmFibGUuXG4gICAgICAgIHRoaXMuYXV0aEdhdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIFwiYXV0aDpkaXNhYmxlZCAtIHRoZSBgc2VydmVyYCBwbHVnaW4gaXMgcmVxdWlyZWQgdG8gZ2F0ZSB0aGUgYXBwOyBhZGQgc2VydmVyKCkgdG8geW91ciBwbHVnaW5zXCIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAodGhpcy5jb250ZXh0Py5vbkxpZmVjeWNsZSkge1xuICAgICAgdGhpcy5jb250ZXh0Lm9uTGlmZWN5Y2xlKFwic2V0dXA6Y29tcGxldGVcIiwgcmVnaXN0ZXJHYXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVnaXN0ZXJHYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGl2ZXIgYSBvbmUtdGltZSBjb2RlIHRvIGBlbWFpbGAgdGhyb3VnaCB0aGlzIHBsdWdpbidzIHRyYW5zcG9ydC4gVGhyb3dzXG4gICAqIG9uIGZhaWx1cmUgKHRoZSBnYXRlIHN3YWxsb3dzIGl0LCBzbyBhIGRlbGl2ZXJ5IGVycm9yIG5ldmVyIGxlYWtzIHdoZXRoZXJcbiAgICogdGhlIGFkZHJlc3Mgd2FzIGFsbG93LWxpc3RlZCkuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNlbmRPdHBFbWFpbChlbWFpbDogc3RyaW5nLCBjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnNlbmQoXG4gICAgICB7XG4gICAgICAgIHRvOiBbZW1haWxdLFxuICAgICAgICBzdWJqZWN0OiBgWW91ciBzaWduLWluIGNvZGU6ICR7Y29kZX1gLFxuICAgICAgICBib2R5OiBbXG4gICAgICAgICAgYFlvdXIgb25lLXRpbWUgc2lnbi1pbiBjb2RlIGlzOmAsXG4gICAgICAgICAgYGAsXG4gICAgICAgICAgYCMjICR7Y29kZX1gLFxuICAgICAgICAgIGBgLFxuICAgICAgICAgIGBJdCBleHBpcmVzIHNob3J0bHkuIElmIHlvdSBkaWRuJ3QgcmVxdWVzdCB0aGlzLCB5b3UgY2FuIGlnbm9yZSB0aGlzIGVtYWlsLmAsXG4gICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgIH0sXG4gICAgICB1bmRlZmluZWQsXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBSdW4gdGhlIHNlbmRlci1vcHRpb25zIGxvb2t1cCB0aHJvdWdoIHRoZSBwbHVnaW4ncyBpbnRlcmNlcHRvciBjaGFpbi4gKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlTGlzdFNlbmRlcnMoKTogUHJvbWlzZTxFeGVjdXRpb25SZXN1bHQ8RW1haWxTZW5kZXJzPj4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoYXN5bmMgKCkgPT4gdGhpcy5saXN0U2VuZGVycygpLCBFTUFJTF9TRU5ERVJTX1NFVFRJTkdTKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIHRoZSBgRnJvbWAgb3B0aW9ucyBvZmZlcmVkIHRvIHRoZSBjdXJyZW50IHVzZXI6IHRoZSBjb25jcmV0ZVxuICAgKiBhZGRyZXNzZXMgdGhlIGVmZmVjdGl2ZSBhbGxvdy1saXN0IHBlcm1pdHMgKGRvbWFpbiB3aWxkY2FyZHMgZXhwYW5kZWRcbiAgICogYWdhaW5zdCB0aGUgT0JPIHVzZXIncyBsb2NhbCBwYXJ0KSwgdGhlIGRlZmF1bHQgYW1vbmcgdGhlbSwgYW5kXG4gICAqIHdoZXRoZXIgdGhlIGxpc3QgaXMgYW4gZW5mb3JjZWQgcmVzdHJpY3Rpb24uIFNlZVxuICAgKiB7QGxpbmsgbGlzdFNlbmRlck9wdGlvbnN9LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsaXN0U2VuZGVycygpOiBQcm9taXNlPEVtYWlsU2VuZGVycz4ge1xuICAgIGNvbnN0IHsgY29uZmlnIH0gPSBnZXRFbWFpbFJ1bnRpbWUoKTtcbiAgICBjb25zdCBzZW5kZXJzID0gbGlzdFNlbmRlck9wdGlvbnMoY29uZmlnLCBjdXJyZW50VXNlckVtYWlsKCkpO1xuICAgIC8vIFByZWZlciB0aGUgYWRkcmVzcyBhIHNlbmQgd291bGQgYWN0dWFsbHkgZGVmYXVsdCB0bzsgZmFsbCBiYWNrIHRvXG4gICAgLy8gdGhlIGZpcnN0IG9mZmVyZWQgb3B0aW9uIHdoZW4gdGhhdCBjYW4ndCBiZSByZXNvbHZlZCAvIHBlcm1pdHRlZC5cbiAgICBsZXQgZGVmYXVsdFNlbmRlciA9IHNlbmRlcnNbMF07XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gdGhpcy5yZXNvbHZlU2VuZGVyKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChpc1NlbmRlckFsbG93ZWQocmVzb2x2ZWQsIGNvbmZpZy5hbGxvd2VkU2VuZGVycykpIGRlZmF1bHRTZW5kZXIgPSByZXNvbHZlZDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEtlZXAgdGhlIGZpcnN0IG9mZmVyZWQgb3B0aW9uIChvciBub25lKSBhcyB0aGUgZGVmYXVsdC5cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlbmRlcnMsXG4gICAgICAuLi4oZGVmYXVsdFNlbmRlciA/IHsgZGVmYXVsdFNlbmRlciB9IDoge30pLFxuICAgICAgcmVzdHJpY3RlZDogY29uZmlnLmFsbG93ZWRTZW5kZXJzLmxlbmd0aCA+IDAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBUaGUgYEZyb21gIGEgc2VuZCBkZWZhdWx0cyB0byBmb3IgdGhlIGNhbGxlciBpbiBzY29wZS4gKi9cbiAgcHJpdmF0ZSByZXNvbHZlU2VuZGVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlc29sdmVTZW5kZXJBZGRyZXNzKGdldEVtYWlsUnVudGltZSgpLmNvbmZpZywgY3VycmVudFVzZXJFbWFpbCgpKTtcbiAgfVxufVxuXG4vKiogVGhlIE9CTyB1c2VyJ3MgYWRkcmVzcywgb3IgdW5kZWZpbmVkIG91dHNpZGUgYSB1c2VyIGNvbnRleHQuICovXG5mdW5jdGlvbiBjdXJyZW50VXNlckVtYWlsKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGN0eCA9IGdldEV4ZWN1dGlvbkNvbnRleHQoKTtcbiAgcmV0dXJuIFwiaXNVc2VyQ29udGV4dFwiIGluIGN0eCA/IGN0eC51c2VyRW1haWwgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmUtcmFpc2UgYSBmYWlsZWQgZXhlY3V0aW9uIGFzIHRoZSBBcHBLaXQgZXJyb3IgY2xhc3MgdGhhdCBhbHJlYWR5IGNhcnJpZXNcbiAqIHRoZSBzdGF0dXMgQXBwS2l0IHJlc29sdmVkLCBzbyBhIHByb2dyYW1tYXRpYyBjYWxsZXIgc2VlcyB0aGUgc2FtZSA0MDAgL1xuICogNDAxIC8gNTAzIGFuIEhUVFAgY2FsbGVyIHdvdWxkLlxuICovXG5mdW5jdGlvbiB0b0FwcEtpdEVycm9yKHN0YXR1czogbnVtYmVyLCBtZXNzYWdlOiBzdHJpbmcpOiBBcHBLaXRFcnJvciB7XG4gIGlmIChzdGF0dXMgPT09IDQwMCkgcmV0dXJuIG5ldyBWYWxpZGF0aW9uRXJyb3IobWVzc2FnZSk7XG4gIGlmIChzdGF0dXMgPT09IDQwMSkgcmV0dXJuIG5ldyBBdXRoZW50aWNhdGlvbkVycm9yKG1lc3NhZ2UpO1xuICBpZiAoc3RhdHVzID09PSA1MDMpIHJldHVybiBuZXcgQ29ubmVjdGlvbkVycm9yKG1lc3NhZ2UpO1xuICByZXR1cm4gbmV3IEV4ZWN1dGlvbkVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIFN1cmZhY2UgYSBmYWlsZWQge0BsaW5rIEV4ZWN1dGlvblJlc3VsdH0gdG8gYSBwcm9ncmFtbWF0aWMgY2FsbGVyIGFzIGFcbiAqIHRocm93LiBIVFRQIGhhbmRsZXJzIG1hcCBgc3RhdHVzYCBvbnRvIHRoZSByZXNwb25zZSBpbnN0ZWFkLlxuICovXG5mdW5jdGlvbiB1bndyYXA8VD4ocmVzdWx0OiBFeGVjdXRpb25SZXN1bHQ8VD4pOiBUIHtcbiAgaWYgKHJlc3VsdC5vaykgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICB0aHJvdyB0b0FwcEtpdEVycm9yKHJlc3VsdC5zdGF0dXMsIHJlc3VsdC5tZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciB0aGUgZW1haWwgcGx1Z2luLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgY3JlYXRlQXBwLCBzZXJ2ZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG4gKiBpbXBvcnQgeyBicmFuZCwgcGx1Z2luIGFzIGVtYWlsUGx1Z2luIH0gZnJvbSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbiAqXG4gKiBhd2FpdCBjcmVhdGVBcHAoe1xuICogICBwbHVnaW5zOiBbXG4gKiAgICAgc2VydmVyKCksXG4gKiAgICAgZW1haWxQbHVnaW4uZW1haWwoe1xuICogICAgICAgZG9tYWluOiBcIm1haWwuZXhhbXBsZS5jb21cIixcbiAqICAgICAgIGFsbG93ZWRTZW5kZXJzOiBbXCIqQG1haWwuZXhhbXBsZS5jb21cIl0sXG4gKiAgICAgICBicmFuZDogYnJhbmQuZGVmYXVsdEVtYWlsQnJhbmQsXG4gKiAgICAgfSksXG4gKiAgIF0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgZW1haWwgPSB0b1BsdWdpbihFbWFpbFBsdWdpbik7XG4iXX0=
|
|
294
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFFSCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsY0FBYyxFQUNkLG1CQUFtQixFQUNuQixNQUFNLEVBQ04sUUFBUSxFQUNSLGVBQWUsR0FLaEIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0wsVUFBVSxFQUNWLG1CQUFtQixFQUNuQixpQkFBaUIsR0FJbEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUNMLEtBQUssSUFBSSxTQUFTLEdBSW5CLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFFLG1CQUFtQixFQUEwQixNQUFNLGFBQWEsQ0FBQztBQUMxRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbkQsT0FBTyxFQUNMLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsU0FBUyxFQUNULGdCQUFnQixFQUNoQixvQkFBb0IsR0FDckIsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QiwrRUFBK0U7QUFDL0UsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDO0FBRWpDLDRFQUE0RTtBQUM1RSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUM7QUFFekIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUVuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztB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QUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVELElBQUksTUFBTSxLQUFLLEdBQUc7UUFBRSxPQUFPLElBQUksZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hELE9BQU8sSUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsTUFBTSxDQUFJLE1BQTBCO0lBQzNDLElBQUksTUFBTSxDQUFDLEVBQUU7UUFBRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDbEMsTUFBTSxhQUFhLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IHBsdWdpbiAocmVnaXN0ZXJlZCBuYW1lOiBgZW1haWxgKSB0aGF0IG93bnMgdGhlIFNNVFAgcnVudGltZVxuICogZm9yIG91dGJvdW5kIG1haWwuIFJlZ2lzdGVyaW5nIGl0IHZhbGlkYXRlcyB0aGUgU01UUCBjb25maWd1cmF0aW9uXG4gKiBhbmQgdmVyaWZpZXMgY29ubmVjdGl2aXR5IGF0IHN0YXJ0dXAsIHNvIGEgYmFkIGhvc3QgLyBjcmVkZW50aWFsXG4gKiBzdXJmYWNlcyBpbiB0aGUgYm9vdCBsb2dzIGluc3RlYWQgb2Ygb24gdGhlIGZpcnN0IGFwcHJvdmVkIHNlbmQsIGFuZFxuICogaW5zdGFsbHMgdGhpcyBwbHVnaW4ncyBgZXhlY3V0ZSgpYCBhcyB0aGUgcnVudGltZSdzIGV4ZWN1dG9yIHNvIGV2ZXJ5XG4gKiBzZW5kIHBpY2tzIHVwIEFwcEtpdCdzIHJldHJ5IC8gdGltZW91dCAvIHRlbGVtZXRyeSBjaGFpbi5cbiAqXG4gKiBUaGUgcGx1Z2luIGlzIGFsc28gYSBgVG9vbFByb3ZpZGVyYCwgc28gYW4gQXBwS2l0IGFnZW50IGNhbiByZWFjaCBhblxuICogYGVtYWlsLnNlbmRgIHRvb2wgZGlyZWN0bHk7IHRoZSB7QGxpbmsgZW1haWxUb29sfSBleHBvcnQgaXMgdGhlIHNhbWVcbiAqIGNhcGFiaWxpdHkgZm9yIGEgTWFzdHJhIGFnZW50LiBCb3RoIHNoYXJlIHRoZSB0cmFuc3BvcnQgcHJpbWVkIGhlcmUsXG4gKiBhbmQge0BsaW5rIHNlbmRFbWFpbH0gaXMgYXZhaWxhYmxlIHRvIG5vbi1hZ2VudCBjYWxsZXJzLlxuICpcbiAqIENvbmZpZ3VyYXRpb24gaXMgdGhlIG1hbmlmZXN0LXB1Ymxpc2hlZCB7QGxpbmsgRW1haWxQbHVnaW5Db25maWd9XG4gKiAoU01UUCBob3N0L3BvcnQvY3JlZGVudGlhbHMsIHNlbmRlciBkb21haW4gb3IgZXhwbGljaXQgYGZyb21gLCB0aGVcbiAqIHNlbmRlciBwb2xpY3ksIGFuZCBhbiBvcHRpb25hbCBgYWxsb3dlZFNlbmRlcnNgIHJlc3RyaWN0aW9uKSwgd2l0aFxuICogdW5wcmVmaXhlZCBgU01UUF8qYCAvIGBFTUFJTF8qYCBlbnZpcm9ubWVudCBmYWxsYmFja3MuXG4gKlxuICogVGhlIHBsdWdpbiBtb3VudHMgb25lIHJvdXRlIHVuZGVyIGl0cyBiYXNlIHBhdGggKGAvYXBpL2VtYWlsYCk6XG4gKiBgR0VUIC9zZW5kZXJzYCByZXR1cm5zIHRoZSBwZXJtaXR0ZWQgYEZyb21gIG9wdGlvbnMgZm9yIHRoZSBjYWxsaW5nXG4gKiB1c2VyLCBzbyBhIGNvbXBvc2UgVUkgY2FuIG9mZmVyIHRoZW0gaW4gYSBkcm9wZG93bi5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHtcbiAgQXV0aGVudGljYXRpb25FcnJvcixcbiAgQ29uZmlndXJhdGlvbkVycm9yLFxuICBDb25uZWN0aW9uRXJyb3IsXG4gIEV4ZWN1dGlvbkVycm9yLFxuICBnZXRFeGVjdXRpb25Db250ZXh0LFxuICBQbHVnaW4sXG4gIHRvUGx1Z2luLFxuICBWYWxpZGF0aW9uRXJyb3IsXG4gIHR5cGUgQXBwS2l0RXJyb3IsXG4gIHR5cGUgRXhlY3V0aW9uUmVzdWx0LFxuICB0eXBlIElBcHBSb3V0ZXIsXG4gIHR5cGUgUGx1Z2luTWFuaWZlc3QsXG59IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7XG4gIGRlZmluZVRvb2wsXG4gIGV4ZWN1dGVGcm9tUmVnaXN0cnksXG4gIHRvb2xzRnJvbVJlZ2lzdHJ5LFxuICB0eXBlIEFnZW50VG9vbERlZmluaXRpb24sXG4gIHR5cGUgVG9vbFByb3ZpZGVyLFxuICB0eXBlIFRvb2xSZWdpc3RyeSxcbn0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdC9iZXRhXCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgZW1haWwgYXMgZW1haWxXaXJlLFxuICB0eXBlIEVtYWlsTWVzc2FnZSxcbiAgdHlwZSBFbWFpbFJlc3VsdCxcbiAgdHlwZSBFbWFpbFNlbmRlcnMsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHsgRU1BSUxfQ09ORklHX1NDSEVNQSwgdHlwZSBFbWFpbFBsdWdpbkNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZy50c1wiO1xuaW1wb3J0IHsgRU1BSUxfU0VOREVSU19TRVRUSU5HUywgRU1BSUxfVkVSSUZZX1NFVFRJTkdTIH0gZnJvbSBcIi4vZGVmYXVsdHMudHNcIjtcbmltcG9ydCB7IGlzU2VuZGVyQWxsb3dlZCwgbGlzdFNlbmRlck9wdGlvbnMsIHJlc29sdmVTZW5kZXJBZGRyZXNzIH0gZnJvbSBcIi4vc2VuZGVyLnRzXCI7XG5pbXBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vdG9vbC50c1wiO1xuaW1wb3J0IHtcbiAgZ2V0RW1haWxSdW50aW1lLFxuICByZXNldEVtYWlsUnVudGltZSxcbiAgc2VuZEVtYWlsLFxuICBzZXRFbWFpbEV4ZWN1dG9yLFxuICB2ZXJpZnlFbWFpbFRyYW5zcG9ydCxcbn0gZnJvbSBcIi4vdHJhbnNwb3J0LnRzXCI7XG5cbi8qKiBNb3VudC1yZWxhdGl2ZSByb3V0ZSAodW5kZXIgYC9hcGkvZW1haWxgKSBmb3IgdGhlIHNlbmRlci1vcHRpb25zIGxvb2t1cC4gKi9cbmNvbnN0IFNFTkRFUlNfUk9VVEUgPSBcIi9zZW5kZXJzXCI7XG5cbi8qKiBSZWdpc3RyeSBrZXkgb2YgdGhlIGFnZW50IHRvb2wsIHdoaWNoIGFnZW50cyBhZGRyZXNzIGFzIGBlbWFpbC5zZW5kYC4gKi9cbmNvbnN0IFNFTkRfVE9PTCA9IFwic2VuZFwiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiZW1haWxcIik7XG5cbi8qKlxuICogQXBwS2l0IHBsdWdpbiB0aGF0IGNvbmZpZ3VyZXMgYW5kIHZlcmlmaWVzIHRoZSBTTVRQIHRyYW5zcG9ydCB1c2VkIGJ5XG4gKiB0aGUgYHNlbmRfZW1haWxgIHRvb2wsIGFuZCBleHBvc2VzIHNlbmRpbmcgYXMgYW4gQXBwS2l0IGFnZW50IHRvb2wuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBjcmVhdGVBcHAsIHNlcnZlciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbiAqIGltcG9ydCB7IHBsdWdpbiBhcyBlbWFpbFBsdWdpbiB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG4gKlxuICogYXdhaXQgY3JlYXRlQXBwKHtcbiAqICAgcGx1Z2luczogW1xuICogICAgIHNlcnZlcigpLFxuICogICAgIGVtYWlsUGx1Z2luLmVtYWlsKHtcbiAqICAgICAgIHNtdHA6IHsgaG9zdDogXCJzbXRwLmV4YW1wbGUuY29tXCIsIHVzZXI6IFwiYXBpa2V5XCIsIHBhc3N3b3JkOiBwcm9jZXNzLmVudi5TTVRQX0tFWSB9LFxuICogICAgICAgZG9tYWluOiBcIm1haWwuZXhhbXBsZS5jb21cIixcbiAqICAgICB9KSxcbiAqICAgXSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBFbWFpbFBsdWdpbiBleHRlbmRzIFBsdWdpbjxFbWFpbFBsdWdpbkNvbmZpZz4gaW1wbGVtZW50cyBUb29sUHJvdmlkZXIge1xuICBzdGF0aWMgbWFuaWZlc3QgPSB7XG4gICAgbmFtZTogXCJlbWFpbFwiLFxuICAgIGRpc3BsYXlOYW1lOiBcIkVtYWlsXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlNlbmRzIGFwcHJvdmFsLWdhdGVkIGVtYWlsIG92ZXIgU01UUCwgd2l0aCB0aGUgc2VuZGVyIGRlcml2ZWQgZnJvbSBcIiArXG4gICAgICBcInRoZSBvbi1iZWhhbGYtb2YgdXNlcidzIGFkZHJlc3Mgb24gYSBjb25maWd1cmVkIGRvbWFpbi5cIixcbiAgICBzdGFiaWxpdHk6IFwiYmV0YVwiLFxuICAgIHJlc291cmNlczoge1xuICAgICAgcmVxdWlyZWQ6IFtdLFxuICAgICAgb3B0aW9uYWw6IFtdLFxuICAgIH0sXG4gICAgY29uZmlnOiB7IHNjaGVtYTogRU1BSUxfQ09ORklHX1NDSEVNQSB9LFxuICB9IHNhdGlzZmllcyBQbHVnaW5NYW5pZmVzdDxcImVtYWlsXCI+O1xuXG4gIC8qKlxuICAgKiBUaGUgdG9vbCB0aGlzIHBsdWdpbiBvZmZlcnMgdG8gYW4gQXBwS2l0IGFnZW50LlxuICAgKlxuICAgKiBOb3QgYGF1dG9Jbmhlcml0YWJsZWA6IGEgc2VuZCBpcyBpcnJldmVyc2libGUgYW5kIGxlYXZlcyB0aGUgd29ya3NwYWNlLFxuICAgKiBzbyBpdCBtdXN0IG9ubHkgYXBwZWFyIGluIGFuIGFnZW50IHRoYXQgYXNrZWQgZm9yIGl0IGFuZCBhY2NlcHRlZCB0aGVcbiAgICogc2VuZGVyIHBvbGljeSB0aGF0IGNvbWVzIHdpdGggaXQuXG4gICAqXG4gICAqIGBleGVjdXRlYCByZS1wYXJzZXMgaXRzIGFyZ3VtZW50cyB3aXRoIHRoZSBsb2NhbCBzY2hlbWE6IEFwcEtpdCB2YWxpZGF0ZXNcbiAgICogYWdhaW5zdCB0aGUgc2FtZSBzY2hlbWEgZmlyc3QsIGJ1dCByZS1wYXJzaW5nIGlzIHdoYXQgZ2l2ZXMgdGhlIGJvZHkgdHlwZWRcbiAgICogYXJndW1lbnRzIGluc3RlYWQgb2YgYHVua25vd25gLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0b29sczogVG9vbFJlZ2lzdHJ5ID0ge1xuICAgIFtTRU5EX1RPT0xdOiBkZWZpbmVUb29sKHtcbiAgICAgIGRlc2NyaXB0aW9uOiBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OLFxuICAgICAgc2NoZW1hOiBlbWFpbFdpcmUuZW1haWxNZXNzYWdlU2NoZW1hLFxuICAgICAgYW5ub3RhdGlvbnM6IHsgZWZmZWN0OiBcIndyaXRlXCIsIHJlcXVpcmVzVXNlckNvbnRleHQ6IHRydWUgfSxcbiAgICAgIGF1dG9Jbmhlcml0YWJsZTogZmFsc2UsXG4gICAgICBleGVjdXRlOiBhc3luYyAoYXJncywgc2lnbmFsKSA9PlxuICAgICAgICB0aGlzLnNlbmQoZW1haWxXaXJlLmVtYWlsTWVzc2FnZVNjaGVtYS5wYXJzZShhcmdzKSwgdW5kZWZpbmVkLCBzaWduYWwpLFxuICAgIH0pLFxuICB9O1xuXG4gIC8qKlxuICAgKiBQcmltZSB0aGUgc2hhcmVkIHJ1bnRpbWUgZnJvbSB0aGlzIHBsdWdpbidzIGNvbmZpZyAob3ZlciBlbnYpLCByb3V0ZSB0aGVcbiAgICogdG9vbHMnIHNlbmRzIHRocm91Z2ggdGhpcyBwbHVnaW4ncyBpbnRlcmNlcHRvciBjaGFpbiwgYW5kIGxvZyB0aGVcbiAgICogZWZmZWN0aXZlIHNlbmRlciBwb2xpY3kgc28gYW4gYWN0aXZlIHJlc3RyaWN0aW9uIGlzIG9idmlvdXMgYXQgYm9vdC4gSW5cbiAgICogU01UUCBtb2RlLCBmYWlsIHNldHVwIHdoZW4gdGhlIHRyYW5zcG9ydCBjYW5ub3QgYmUgdmVyaWZpZWQ6IGEgYmFkIGhvc3RcbiAgICogb3IgY3JlZGVudGlhbCBpcyBhIGRlcGxveS10aW1lIG1pc3Rha2UgYW5kIHNob3VsZCBzdG9wIHRoZSBhcHAgcmF0aGVyXG4gICAqIHRoYW4gd2FpdCBmb3IgYSB1c2VyIHRvIGFwcHJvdmUgYSBzZW5kIHRoYXQgY2Fubm90IHdvcmsuIFdpdGggbm8gU01UUFxuICAgKiBjcmVkZW50aWFscyB0aGUgcnVudGltZSBpcyBpbiBmaWxlL291dGJveCBtb2RlIChvbmx5IHdoZW5cbiAgICogYEVNQUlMX09VVEJPWF9NT0RFYCBpcyBzZXQpLCBsb2dnZWQgbG91ZGx5IGhlcmUgc28gaXQgaXMgb2J2aW91cyBtYWlsXG4gICAqIGlzIGJlaW5nIHdyaXR0ZW4gdG8gZGlzayByYXRoZXIgdGhhbiBzZW50LlxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgc2V0dXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyB0cmFuc3BvcnRlciwgY29uZmlnIH0gPSBnZXRFbWFpbFJ1bnRpbWUodGhpcy5jb25maWcpO1xuICAgIHNldEVtYWlsRXhlY3V0b3IoKGZuLCBzZXR0aW5ncykgPT4gdGhpcy5leGVjdXRlKGZuLCBzZXR0aW5ncykpO1xuICAgIGNvbnN0IHBvbGljeSA9IHtcbiAgICAgIG1vZGU6IGNvbmZpZy5tb2RlLFxuICAgICAgc2VuZGVyUG9saWN5OiBjb25maWcuc2VuZGVyUG9saWN5LFxuICAgICAgcmVzdHJpY3RlZDogY29uZmlnLmFsbG93ZWRTZW5kZXJzLmxlbmd0aCA+IDAsXG4gICAgICAuLi4oY29uZmlnLmFsbG93ZWRTZW5kZXJzLmxlbmd0aCA+IDAgPyB7IGFsbG93ZWRTZW5kZXJzOiBjb25maWcuYWxsb3dlZFNlbmRlcnMgfSA6IHt9KSxcbiAgICB9O1xuICAgIGlmIChjb25maWcubW9kZSA9PT0gXCJmaWxlXCIpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwib3V0Ym94OmVuYWJsZWRcIiwge1xuICAgICAgICBkaXI6IGNvbmZpZy5vdXREaXIsXG4gICAgICAgIHJlYXNvbjogXCJubyBTTVRQIGNyZWRlbnRpYWxzIGNvbmZpZ3VyZWQ7IGVtYWlscyBhcmUgd3JpdHRlbiB0byBkaXNrIGluc3RlYWQgb2Ygc2VudFwiLFxuICAgICAgfSk7XG4gICAgICBsb2dnZXIuaW5mbyhcInJlYWR5XCIsIHBvbGljeSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHZlcmlmaWVkID0gYXdhaXQgdGhpcy5leGVjdXRlKFxuICAgICAgYXN5bmMgKHNpZ25hbCkgPT4gdmVyaWZ5RW1haWxUcmFuc3BvcnQodHJhbnNwb3J0ZXIsIHNpZ25hbCksXG4gICAgICBFTUFJTF9WRVJJRllfU0VUVElOR1MsXG4gICAgKTtcbiAgICBpZiAoIXZlcmlmaWVkLm9rKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoXCJzbXRwOnVudmVyaWZpZWRcIiwge1xuICAgICAgICBob3N0OiBjb25maWcuaG9zdCxcbiAgICAgICAgcG9ydDogY29uZmlnLnBvcnQsXG4gICAgICAgIHN0YXR1czogdmVyaWZpZWQuc3RhdHVzLFxuICAgICAgICBlcnJvcjogdmVyaWZpZWQubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgICAgdGhyb3cgQ29uZmlndXJhdGlvbkVycm9yLmludmFsaWRDb25uZWN0aW9uKFxuICAgICAgICBcIlNNVFBcIixcbiAgICAgICAgYENvdWxkIG5vdCB2ZXJpZnkgJHtjb25maWcuaG9zdH06JHtjb25maWcucG9ydH0uIENoZWNrIFNNVFBfSE9TVCwgU01UUF9QT1JULCBTTVRQX1NFQ1VSRSwgYW5kIHRoZSBjcmVkZW50aWFscywgb3Igc2V0IEVNQUlMX09VVEJPWF9NT0RFPTEgZm9yIGxvY2FsIG91dGJveCB0ZXN0aW5nLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbyhcInJlYWR5XCIsIHtcbiAgICAgIC4uLnBvbGljeSxcbiAgICAgIGhvc3Q6IGNvbmZpZy5ob3N0LFxuICAgICAgcG9ydDogY29uZmlnLnBvcnQsXG4gICAgICBzZWN1cmU6IGNvbmZpZy5zZWN1cmUsXG4gICAgfSk7XG4gIH1cblxuICAvKiogQ2xvc2UgdGhlIFNNVFAgY29ubmVjdGlvbiBwb29sLiBJZGVtcG90ZW50LiAqL1xuICBhc3luYyBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXNldEVtYWlsUnVudGltZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFib3J0IGluLWZsaWdodCB3b3JrLiBBcHBLaXQncyBncmFjZWZ1bCBzaHV0ZG93biBvbmx5IGludm9rZXMgdGhpcyBob29rIC1cbiAgICogaXQgbmV2ZXIgY2FsbHMge0BsaW5rIHNodXRkb3dufSAtIHNvIHRoZSBTTVRQIHBvb2wgaXMgY2xvc2VkIGZyb20gaGVyZSBvclxuICAgKiBpdCBsZWFrcyBhdCBTSUdURVJNLiBUaGUgdGVhcmRvd24gaXMgc3luY2hyb25vdXMgYW5kIGlkZW1wb3RlbnQsIHNvIHRoZVxuICAgKiB1bi1hd2FpdGVkIGNhbGwgY29zdHMgbm90aGluZy5cbiAgICovXG4gIG92ZXJyaWRlIGFib3J0QWN0aXZlT3BlcmF0aW9ucygpOiB2b2lkIHtcbiAgICBzdXBlci5hYm9ydEFjdGl2ZU9wZXJhdGlvbnMoKTtcbiAgICB2b2lkIHRoaXMuc2h1dGRvd24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvc2UgdGhlIHNlbmRlci1vcHRpb25zIGxvb2t1cCBzbyBVSSBjb21wb3NlIHZpZXdzIGNhbiBwb3B1bGF0ZSBhXG4gICAqIGBGcm9tYCBkcm9wZG93biBmcm9tIHRoZSBjb25maWd1cmVkIGFsbG93LWxpc3QuIE1vdW50ZWQgdW5kZXIgdGhlXG4gICAqIHBsdWdpbiBiYXNlIHBhdGgsIGkuZS4gYEdFVCAvYXBpL2VtYWlsL3NlbmRlcnNgLiBSdW5zIGluIHRoZSBPQk9cbiAgICogdXNlciBzY29wZSBzbyBkb21haW4gd2lsZGNhcmRzIHJlc29sdmUgYWdhaW5zdCB0aGUgY2FsbGVyJ3Mgb3duXG4gICAqIGxvY2FsIHBhcnQuXG4gICAqL1xuICBvdmVycmlkZSBpbmplY3RSb3V0ZXMocm91dGVyOiBJQXBwUm91dGVyKTogdm9pZCB7XG4gICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgIG5hbWU6IFwibGlzdFNlbmRlcnNcIixcbiAgICAgIG1ldGhvZDogXCJnZXRcIixcbiAgICAgIHBhdGg6IFNFTkRFUlNfUk9VVEUsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hc1VzZXIocmVxKS5leGVjdXRlTGlzdFNlbmRlcnMoKTtcbiAgICAgICAgaWYgKCFyZXN1bHQub2spIHtcbiAgICAgICAgICByZXMuc3RhdHVzKHJlc3VsdC5zdGF0dXMpLmpzb24oeyBlcnJvcjogcmVzdWx0Lm1lc3NhZ2UgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5qc29uKHJlc3VsdC5kYXRhKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBvdmVycmlkZSBleHBvcnRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIFNlbmQgYSBtZXNzYWdlIGltbWVkaWF0ZWx5IGZyb20gYGZyb21gIHRocm91Z2ggdGhlIHNoYXJlZFxuICAgICAgICogdHJhbnNwb3J0LCBieXBhc3NpbmcgdGhlIGFwcHJvdmFsIGZsb3cuIEZvciBhZ2VudC1kcml2ZW4gc2VuZHNcbiAgICAgICAqIHVzZSB7QGxpbmsgZW1haWxUb29sfSBpbnN0ZWFkLlxuICAgICAgICovXG4gICAgICBzZW5kRW1haWw6IChcbiAgICAgICAgbWVzc2FnZTogRW1haWxNZXNzYWdlLFxuICAgICAgICBmcm9tOiBzdHJpbmcsXG4gICAgICAgIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuICAgICAgKTogUHJvbWlzZTxFbWFpbFJlc3VsdD4gPT4gdGhpcy5zZW5kKG1lc3NhZ2UsIGZyb20sIHNpZ25hbCksXG4gICAgICAvKipcbiAgICAgICAqIFNlbmRlciBvcHRpb25zIGZvciB0aGUgY3VycmVudCB1c2VyICh0aGUgYEdFVCAvc2VuZGVyc2AgcGF5bG9hZCkuXG4gICAgICAgKiBBcHBLaXQgd3JhcHMgdGhpcyB3aXRoIGBhc1VzZXIocmVxKWAgZm9yIE9CTyBzY29waW5nLlxuICAgICAgICovXG4gICAgICBsaXN0U2VuZGVyczogYXN5bmMgKCk6IFByb21pc2U8RW1haWxTZW5kZXJzPiA9PiB1bndyYXAoYXdhaXQgdGhpcy5leGVjdXRlTGlzdFNlbmRlcnMoKSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBBcHBLaXQgYFRvb2xQcm92aWRlcmA6IHRoZSB0b29sIGRlZmluaXRpb25zIG9mZmVyZWQgdG8gYW4gYWdlbnQuICovXG4gIGdldEFnZW50VG9vbHMoKTogQWdlbnRUb29sRGVmaW5pdGlvbltdIHtcbiAgICByZXR1cm4gdG9vbHNGcm9tUmVnaXN0cnkodGhpcy50b29scyk7XG4gIH1cblxuICAvKipcbiAgICogQXBwS2l0IGBUb29sUHJvdmlkZXJgOiBydW4gb25lIHRvb2wgY2FsbC4gQXJndW1lbnRzIGFyZSB2YWxpZGF0ZWQgYWdhaW5zdFxuICAgKiB0aGUgdG9vbCdzIHNjaGVtYSBmaXJzdCwgYW5kIGEgdmFsaWRhdGlvbiBmYWlsdXJlIGNvbWVzIGJhY2sgYXMgYW5cbiAgICogTExNLWZyaWVuZGx5IHN0cmluZyBzbyB0aGUgbW9kZWwgY2FuIGNvcnJlY3QgaXRzZWxmIG9uIHRoZSBuZXh0IHR1cm4uXG4gICAqL1xuICBhc3luYyBleGVjdXRlQWdlbnRUb29sKG5hbWU6IHN0cmluZywgYXJnczogdW5rbm93biwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICByZXR1cm4gZXhlY3V0ZUZyb21SZWdpc3RyeSh0aGlzLnRvb2xzLCBuYW1lLCBhcmdzLCBzaWduYWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgb25lIG1lc3NhZ2UsIHJlc29sdmluZyB0aGUgc2VuZGVyIGZvciB0aGUgY2FsbGVyIGluIHNjb3BlIHdoZW5cbiAgICogYGZyb21gIGlzIG5vdCBwaW5uZWQuIFRoZSBpbnRlcmNlcHRvciBjaGFpbiBpcyBhcHBsaWVkIGluc2lkZVxuICAgKiB7QGxpbmsgc2VuZEVtYWlsfSB0aHJvdWdoIHRoZSBleGVjdXRvciBpbnN0YWxsZWQgYXQgc2V0dXAsIHNvIHRoaXMgbXVzdFxuICAgKiBub3Qgd3JhcCBpdCBhZ2Fpbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2VuZChcbiAgICBtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsXG4gICAgZnJvbTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPEVtYWlsUmVzdWx0PiB7XG4gICAgcmV0dXJuIHNlbmRFbWFpbChtZXNzYWdlLCBmcm9tID8/IHRoaXMucmVzb2x2ZVNlbmRlcigpLCBzaWduYWwpO1xuICB9XG5cbiAgLyoqIFJ1biB0aGUgc2VuZGVyLW9wdGlvbnMgbG9va3VwIHRocm91Z2ggdGhlIHBsdWdpbidzIGludGVyY2VwdG9yIGNoYWluLiAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVMaXN0U2VuZGVycygpOiBQcm9taXNlPEV4ZWN1dGlvblJlc3VsdDxFbWFpbFNlbmRlcnM+PiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZShhc3luYyAoKSA9PiB0aGlzLmxpc3RTZW5kZXJzKCksIEVNQUlMX1NFTkRFUlNfU0VUVElOR1MpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgdGhlIGBGcm9tYCBvcHRpb25zIG9mZmVyZWQgdG8gdGhlIGN1cnJlbnQgdXNlcjogdGhlIGNvbmNyZXRlXG4gICAqIGFkZHJlc3NlcyB0aGUgZWZmZWN0aXZlIGFsbG93LWxpc3QgcGVybWl0cyAoZG9tYWluIHdpbGRjYXJkcyBleHBhbmRlZFxuICAgKiBhZ2FpbnN0IHRoZSBPQk8gdXNlcidzIGxvY2FsIHBhcnQpLCB0aGUgZGVmYXVsdCBhbW9uZyB0aGVtLCBhbmRcbiAgICogd2hldGhlciB0aGUgbGlzdCBpcyBhbiBlbmZvcmNlZCByZXN0cmljdGlvbi4gU2VlXG4gICAqIHtAbGluayBsaXN0U2VuZGVyT3B0aW9uc30uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxpc3RTZW5kZXJzKCk6IFByb21pc2U8RW1haWxTZW5kZXJzPiB7XG4gICAgY29uc3QgeyBjb25maWcgfSA9IGdldEVtYWlsUnVudGltZSgpO1xuICAgIGNvbnN0IHNlbmRlcnMgPSBsaXN0U2VuZGVyT3B0aW9ucyhjb25maWcsIGN1cnJlbnRVc2VyRW1haWwoKSk7XG4gICAgLy8gUHJlZmVyIHRoZSBhZGRyZXNzIGEgc2VuZCB3b3VsZCBhY3R1YWxseSBkZWZhdWx0IHRvOyBmYWxsIGJhY2sgdG9cbiAgICAvLyB0aGUgZmlyc3Qgb2ZmZXJlZCBvcHRpb24gd2hlbiB0aGF0IGNhbid0IGJlIHJlc29sdmVkIC8gcGVybWl0dGVkLlxuICAgIGxldCBkZWZhdWx0U2VuZGVyID0gc2VuZGVyc1swXTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSB0aGlzLnJlc29sdmVTZW5kZXIoKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGlzU2VuZGVyQWxsb3dlZChyZXNvbHZlZCwgY29uZmlnLmFsbG93ZWRTZW5kZXJzKSkgZGVmYXVsdFNlbmRlciA9IHJlc29sdmVkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gS2VlcCB0aGUgZmlyc3Qgb2ZmZXJlZCBvcHRpb24gKG9yIG5vbmUpIGFzIHRoZSBkZWZhdWx0LlxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgc2VuZGVycyxcbiAgICAgIC4uLihkZWZhdWx0U2VuZGVyID8geyBkZWZhdWx0U2VuZGVyIH0gOiB7fSksXG4gICAgICByZXN0cmljdGVkOiBjb25maWcuYWxsb3dlZFNlbmRlcnMubGVuZ3RoID4gMCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFRoZSBgRnJvbWAgYSBzZW5kIGRlZmF1bHRzIHRvIGZvciB0aGUgY2FsbGVyIGluIHNjb3BlLiAqL1xuICBwcml2YXRlIHJlc29sdmVTZW5kZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZVNlbmRlckFkZHJlc3MoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLCBjdXJyZW50VXNlckVtYWlsKCkpO1xuICB9XG59XG5cbi8qKiBUaGUgT0JPIHVzZXIncyBhZGRyZXNzLCBvciB1bmRlZmluZWQgb3V0c2lkZSBhIHVzZXIgY29udGV4dC4gKi9cbmZ1bmN0aW9uIGN1cnJlbnRVc2VyRW1haWwoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY3R4ID0gZ2V0RXhlY3V0aW9uQ29udGV4dCgpO1xuICByZXR1cm4gXCJpc1VzZXJDb250ZXh0XCIgaW4gY3R4ID8gY3R4LnVzZXJFbWFpbCA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZS1yYWlzZSBhIGZhaWxlZCBleGVjdXRpb24gYXMgdGhlIEFwcEtpdCBlcnJvciBjbGFzcyB0aGF0IGFscmVhZHkgY2Fycmllc1xuICogdGhlIHN0YXR1cyBBcHBLaXQgcmVzb2x2ZWQsIHNvIGEgcHJvZ3JhbW1hdGljIGNhbGxlciBzZWVzIHRoZSBzYW1lIDQwMCAvXG4gKiA0MDEgLyA1MDMgYW4gSFRUUCBjYWxsZXIgd291bGQuXG4gKi9cbmZ1bmN0aW9uIHRvQXBwS2l0RXJyb3Ioc3RhdHVzOiBudW1iZXIsIG1lc3NhZ2U6IHN0cmluZyk6IEFwcEtpdEVycm9yIHtcbiAgaWYgKHN0YXR1cyA9PT0gNDAwKSByZXR1cm4gbmV3IFZhbGlkYXRpb25FcnJvcihtZXNzYWdlKTtcbiAgaWYgKHN0YXR1cyA9PT0gNDAxKSByZXR1cm4gbmV3IEF1dGhlbnRpY2F0aW9uRXJyb3IobWVzc2FnZSk7XG4gIGlmIChzdGF0dXMgPT09IDUwMykgcmV0dXJuIG5ldyBDb25uZWN0aW9uRXJyb3IobWVzc2FnZSk7XG4gIHJldHVybiBuZXcgRXhlY3V0aW9uRXJyb3IobWVzc2FnZSk7XG59XG5cbi8qKlxuICogU3VyZmFjZSBhIGZhaWxlZCB7QGxpbmsgRXhlY3V0aW9uUmVzdWx0fSB0byBhIHByb2dyYW1tYXRpYyBjYWxsZXIgYXMgYVxuICogdGhyb3cuIEhUVFAgaGFuZGxlcnMgbWFwIGBzdGF0dXNgIG9udG8gdGhlIHJlc3BvbnNlIGluc3RlYWQuXG4gKi9cbmZ1bmN0aW9uIHVud3JhcDxUPihyZXN1bHQ6IEV4ZWN1dGlvblJlc3VsdDxUPik6IFQge1xuICBpZiAocmVzdWx0Lm9rKSByZXR1cm4gcmVzdWx0LmRhdGE7XG4gIHRocm93IHRvQXBwS2l0RXJyb3IocmVzdWx0LnN0YXR1cywgcmVzdWx0Lm1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBlbWFpbCBwbHVnaW4uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBjcmVhdGVBcHAsIHNlcnZlciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbiAqIGltcG9ydCB7IGJyYW5kLCBwbHVnaW4gYXMgZW1haWxQbHVnaW4gfSBmcm9tIFwiQGRieC10b29scy9lbWFpbFwiO1xuICpcbiAqIGF3YWl0IGNyZWF0ZUFwcCh7XG4gKiAgIHBsdWdpbnM6IFtcbiAqICAgICBzZXJ2ZXIoKSxcbiAqICAgICBlbWFpbFBsdWdpbi5lbWFpbCh7XG4gKiAgICAgICBkb21haW46IFwibWFpbC5leGFtcGxlLmNvbVwiLFxuICogICAgICAgYWxsb3dlZFNlbmRlcnM6IFtcIipAbWFpbC5leGFtcGxlLmNvbVwiXSxcbiAqICAgICAgIGJyYW5kOiBicmFuZC5kZWZhdWx0RW1haWxCcmFuZCxcbiAqICAgICB9KSxcbiAqICAgXSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBlbWFpbCA9IHRvUGx1Z2luKEVtYWlsUGx1Z2luKTtcbiJdfQ==
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/brand.ts","../src/config.ts","../src/defaults.ts","../src/email-html.ts","../src/juice.d.ts","../src/markdown.ts","../src/outbox.ts","../src/plugin.ts","../src/sender.ts","../src/tool.ts","../src/transport.ts","../
|
|
1
|
+
{"root":["../src/brand.ts","../src/config.ts","../src/defaults.ts","../src/email-html.ts","../src/juice.d.ts","../src/markdown.ts","../src/outbox.ts","../src/plugin.ts","../src/sender.ts","../src/tool.ts","../src/transport.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -27,10 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@databricks/appkit": "^0.43.0",
|
|
30
|
-
"@dbx-tools/shared-core": "0.6.
|
|
31
|
-
"@dbx-tools/shared-email": "0.6.
|
|
30
|
+
"@dbx-tools/shared-core": "0.6.45",
|
|
31
|
+
"@dbx-tools/shared-email": "0.6.45",
|
|
32
32
|
"@mastra/core": "^1.47.0",
|
|
33
|
-
"jose": "^6.2.3",
|
|
34
33
|
"juice": "^12.1.1",
|
|
35
34
|
"marked": "^18.0.5",
|
|
36
35
|
"nodemailer": "^7.0.13"
|
|
@@ -49,7 +48,7 @@
|
|
|
49
48
|
"./package.json": "./package.json"
|
|
50
49
|
}
|
|
51
50
|
},
|
|
52
|
-
"version": "0.6.
|
|
51
|
+
"version": "0.6.45",
|
|
53
52
|
"types": "index.ts",
|
|
54
53
|
"type": "module",
|
|
55
54
|
"exports": {
|
package/src/config.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { resolve } from "node:path";
|
|
27
27
|
import { ConfigurationError, ValidationError, type BasePluginConfig } from "@databricks/appkit";
|
|
28
|
-
import { object
|
|
28
|
+
import { object } from "@dbx-tools/shared-core";
|
|
29
29
|
import type { JSONSchema7 } from "json-schema";
|
|
30
30
|
import type { EmailBrand } from "./brand.ts";
|
|
31
31
|
import { parseAllowedSenders } from "./sender.ts";
|
|
@@ -114,33 +114,6 @@ export interface EmailPluginConfig extends BasePluginConfig {
|
|
|
114
114
|
* `BrandContext`.
|
|
115
115
|
*/
|
|
116
116
|
brand?: EmailBrand;
|
|
117
|
-
/**
|
|
118
|
-
* Optional email-OTP ACCESS GATE. When `enabled`, the plugin mounts a login
|
|
119
|
-
* flow (`/api/email/auth/*`) and gates every other route behind a session
|
|
120
|
-
* cookie - the front door for an app exposed publicly (e.g. through a portr
|
|
121
|
-
* tunnel that bypasses the Databricks OAuth proxy). Reuses this plugin's
|
|
122
|
-
* transport to email the code. Omit or `enabled: false` to leave the app open.
|
|
123
|
-
*/
|
|
124
|
-
auth?: AuthConfig;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** Email-OTP access-gate configuration (see {@link EmailPluginConfig.auth}). */
|
|
128
|
-
export interface AuthConfig {
|
|
129
|
-
/** Turn the gate on. Falls back to `EMAIL_AUTH_ENABLED`. Default off. */
|
|
130
|
-
enabled?: boolean;
|
|
131
|
-
/**
|
|
132
|
-
* Who may request a code. Each entry is a domain shortcut (`databricks.com`
|
|
133
|
-
* or `@databricks.com`), a glob (`*.databricks.com`), or a `/regex/`. An
|
|
134
|
-
* EMPTY list allows nobody (fail closed). Falls back to `EMAIL_AUTH_ALLOW`
|
|
135
|
-
* (comma/space-separated).
|
|
136
|
-
*/
|
|
137
|
-
allow?: string | string[];
|
|
138
|
-
/** Session lifetime (seconds). Falls back to `EMAIL_AUTH_SESSION_TTL`. Default 43200 (12h). */
|
|
139
|
-
sessionTtlSeconds?: number;
|
|
140
|
-
/** One-time-code lifetime (seconds). Falls back to `EMAIL_AUTH_CODE_TTL`. Default 600 (10m). */
|
|
141
|
-
codeTtlSeconds?: number;
|
|
142
|
-
/** Max verify attempts per issued code. Default 5. */
|
|
143
|
-
maxAttempts?: number;
|
|
144
117
|
}
|
|
145
118
|
|
|
146
119
|
/** Config shared by both resolved modes. */
|
|
@@ -260,71 +233,9 @@ export const EMAIL_CONFIG_SCHEMA: JSONSchema7 = {
|
|
|
260
233
|
},
|
|
261
234
|
required: ["accent", "fontFamily"],
|
|
262
235
|
},
|
|
263
|
-
auth: {
|
|
264
|
-
type: "object",
|
|
265
|
-
description:
|
|
266
|
-
"Email-OTP access gate. When enabled, mounts a login flow at /api/email/auth/* and gates every other route behind a session cookie.",
|
|
267
|
-
properties: {
|
|
268
|
-
enabled: {
|
|
269
|
-
type: "boolean",
|
|
270
|
-
description: "Turn the gate on (env EMAIL_AUTH_ENABLED). Default off.",
|
|
271
|
-
},
|
|
272
|
-
allow: {
|
|
273
|
-
type: "array",
|
|
274
|
-
items: { type: "string" },
|
|
275
|
-
description:
|
|
276
|
-
'Allow-list of who may request a code: domain shortcut ("databricks.com"), glob ("*.databricks.com"), or "/regex/". Empty = nobody. Also accepts a comma/space-separated string. Env EMAIL_AUTH_ALLOW.',
|
|
277
|
-
},
|
|
278
|
-
sessionTtlSeconds: {
|
|
279
|
-
type: "number",
|
|
280
|
-
description: "Session lifetime in seconds (env EMAIL_AUTH_SESSION_TTL). Default 43200.",
|
|
281
|
-
},
|
|
282
|
-
codeTtlSeconds: {
|
|
283
|
-
type: "number",
|
|
284
|
-
description: "One-time-code lifetime in seconds (env EMAIL_AUTH_CODE_TTL). Default 600.",
|
|
285
|
-
},
|
|
286
|
-
maxAttempts: {
|
|
287
|
-
type: "number",
|
|
288
|
-
description: "Max verify attempts per issued code. Default 5.",
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
236
|
},
|
|
293
237
|
};
|
|
294
238
|
|
|
295
|
-
/** Resolved email-OTP gate config, with env fallbacks applied (or `undefined` when off). */
|
|
296
|
-
export interface ResolvedAuthConfig {
|
|
297
|
-
readonly allow: string[];
|
|
298
|
-
readonly sessionTtlSeconds: number;
|
|
299
|
-
readonly codeTtlSeconds: number;
|
|
300
|
-
readonly maxAttempts: number;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Resolve {@link AuthConfig} against env, returning `undefined` when the gate is
|
|
305
|
-
* off. `enabled` gates everything; `allow` merges the config list + env
|
|
306
|
-
* (`parseList` handles a `string[]` or a delimited string). Empty `allow` is
|
|
307
|
-
* allowed here (the gate then denies everyone - a deliberate fail-closed state).
|
|
308
|
-
*/
|
|
309
|
-
export function resolveAuthConfig(auth: AuthConfig | undefined): ResolvedAuthConfig | undefined {
|
|
310
|
-
const enabled = auth?.enabled ?? object.toBoolean(process.env.EMAIL_AUTH_ENABLED) ?? false;
|
|
311
|
-
if (!enabled) return undefined;
|
|
312
|
-
const allow = [
|
|
313
|
-
...string.parseList(auth?.allow),
|
|
314
|
-
...string.parseList(process.env.EMAIL_AUTH_ALLOW),
|
|
315
|
-
];
|
|
316
|
-
const num = (value: number | undefined, env: string | undefined, fallback: number): number => {
|
|
317
|
-
const raw = value ?? (env ? Number(env) : undefined);
|
|
318
|
-
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : fallback;
|
|
319
|
-
};
|
|
320
|
-
return {
|
|
321
|
-
allow,
|
|
322
|
-
sessionTtlSeconds: num(auth?.sessionTtlSeconds, process.env.EMAIL_AUTH_SESSION_TTL, 43200),
|
|
323
|
-
codeTtlSeconds: num(auth?.codeTtlSeconds, process.env.EMAIL_AUTH_CODE_TTL, 600),
|
|
324
|
-
maxAttempts: auth?.maxAttempts ?? 5,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
239
|
/** Parse the `SMTP_SECURE` env / config flag, defaulting by port. */
|
|
329
240
|
function resolveSecure(flag: boolean | undefined, port: number): boolean {
|
|
330
241
|
if (typeof flag === "boolean") return flag;
|