sliftutils 1.7.130 → 1.7.132
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.d.ts +4 -51
- package/package.json +1 -1
- package/security/authorizedKeys/authorizedKeys.d.ts +37 -0
- package/security/authorizedKeys/daemon/changes.d.ts +17 -0
- package/security/authorizedKeys/daemon/git.d.ts +35 -0
- package/security/authorizedKeys/daemon/notify.d.ts +8 -0
- package/security/authorizedKeys/daemon/paths.d.ts +15 -0
- package/security/authorizedKeys/daemon/repoFiles.d.ts +25 -0
- package/security/authorizedKeys/daemon/revocation.d.ts +74 -0
- package/security/authorizedKeys/daemon/sessions.d.ts +19 -0
- package/security/authorizedKeys/daemon/state.d.ts +67 -0
- package/security/authorizedKeys/daemon/trust.d.ts +20 -0
- package/security/authorizedKeys/keysRepo.d.ts +10 -0
- package/security/authorizedKeys/revokeSource.d.ts +13 -0
- package/security/authorizedKeys/sources.d.ts +17 -0
- package/security/helpers/paths.d.ts +4 -0
- package/security/helpers/spawn.d.ts +16 -0
- package/security/keys/deriveKey.d.ts +16 -0
- package/security/keys/sshKeyFile.d.ts +18 -0
- package/security/machines/addMachine.ts +76 -24
- package/security/machines/dist/addMachine.ts.cache +6 -5
- package/security/machines/dist/machines.ts.cache +80 -13
- package/security/machines/machines.d.ts +81 -0
- package/security/machines/machines.ts +89 -14
- package/security/notifications/discord.d.ts +36 -0
- package/security/signedFiles/manifest.d.ts +44 -0
- package/storage/remoteStorage/ArchivesRemote.ts +8 -10
- package/storage/remoteStorage/accessPage.tsx +13 -90
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +11 -12
- package/storage/remoteStorage/dist/serverConfig.ts.cache +7 -49
- package/storage/remoteStorage/dist/storageController.ts.cache +33 -114
- package/storage/remoteStorage/serverConfig.d.ts +0 -10
- package/storage/remoteStorage/serverConfig.ts +6 -48
- package/storage/remoteStorage/storageController.d.ts +4 -36
- package/storage/remoteStorage/storageController.ts +40 -126
- package/storage/remoteStorage/storageServer.ts +1 -8
- package/storage/remoteStorage/storageServerCli.ts +14 -0
- package/storage/remoteStorage/grantAccess.js +0 -4
- package/storage/remoteStorage/grantAccessCli.d.ts +0 -1
- package/storage/remoteStorage/grantAccessCli.ts +0 -25
|
@@ -1,37 +1,75 @@
|
|
|
1
1
|
import os from "os";
|
|
2
|
+
import { runPromise } from "socket-function/src/runPromise";
|
|
2
3
|
import { getOwnIPs } from "../../misc/ownIPs";
|
|
3
4
|
import { describeHost } from "../helpers/remoteSSH";
|
|
4
5
|
import { createRemoteIdentity, Identity, localDomains, localIdentity, remoteIdentity } from "./identity";
|
|
5
6
|
import { resolveKeysRepo } from "../authorizedKeys/keysRepo";
|
|
7
|
+
import { signRepo } from "../signedFiles/signFiles";
|
|
6
8
|
import { getMachines, setMachines } from "./machines";
|
|
7
9
|
|
|
8
|
-
const
|
|
10
|
+
const GIT_KEYWORD = "git";
|
|
11
|
+
const COMMIT_MESSAGE = "trusting a machine";
|
|
12
|
+
// A machine id is the base32 hash of a public key, written with a leading b. Nothing else that can
|
|
13
|
+
// appear in these arguments looks like that, which is what tells it apart from an ssh target.
|
|
14
|
+
const MACHINE_ID = /^b[a-z2-7]{20}$/;
|
|
15
|
+
const USAGE = `Usage:
|
|
16
|
+
yarn addmachine <domain> [${GIT_KEYWORD}]
|
|
17
|
+
yarn addmachine <domain> <ssh-host> [${GIT_KEYWORD}]
|
|
18
|
+
yarn addmachine <domain> <machine-id> <ip> [ip...] [${GIT_KEYWORD}]
|
|
9
19
|
|
|
10
20
|
The domain is required: a machine has a different identity, and so a different machine id, under
|
|
11
21
|
every domain it runs under, so there is no such thing as "this machine" without one.
|
|
12
22
|
|
|
13
|
-
With
|
|
14
|
-
for its identity under that domain, gives it one if it has none, and adds it under that
|
|
23
|
+
With nothing else it adds this machine, with its own addresses. With an ssh host it asks that
|
|
24
|
+
machine for its identity under that domain, gives it one if it has none, and adds it under that
|
|
25
|
+
address. With a machine id it adds exactly that machine at exactly those addresses, without
|
|
26
|
+
talking to anything.
|
|
15
27
|
|
|
16
28
|
It edits the keys repo this machine reads, wherever that is, not whatever directory this was run
|
|
17
|
-
from.
|
|
18
|
-
|
|
29
|
+
from. With ${GIT_KEYWORD} it signs, commits and pushes; without it nothing else will believe any of
|
|
30
|
+
this until you do.`;
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
/** A domain, then either nothing, an ssh host, or a machine id and the addresses it may talk from. */
|
|
33
|
+
function parseArgs(argv: string[]) {
|
|
34
|
+
let pushToGit = argv.includes(GIT_KEYWORD);
|
|
35
|
+
let positional = argv.filter(arg => arg !== GIT_KEYWORD);
|
|
36
|
+
let [domain, second, ...rest] = positional;
|
|
37
|
+
if (!domain) {
|
|
38
|
+
throw new Error(`Expected a domain\n${USAGE}`);
|
|
39
|
+
}
|
|
40
|
+
if (!second) {
|
|
41
|
+
return { domain, host: "", machineId: "", addresses: [] as string[], pushToGit };
|
|
42
|
+
}
|
|
43
|
+
if (MACHINE_ID.test(second)) {
|
|
44
|
+
if (!rest.length) {
|
|
45
|
+
throw new Error(`Expected at least one address for ${second}, was none\n${USAGE}`);
|
|
46
|
+
}
|
|
47
|
+
return { domain, host: "", machineId: second, addresses: rest, pushToGit };
|
|
48
|
+
}
|
|
49
|
+
if (rest.length) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Expected nothing after the ssh host ${second}, was ${rest.join(" ")}.\n`
|
|
52
|
+
+ `Addresses are only given alongside a machine id.\n${USAGE}`
|
|
53
|
+
);
|
|
24
54
|
}
|
|
25
|
-
|
|
55
|
+
return { domain, host: second, machineId: "", addresses: [] as string[], pushToGit };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function main() {
|
|
59
|
+
let { domain, host, machineId, addresses, pushToGit } = parseArgs(process.argv.slice(2));
|
|
26
60
|
// The same repo the acceptance check reads. Editing anything else would write a machine list
|
|
27
61
|
// nothing on this machine ever looks at.
|
|
28
62
|
let { repoPath } = await resolveKeysRepo();
|
|
29
63
|
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
let describe = machineId;
|
|
65
|
+
if (machineId) {
|
|
66
|
+
// Named outright, so there is nothing to ask anyone. The id is the hash of that machine's
|
|
67
|
+
// public key, so naming it is enough - it still has to prove it holds the key before any
|
|
68
|
+
// of this means anything.
|
|
69
|
+
describe = `${machineId} (named)`;
|
|
70
|
+
} else if (!host) {
|
|
71
|
+
let identity = await localIdentity(domain);
|
|
72
|
+
if (!identity) {
|
|
35
73
|
throw new Error(
|
|
36
74
|
`Expected an identity for ${domain} in ${os.homedir()}, this machine has none.\n`
|
|
37
75
|
+ `It has: ${(await localDomains()).join(", ") || "no identities at all"}\n`
|
|
@@ -39,7 +77,8 @@ export async function main() {
|
|
|
39
77
|
+ ` first, or name another machine to add instead.`
|
|
40
78
|
);
|
|
41
79
|
}
|
|
42
|
-
|
|
80
|
+
machineId = identity.machineId;
|
|
81
|
+
describe = identity.fullDomain;
|
|
43
82
|
addresses = await getOwnIPs();
|
|
44
83
|
if (!addresses.length) {
|
|
45
84
|
throw new Error(`Expected this machine to have an address anything else can see, it has none`);
|
|
@@ -51,7 +90,9 @@ export async function main() {
|
|
|
51
90
|
if (!found) {
|
|
52
91
|
console.log(`${describeHost(host)} has no identity for ${domain}, generating one`);
|
|
53
92
|
}
|
|
54
|
-
identity = found || await createRemoteIdentity({ host, domain });
|
|
93
|
+
let identity: Identity = found || await createRemoteIdentity({ host, domain });
|
|
94
|
+
machineId = identity.machineId;
|
|
95
|
+
describe = identity.fullDomain;
|
|
55
96
|
// The address it was named by is the address it talks to us from, which is the one thing
|
|
56
97
|
// it cannot lie about.
|
|
57
98
|
addresses = [host];
|
|
@@ -60,25 +101,36 @@ export async function main() {
|
|
|
60
101
|
// The whole list is read and written back, because setting is by the set: writing this one
|
|
61
102
|
// machine alone would remove every other machine from the repo.
|
|
62
103
|
let machines = await getMachines(repoPath);
|
|
63
|
-
let existing = machines.find(machine => machine.machineId ===
|
|
104
|
+
let existing = machines.find(machine => machine.machineId === machineId);
|
|
64
105
|
let ips = [...(existing?.ips || [])];
|
|
65
106
|
let added = addresses.filter(address => !ips.includes(address));
|
|
66
107
|
if (existing) {
|
|
67
108
|
existing.ips = [...ips, ...added];
|
|
68
109
|
} else {
|
|
69
|
-
machines.push({ machineId
|
|
110
|
+
machines.push({ machineId, ips: [...added], addedAt: "" });
|
|
70
111
|
}
|
|
71
112
|
await setMachines({ repoPath, machines });
|
|
72
113
|
|
|
73
|
-
console.log(`\nTrusting machine ${
|
|
114
|
+
console.log(`\nTrusting machine ${machineId}`);
|
|
74
115
|
console.log(`Allowing IP ${[...ips, ...added].join(", ")}`);
|
|
75
116
|
if (added.length) {
|
|
76
|
-
console.log(` added to machines/${
|
|
117
|
+
console.log(` added to machines/${machineId}.json: ${added.join(", ")}`);
|
|
77
118
|
} else {
|
|
78
119
|
console.log(` already allowed from ${addresses.join(", ")}`);
|
|
79
120
|
}
|
|
80
|
-
console.log(` identity ${
|
|
121
|
+
console.log(` identity ${describe}`);
|
|
81
122
|
console.log(` in ${repoPath}`);
|
|
82
|
-
|
|
83
|
-
|
|
123
|
+
|
|
124
|
+
if (!pushToGit) {
|
|
125
|
+
console.log(`\nNothing believes this until it is signed. In that repo, run:`);
|
|
126
|
+
console.log(`\`\`\`\nyarn signfiles ${GIT_KEYWORD}\n\`\`\``);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Signed here rather than left as a step to remember, the same as unrevoke does it. A machine
|
|
130
|
+
// list nobody signed is ignored by every machine that reads it.
|
|
131
|
+
await signRepo({ repoPath });
|
|
132
|
+
await runPromise(`git add -A`, { cwd: repoPath });
|
|
133
|
+
await runPromise(`git commit -m "${COMMIT_MESSAGE}"`, { cwd: repoPath });
|
|
134
|
+
await runPromise(`git push`, { cwd: repoPath });
|
|
135
|
+
console.log(`\nSigned, committed and pushed. Machines pick it up as they sync.`);
|
|
84
136
|
}
|
|
@@ -8,6 +8,7 @@ const os_1 = __importDefault(require("os"));
|
|
|
8
8
|
const ownIPs_1 = require("../../misc/ownIPs");
|
|
9
9
|
const remoteSSH_1 = require("../helpers/remoteSSH");
|
|
10
10
|
const identity_1 = require("./identity");
|
|
11
|
+
const keysRepo_1 = require("../authorizedKeys/keysRepo");
|
|
11
12
|
const machines_1 = require("./machines");
|
|
12
13
|
const USAGE = `Usage: yarn addmachine <domain> [ip]
|
|
13
14
|
|
|
@@ -28,7 +29,7 @@ async function main() {
|
|
|
28
29
|
let [domain, host = ""] = argv;
|
|
29
30
|
// The same repo the acceptance check reads. Editing anything else would write a machine list
|
|
30
31
|
// nothing on this machine ever looks at.
|
|
31
|
-
let { repoPath } = await (0,
|
|
32
|
+
let { repoPath } = await (0, keysRepo_1.resolveKeysRepo)();
|
|
32
33
|
let identity;
|
|
33
34
|
let addresses;
|
|
34
35
|
if (!host) {
|
|
@@ -59,7 +60,7 @@ async function main() {
|
|
|
59
60
|
}
|
|
60
61
|
// The whole list is read and written back, because setting is by the set: writing this one
|
|
61
62
|
// machine alone would remove every other machine from the repo.
|
|
62
|
-
let machines = await (0, machines_1.
|
|
63
|
+
let machines = await (0, machines_1.getMachines)(repoPath);
|
|
63
64
|
let existing = machines.find(machine => machine.machineId === identity.machineId);
|
|
64
65
|
let ips = [...((existing === null || existing === void 0 ? void 0 : existing.ips) || [])];
|
|
65
66
|
let added = addresses.filter(address => !ips.includes(address));
|
|
@@ -69,7 +70,7 @@ async function main() {
|
|
|
69
70
|
else {
|
|
70
71
|
machines.push({ machineId: identity.machineId, ips: [...added], addedAt: "" });
|
|
71
72
|
}
|
|
72
|
-
await (0, machines_1.
|
|
73
|
+
await (0, machines_1.setMachines)({ repoPath, machines });
|
|
73
74
|
console.log(`\nTrusting machine ${identity.machineId}`);
|
|
74
75
|
console.log(`Allowing IP ${[...ips, ...added].join(", ")}`);
|
|
75
76
|
if (added.length) {
|
|
@@ -84,5 +85,5 @@ async function main() {
|
|
|
84
85
|
console.log(`\`\`\`\nyarn signfiles git\n\`\`\``);
|
|
85
86
|
}
|
|
86
87
|
exports.main = main;
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
88
|
-
/* _JS_SOURCE_HASH = "
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkTWFjaGluZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFkZE1hY2hpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhDQUE4QztBQUM5QyxvREFBb0Q7QUFDcEQseUNBQXlHO0FBQ3pHLHlEQUE2RDtBQUM3RCx5Q0FBc0Q7QUFFdEQsTUFBTSxLQUFLLEdBQUc7Ozs7Ozs7Ozs7Z0NBVWtCLENBQUM7QUFFMUIsS0FBSyxVQUFVLElBQUk7SUFDdEIsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxJQUFJLENBQUMsTUFBTSxpQkFBaUIsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN4RyxDQUFDO0lBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQy9CLDZGQUE2RjtJQUM3Rix5Q0FBeUM7SUFDekMsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sSUFBQSwwQkFBZSxHQUFFLENBQUM7SUFFM0MsSUFBSSxRQUFrQixDQUFDO0lBQ3ZCLElBQUksU0FBbUIsQ0FBQztJQUN4QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixJQUFJLEtBQUssR0FBRyxNQUFNLElBQUEsd0JBQWEsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDVCxNQUFNLElBQUksS0FBSyxDQUNYLDRCQUE0QixNQUFNLE9BQU8sWUFBRSxDQUFDLE9BQU8sRUFBRSw0QkFBNEI7a0JBQy9FLFdBQVcsQ0FBQyxNQUFNLElBQUEsdUJBQVksR0FBRSxDQUFDLENBQUMsSUFBSSxD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RSxDQUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO0lBQzlFLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0NBQW9DLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBaEVELG9CQWdFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCB7IGdldE93bklQcyB9IGZyb20gXCIuLi8uLi9taXNjL293bklQc1wiO1xuaW1wb3J0IHsgZGVzY3JpYmVIb3N0IH0gZnJvbSBcIi4uL2hlbHBlcnMvcmVtb3RlU1NIXCI7XG5pbXBvcnQgeyBjcmVhdGVSZW1vdGVJZGVudGl0eSwgSWRlbnRpdHksIGxvY2FsRG9tYWlucywgbG9jYWxJZGVudGl0eSwgcmVtb3RlSWRlbnRpdHkgfSBmcm9tIFwiLi9pZGVudGl0eVwiO1xuaW1wb3J0IHsgcmVzb2x2ZUtleXNSZXBvIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2tleXNSZXBvXCI7XG5pbXBvcnQgeyBnZXRNYWNoaW5lcywgc2V0TWFjaGluZXMgfSBmcm9tIFwiLi9tYWNoaW5lc1wiO1xuXG5jb25zdCBVU0FHRSA9IGBVc2FnZTogeWFybiBhZGRtYWNoaW5lIDxkb21haW4+IFtpcF1cblxuVGhlIGRvbWFpbiBpcyByZXF1aXJlZDogYSBtYWNoaW5lIGhhcyBhIGRpZmZlcmVudCBpZGVudGl0eSwgYW5kIHNvIGEgZGlmZmVyZW50IG1hY2hpbmUgaWQsIHVuZGVyXG5ldmVyeSBkb21haW4gaXQgcnVucyB1bmRlciwgc28gdGhlcmUgaXMgbm8gc3VjaCB0aGluZyBhcyBcInRoaXMgbWFjaGluZVwiIHdpdGhvdXQgb25lLlxuXG5XaXRoIG5vIGlwIGl0IGFkZHMgdGhpcyBtYWNoaW5lLCB3aXRoIGl0cyBvd24gYWRkcmVzc2VzLiBXaXRoIGFuIGlwIGl0IGFza3MgdGhhdCBtYWNoaW5lIG92ZXIgc3NoXG5mb3IgaXRzIGlkZW50aXR5IHVuZGVyIHRoYXQgZG9tYWluLCBnaXZlcyBpdCBvbmUgaWYgaXQgaGFzIG5vbmUsIGFuZCBhZGRzIGl0IHVuZGVyIHRoYXQgYWRkcmVzcy5cblxuSXQgZWRpdHMgdGhlIGtleXMgcmVwbyB0aGlzIG1hY2hpbmUgcmVhZHMsIHdoZXJldmVyIHRoYXQgaXMsIG5vdCB3aGF0ZXZlciBkaXJlY3RvcnkgdGhpcyB3YXMgcnVuXG5mcm9tLiBOb3RoaW5nIGlzIHNpZ25lZCBvciBwdXNoZWQgaGVyZS4gUnVuIFwieWFybiBzaWduZmlsZXMgZ2l0XCIgaW4gdGhhdCByZXBvIGFmdGVyd2FyZHMsIG9yIG5vXG5tYWNoaW5lIHdpbGwgYmVsaWV2ZSBhbnkgb2YgaXQuYDtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gICAgbGV0IGFyZ3YgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG4gICAgaWYgKCFhcmd2Lmxlbmd0aCB8fCBhcmd2Lmxlbmd0aCA+IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhIGRvbWFpbiBhbmQgb3B0aW9uYWxseSBhbiBpcCwgd2FzICR7YXJndi5sZW5ndGh9IGFyZ3VtZW50KHMpXFxuJHtVU0FHRX1gKTtcbiAgICB9XG4gICAgbGV0IFtkb21haW4sIGhvc3QgPSBcIlwiXSA9IGFyZ3Y7XG4gICAgLy8gVGhlIHNhbWUgcmVwbyB0aGUgYWNjZXB0YW5jZSBjaGVjayByZWFkcy4gRWRpdGluZyBhbnl0aGluZyBlbHNlIHdvdWxkIHdyaXRlIGEgbWFjaGluZSBsaXN0XG4gICAgLy8gbm90aGluZyBvbiB0aGlzIG1hY2hpbmUgZXZlciBsb29rcyBhdC5cbiAgICBsZXQgeyByZXBvUGF0aCB9ID0gYXdhaXQgcmVzb2x2ZUtleXNSZXBvKCk7XG5cbiAgICBsZXQgaWRlbnRpdHk6IElkZW50aXR5O1xuICAgIGxldCBhZGRyZXNzZXM6IHN0cmluZ1tdO1xuICAgIGlmICghaG9zdCkge1xuICAgICAgICBsZXQgZm91bmQgPSBhd2FpdCBsb2NhbElkZW50aXR5KGRvbWFpbik7XG4gICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYW4gaWRlbnRpdHkgZm9yICR7ZG9tYWlufSBpbiAke29zLmhvbWVkaXIoKX0sIHRoaXMgbWFjaGluZSBoYXMgbm9uZS5cXG5gXG4gICAgICAgICAgICAgICAgKyBgSXQgaGFzOiAkeyhhd2FpdCBsb2NhbERvbWFpbnMoKSkuam9pbihcIiwgXCIpIHx8IFwibm8gaWRlbnRpdGllcyBhdCBhbGxcIn1cXG5gXG4gICAgICAgICAgICAgICAgKyBgT25lIGlzIGdlbmVyYXRlZCB0aGUgZmlyc3QgdGltZSBzb21ldGhpbmcgcnVucyBoZXJlIHVuZGVyIGEgZG9tYWluLCBzbyBydW4gdGhhdGBcbiAgICAgICAgICAgICAgICArIGAgZmlyc3QsIG9yIG5hbWUgYW5vdGhlciBtYWNoaW5lIHRvIGFkZCBpbnN0ZWFkLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWRlbnRpdHkgPSBmb3VuZDtcbiAgICAgICAgYWRkcmVzc2VzID0gYXdhaXQgZ2V0T3duSVBzKCk7XG4gICAgICAgIGlmICghYWRkcmVzc2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCB0aGlzIG1hY2hpbmUgdG8gaGF2ZSBhbiBhZGRyZXNzIGFueXRoaW5nIGVsc2UgY2FuIHNlZSwgaXQgaGFzIG5vbmVgKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vdGhpbmcgdGhlcmUgdW5kZXIgdGhpcyBkb21haW4gbWVhbnMgaXQgZ2V0cyBvbmUuIEl0cyBvd24gZnJvbSB0aGlzIHBvaW50IG9uOiB0aGUga2V5XG4gICAgICAgIC8vIGlzIHdyaXR0ZW4gdGhlcmUgYW5kIG5vdGhpbmcga2VlcHMgYSBjb3B5LlxuICAgICAgICBsZXQgZm91bmQgPSBhd2FpdCByZW1vdGVJZGVudGl0eShob3N0LCBkb21haW4pO1xuICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtkZXNjcmliZUhvc3QoaG9zdCl9IGhhcyBubyBpZGVudGl0eSBmb3IgJHtkb21haW59LCBnZW5lcmF0aW5nIG9uZWApO1xuICAgICAgICB9XG4gICAgICAgIGlkZW50aXR5ID0gZm91bmQgfHwgYXdhaXQgY3JlYXRlUmVtb3RlSWRlbnRpdHkoeyBob3N0LCBkb21haW4gfSk7XG4gICAgICAgIC8vIFRoZSBhZGRyZXNzIGl0IHdhcyBuYW1lZCBieSBpcyB0aGUgYWRkcmVzcyBpdCB0YWxrcyB0byB1cyBmcm9tLCB3aGljaCBpcyB0aGUgb25lIHRoaW5nXG4gICAgICAgIC8vIGl0IGNhbm5vdCBsaWUgYWJvdXQuXG4gICAgICAgIGFkZHJlc3NlcyA9IFtob3N0XTtcbiAgICB9XG5cbiAgICAvLyBUaGUgd2hvbGUgbGlzdCBpcyByZWFkIGFuZCB3cml0dGVuIGJhY2ssIGJlY2F1c2Ugc2V0dGluZyBpcyBieSB0aGUgc2V0OiB3cml0aW5nIHRoaXMgb25lXG4gICAgLy8gbWFjaGluZSBhbG9uZSB3b3VsZCByZW1vdmUgZXZlcnkgb3RoZXIgbWFjaGluZSBmcm9tIHRoZSByZXBvLlxuICAgIGxldCBtYWNoaW5lcyA9IGF3YWl0IGdldE1hY2hpbmVzKHJlcG9QYXRoKTtcbiAgICBsZXQgZXhpc3RpbmcgPSBtYWNoaW5lcy5maW5kKG1hY2hpbmUgPT4gbWFjaGluZS5tYWNoaW5lSWQgPT09IGlkZW50aXR5Lm1hY2hpbmVJZCk7XG4gICAgbGV0IGlwcyA9IFsuLi4oZXhpc3Rpbmc/LmlwcyB8fCBbXSldO1xuICAgIGxldCBhZGRlZCA9IGFkZHJlc3Nlcy5maWx0ZXIoYWRkcmVzcyA9PiAhaXBzLmluY2x1ZGVzKGFkZHJlc3MpKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgZXhpc3RpbmcuaXBzID0gWy4uLmlwcywgLi4uYWRkZWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG1hY2hpbmVzLnB1c2goeyBtYWNoaW5lSWQ6IGlkZW50aXR5Lm1hY2hpbmVJZCwgaXBzOiBbLi4uYWRkZWRdLCBhZGRlZEF0OiBcIlwiIH0pO1xuICAgIH1cbiAgICBhd2FpdCBzZXRNYWNoaW5lcyh7IHJlcG9QYXRoLCBtYWNoaW5lcyB9KTtcblxuICAgIGNvbnNvbGUubG9nKGBcXG5UcnVzdGluZyBtYWNoaW5lICR7aWRlbnRpdHkubWFjaGluZUlkfWApO1xuICAgIGNvbnNvbGUubG9nKGBBbGxvd2luZyBJUCAke1suLi5pcHMsIC4uLmFkZGVkXS5qb2luKFwiLCBcIil9YCk7XG4gICAgaWYgKGFkZGVkLmxlbmd0aCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgICBhZGRlZCB0byBtYWNoaW5lcy8ke2lkZW50aXR5Lm1hY2hpbmVJZH0uanNvbjogJHthZGRlZC5qb2luKFwiLCBcIil9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgYWxyZWFkeSBhbGxvd2VkIGZyb20gJHthZGRyZXNzZXMuam9pbihcIiwgXCIpfWApO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgICBpZGVudGl0eSAke2lkZW50aXR5LmZ1bGxEb21haW59YCk7XG4gICAgY29uc29sZS5sb2coYCAgaW4gJHtyZXBvUGF0aH1gKTtcbiAgICBjb25zb2xlLmxvZyhgXFxuTm90aGluZyBiZWxpZXZlcyB0aGlzIHVudGlsIGl0IGlzIHNpZ25lZC4gSW4gdGhhdCByZXBvLCBydW46YCk7XG4gICAgY29uc29sZS5sb2coYFxcYFxcYFxcYFxcbnlhcm4gc2lnbmZpbGVzIGdpdFxcblxcYFxcYFxcYGApO1xufVxuIl19
|
|
89
|
+
/* _JS_SOURCE_HASH = "a28aef51d4e5c15665559ba6341cc219350f5b54987e7f2f257ccacaf827c938"; */
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
6
|
-
//exports.isMachineAccepted = exports.setMachines = exports.getMachines = exports.MACHINES_DIR = void 0;
|
|
6
|
+
//exports.isMachineAccepted = exports.addMachineCommand = exports.setMachines = exports.getTrustedMachines = exports.getMachines = exports.keysRepo = exports.MACHINES_DIR = void 0;
|
|
7
7
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
8
|
const os_1 = __importDefault(require("os"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -17,6 +17,8 @@ const trust_1 = require("../authorizedKeys/daemon/trust");
|
|
|
17
17
|
const revokeSource_1 = require("../authorizedKeys/revokeSource");
|
|
18
18
|
const notify_1 = require("../authorizedKeys/daemon/notify");
|
|
19
19
|
const discord_1 = require("../notifications/discord");
|
|
20
|
+
const caching_1 = require("socket-function/src/caching");
|
|
21
|
+
const batching_1 = require("socket-function/src/batching");
|
|
20
22
|
// Which machines this system talks to, kept in the same repo as the ssh keys. That repo is already
|
|
21
23
|
// signed, already distributed to every machine, and already has somewhere to record a rejection,
|
|
22
24
|
// so a second one would only be a second thing to keep in step.
|
|
@@ -26,6 +28,14 @@ const REVOCATION_REASON = "a machine talked to us from an unapproved IP";
|
|
|
26
28
|
// The revoke repo is pulled at most this often. A check happens per request, and a request must
|
|
27
29
|
// not cost a round trip to github.
|
|
28
30
|
const REVOKE_SYNC_INTERVAL = 60 * 1000;
|
|
31
|
+
// And the machine list is re-read from the checkout on this interval, in the background. The
|
|
32
|
+
// checkout itself only moves when the daemon pulls it, which is on the same sort of interval, so
|
|
33
|
+
// reading more often than this would only re-read the same bytes.
|
|
34
|
+
const MACHINES_REFRESH_INTERVAL = 60 * 1000;
|
|
35
|
+
// How long a failure to find the keys repo is remembered. A long lived process may start before
|
|
36
|
+
// the machine is set up, and should pick it up once it is, without being restarted - but it must
|
|
37
|
+
// not pay for resolving the repo on every request either.
|
|
38
|
+
const REPO_RETRY_DELAY = 15 * 1000;
|
|
29
39
|
async function pathExists(filePath) {
|
|
30
40
|
try {
|
|
31
41
|
await promises_1.default.access(filePath);
|
|
@@ -38,11 +48,56 @@ async function pathExists(filePath) {
|
|
|
38
48
|
function machineFilePath(repoPath, machineId) {
|
|
39
49
|
return path_1.default.join(repoPath, exports.MACHINES_DIR, `${machineId}.json`);
|
|
40
50
|
}
|
|
41
|
-
/**
|
|
51
|
+
/** This machine's keys repo, worked out once and then remembered.
|
|
52
|
+
|
|
53
|
+
A failure is remembered too, but only briefly: a server may well start before the machine has
|
|
54
|
+
been set up, and should start working when it is, rather than needing a restart. */
|
|
55
|
+
exports.keysRepo = (0, caching_1.lazy)(async () => {
|
|
56
|
+
let lookup = (0, keysRepo_1.resolveKeysRepo)();
|
|
57
|
+
lookup.catch(() => {
|
|
58
|
+
setTimeout(() => exports.keysRepo.reset(), REPO_RETRY_DELAY).unref();
|
|
59
|
+
});
|
|
60
|
+
return await lookup;
|
|
61
|
+
});
|
|
62
|
+
/** Every machine a checkout lists. Without a repo, this machine's own. */
|
|
42
63
|
async function getMachines(repoPath) {
|
|
43
|
-
return [...(await readMachines(repoPath)).values()];
|
|
64
|
+
return [...(await readMachines(repoPath || (await (0, exports.keysRepo)()).repoPath)).values()];
|
|
44
65
|
}
|
|
45
66
|
exports.getMachines = getMachines;
|
|
67
|
+
/** Reads the machine list, once its signature has been checked. An unsigned machine list, or one
|
|
68
|
+
signed over different contents, is not evidence of anything, so this throws rather than
|
|
69
|
+
quietly trusting nobody. */
|
|
70
|
+
async function readTrustedMachines() {
|
|
71
|
+
let { repoPath } = await (0, exports.keysRepo)();
|
|
72
|
+
await (0, trust_1.verifyCheckout)(repoPath);
|
|
73
|
+
return await getMachines(repoPath);
|
|
74
|
+
}
|
|
75
|
+
const trustedMachines = (0, caching_1.lazy)(async () => {
|
|
76
|
+
let read = readTrustedMachines();
|
|
77
|
+
read.catch(() => trustedMachines.reset());
|
|
78
|
+
return await read;
|
|
79
|
+
});
|
|
80
|
+
let refreshing = false;
|
|
81
|
+
/** The machines this system trusts, as the signed repo lists them.
|
|
82
|
+
|
|
83
|
+
Held rather than read per call, and refreshed in the background, so nobody asking whether a
|
|
84
|
+
machine is trusted waits for a directory of files to be read and a signature to be checked. A
|
|
85
|
+
refresh that fails leaves the list we already have: the checkout is only stale, not wrong. */
|
|
86
|
+
async function getTrustedMachines() {
|
|
87
|
+
if (!refreshing) {
|
|
88
|
+
refreshing = true;
|
|
89
|
+
(0, batching_1.runInfinitePoll)(MACHINES_REFRESH_INTERVAL, async () => {
|
|
90
|
+
try {
|
|
91
|
+
trustedMachines.set(Promise.resolve(await readTrustedMachines()));
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
console.log(`Could not re-read the trusted machines, keeping the ones we have. ${e}`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return await trustedMachines();
|
|
99
|
+
}
|
|
100
|
+
exports.getTrustedMachines = getTrustedMachines;
|
|
46
101
|
/** Makes a checkout list exactly these machines: those named are written with the addresses given,
|
|
47
102
|
and anything not named is removed. So read them, change what you want, and write the result.
|
|
48
103
|
|
|
@@ -55,7 +110,10 @@ exports.getMachines = getMachines;
|
|
|
55
110
|
run afterwards. */
|
|
56
111
|
async function setMachines(config) {
|
|
57
112
|
var _a;
|
|
58
|
-
let {
|
|
113
|
+
let { machines } = config;
|
|
114
|
+
let repoPath = config.repoPath || (await (0, exports.keysRepo)()).repoPath;
|
|
115
|
+
// Whatever was held is now stale, whoever reads it next.
|
|
116
|
+
trustedMachines.reset();
|
|
59
117
|
let existing = await readMachines(repoPath);
|
|
60
118
|
let directory = path_1.default.join(repoPath, exports.MACHINES_DIR);
|
|
61
119
|
let written = [];
|
|
@@ -147,6 +205,17 @@ async function readMachineRevocations(sourceURL) {
|
|
|
147
205
|
}
|
|
148
206
|
return revocations;
|
|
149
207
|
}
|
|
208
|
+
/** What to run to trust a machine that has just been refused.
|
|
209
|
+
|
|
210
|
+
Everything in it is already known to whoever is being refused: their machine id, the address we
|
|
211
|
+
saw them at, and the domain they just talked to. Handing it back saves them working out the
|
|
212
|
+
parts of a command they have every right to know. Running it still takes the hardware key on
|
|
213
|
+
the machine that owns the repo, so telling them costs nothing. */
|
|
214
|
+
function addMachineCommand(config) {
|
|
215
|
+
let { machineId, ip, domain } = config;
|
|
216
|
+
return `To trust it, run: yarn addmachine ${domain || "<domain>"} ${machineId} ${ip} git`;
|
|
217
|
+
}
|
|
218
|
+
exports.addMachineCommand = addMachineCommand;
|
|
150
219
|
/** Sends the one notification this file is allowed to send, when it can.
|
|
151
220
|
|
|
152
221
|
The daemon configures notifications on startup and would simply send. This can also run in some
|
|
@@ -210,17 +279,15 @@ async function recordMachineRevocation(config) {
|
|
|
210
279
|
+ `\nfrozen by: \`${hostLabel}\``);
|
|
211
280
|
}
|
|
212
281
|
async function isMachineAccepted(config) {
|
|
213
|
-
let { machineId, ip } = config;
|
|
282
|
+
let { machineId, ip, domain } = config;
|
|
214
283
|
if (!machineId || !ip) {
|
|
215
284
|
throw new Error(`Expected a machineId and an ip, was ${JSON.stringify(machineId)} and ${JSON.stringify(ip)}`);
|
|
216
285
|
}
|
|
217
|
-
let {
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
await (0, trust_1.verifyCheckout)(repoPath);
|
|
221
|
-
let machine = (await readMachines(repoPath)).get(machineId);
|
|
286
|
+
let { sourceURL } = await (0, exports.keysRepo)();
|
|
287
|
+
// Verified before it is believed, and cached, since this is asked once per request.
|
|
288
|
+
let machine = (await getTrustedMachines()).find(entry => entry.machineId === machineId);
|
|
222
289
|
if (!machine) {
|
|
223
|
-
return { accepted: false, reason:
|
|
290
|
+
return { accepted: false, reason: `that machine is not trusted. ${addMachineCommand({ machineId, ip, domain })}` };
|
|
224
291
|
}
|
|
225
292
|
await syncRevocations(sourceURL);
|
|
226
293
|
let unrevokes = await (0, revocation_1.readUnrevokes)(sourceURL).catch(() => ({ pairs: new Map(), legacyIds: new Map() }));
|
|
@@ -260,5 +327,5 @@ async function isMachineAccepted(config) {
|
|
|
260
327
|
return { accepted: false, reason: `that machine is not allowed from ${ip}` };
|
|
261
328
|
}
|
|
262
329
|
exports.isMachineAccepted = isMachineAccepted;
|
|
263
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjaGluZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNoaW5lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwyREFBNkI7QUFDN0IsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4Qix5REFBNkQ7QUFDN0Qsa0VBQStFO0FBQy9FLGtFQUErRTtBQUMvRSxvRUFBbUg7QUFDbkgsc0RBQXNEO0FBQ3RELGtFQUFxRTtBQUNyRSwwREFBZ0U7QUFDaEUsaUVBQStFO0FBQy9FLDREQUF5RDtBQUN6RCxzREFBdUk7QUFHdkksbUdBQW1HO0FBQ25HLGlHQUFpRztBQUNqRyxnRUFBZ0U7QUFDbkQsUUFBQSxZQUFZLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQztBQUN0QyxNQUFNLGlCQUFpQixHQUFHLDhDQUE4QyxDQUFDO0FBQ3pFLGdHQUFnRztBQUNoRyxtQ0FBbUM7QUFDbkMsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBU3ZDLEtBQUssVUFBVSxVQUFVLENBQUMsUUFBZ0I7SUFDdEMsSUFBSSxDQUFDO1FBQ0QsTUFBTSxrQkFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNULE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsUUFBZ0IsRUFBRSxTQUFpQjtJQUN4RCxPQUFPLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLG9CQUFZLEVBQUUsR0FBRyxTQUFTLE9BQU8sQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFFRCxzQ0FBc0M7QUFDL0IsS0FBSyxVQUFVLFdBQVcsQ0FBQyxRQUFnQjtJQUM5QyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMs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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHJlc29sdmVLZXlzUmVwbyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9rZXlzUmVwb1wiO1xuaW1wb3J0IHsgcmV2b2tlUmVwbywgc3luY1JlcG9GaWxlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyBsaXN0UmVwb0RpciwgcmVhZFJlcG9GaWxlIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9yZXBvRmlsZXNcIjtcbmltcG9ydCB7IG5ld1Jldm9jYXRpb25JZCwgcGFpcktleSwgcmVhZFJldm9jYXRpb25GaWxlcywgcmVhZFVucmV2b2tlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmV2b2NhdGlvblwiO1xuaW1wb3J0IHsgcnVuR2l0IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9naXRcIjtcbmltcG9ydCB7IGVuc3VyZVJldm9rZUtleSB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyB2ZXJpZnlDaGVja291dCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vdHJ1c3RcIjtcbmltcG9ydCB7IHJldm9rZVJlcG9QYXRoLCByZXZva2VSZXBvVVJMIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL3Jldm9rZVNvdXJjZVwiO1xuaW1wb3J0IHsgbm90aWZ5IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9ub3RpZnlcIjtcbmltcG9ydCB7IGFyZURpc2NvcmROb3RpZmljYXRpb25zQ29uZmlndXJlZCwgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMsIERFRkFVTFRfV0VCSE9PS19GSUxFX1BBVEggfSBmcm9tIFwiLi4vbm90aWZpY2F0aW9ucy9kaXNjb3JkXCI7XG5pbXBvcnQgeyBzcGF3blByb21pc2UgfSBmcm9tIFwiLi4vaGVscGVycy9zcGF3blwiO1xuXG4vLyBXaGljaCBtYWNoaW5lcyB0aGlzIHN5c3RlbSB0YWxrcyB0bywga2VwdCBpbiB0aGUgc2FtZSByZXBvIGFzIHRoZSBzc2gga2V5cy4gVGhhdCByZXBvIGlzIGFscmVhZHlcbi8vIHNpZ25lZCwgYWxyZWFkeSBkaXN0cmlidXRlZCB0byBldmVyeSBtYWNoaW5lLCBhbmQgYWxyZWFkeSBoYXMgc29tZXdoZXJlIHRvIHJlY29yZCBhIHJlamVjdGlvbixcbi8vIHNvIGEgc2Vjb25kIG9uZSB3b3VsZCBvbmx5IGJlIGEgc2Vjb25kIHRoaW5nIHRvIGtlZXAgaW4gc3RlcC5cbmV4cG9ydCBjb25zdCBNQUNISU5FU19ESVIgPSBcIm1hY2hpbmVzXCI7XG5jb25zdCBSRVZPQ0FUSU9OU19ESVIgPSBcInJldm9jYXRpb25zXCI7XG5jb25zdCBSRVZPQ0FUSU9OX1JFQVNPTiA9IFwiYSBtYWNoaW5lIHRhbGtlZCB0byB1cyBmcm9tIGFuIHVuYXBwcm92ZWQgSVBcIjtcbi8vIFRoZSByZXZva2UgcmVwbyBpcyBwdWxsZWQgYXQgbW9zdCB0aGlzIG9mdGVuLiBBIGNoZWNrIGhhcHBlbnMgcGVyIHJlcXVlc3QsIGFuZCBhIHJlcXVlc3QgbXVzdFxuLy8gbm90IGNvc3QgYSByb3VuZCB0cmlwIHRvIGdpdGh1Yi5cbmNvbnN0IFJFVk9LRV9TWU5DX0lOVEVSVkFMID0gNjAgKiAxMDAwO1xuXG4vKiogT25lIG1hY2hpbmUgd2UgYXJlIHdpbGxpbmcgdG8gdGFsayB0bywgYW5kIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgdG8gdXMgZnJvbS4gKi9cbmV4cG9ydCB0eXBlIE1hY2hpbmVTdGF0ZSA9IHtcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBpcHM6IHN0cmluZ1tdO1xuICAgIGFkZGVkQXQ6IHN0cmluZztcbn07XG5cbmFzeW5jIGZ1bmN0aW9uIHBhdGhFeGlzdHMoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmFjY2VzcyhmaWxlUGF0aCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gbWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoOiBzdHJpbmcsIG1hY2hpbmVJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHBhdGguam9pbihyZXBvUGF0aCwgTUFDSElORVNfRElSLCBgJHttYWNoaW5lSWR9Lmpzb25gKTtcbn1cblxuLyoqIEV2ZXJ5IG1hY2hpbmUgYSBjaGVja291dCBsaXN0cy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKTogUHJvbWlzZTxNYWNoaW5lU3RhdGVbXT4ge1xuICAgIHJldHVybiBbLi4uKGF3YWl0IHJlYWRNYWNoaW5lcyhyZXBvUGF0aCkpLnZhbHVlcygpXTtcbn1cblxuLyoqIE1ha2VzIGEgY2hlY2tvdXQgbGlzdCBleGFjdGx5IHRoZXNlIG1hY2hpbmVzOiB0aG9zZSBuYW1lZCBhcmUgd3JpdHRlbiB3aXRoIHRoZSBhZGRyZXNzZXMgZ2l2ZW4sXG4gICAgYW5kIGFueXRoaW5nIG5vdCBuYW1lZCBpcyByZW1vdmVkLiBTbyByZWFkIHRoZW0sIGNoYW5nZSB3aGF0IHlvdSB3YW50LCBhbmQgd3JpdGUgdGhlIHJlc3VsdC5cblxuICAgIFRoZSBhZGRyZXNzZXMgYXJlIHBhcnQgb2Ygc2V0dGluZyByYXRoZXIgdGhhbiBhIHNlcGFyYXRlIHN0ZXAsIGJlY2F1c2UgYSBtYWNoaW5lIHdpdGggbm9cbiAgICBhZGRyZXNzIGl0IG1heSB0YWxrIGZyb20gaXMgbm90IGEgbWFjaGluZSB0aGF0IHdvdWxkIGV2ZXIgYmUgYWNjZXB0ZWQgLSB0aGVyZSBpcyBubyBzdGF0ZSB3aGVyZVxuICAgIG5hbWluZyBvbmUgd2l0aG91dCB0aGVtIG1lYW5zIGFueXRoaW5nLlxuXG4gICAgTm90aGluZyBoZXJlIHNpZ25zIG9yIGNvbW1pdHMuIFRoZSBzaWduYXR1cmUgaXMgd2hhdCBldmVyeSBvdGhlciBtYWNoaW5lIGNoZWNrcyBiZWZvcmVcbiAgICBiZWxpZXZpbmcgYW55IG9mIHRoaXMsIGFuZCBpdCB0YWtlcyB0aGUgaGFyZHdhcmUga2V5LCBzbyBgeWFybiBzaWduZmlsZXMgZ2l0YCBpcyBzdGlsbCB5b3VycyB0b1xuICAgIHJ1biBhZnRlcndhcmRzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldE1hY2hpbmVzKGNvbmZpZzoge1xuICAgIHJlcG9QYXRoOiBzdHJpbmc7XG4gICAgbWFjaGluZXM6IHsgbWFjaGluZUlkOiBzdHJpbmc7IGlwczogc3RyaW5nW10gfVtdO1xufSk6IFByb21pc2U8TWFjaGluZVN0YXRlW10+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgbWFjaGluZXMgfSA9IGNvbmZpZztcbiAgICBsZXQgZXhpc3RpbmcgPSBhd2FpdCByZWFkTWFjaGluZXMocmVwb1BhdGgpO1xuICAgIGxldCBkaXJlY3RvcnkgPSBwYXRoLmpvaW4ocmVwb1BhdGgsIE1BQ0hJTkVTX0RJUik7XG4gICAgbGV0IHdyaXR0ZW46IE1hY2hpbmVTdGF0ZVtdID0gW107XG4gICAgZm9yIChsZXQgbWFjaGluZSBvZiBtYWNoaW5lcykge1xuICAgICAgICBpZiAoIW1hY2hpbmUubWFjaGluZUlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkLCB3YXMgJHtKU09OLnN0cmluZ2lmeShtYWNoaW5lLm1hY2hpbmVJZCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtYWNoaW5lLmlwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYWRkcmVzc2VzIGZvciAke21hY2hpbmUubWFjaGluZUlkfSwgd2FzIG5vbmUuIEEgbWFjaGluZSBpcyB0cnVzdGVkIGZyb21gXG4gICAgICAgICAgICAgICAgKyBgIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgZnJvbSwgc28gbGVhdmUgaXQgb3V0IG9mIHRoZSBsaXN0IHRvIHJlbW92ZSBpdC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpcHMgPSBtYWNoaW5lLmlwcy5maWx0ZXIoKGlwLCBpbmRleCkgPT4gaXAgJiYgbWFjaGluZS5pcHMuaW5kZXhPZihpcCkgPT09IGluZGV4KTtcbiAgICAgICAgbGV0IHN0YXRlOiBNYWNoaW5lU3RhdGUgPSB7XG4gICAgICAgICAgICBtYWNoaW5lSWQ6IG1hY2hpbmUubWFjaGluZUlkLFxuICAgICAgICAgICAgLy8gSW4gdGhlIG9yZGVyIGdpdmVuLCB3aXRob3V0IGR1cGxpY2F0ZXMsIHNvIHRoZSBmaWxlIHJlYWRzIHRoZSB3YXkgaXQgd2FzIHNldC5cbiAgICAgICAgICAgIGlwcyxcbiAgICAgICAgICAgIGFkZGVkQXQ6IGV4aXN0aW5nLmdldChtYWNoaW5lLm1hY2hpbmVJZCk/LmFkZGVkQXQgfHwgbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBmcy5ta2RpcihkaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUobWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBzdGF0ZS5tYWNoaW5lSWQpLCBKU09OLnN0cmluZ2lmeShzdGF0ZSwgdW5kZWZpbmVkLCA0KSArIFwiXFxuXCIpO1xuICAgICAgICB3cml0dGVuLnB1c2goc3RhdGUpO1xuICAgIH1cblxuICAgIC8vIFdoYXRldmVyIHRoZSByZXBvIGhhZCBhbmQgdGhlIGNhbGxlciBkaWQgbm90IG5hbWUgaXMgbm8gbG9uZ2VyIHRydXN0ZWQuXG4gICAgZm9yIChsZXQgbWFjaGluZUlkIG9mIGV4aXN0aW5nLmtleXMoKSkge1xuICAgICAgICBpZiAoIW1hY2hpbmVzLnNvbWUobWFjaGluZSA9PiBtYWNoaW5lLm1hY2hpbmVJZCA9PT0gbWFjaGluZUlkKSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucm0obWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBtYWNoaW5lSWQpLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB3cml0dGVuO1xufVxuXG4vKiogRXZlcnkgbWFjaGluZSB0aGUgcmVwbyBsaXN0cy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IG1hY2hpbmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hY2hpbmVTdGF0ZT4oKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIpO1xuICAgIGxldCBuYW1lcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyZWN0b3J5KS5jYXRjaCgoKSA9PiBbXSBhcyBzdHJpbmdbXSk7XG4gICAgZm9yIChsZXQgbmFtZSBvZiBuYW1lcy5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4oZGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBwYXJzZWQubWFjaGluZUlkIHx8IG5hbWUucmVwbGFjZSgvXFwuanNvbiQvLCBcIlwiKTtcbiAgICAgICAgICAgIG1hY2hpbmVzLnNldChtYWNoaW5lSWQsIHsgbWFjaGluZUlkLCBpcHM6IHBhcnNlZC5pcHMgfHwgW10sIGFkZGVkQXQ6IHBhcnNlZC5hZGRlZEF0IHx8IFwiXCIgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIG1hY2hpbmUgZmlsZSAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hY2hpbmVzO1xufVxuXG5sZXQgbGFzdFJldm9rZVN5bmMgPSAwO1xuXG4vKiogUHVsbGVkIGF0IG1vc3Qgb25jZSBhIFJFVk9LRV9TWU5DX0lOVEVSVkFMLCBiZWNhdXNlIHRoaXMgaXMgYXNrZWQgcGVyIHJlcXVlc3QuIEEgc3luYyB0aGF0XG4gICAgZmFpbHMgbGVhdmVzIHRoZSBjaGVja291dCB3ZSBhbHJlYWR5IGhhdmUsIHdoaWNoIGlzIHRoZSBzYWZlIGRpcmVjdGlvbjogcmV2b2NhdGlvbnMgd2Uga25vd1xuICAgIGFib3V0IHN0YXkga25vd24uICovXG5hc3luYyBmdW5jdGlvbiBzeW5jUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBpZiAoRGF0ZS5ub3coKSAtIGxhc3RSZXZva2VTeW5jIDwgUkVWT0tFX1NZTkNfSU5URVJWQUwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsYXN0UmV2b2tlU3luYyA9IERhdGUubm93KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3luY1JlcG9GaWxlcyhyZXZva2VSZXBvKHNvdXJjZVVSTCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCByZWFkICR7cmV2b2tlUmVwb1VSTChzb3VyY2VVUkwpfSwgdXNpbmcgdGhlIHJldm9jYXRpb25zIGFscmVhZHkgaGVyZS4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIE1hY2hpbmUgcmV2b2NhdGlvbnMsIHJlYWQgb3V0IG9mIHRoZSByZXZva2UgcmVwbyB0aGUgc2FtZSB3YXkga2V5IHJldm9jYXRpb25zIGFyZS4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBsZXQgcmVwbyA9IHJldm9rZVJlcG8oc291cmNlVVJMKTtcbiAgICBsZXQgcmV2b2NhdGlvbnM6IHsgcmV2b2NhdGlvbklkOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IG5hbWUgb2YgYXdhaXQgbGlzdFJlcG9EaXIocmVwbywgUkVWT0NBVElPTlNfRElSKSkge1xuICAgICAgICBpZiAoIW5hbWUuZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBwYXJzZWQgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRSZXBvRmlsZShyZXBvLCBwYXRoLmpvaW4oUkVWT0NBVElPTlNfRElSLCBuYW1lKSkgfHwgXCJcIik7XG4gICAgICAgICAgICBpZiAocGFyc2VkLm1hY2hpbmVJZCkge1xuICAgICAgICAgICAgICAgIHJldm9jYXRpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICByZXZvY2F0aW9uSWQ6IHBhcnNlZC5yZXZvY2F0aW9uSWQgfHwgbmFtZS5yZXBsYWNlKC9cXC5qc29uJC8sIFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICBtYWNoaW5lSWQ6IHBhcnNlZC5tYWNoaW5lSWQsXG4gICAgICAgICAgICAgICAgICAgIGlwOiBwYXJzZWQuaXAgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYElnbm9yaW5nIHVucmVhZGFibGUgcmV2b2NhdGlvbiAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldm9jYXRpb25zO1xufVxuXG4vKiogU2VuZHMgdGhlIG9uZSBub3RpZmljYXRpb24gdGhpcyBmaWxlIGlzIGFsbG93ZWQgdG8gc2VuZCwgd2hlbiBpdCBjYW4uXG5cbiAgICBUaGUgZGFlbW9uIGNvbmZpZ3VyZXMgbm90aWZpY2F0aW9ucyBvbiBzdGFydHVwIGFuZCB3b3VsZCBzaW1wbHkgc2VuZC4gVGhpcyBjYW4gYWxzbyBydW4gaW4gc29tZVxuICAgIG90aGVyIHByb2Nlc3MsIHdoaWNoIGhhcyBub3QsIHNvIHRoZSB3ZWJob29rIGlzIHBpY2tlZCB1cCBoZXJlIGlmIGl0IGlzIHJlYWRhYmxlLiBBIG1hY2hpbmVcbiAgICB3aXRoIG5vIHdlYmhvb2sgc2V0IHVwIHN0aWxsIHJlY29yZHMgdGhlIHJldm9jYXRpb24gLSBiZWluZyB1bmFibGUgdG8gdGVsbCBhbnlvbmUgaXMgbm90IGFcbiAgICByZWFzb24gdG8ga2VlcCBhY2NlcHRpbmcgYSBtYWNoaW5lIHRoYXQgaXMgYmVpbmcgbWlzdXNlZC4gKi9cbmFzeW5jIGZ1bmN0aW9uIG5vdGlmeUJlc3RFZmZvcnQoaGVhZGxpbmU6IHN0cmluZywgYm9keTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKCFhcmVEaXNjb3JkTm90aWZpY2F0aW9uc0NvbmZpZ3VyZWQoKSkge1xuICAgICAgICAgICAgLy8gUmVhZCBmaXJzdDogY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMgZXhpdHMgdGhlIHByb2Nlc3Mgd2hlbiB0aGUgZmlsZSBpcyBtaXNzaW5nLFxuICAgICAgICAgICAgLy8gd2hpY2ggaXMgcmlnaHQgZm9yIHRoZSBkYWVtb24gYXQgc3RhcnR1cCBhbmQgd3JvbmcgZm9yIGEgbGlicmFyeSBjYWxsLlxuICAgICAgICAgICAgYXdhaXQgZnMucmVhZEZpbGUoREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCwgXCJ1dGY4XCIpO1xuICAgICAgICAgICAgYXdhaXQgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMoeyBmaWxlUGF0aDogREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBub3RpZnkoaGVhZGxpbmUsIGJvZHkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBzZW5kIGEgbm90aWZpY2F0aW9uIGFib3V0IHRoaXMsIGl0IGlzIG9ubHkgaW4gdGhlIGxvZy4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIFJlY29yZHMgdGhhdCBhIG1hY2hpbmUgd2UgYWNjZXB0IHRhbGtlZCB0byB1cyBmcm9tIGFuIGFkZHJlc3MgaXQgaXMgbm90IGFsbG93ZWQgZnJvbS4gT25lIHBlclxuICAgIG1hY2hpbmUgYW5kIGFkZHJlc3MsIHNvIGEgc2Vjb25kIGFkZHJlc3MgaXMgYSBzZWNvbmQgcmV2b2NhdGlvbiBhbmQgYW4gdW5yZXZva2Ugb2YgdGhlIGZpcnN0XG4gICAgZG9lcyBub3QgY292ZXIgaXQuICovXG5hc3luYyBmdW5jdGlvbiByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbihjb25maWc6IHtcbiAgICBzb3VyY2VVUkw6IHN0cmluZztcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBpcDogc3RyaW5nO1xuICAgIGhvc3RMYWJlbDogc3RyaW5nO1xufSkge1xuICAgIGxldCB7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsIH0gPSBjb25maWc7XG4gICAgbGV0IHJlcG9QYXRoID0gcmV2b2tlUmVwb1BhdGgoc291cmNlVVJMKTtcbiAgICBsZXQga2V5UGF0aCA9IGF3YWl0IGVuc3VyZVJldm9rZUtleShzb3VyY2VVUkwpO1xuICAgIGxldCByZXZvY2F0aW9uSWQgPSBuZXdSZXZvY2F0aW9uSWQobWFjaGluZUlkKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBSRVZPQ0FUSU9OU19ESVIpO1xuICAgIGF3YWl0IGZzLm1rZGlyKGRpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHBhdGguam9pbihkaXJlY3RvcnksIGAke3Jldm9jYXRpb25JZH0uanNvbmApLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHJldm9jYXRpb25JZCxcbiAgICAgICAgbWFjaGluZUlkLFxuICAgICAgICBpcCxcbiAgICAgICAgcmV2b2tlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIHJldm9rZWRCeTogaG9zdExhYmVsLFxuICAgICAgICByZWFzb246IFJFVk9DQVRJT05fUkVBU09OLFxuICAgIH0sIHVuZGVmaW5lZCwgNCkgKyBcIlxcblwiKTtcblxuICAgIGF3YWl0IHJ1bkdpdCh7IGFyZ3M6IFtcImFkZFwiLCBcIi1BXCJdLCBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoIH0pO1xuICAgIGF3YWl0IHJ1bkdpdCh7XG4gICAgICAgIGFyZ3M6IFtcIi1jXCIsIFwidXNlci5lbWFpbD1wb3J0c2VjdXJlQGxvY2FsaG9zdFwiLCBcIi1jXCIsIFwidXNlci5uYW1lPXBvcnRzZWN1cmVcIiwgXCJjb21taXRcIiwgXCItbVwiLCBgcmV2b2tlICR7cmV2b2NhdGlvbklkfWBdLFxuICAgICAgICBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoLFxuICAgIH0pO1xuICAgIGxldCBwdXNoID0gYXdhaXQgcnVuR2l0KHsgYXJnczogW1wicHVzaFwiLCBcIm9yaWdpblwiLCBcIkhFQURcIl0sIGN3ZDogcmVwb1BhdGgsIGtleVBhdGgsIGFsbG93RmFpbHVyZTogdHJ1ZSB9KTtcbiAgICBpZiAocHVzaC5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgLy8gQW5vdGhlciBtYWNoaW5lIG1vc3QgbGlrZWx5IHJlY29yZGVkIHRoZSBzYW1lIHRoaW5nIGZpcnN0LCBhbmQgdGhlIG5leHQgcmVhZCBwaWNrcyBpdCB1cC5cbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBwdXNoIHRoZSByZXZvY2F0aW9uIG9mICR7bWFjaGluZUlkfSBmcm9tICR7aXB9LiAkeyhwdXNoLnN0ZG91dCArIHB1c2guc3RkZXJyKS50cmltKCl9YCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYFJldm9rZWQgJHttYWNoaW5lSWR9IGZyb20gJHtpcH0sICR7cmV2b2NhdGlvbklkfWApO1xuXG4gICAgLy8gU2FpZCBieSB3aG9ldmVyIHdyb3RlIHRoZSByZXZvY2F0aW9uLCBvbmNlLCB0aGUgc2FtZSBhcyBmb3IgYW4gc3NoIGtleS4gTWFjaGluZXMgdGhhdCBvbmx5XG4gICAgLy8gcmVhZCBpdCBsYXRlciBzYXkgbm90aGluZywgb3Igb25lIGV2ZW50IHdvdWxkIGJlIHJlcG9ydGVkIGJ5IGV2ZXJ5IG1hY2hpbmUgdGhhdCBzYXcgaXQuXG4gICAgYXdhaXQgbm90aWZ5QmVzdEVmZm9ydChcbiAgICAgICAgYFNVU1BJQ0lPVVMgSVAgJHtpcH0gRlJPWkUgTUFDSElORSAke21hY2hpbmVJZH1gLFxuICAgICAgICBgQSBtYWNoaW5lIHdlIHRydXN0IHRhbGtlZCB0byB1cyBmcm9tICR7aXB9LCB3aGljaCBpcyBub3QgYW4gYWRkcmVzcyBpdCBpcyBhbGxvd2VkIHRvIHRhbGtgXG4gICAgICAgICsgYCBmcm9tLiBJdCBwcm92ZWQgaXQgaG9sZHMgdGhhdCBtYWNoaW5lJ3Mga2V5LCBzbyBlaXRoZXIgc29tZW9uZSBlbHNlIGhhcyBhIGNvcHkgb2YgaXQsYFxuICAgICAgICArIGAgb3IgdGhhdCBtYWNoaW5lJ3MgYWRkcmVzcyBjaGFuZ2VkLmBcbiAgICAgICAgKyBgXFxuXFxuSXQgaXMgZnJvemVuIGV2ZXJ5d2hlcmUgbm93LCBhbmQgbm90aGluZyBhY2NlcHRzIGl0LmBcbiAgICAgICAgKyBgXFxuXFxuSWYgdGhpcyB3YXMgYW4gYXR0YWNrLCByZW1vdmUgXFxgbWFjaGluZXMvJHttYWNoaW5lSWR9Lmpzb25cXGAgZnJvbSBcXGAke3NvdXJjZVVSTH1cXGAgbm93LmBcbiAgICAgICAgKyBgXFxuSWYgaXQgd2FzIGxlZ2l0aW1hdGUsIHJ1biBcXGB5YXJuIHVucmV2b2tlIGdpdFxcYCBpbiB0aGF0IHJlcG8uIEl0IGFsbG93cyAke2lwfSBmb3IgdGhhdGBcbiAgICAgICAgKyBgIG1hY2hpbmUsIGFuZCB0YWtlcyBlZmZlY3QgYXMgZWFjaCBtYWNoaW5lIHBpY2tzIGl0IHVwLmBcbiAgICAgICAgKyBgXFxuXFxubWFjaGluZTogXFxgJHttYWNoaW5lSWR9XFxgYFxuICAgICAgICArIGBcXG5mcm96ZW4gYnk6IFxcYCR7aG9zdExhYmVsfVxcYGBcbiAgICApO1xufVxuXG4vKiogV2hldGhlciB3ZSB3aWxsIHRhbGsgdG8gdGhpcyBtYWNoaW5lLCBjb21pbmcgZnJvbSB0aGlzIGFkZHJlc3MuXG5cbiAgICBCb3RoIGhhbHZlcyBhcmUgcmVxdWlyZWQgYW5kIG5laXRoZXIgaXMgYSBndWVzczogdGhlIGNhbGxlciBrbm93cyB0aGUgbWFjaGluZSBpZCBiZWNhdXNlIHRoZVxuICAgIGNvbm5lY3Rpb24gcHJvdmVkIGl0LCBhbmQga25vd3MgdGhlIGFkZHJlc3MgYmVjYXVzZSB0aGUgcGFja2V0cyBjYW1lIGZyb20gdGhlcmUuIEEgbWFjaGluZSB3ZVxuICAgIGRvIG5vdCBsaXN0IGlzIHNpbXBseSBub3QgYWNjZXB0ZWQuIEEgbWFjaGluZSB3ZSBkbyBsaXN0LCBhcnJpdmluZyBmcm9tIGFuIGFkZHJlc3MgaXQgZG9lcyBub3RcbiAgICBoYXZlLCBpcyB0cmVhdGVkIGFzIHRoZSBzYW1lIGtpbmQgb2YgZXZlbnQgYXMgYSBzdG9sZW4gc3NoIGtleSAtIGl0IGlzIHJldm9rZWQgZXZlcnl3aGVyZSwgYW5kXG4gICAgc3RheXMgcmV2b2tlZCB1bnRpbCBhbiB1bnJldm9rZSBhbGxvd3MgdGhhdCBtYWNoaW5lIGZyb20gdGhhdCBhZGRyZXNzLlxuXG4gICAgU2F5cyB3aHkgd2hlbiB0aGUgYW5zd2VyIGlzIG5vLCBiZWNhdXNlIHRoZSB0aHJlZSB3YXlzIHRvIGJlIHJlZnVzZWQgYXJlIGVudGlyZWx5IGRpZmZlcmVudFxuICAgIHRoaW5ncyB0byBhIHBlcnNvbiByZWFkaW5nIGl0OiBuZXZlciB0cnVzdGVkIGF0IGFsbCwgdHJ1c3RlZCBidXQgZnJvemVuLCBvciB0cnVzdGVkIGFuZCB0YWxraW5nXG4gICAgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS5cblxuICAgIFRocm93cyB3aGVuIHRoZSByZXBvIGl0c2VsZiBjYW5ub3QgYmUgcmVhZCBvciBpcyBub3Qgc2lnbmVkLCByYXRoZXIgdGhhbiBhbnN3ZXJpbmcgZmFsc2U6IHRoYXRcbiAgICBpcyBhIGJyb2tlbiBpbnN0YWxsYXRpb24sIG5vdCBhIHJlamVjdGVkIG1hY2hpbmUsIGFuZCB0aGUgdHdvIGRlc2VydmUgZGlmZmVyZW50IGhhbmRsaW5nLiAqL1xuZXhwb3J0IHR5cGUgTWFjaGluZVZlcmRpY3QgPSB7IGFjY2VwdGVkOiBib29sZWFuOyByZWFzb246IHN0cmluZyB9O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNNYWNoaW5lQWNjZXB0ZWQoY29uZmlnOiB7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0pOiBQcm9taXNlPE1hY2hpbmVWZXJkaWN0PiB7XG4gICAgbGV0IHsgbWFjaGluZUlkLCBpcCB9ID0gY29uZmlnO1xuICAgIGlmICghbWFjaGluZUlkIHx8ICFpcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkIGFuZCBhbiBpcCwgd2FzICR7SlNPTi5zdHJpbmdpZnkobWFjaGluZUlkKX0gYW5kICR7SlNPTi5zdHJpbmdpZnkoaXApfWApO1xuICAgIH1cbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBhd2FpdCByZXNvbHZlS2V5c1JlcG8oKTtcbiAgICAvLyBVbnNpZ25lZCwgb3Igc2lnbmVkIG92ZXIgZGlmZmVyZW50IGNvbnRlbnRzLCBtZWFucyB0aGUgbWFjaGluZSBsaXN0IGlzIG5vdCBldmlkZW5jZSBvZlxuICAgIC8vIGFueXRoaW5nLiBTYW1lIGdhdGUgdGhlIHNzaCBrZXlzIGdvIHRocm91Z2guXG4gICAgYXdhaXQgdmVyaWZ5Q2hlY2tvdXQocmVwb1BhdGgpO1xuXG4gICAgbGV0IG1hY2hpbmUgPSAoYXdhaXQgcmVhZE1hY2hpbmVzKHJlcG9QYXRoKSkuZ2V0KG1hY2hpbmVJZCk7XG4gICAgaWYgKCFtYWNoaW5lKSB7XG4gICAgICAgIHJldHVybiB7IGFjY2VwdGVkOiBmYWxzZSwgcmVhc29uOiBcInRoYXQgbWFjaGluZSBpcyBub3QgdHJ1c3RlZFwiIH07XG4gICAgfVxuXG4gICAgYXdhaXQgc3luY1Jldm9jYXRpb25zKHNvdXJjZVVSTCk7XG4gICAgbGV0IHVucmV2b2tlcyA9IGF3YWl0IHJlYWRVbnJldm9rZXMoc291cmNlVVJMKS5jYXRjaCgoKSA9PiAoeyBwYWlyczogbmV3IE1hcCgpLCBsZWdhY3lJZHM6IG5ldyBNYXAoKSB9KSk7XG4gICAgLy8gQW4gdW5yZXZva2UgY291bnRzIGFzIHNvb24gYXMgaXQgaXMgc2Vlbi4gSXQgaXMgc2lnbmVkLCBzbyB3cml0aW5nIG9uZSBhbHJlYWR5IHRha2VzIHRoZVxuICAgIC8vIGhhcmR3YXJlIGtleSwgYW5kIGFueW9uZSBob2xkaW5nIHRoYXQgY2FuIHNpZ24gYW55dGhpbmcgYXQgYWxsIC0gYSB3YWl0IGJlZm9yZSBob25vdXJpbmcgaXRcbiAgICAvLyBndWFyZHMgYWdhaW5zdCBhbiBhdHRhY2tlciB3aG8gaGFzIG5vIG5lZWQgb2YgaXQuXG4gICAgbGV0IGFsbG93ZWRBZ2FpbiA9IChwYWlyOiBzdHJpbmcpID0+ICEhdW5yZXZva2VzLnBhaXJzLmdldChwYWlyKT8ubGVuZ3RoO1xuICAgIGxldCByZXZvY2F0aW9ucyA9IGF3YWl0IHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMKTtcbiAgICAvLyBBbnkgcmV2b2NhdGlvbiBub3RoaW5nIGhhcyB1bmRvbmUga2VlcHMgdGhlIG1hY2hpbmUgb3V0LCBmcm9tIGV2ZXJ5d2hlcmUsIHRoZSB3YXkgYSByZXZva2VkXG4gICAgLy8gc3NoIGtleSBpcyBvdXQgZXZlcnl3aGVyZSByYXRoZXIgdGhhbiBvbmx5IGZyb20gdGhlIGFkZHJlc3MgaXQgd2FzIG1pc3VzZWQgZnJvbS5cbiAgICBsZXQgZnJvemVuRnJvbSA9IFwiXCI7XG4gICAgZm9yIChsZXQgcmV2b2NhdGlvbiBvZiByZXZvY2F0aW9ucykge1xuICAgICAgICBpZiAocmV2b2NhdGlvbi5tYWNoaW5lSWQgIT09IG1hY2hpbmVJZCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbGxvd2VkQWdhaW4ocGFpcktleSh7IGZpbmdlcnByaW50OiByZXZvY2F0aW9uLm1hY2hpbmVJZCwgaXA6IHJldm9jYXRpb24uaXAgfSkpKSB7XG4gICAgICAgICAgICBmcm96ZW5Gcm9tID0gcmV2b2NhdGlvbi5pcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZnJvemVuRnJvbSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWNjZXB0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIGZyb3plbiwgaXQgd2FzIHVzZWQgZnJvbSAke2Zyb3plbkZyb219IHdoaWNoIGl0IGlzIG5vdCBhbGxvd2VkIGZyb21gLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChtYWNoaW5lLmlwcy5pbmNsdWRlcyhpcCkpIHtcbiAgICAgICAgcmV0dXJuIHsgYWNjZXB0ZWQ6IHRydWUsIHJlYXNvbjogXCJcIiB9O1xuICAgIH1cblxuICAgIC8vIExpc3RlZCwgYnV0IHRhbGtpbmcgdG8gdXMgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS4gUmVjb3JkZWQgb25jZSBmb3IgdGhpcyBtYWNoaW5lXG4gICAgLy8gYW5kIGFkZHJlc3MsIHNvIGJlaW5nIHRhbGtlZCB0byByZXBlYXRlZGx5IGRvZXMgbm90IHdyaXRlIHJlcGVhdGVkbHkuXG4gICAgbGV0IHBhaXIgPSBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IG1hY2hpbmVJZCwgaXAgfSk7XG4gICAgbGV0IGFscmVhZHlSZWNvcmRlZCA9IHJldm9jYXRpb25zLnNvbWUocmV2b2NhdGlvbiA9PlxuICAgICAgICBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IHJldm9jYXRpb24ubWFjaGluZUlkLCBpcDogcmV2b2NhdGlvbi5pcCB9KSA9PT0gcGFpcik7XG4gICAgaWYgKCFhbHJlYWR5UmVjb3JkZWQgJiYgIWFsbG93ZWRBZ2FpbihwYWlyKSkge1xuICAgICAgICBhd2FpdCByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbih7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsOiBvcy5ob3N0bmFtZSgpIH0pO1xuICAgICAgICByZXR1cm4geyBhY2NlcHRlZDogZmFsc2UsIHJlYXNvbjogYHRoYXQgbWFjaGluZSBpcyBub3QgYWxsb3dlZCBmcm9tICR7aXB9LCBzbyBpdCBpcyBub3cgZnJvemVuIGV2ZXJ5d2hlcmVgIH07XG4gICAgfVxuICAgIHJldHVybiB7IGFjY2VwdGVkOiBmYWxzZSwgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIG5vdCBhbGxvd2VkIGZyb20gJHtpcH1gIH07XG59XG4iXX0=
|
|
264
|
-
/* _JS_SOURCE_HASH = "
|
|
330
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjaGluZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNoaW5lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwyREFBNkI7QUFDN0IsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4Qix5REFBNkQ7QUFDN0Qsa0VBQStFO0FBQy9FLGtFQUErRTtBQUMvRSxvRUFBbUg7QUFDbkgsc0RBQXNEO0FBQ3RELGtFQUFxRTtBQUNyRSwwREFBZ0U7QUFDaEUsaUVBQStFO0FBQy9FLDREQUF5RDtBQUN6RCxzREFBdUk7QUFDdkkseURBQW1EO0FBQ25ELDJEQUErRDtBQUcvRCxtR0FBbUc7QUFDbkcsaUdBQWlHO0FBQ2pHLGdFQUFnRTtBQUNuRCxRQUFBLFlBQVksR0FBRyxVQUFVLENBQUM7QUFDdkMsTUFBTSxlQUFlLEdBQUcsYUFBYSxDQUFDO0FBQ3RDLE1BQU0saUJBQWlCLEdBQUcsOENBQThDLENBQUM7QUFDekUsZ0dBQWdHO0FBQ2hHLG1DQUFtQztBQUNuQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDdkMsNkZBQTZGO0FBQzdGLGlHQUFpRztBQUNqRyxrRUFBa0U7QUFDbEUsTUFBTSx5QkFBeUIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzVDLGdHQUFnRztBQUNoRyxpR0FBaUc7QUFDakcsMERBQTBEO0FBQzFELE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQVNuQyxLQUFLLFVBQVUsVUFBVSxDQUFDLFFBQWdCO0lBQ3RDLElBQUksQ0FBQztRQUNELE1BQU0sa0JBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLFFBQWdCLEVBQUUsU0FBaUI7SUFD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RUFBRSxLQUFLO1lBQ2YsTUFBTSxFQUFFLDRDQUE0QyxVQUFVLCtCQUErQjtTQUNoRyxDQUFDO0lBQ04sQ0FBQztJQUVELElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUMzQixPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVELDRGQUE0RjtJQUM1Rix3RUFBd0U7SUFDeEUsSUFBSSxJQUFJLEdBQUcsSUFBQSxvQkFBTyxFQUFDLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELElBQUksZUFBZSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FDaEQsSUFBQSxvQkFBTyxFQUFDLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDO0lBQ2hGLElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxNQUFNLHVCQUF1QixDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFlBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEYsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLG9DQUFvQyxFQUFFLGtDQUFrQyxFQUFFLENBQUM7SUFDakgsQ0FBQztJQUNELE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxvQ0FBb0MsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUNqRixDQUFDO0FBekRELDhDQXlEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyByZXNvbHZlS2V5c1JlcG8gfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMva2V5c1JlcG9cIjtcbmltcG9ydCB7IHJldm9rZVJlcG8sIHN5bmNSZXBvRmlsZXMgfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMvZGFlbW9uL3JlcG9GaWxlc1wiO1xuaW1wb3J0IHsgbGlzdFJlcG9EaXIsIHJlYWRSZXBvRmlsZSB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyBuZXdSZXZvY2F0aW9uSWQsIHBhaXJLZXksIHJlYWRSZXZvY2F0aW9uRmlsZXMsIHJlYWRVbnJldm9rZXMgfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMvZGFlbW9uL3Jldm9jYXRpb25cIjtcbmltcG9ydCB7IHJ1bkdpdCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vZ2l0XCI7XG5pbXBvcnQgeyBlbnN1cmVSZXZva2VLZXkgfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMvZGFlbW9uL3JlcG9GaWxlc1wiO1xuaW1wb3J0IHsgdmVyaWZ5Q2hlY2tvdXQgfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMvZGFlbW9uL3RydXN0XCI7XG5pbXBvcnQgeyByZXZva2VSZXBvUGF0aCwgcmV2b2tlUmVwb1VSTCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9yZXZva2VTb3VyY2VcIjtcbmltcG9ydCB7IG5vdGlmeSB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vbm90aWZ5XCI7XG5pbXBvcnQgeyBhcmVEaXNjb3JkTm90aWZpY2F0aW9uc0NvbmZpZ3VyZWQsIGNvbmZpZ3VyZURpc2NvcmROb3RpZmljYXRpb25zLCBERUZBVUxUX1dFQkhPT0tfRklMRV9QQVRIIH0gZnJvbSBcIi4uL25vdGlmaWNhdGlvbnMvZGlzY29yZFwiO1xuaW1wb3J0IHsgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IHJ1bkluZmluaXRlUG9sbCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBzcGF3blByb21pc2UgfSBmcm9tIFwiLi4vaGVscGVycy9zcGF3blwiO1xuXG4vLyBXaGljaCBtYWNoaW5lcyB0aGlzIHN5c3RlbSB0YWxrcyB0bywga2VwdCBpbiB0aGUgc2FtZSByZXBvIGFzIHRoZSBzc2gga2V5cy4gVGhhdCByZXBvIGlzIGFscmVhZHlcbi8vIHNpZ25lZCwgYWxyZWFkeSBkaXN0cmlidXRlZCB0byBldmVyeSBtYWNoaW5lLCBhbmQgYWxyZWFkeSBoYXMgc29tZXdoZXJlIHRvIHJlY29yZCBhIHJlamVjdGlvbixcbi8vIHNvIGEgc2Vjb25kIG9uZSB3b3VsZCBvbmx5IGJlIGEgc2Vjb25kIHRoaW5nIHRvIGtlZXAgaW4gc3RlcC5cbmV4cG9ydCBjb25zdCBNQUNISU5FU19ESVIgPSBcIm1hY2hpbmVzXCI7XG5jb25zdCBSRVZPQ0FUSU9OU19ESVIgPSBcInJldm9jYXRpb25zXCI7XG5jb25zdCBSRVZPQ0FUSU9OX1JFQVNPTiA9IFwiYSBtYWNoaW5lIHRhbGtlZCB0byB1cyBmcm9tIGFuIHVuYXBwcm92ZWQgSVBcIjtcbi8vIFRoZSByZXZva2UgcmVwbyBpcyBwdWxsZWQgYXQgbW9zdCB0aGlzIG9mdGVuLiBBIGNoZWNrIGhhcHBlbnMgcGVyIHJlcXVlc3QsIGFuZCBhIHJlcXVlc3QgbXVzdFxuLy8gbm90IGNvc3QgYSByb3VuZCB0cmlwIHRvIGdpdGh1Yi5cbmNvbnN0IFJFVk9LRV9TWU5DX0lOVEVSVkFMID0gNjAgKiAxMDAwO1xuLy8gQW5kIHRoZSBtYWNoaW5lIGxpc3QgaXMgcmUtcmVhZCBmcm9tIHRoZSBjaGVja291dCBvbiB0aGlzIGludGVydmFsLCBpbiB0aGUgYmFja2dyb3VuZC4gVGhlXG4vLyBjaGVja291dCBpdHNlbGYgb25seSBtb3ZlcyB3aGVuIHRoZSBkYWVtb24gcHVsbHMgaXQsIHdoaWNoIGlzIG9uIHRoZSBzYW1lIHNvcnQgb2YgaW50ZXJ2YWwsIHNvXG4vLyByZWFkaW5nIG1vcmUgb2Z0ZW4gdGhhbiB0aGlzIHdvdWxkIG9ubHkgcmUtcmVhZCB0aGUgc2FtZSBieXRlcy5cbmNvbnN0IE1BQ0hJTkVTX1JFRlJFU0hfSU5URVJWQUwgPSA2MCAqIDEwMDA7XG4vLyBIb3cgbG9uZyBhIGZhaWx1cmUgdG8gZmluZCB0aGUga2V5cyByZXBvIGlzIHJlbWVtYmVyZWQuIEEgbG9uZyBsaXZlZCBwcm9jZXNzIG1heSBzdGFydCBiZWZvcmVcbi8vIHRoZSBtYWNoaW5lIGlzIHNldCB1cCwgYW5kIHNob3VsZCBwaWNrIGl0IHVwIG9uY2UgaXQgaXMsIHdpdGhvdXQgYmVpbmcgcmVzdGFydGVkIC0gYnV0IGl0IG11c3Rcbi8vIG5vdCBwYXkgZm9yIHJlc29sdmluZyB0aGUgcmVwbyBvbiBldmVyeSByZXF1ZXN0IGVpdGhlci5cbmNvbnN0IFJFUE9fUkVUUllfREVMQVkgPSAxNSAqIDEwMDA7XG5cbi8qKiBPbmUgbWFjaGluZSB3ZSBhcmUgd2lsbGluZyB0byB0YWxrIHRvLCBhbmQgdGhlIGFkZHJlc3NlcyBpdCBtYXkgdGFsayB0byB1cyBmcm9tLiAqL1xuZXhwb3J0IHR5cGUgTWFjaGluZVN0YXRlID0ge1xuICAgIG1hY2hpbmVJZDogc3RyaW5nO1xuICAgIGlwczogc3RyaW5nW107XG4gICAgYWRkZWRBdDogc3RyaW5nO1xufTtcblxuYXN5bmMgZnVuY3Rpb24gcGF0aEV4aXN0cyhmaWxlUGF0aDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMuYWNjZXNzKGZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYWNoaW5lRmlsZVBhdGgocmVwb1BhdGg6IHN0cmluZywgbWFjaGluZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIsIGAke21hY2hpbmVJZH0uanNvbmApO1xufVxuXG4vKiogVGhpcyBtYWNoaW5lJ3Mga2V5cyByZXBvLCB3b3JrZWQgb3V0IG9uY2UgYW5kIHRoZW4gcmVtZW1iZXJlZC5cblxuICAgIEEgZmFpbHVyZSBpcyByZW1lbWJlcmVkIHRvbywgYnV0IG9ubHkgYnJpZWZseTogYSBzZXJ2ZXIgbWF5IHdlbGwgc3RhcnQgYmVmb3JlIHRoZSBtYWNoaW5lIGhhc1xuICAgIGJlZW4gc2V0IHVwLCBhbmQgc2hvdWxkIHN0YXJ0IHdvcmtpbmcgd2hlbiBpdCBpcywgcmF0aGVyIHRoYW4gbmVlZGluZyBhIHJlc3RhcnQuICovXG5leHBvcnQgY29uc3Qga2V5c1JlcG8gPSBsYXp5KGFzeW5jICgpID0+IHtcbiAgICBsZXQgbG9va3VwID0gcmVzb2x2ZUtleXNSZXBvKCk7XG4gICAgbG9va3VwLmNhdGNoKCgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiBrZXlzUmVwby5yZXNldCgpLCBSRVBPX1JFVFJZX0RFTEFZKS51bnJlZigpO1xuICAgIH0pO1xuICAgIHJldHVybiBhd2FpdCBsb29rdXA7XG59KTtcblxuLyoqIEV2ZXJ5IG1hY2hpbmUgYSBjaGVja291dCBsaXN0cy4gV2l0aG91dCBhIHJlcG8sIHRoaXMgbWFjaGluZSdzIG93bi4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRNYWNoaW5lcyhyZXBvUGF0aD86IHN0cmluZyk6IFByb21pc2U8TWFjaGluZVN0YXRlW10+IHtcbiAgICByZXR1cm4gWy4uLihhd2FpdCByZWFkTWFjaGluZXMocmVwb1BhdGggfHwgKGF3YWl0IGtleXNSZXBvKCkpLnJlcG9QYXRoKSkudmFsdWVzKCldO1xufVxuXG4vKiogUmVhZHMgdGhlIG1hY2hpbmUgbGlzdCwgb25jZSBpdHMgc2lnbmF0dXJlIGhhcyBiZWVuIGNoZWNrZWQuIEFuIHVuc2lnbmVkIG1hY2hpbmUgbGlzdCwgb3Igb25lXG4gICAgc2lnbmVkIG92ZXIgZGlmZmVyZW50IGNvbnRlbnRzLCBpcyBub3QgZXZpZGVuY2Ugb2YgYW55dGhpbmcsIHNvIHRoaXMgdGhyb3dzIHJhdGhlciB0aGFuXG4gICAgcXVpZXRseSB0cnVzdGluZyBub2JvZHkuICovXG5hc3luYyBmdW5jdGlvbiByZWFkVHJ1c3RlZE1hY2hpbmVzKCkge1xuICAgIGxldCB7IHJlcG9QYXRoIH0gPSBhd2FpdCBrZXlzUmVwbygpO1xuICAgIGF3YWl0IHZlcmlmeUNoZWNrb3V0KHJlcG9QYXRoKTtcbiAgICByZXR1cm4gYXdhaXQgZ2V0TWFjaGluZXMocmVwb1BhdGgpO1xufVxuXG5jb25zdCB0cnVzdGVkTWFjaGluZXMgPSBsYXp5KGFzeW5jICgpID0+IHtcbiAgICBsZXQgcmVhZCA9IHJlYWRUcnVzdGVkTWFjaGluZXMoKTtcbiAgICByZWFkLmNhdGNoKCgpID0+IHRydXN0ZWRNYWNoaW5lcy5yZXNldCgpKTtcbiAgICByZXR1cm4gYXdhaXQgcmVhZDtcbn0pO1xuXG5sZXQgcmVmcmVzaGluZyA9IGZhbHNlO1xuXG4vKiogVGhlIG1hY2hpbmVzIHRoaXMgc3lzdGVtIHRydXN0cywgYXMgdGhlIHNpZ25lZCByZXBvIGxpc3RzIHRoZW0uXG5cbiAgICBIZWxkIHJhdGhlciB0aGFuIHJlYWQgcGVyIGNhbGwsIGFuZCByZWZyZXNoZWQgaW4gdGhlIGJhY2tncm91bmQsIHNvIG5vYm9keSBhc2tpbmcgd2hldGhlciBhXG4gICAgbWFjaGluZSBpcyB0cnVzdGVkIHdhaXRzIGZvciBhIGRpcmVjdG9yeSBvZiBmaWxlcyB0byBiZSByZWFkIGFuZCBhIHNpZ25hdHVyZSB0byBiZSBjaGVja2VkLiBBXG4gICAgcmVmcmVzaCB0aGF0IGZhaWxzIGxlYXZlcyB0aGUgbGlzdCB3ZSBhbHJlYWR5IGhhdmU6IHRoZSBjaGVja291dCBpcyBvbmx5IHN0YWxlLCBub3Qgd3JvbmcuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0VHJ1c3RlZE1hY2hpbmVzKCk6IFByb21pc2U8TWFjaGluZVN0YXRlW10+IHtcbiAgICBpZiAoIXJlZnJlc2hpbmcpIHtcbiAgICAgICAgcmVmcmVzaGluZyA9IHRydWU7XG4gICAgICAgIHJ1bkluZmluaXRlUG9sbChNQUNISU5FU19SRUZSRVNIX0lOVEVSVkFMLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRydXN0ZWRNYWNoaW5lcy5zZXQoUHJvbWlzZS5yZXNvbHZlKGF3YWl0IHJlYWRUcnVzdGVkTWFjaGluZXMoKSkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb3VsZCBub3QgcmUtcmVhZCB0aGUgdHJ1c3RlZCBtYWNoaW5lcywga2VlcGluZyB0aGUgb25lcyB3ZSBoYXZlLiAke2V9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgdHJ1c3RlZE1hY2hpbmVzKCk7XG59XG5cbi8qKiBNYWtlcyBhIGNoZWNrb3V0IGxpc3QgZXhhY3RseSB0aGVzZSBtYWNoaW5lczogdGhvc2UgbmFtZWQgYXJlIHdyaXR0ZW4gd2l0aCB0aGUgYWRkcmVzc2VzIGdpdmVuLFxuICAgIGFuZCBhbnl0aGluZyBub3QgbmFtZWQgaXMgcmVtb3ZlZC4gU28gcmVhZCB0aGVtLCBjaGFuZ2Ugd2hhdCB5b3Ugd2FudCwgYW5kIHdyaXRlIHRoZSByZXN1bHQuXG5cbiAgICBUaGUgYWRkcmVzc2VzIGFyZSBwYXJ0IG9mIHNldHRpbmcgcmF0aGVyIHRoYW4gYSBzZXBhcmF0ZSBzdGVwLCBiZWNhdXNlIGEgbWFjaGluZSB3aXRoIG5vXG4gICAgYWRkcmVzcyBpdCBtYXkgdGFsayBmcm9tIGlzIG5vdCBhIG1hY2hpbmUgdGhhdCB3b3VsZCBldmVyIGJlIGFjY2VwdGVkIC0gdGhlcmUgaXMgbm8gc3RhdGUgd2hlcmVcbiAgICBuYW1pbmcgb25lIHdpdGhvdXQgdGhlbSBtZWFucyBhbnl0aGluZy5cblxuICAgIE5vdGhpbmcgaGVyZSBzaWducyBvciBjb21taXRzLiBUaGUgc2lnbmF0dXJlIGlzIHdoYXQgZXZlcnkgb3RoZXIgbWFjaGluZSBjaGVja3MgYmVmb3JlXG4gICAgYmVsaWV2aW5nIGFueSBvZiB0aGlzLCBhbmQgaXQgdGFrZXMgdGhlIGhhcmR3YXJlIGtleSwgc28gYHlhcm4gc2lnbmZpbGVzIGdpdGAgaXMgc3RpbGwgeW91cnMgdG9cbiAgICBydW4gYWZ0ZXJ3YXJkcy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXRNYWNoaW5lcyhjb25maWc6IHtcbiAgICByZXBvUGF0aD86IHN0cmluZztcbiAgICBtYWNoaW5lczogeyBtYWNoaW5lSWQ6IHN0cmluZzsgaXBzOiBzdHJpbmdbXSB9W107XG59KTogUHJvbWlzZTxNYWNoaW5lU3RhdGVbXT4ge1xuICAgIGxldCB7IG1hY2hpbmVzIH0gPSBjb25maWc7XG4gICAgbGV0IHJlcG9QYXRoID0gY29uZmlnLnJlcG9QYXRoIHx8IChhd2FpdCBrZXlzUmVwbygpKS5yZXBvUGF0aDtcbiAgICAvLyBXaGF0ZXZlciB3YXMgaGVsZCBpcyBub3cgc3RhbGUsIHdob2V2ZXIgcmVhZHMgaXQgbmV4dC5cbiAgICB0cnVzdGVkTWFjaGluZXMucmVzZXQoKTtcbiAgICBsZXQgZXhpc3RpbmcgPSBhd2FpdCByZWFkTWFjaGluZXMocmVwb1BhdGgpO1xuICAgIGxldCBkaXJlY3RvcnkgPSBwYXRoLmpvaW4ocmVwb1BhdGgsIE1BQ0hJTkVTX0RJUik7XG4gICAgbGV0IHdyaXR0ZW46IE1hY2hpbmVTdGF0ZVtdID0gW107XG4gICAgZm9yIChsZXQgbWFjaGluZSBvZiBtYWNoaW5lcykge1xuICAgICAgICBpZiAoIW1hY2hpbmUubWFjaGluZUlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkLCB3YXMgJHtKU09OLnN0cmluZ2lmeShtYWNoaW5lLm1hY2hpbmVJZCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtYWNoaW5lLmlwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYWRkcmVzc2VzIGZvciAke21hY2hpbmUubWFjaGluZUlkfSwgd2FzIG5vbmUuIEEgbWFjaGluZSBpcyB0cnVzdGVkIGZyb21gXG4gICAgICAgICAgICAgICAgKyBgIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgZnJvbSwgc28gbGVhdmUgaXQgb3V0IG9mIHRoZSBsaXN0IHRvIHJlbW92ZSBpdC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpcHMgPSBtYWNoaW5lLmlwcy5maWx0ZXIoKGlwLCBpbmRleCkgPT4gaXAgJiYgbWFjaGluZS5pcHMuaW5kZXhPZihpcCkgPT09IGluZGV4KTtcbiAgICAgICAgbGV0IHN0YXRlOiBNYWNoaW5lU3RhdGUgPSB7XG4gICAgICAgICAgICBtYWNoaW5lSWQ6IG1hY2hpbmUubWFjaGluZUlkLFxuICAgICAgICAgICAgLy8gSW4gdGhlIG9yZGVyIGdpdmVuLCB3aXRob3V0IGR1cGxpY2F0ZXMsIHNvIHRoZSBmaWxlIHJlYWRzIHRoZSB3YXkgaXQgd2FzIHNldC5cbiAgICAgICAgICAgIGlwcyxcbiAgICAgICAgICAgIGFkZGVkQXQ6IGV4aXN0aW5nLmdldChtYWNoaW5lLm1hY2hpbmVJZCk/LmFkZGVkQXQgfHwgbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBmcy5ta2RpcihkaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUobWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBzdGF0ZS5tYWNoaW5lSWQpLCBKU09OLnN0cmluZ2lmeShzdGF0ZSwgdW5kZWZpbmVkLCA0KSArIFwiXFxuXCIpO1xuICAgICAgICB3cml0dGVuLnB1c2goc3RhdGUpO1xuICAgIH1cblxuICAgIC8vIFdoYXRldmVyIHRoZSByZXBvIGhhZCBhbmQgdGhlIGNhbGxlciBkaWQgbm90IG5hbWUgaXMgbm8gbG9uZ2VyIHRydXN0ZWQuXG4gICAgZm9yIChsZXQgbWFjaGluZUlkIG9mIGV4aXN0aW5nLmtleXMoKSkge1xuICAgICAgICBpZiAoIW1hY2hpbmVzLnNvbWUobWFjaGluZSA9PiBtYWNoaW5lLm1hY2hpbmVJZCA9PT0gbWFjaGluZUlkKSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucm0obWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBtYWNoaW5lSWQpLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB3cml0dGVuO1xufVxuXG4vKiogRXZlcnkgbWFjaGluZSB0aGUgcmVwbyBsaXN0cy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IG1hY2hpbmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hY2hpbmVTdGF0ZT4oKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIpO1xuICAgIGxldCBuYW1lcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyZWN0b3J5KS5jYXRjaCgoKSA9PiBbXSBhcyBzdHJpbmdbXSk7XG4gICAgZm9yIChsZXQgbmFtZSBvZiBuYW1lcy5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4oZGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBwYXJzZWQubWFjaGluZUlkIHx8IG5hbWUucmVwbGFjZSgvXFwuanNvbiQvLCBcIlwiKTtcbiAgICAgICAgICAgIG1hY2hpbmVzLnNldChtYWNoaW5lSWQsIHsgbWFjaGluZUlkLCBpcHM6IHBhcnNlZC5pcHMgfHwgW10sIGFkZGVkQXQ6IHBhcnNlZC5hZGRlZEF0IHx8IFwiXCIgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIG1hY2hpbmUgZmlsZSAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hY2hpbmVzO1xufVxuXG5sZXQgbGFzdFJldm9rZVN5bmMgPSAwO1xuXG4vKiogUHVsbGVkIGF0IG1vc3Qgb25jZSBhIFJFVk9LRV9TWU5DX0lOVEVSVkFMLCBiZWNhdXNlIHRoaXMgaXMgYXNrZWQgcGVyIHJlcXVlc3QuIEEgc3luYyB0aGF0XG4gICAgZmFpbHMgbGVhdmVzIHRoZSBjaGVja291dCB3ZSBhbHJlYWR5IGhhdmUsIHdoaWNoIGlzIHRoZSBzYWZlIGRpcmVjdGlvbjogcmV2b2NhdGlvbnMgd2Uga25vd1xuICAgIGFib3V0IHN0YXkga25vd24uICovXG5hc3luYyBmdW5jdGlvbiBzeW5jUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBpZiAoRGF0ZS5ub3coKSAtIGxhc3RSZXZva2VTeW5jIDwgUkVWT0tFX1NZTkNfSU5URVJWQUwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsYXN0UmV2b2tlU3luYyA9IERhdGUubm93KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3luY1JlcG9GaWxlcyhyZXZva2VSZXBvKHNvdXJjZVVSTCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCByZWFkICR7cmV2b2tlUmVwb1VSTChzb3VyY2VVUkwpfSwgdXNpbmcgdGhlIHJldm9jYXRpb25zIGFscmVhZHkgaGVyZS4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIE1hY2hpbmUgcmV2b2NhdGlvbnMsIHJlYWQgb3V0IG9mIHRoZSByZXZva2UgcmVwbyB0aGUgc2FtZSB3YXkga2V5IHJldm9jYXRpb25zIGFyZS4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBsZXQgcmVwbyA9IHJldm9rZVJlcG8oc291cmNlVVJMKTtcbiAgICBsZXQgcmV2b2NhdGlvbnM6IHsgcmV2b2NhdGlvbklkOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IG5hbWUgb2YgYXdhaXQgbGlzdFJlcG9EaXIocmVwbywgUkVWT0NBVElPTlNfRElSKSkge1xuICAgICAgICBpZiAoIW5hbWUuZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBwYXJzZWQgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRSZXBvRmlsZShyZXBvLCBwYXRoLmpvaW4oUkVWT0NBVElPTlNfRElSLCBuYW1lKSkgfHwgXCJcIik7XG4gICAgICAgICAgICBpZiAocGFyc2VkLm1hY2hpbmVJZCkge1xuICAgICAgICAgICAgICAgIHJldm9jYXRpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICByZXZvY2F0aW9uSWQ6IHBhcnNlZC5yZXZvY2F0aW9uSWQgfHwgbmFtZS5yZXBsYWNlKC9cXC5qc29uJC8sIFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICBtYWNoaW5lSWQ6IHBhcnNlZC5tYWNoaW5lSWQsXG4gICAgICAgICAgICAgICAgICAgIGlwOiBwYXJzZWQuaXAgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYElnbm9yaW5nIHVucmVhZGFibGUgcmV2b2NhdGlvbiAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldm9jYXRpb25zO1xufVxuXG4vKiogV2hhdCB0byBydW4gdG8gdHJ1c3QgYSBtYWNoaW5lIHRoYXQgaGFzIGp1c3QgYmVlbiByZWZ1c2VkLlxuXG4gICAgRXZlcnl0aGluZyBpbiBpdCBpcyBhbHJlYWR5IGtub3duIHRvIHdob2V2ZXIgaXMgYmVpbmcgcmVmdXNlZDogdGhlaXIgbWFjaGluZSBpZCwgdGhlIGFkZHJlc3Mgd2VcbiAgICBzYXcgdGhlbSBhdCwgYW5kIHRoZSBkb21haW4gdGhleSBqdXN0IHRhbGtlZCB0by4gSGFuZGluZyBpdCBiYWNrIHNhdmVzIHRoZW0gd29ya2luZyBvdXQgdGhlXG4gICAgcGFydHMgb2YgYSBjb21tYW5kIHRoZXkgaGF2ZSBldmVyeSByaWdodCB0byBrbm93LiBSdW5uaW5nIGl0IHN0aWxsIHRha2VzIHRoZSBoYXJkd2FyZSBrZXkgb25cbiAgICB0aGUgbWFjaGluZSB0aGF0IG93bnMgdGhlIHJlcG8sIHNvIHRlbGxpbmcgdGhlbSBjb3N0cyBub3RoaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZE1hY2hpbmVDb21tYW5kKGNvbmZpZzogeyBtYWNoaW5lSWQ6IHN0cmluZzsgaXA6IHN0cmluZzsgZG9tYWluPzogc3RyaW5nIH0pIHtcbiAgICBsZXQgeyBtYWNoaW5lSWQsIGlwLCBkb21haW4gfSA9IGNvbmZpZztcbiAgICByZXR1cm4gYFRvIHRydXN0IGl0LCBydW46IHlhcm4gYWRkbWFjaGluZSAke2RvbWFpbiB8fCBcIjxkb21haW4+XCJ9ICR7bWFjaGluZUlkfSAke2lwfSBnaXRgO1xufVxuXG4vKiogU2VuZHMgdGhlIG9uZSBub3RpZmljYXRpb24gdGhpcyBmaWxlIGlzIGFsbG93ZWQgdG8gc2VuZCwgd2hlbiBpdCBjYW4uXG5cbiAgICBUaGUgZGFlbW9uIGNvbmZpZ3VyZXMgbm90aWZpY2F0aW9ucyBvbiBzdGFydHVwIGFuZCB3b3VsZCBzaW1wbHkgc2VuZC4gVGhpcyBjYW4gYWxzbyBydW4gaW4gc29tZVxuICAgIG90aGVyIHByb2Nlc3MsIHdoaWNoIGhhcyBub3QsIHNvIHRoZSB3ZWJob29rIGlzIHBpY2tlZCB1cCBoZXJlIGlmIGl0IGlzIHJlYWRhYmxlLiBBIG1hY2hpbmVcbiAgICB3aXRoIG5vIHdlYmhvb2sgc2V0IHVwIHN0aWxsIHJlY29yZHMgdGhlIHJldm9jYXRpb24gLSBiZWluZyB1bmFibGUgdG8gdGVsbCBhbnlvbmUgaXMgbm90IGFcbiAgICByZWFzb24gdG8ga2VlcCBhY2NlcHRpbmcgYSBtYWNoaW5lIHRoYXQgaXMgYmVpbmcgbWlzdXNlZC4gKi9cbmFzeW5jIGZ1bmN0aW9uIG5vdGlmeUJlc3RFZmZvcnQoaGVhZGxpbmU6IHN0cmluZywgYm9keTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKCFhcmVEaXNjb3JkTm90aWZpY2F0aW9uc0NvbmZpZ3VyZWQoKSkge1xuICAgICAgICAgICAgLy8gUmVhZCBmaXJzdDogY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMgZXhpdHMgdGhlIHByb2Nlc3Mgd2hlbiB0aGUgZmlsZSBpcyBtaXNzaW5nLFxuICAgICAgICAgICAgLy8gd2hpY2ggaXMgcmlnaHQgZm9yIHRoZSBkYWVtb24gYXQgc3RhcnR1cCBhbmQgd3JvbmcgZm9yIGEgbGlicmFyeSBjYWxsLlxuICAgICAgICAgICAgYXdhaXQgZnMucmVhZEZpbGUoREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCwgXCJ1dGY4XCIpO1xuICAgICAgICAgICAgYXdhaXQgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMoeyBmaWxlUGF0aDogREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBub3RpZnkoaGVhZGxpbmUsIGJvZHkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBzZW5kIGEgbm90aWZpY2F0aW9uIGFib3V0IHRoaXMsIGl0IGlzIG9ubHkgaW4gdGhlIGxvZy4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIFJlY29yZHMgdGhhdCBhIG1hY2hpbmUgd2UgYWNjZXB0IHRhbGtlZCB0byB1cyBmcm9tIGFuIGFkZHJlc3MgaXQgaXMgbm90IGFsbG93ZWQgZnJvbS4gT25lIHBlclxuICAgIG1hY2hpbmUgYW5kIGFkZHJlc3MsIHNvIGEgc2Vjb25kIGFkZHJlc3MgaXMgYSBzZWNvbmQgcmV2b2NhdGlvbiBhbmQgYW4gdW5yZXZva2Ugb2YgdGhlIGZpcnN0XG4gICAgZG9lcyBub3QgY292ZXIgaXQuICovXG5hc3luYyBmdW5jdGlvbiByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbihjb25maWc6IHtcbiAgICBzb3VyY2VVUkw6IHN0cmluZztcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBpcDogc3RyaW5nO1xuICAgIGhvc3RMYWJlbDogc3RyaW5nO1xufSkge1xuICAgIGxldCB7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsIH0gPSBjb25maWc7XG4gICAgbGV0IHJlcG9QYXRoID0gcmV2b2tlUmVwb1BhdGgoc291cmNlVVJMKTtcbiAgICBsZXQga2V5UGF0aCA9IGF3YWl0IGVuc3VyZVJldm9rZUtleShzb3VyY2VVUkwpO1xuICAgIGxldCByZXZvY2F0aW9uSWQgPSBuZXdSZXZvY2F0aW9uSWQobWFjaGluZUlkKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBSRVZPQ0FUSU9OU19ESVIpO1xuICAgIGF3YWl0IGZzLm1rZGlyKGRpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHBhdGguam9pbihkaXJlY3RvcnksIGAke3Jldm9jYXRpb25JZH0uanNvbmApLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHJldm9jYXRpb25JZCxcbiAgICAgICAgbWFjaGluZUlkLFxuICAgICAgICBpcCxcbiAgICAgICAgcmV2b2tlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIHJldm9rZWRCeTogaG9zdExhYmVsLFxuICAgICAgICByZWFzb246IFJFVk9DQVRJT05fUkVBU09OLFxuICAgIH0sIHVuZGVmaW5lZCwgNCkgKyBcIlxcblwiKTtcblxuICAgIGF3YWl0IHJ1bkdpdCh7IGFyZ3M6IFtcImFkZFwiLCBcIi1BXCJdLCBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoIH0pO1xuICAgIGF3YWl0IHJ1bkdpdCh7XG4gICAgICAgIGFyZ3M6IFtcIi1jXCIsIFwidXNlci5lbWFpbD1wb3J0c2VjdXJlQGxvY2FsaG9zdFwiLCBcIi1jXCIsIFwidXNlci5uYW1lPXBvcnRzZWN1cmVcIiwgXCJjb21taXRcIiwgXCItbVwiLCBgcmV2b2tlICR7cmV2b2NhdGlvbklkfWBdLFxuICAgICAgICBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoLFxuICAgIH0pO1xuICAgIGxldCBwdXNoID0gYXdhaXQgcnVuR2l0KHsgYXJnczogW1wicHVzaFwiLCBcIm9yaWdpblwiLCBcIkhFQURcIl0sIGN3ZDogcmVwb1BhdGgsIGtleVBhdGgsIGFsbG93RmFpbHVyZTogdHJ1ZSB9KTtcbiAgICBpZiAocHVzaC5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgLy8gQW5vdGhlciBtYWNoaW5lIG1vc3QgbGlrZWx5IHJlY29yZGVkIHRoZSBzYW1lIHRoaW5nIGZpcnN0LCBhbmQgdGhlIG5leHQgcmVhZCBwaWNrcyBpdCB1cC5cbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBwdXNoIHRoZSByZXZvY2F0aW9uIG9mICR7bWFjaGluZUlkfSBmcm9tICR7aXB9LiAkeyhwdXNoLnN0ZG91dCArIHB1c2guc3RkZXJyKS50cmltKCl9YCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYFJldm9rZWQgJHttYWNoaW5lSWR9IGZyb20gJHtpcH0sICR7cmV2b2NhdGlvbklkfWApO1xuXG4gICAgLy8gU2FpZCBieSB3aG9ldmVyIHdyb3RlIHRoZSByZXZvY2F0aW9uLCBvbmNlLCB0aGUgc2FtZSBhcyBmb3IgYW4gc3NoIGtleS4gTWFjaGluZXMgdGhhdCBvbmx5XG4gICAgLy8gcmVhZCBpdCBsYXRlciBzYXkgbm90aGluZywgb3Igb25lIGV2ZW50IHdvdWxkIGJlIHJlcG9ydGVkIGJ5IGV2ZXJ5IG1hY2hpbmUgdGhhdCBzYXcgaXQuXG4gICAgYXdhaXQgbm90aWZ5QmVzdEVmZm9ydChcbiAgICAgICAgYFNVU1BJQ0lPVVMgSVAgJHtpcH0gRlJPWkUgTUFDSElORSAke21hY2hpbmVJZH1gLFxuICAgICAgICBgQSBtYWNoaW5lIHdlIHRydXN0IHRhbGtlZCB0byB1cyBmcm9tICR7aXB9LCB3aGljaCBpcyBub3QgYW4gYWRkcmVzcyBpdCBpcyBhbGxvd2VkIHRvIHRhbGtgXG4gICAgICAgICsgYCBmcm9tLiBJdCBwcm92ZWQgaXQgaG9sZHMgdGhhdCBtYWNoaW5lJ3Mga2V5LCBzbyBlaXRoZXIgc29tZW9uZSBlbHNlIGhhcyBhIGNvcHkgb2YgaXQsYFxuICAgICAgICArIGAgb3IgdGhhdCBtYWNoaW5lJ3MgYWRkcmVzcyBjaGFuZ2VkLmBcbiAgICAgICAgKyBgXFxuXFxuSXQgaXMgZnJvemVuIGV2ZXJ5d2hlcmUgbm93LCBhbmQgbm90aGluZyBhY2NlcHRzIGl0LmBcbiAgICAgICAgKyBgXFxuXFxuSWYgdGhpcyB3YXMgYW4gYXR0YWNrLCByZW1vdmUgXFxgbWFjaGluZXMvJHttYWNoaW5lSWR9Lmpzb25cXGAgZnJvbSBcXGAke3NvdXJjZVVSTH1cXGAgbm93LmBcbiAgICAgICAgKyBgXFxuSWYgaXQgd2FzIGxlZ2l0aW1hdGUsIHJ1biBcXGB5YXJuIHVucmV2b2tlIGdpdFxcYCBpbiB0aGF0IHJlcG8uIEl0IGFsbG93cyAke2lwfSBmb3IgdGhhdGBcbiAgICAgICAgKyBgIG1hY2hpbmUsIGFuZCB0YWtlcyBlZmZlY3QgYXMgZWFjaCBtYWNoaW5lIHBpY2tzIGl0IHVwLmBcbiAgICAgICAgKyBgXFxuXFxubWFjaGluZTogXFxgJHttYWNoaW5lSWR9XFxgYFxuICAgICAgICArIGBcXG5mcm96ZW4gYnk6IFxcYCR7aG9zdExhYmVsfVxcYGBcbiAgICApO1xufVxuXG4vKiogV2hldGhlciB3ZSB3aWxsIHRhbGsgdG8gdGhpcyBtYWNoaW5lLCBjb21pbmcgZnJvbSB0aGlzIGFkZHJlc3MuXG5cbiAgICBCb3RoIGhhbHZlcyBhcmUgcmVxdWlyZWQgYW5kIG5laXRoZXIgaXMgYSBndWVzczogdGhlIGNhbGxlciBrbm93cyB0aGUgbWFjaGluZSBpZCBiZWNhdXNlIHRoZVxuICAgIGNvbm5lY3Rpb24gcHJvdmVkIGl0LCBhbmQga25vd3MgdGhlIGFkZHJlc3MgYmVjYXVzZSB0aGUgcGFja2V0cyBjYW1lIGZyb20gdGhlcmUuIEEgbWFjaGluZSB3ZVxuICAgIGRvIG5vdCBsaXN0IGlzIHNpbXBseSBub3QgYWNjZXB0ZWQuIEEgbWFjaGluZSB3ZSBkbyBsaXN0LCBhcnJpdmluZyBmcm9tIGFuIGFkZHJlc3MgaXQgZG9lcyBub3RcbiAgICBoYXZlLCBpcyB0cmVhdGVkIGFzIHRoZSBzYW1lIGtpbmQgb2YgZXZlbnQgYXMgYSBzdG9sZW4gc3NoIGtleSAtIGl0IGlzIHJldm9rZWQgZXZlcnl3aGVyZSwgYW5kXG4gICAgc3RheXMgcmV2b2tlZCB1bnRpbCBhbiB1bnJldm9rZSBhbGxvd3MgdGhhdCBtYWNoaW5lIGZyb20gdGhhdCBhZGRyZXNzLlxuXG4gICAgU2F5cyB3aHkgd2hlbiB0aGUgYW5zd2VyIGlzIG5vLCBiZWNhdXNlIHRoZSB0aHJlZSB3YXlzIHRvIGJlIHJlZnVzZWQgYXJlIGVudGlyZWx5IGRpZmZlcmVudFxuICAgIHRoaW5ncyB0byBhIHBlcnNvbiByZWFkaW5nIGl0OiBuZXZlciB0cnVzdGVkIGF0IGFsbCwgdHJ1c3RlZCBidXQgZnJvemVuLCBvciB0cnVzdGVkIGFuZCB0YWxraW5nXG4gICAgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS5cblxuICAgIFRocm93cyB3aGVuIHRoZSByZXBvIGl0c2VsZiBjYW5ub3QgYmUgcmVhZCBvciBpcyBub3Qgc2lnbmVkLCByYXRoZXIgdGhhbiBhbnN3ZXJpbmcgZmFsc2U6IHRoYXRcbiAgICBpcyBhIGJyb2tlbiBpbnN0YWxsYXRpb24sIG5vdCBhIHJlamVjdGVkIG1hY2hpbmUsIGFuZCB0aGUgdHdvIGRlc2VydmUgZGlmZmVyZW50IGhhbmRsaW5nLiAqL1xuZXhwb3J0IHR5cGUgTWFjaGluZVZlcmRpY3QgPSB7IGFjY2VwdGVkOiBib29sZWFuOyByZWFzb246IHN0cmluZyB9O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNNYWNoaW5lQWNjZXB0ZWQoY29uZmlnOiB7XG4gICAgbWFjaGluZUlkOiBzdHJpbmc7XG4gICAgaXA6IHN0cmluZztcbiAgICAvLyBPbmx5IHVzZWQgdG8gd3JpdGUgYSBjb21wbGV0ZSBjb21tYW5kIGludG8gdGhlIHJlZnVzYWwuIEEgY2FsbGVyIHRoYXQga25vd3Mgd2hpY2ggZG9tYWluIGl0XG4gICAgLy8gaXMgYW5zd2VyaW5nIGFzIHNhdmVzIHdob2V2ZXIgaXMgcmVmdXNlZCBmcm9tIGhhdmluZyB0byBndWVzcyBpdC5cbiAgICBkb21haW4/OiBzdHJpbmc7XG59KTogUHJvbWlzZTxNYWNoaW5lVmVyZGljdD4ge1xuICAgIGxldCB7IG1hY2hpbmVJZCwgaXAsIGRvbWFpbiB9ID0gY29uZmlnO1xuICAgIGlmICghbWFjaGluZUlkIHx8ICFpcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkIGFuZCBhbiBpcCwgd2FzICR7SlNPTi5zdHJpbmdpZnkobWFjaGluZUlkKX0gYW5kICR7SlNPTi5zdHJpbmdpZnkoaXApfWApO1xuICAgIH1cbiAgICBsZXQgeyBzb3VyY2VVUkwgfSA9IGF3YWl0IGtleXNSZXBvKCk7XG4gICAgLy8gVmVyaWZpZWQgYmVmb3JlIGl0IGlzIGJlbGlldmVkLCBhbmQgY2FjaGVkLCBzaW5jZSB0aGlzIGlzIGFza2VkIG9uY2UgcGVyIHJlcXVlc3QuXG4gICAgbGV0IG1hY2hpbmUgPSAoYXdhaXQgZ2V0VHJ1c3RlZE1hY2hpbmVzKCkpLmZpbmQoZW50cnkgPT4gZW50cnkubWFjaGluZUlkID09PSBtYWNoaW5lSWQpO1xuICAgIGlmICghbWFjaGluZSkge1xuICAgICAgICByZXR1cm4geyBhY2NlcHRlZDogZmFsc2UsIHJlYXNvbjogYHRoYXQgbWFjaGluZSBpcyBub3QgdHJ1c3RlZC4gJHthZGRNYWNoaW5lQ29tbWFuZCh7IG1hY2hpbmVJZCwgaXAsIGRvbWFpbiB9KX1gIH07XG4gICAgfVxuXG4gICAgYXdhaXQgc3luY1Jldm9jYXRpb25zKHNvdXJjZVVSTCk7XG4gICAgbGV0IHVucmV2b2tlcyA9IGF3YWl0IHJlYWRVbnJldm9rZXMoc291cmNlVVJMKS5jYXRjaCgoKSA9PiAoeyBwYWlyczogbmV3IE1hcCgpLCBsZWdhY3lJZHM6IG5ldyBNYXAoKSB9KSk7XG4gICAgLy8gQW4gdW5yZXZva2UgY291bnRzIGFzIHNvb24gYXMgaXQgaXMgc2Vlbi4gSXQgaXMgc2lnbmVkLCBzbyB3cml0aW5nIG9uZSBhbHJlYWR5IHRha2VzIHRoZVxuICAgIC8vIGhhcmR3YXJlIGtleSwgYW5kIGFueW9uZSBob2xkaW5nIHRoYXQgY2FuIHNpZ24gYW55dGhpbmcgYXQgYWxsIC0gYSB3YWl0IGJlZm9yZSBob25vdXJpbmcgaXRcbiAgICAvLyBndWFyZHMgYWdhaW5zdCBhbiBhdHRhY2tlciB3aG8gaGFzIG5vIG5lZWQgb2YgaXQuXG4gICAgbGV0IGFsbG93ZWRBZ2FpbiA9IChwYWlyOiBzdHJpbmcpID0+ICEhdW5yZXZva2VzLnBhaXJzLmdldChwYWlyKT8ubGVuZ3RoO1xuICAgIGxldCByZXZvY2F0aW9ucyA9IGF3YWl0IHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMKTtcbiAgICAvLyBBbnkgcmV2b2NhdGlvbiBub3RoaW5nIGhhcyB1bmRvbmUga2VlcHMgdGhlIG1hY2hpbmUgb3V0LCBmcm9tIGV2ZXJ5d2hlcmUsIHRoZSB3YXkgYSByZXZva2VkXG4gICAgLy8gc3NoIGtleSBpcyBvdXQgZXZlcnl3aGVyZSByYXRoZXIgdGhhbiBvbmx5IGZyb20gdGhlIGFkZHJlc3MgaXQgd2FzIG1pc3VzZWQgZnJvbS5cbiAgICBsZXQgZnJvemVuRnJvbSA9IFwiXCI7XG4gICAgZm9yIChsZXQgcmV2b2NhdGlvbiBvZiByZXZvY2F0aW9ucykge1xuICAgICAgICBpZiAocmV2b2NhdGlvbi5tYWNoaW5lSWQgIT09IG1hY2hpbmVJZCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbGxvd2VkQWdhaW4ocGFpcktleSh7IGZpbmdlcnByaW50OiByZXZvY2F0aW9uLm1hY2hpbmVJZCwgaXA6IHJldm9jYXRpb24uaXAgfSkpKSB7XG4gICAgICAgICAgICBmcm96ZW5Gcm9tID0gcmV2b2NhdGlvbi5pcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZnJvemVuRnJvbSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWNjZXB0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIGZyb3plbiwgaXQgd2FzIHVzZWQgZnJvbSAke2Zyb3plbkZyb219IHdoaWNoIGl0IGlzIG5vdCBhbGxvd2VkIGZyb21gLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChtYWNoaW5lLmlwcy5pbmNsdWRlcyhpcCkpIHtcbiAgICAgICAgcmV0dXJuIHsgYWNjZXB0ZWQ6IHRydWUsIHJlYXNvbjogXCJcIiB9O1xuICAgIH1cblxuICAgIC8vIExpc3RlZCwgYnV0IHRhbGtpbmcgdG8gdXMgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS4gUmVjb3JkZWQgb25jZSBmb3IgdGhpcyBtYWNoaW5lXG4gICAgLy8gYW5kIGFkZHJlc3MsIHNvIGJlaW5nIHRhbGtlZCB0byByZXBlYXRlZGx5IGRvZXMgbm90IHdyaXRlIHJlcGVhdGVkbHkuXG4gICAgbGV0IHBhaXIgPSBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IG1hY2hpbmVJZCwgaXAgfSk7XG4gICAgbGV0IGFscmVhZHlSZWNvcmRlZCA9IHJldm9jYXRpb25zLnNvbWUocmV2b2NhdGlvbiA9PlxuICAgICAgICBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IHJldm9jYXRpb24ubWFjaGluZUlkLCBpcDogcmV2b2NhdGlvbi5pcCB9KSA9PT0gcGFpcik7XG4gICAgaWYgKCFhbHJlYWR5UmVjb3JkZWQgJiYgIWFsbG93ZWRBZ2FpbihwYWlyKSkge1xuICAgICAgICBhd2FpdCByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbih7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsOiBvcy5ob3N0bmFtZSgpIH0pO1xuICAgICAgICByZXR1cm4geyBhY2NlcHRlZDogZmFsc2UsIHJlYXNvbjogYHRoYXQgbWFjaGluZSBpcyBub3QgYWxsb3dlZCBmcm9tICR7aXB9LCBzbyBpdCBpcyBub3cgZnJvemVuIGV2ZXJ5d2hlcmVgIH07XG4gICAgfVxuICAgIHJldHVybiB7IGFjY2VwdGVkOiBmYWxzZSwgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIG5vdCBhbGxvd2VkIGZyb20gJHtpcH1gIH07XG59XG4iXX0=
|
|
331
|
+
/* _JS_SOURCE_HASH = "2d9e826cd3b14184bf081d819b9343dd010bb4fee837a56e1b15c1abee236d95"; */
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export declare const MACHINES_DIR = "machines";
|
|
2
|
+
/** One machine we are willing to talk to, and the addresses it may talk to us from. */
|
|
3
|
+
export type MachineState = {
|
|
4
|
+
machineId: string;
|
|
5
|
+
ips: string[];
|
|
6
|
+
addedAt: string;
|
|
7
|
+
};
|
|
8
|
+
/** This machine's keys repo, worked out once and then remembered.
|
|
9
|
+
|
|
10
|
+
A failure is remembered too, but only briefly: a server may well start before the machine has
|
|
11
|
+
been set up, and should start working when it is, rather than needing a restart. */
|
|
12
|
+
export declare const keysRepo: {
|
|
13
|
+
(): Promise<{
|
|
14
|
+
repoPath: string;
|
|
15
|
+
sourceURL: string;
|
|
16
|
+
}>;
|
|
17
|
+
reset(): void;
|
|
18
|
+
set(newValue: Promise<{
|
|
19
|
+
repoPath: string;
|
|
20
|
+
sourceURL: string;
|
|
21
|
+
}>): void;
|
|
22
|
+
};
|
|
23
|
+
/** Every machine a checkout lists. Without a repo, this machine's own. */
|
|
24
|
+
export declare function getMachines(repoPath?: string): Promise<MachineState[]>;
|
|
25
|
+
/** The machines this system trusts, as the signed repo lists them.
|
|
26
|
+
|
|
27
|
+
Held rather than read per call, and refreshed in the background, so nobody asking whether a
|
|
28
|
+
machine is trusted waits for a directory of files to be read and a signature to be checked. A
|
|
29
|
+
refresh that fails leaves the list we already have: the checkout is only stale, not wrong. */
|
|
30
|
+
export declare function getTrustedMachines(): Promise<MachineState[]>;
|
|
31
|
+
/** Makes a checkout list exactly these machines: those named are written with the addresses given,
|
|
32
|
+
and anything not named is removed. So read them, change what you want, and write the result.
|
|
33
|
+
|
|
34
|
+
The addresses are part of setting rather than a separate step, because a machine with no
|
|
35
|
+
address it may talk from is not a machine that would ever be accepted - there is no state where
|
|
36
|
+
naming one without them means anything.
|
|
37
|
+
|
|
38
|
+
Nothing here signs or commits. The signature is what every other machine checks before
|
|
39
|
+
believing any of this, and it takes the hardware key, so `yarn signfiles git` is still yours to
|
|
40
|
+
run afterwards. */
|
|
41
|
+
export declare function setMachines(config: {
|
|
42
|
+
repoPath?: string;
|
|
43
|
+
machines: {
|
|
44
|
+
machineId: string;
|
|
45
|
+
ips: string[];
|
|
46
|
+
}[];
|
|
47
|
+
}): Promise<MachineState[]>;
|
|
48
|
+
/** What to run to trust a machine that has just been refused.
|
|
49
|
+
|
|
50
|
+
Everything in it is already known to whoever is being refused: their machine id, the address we
|
|
51
|
+
saw them at, and the domain they just talked to. Handing it back saves them working out the
|
|
52
|
+
parts of a command they have every right to know. Running it still takes the hardware key on
|
|
53
|
+
the machine that owns the repo, so telling them costs nothing. */
|
|
54
|
+
export declare function addMachineCommand(config: {
|
|
55
|
+
machineId: string;
|
|
56
|
+
ip: string;
|
|
57
|
+
domain?: string;
|
|
58
|
+
}): string;
|
|
59
|
+
/** Whether we will talk to this machine, coming from this address.
|
|
60
|
+
|
|
61
|
+
Both halves are required and neither is a guess: the caller knows the machine id because the
|
|
62
|
+
connection proved it, and knows the address because the packets came from there. A machine we
|
|
63
|
+
do not list is simply not accepted. A machine we do list, arriving from an address it does not
|
|
64
|
+
have, is treated as the same kind of event as a stolen ssh key - it is revoked everywhere, and
|
|
65
|
+
stays revoked until an unrevoke allows that machine from that address.
|
|
66
|
+
|
|
67
|
+
Says why when the answer is no, because the three ways to be refused are entirely different
|
|
68
|
+
things to a person reading it: never trusted at all, trusted but frozen, or trusted and talking
|
|
69
|
+
from somewhere it should not be.
|
|
70
|
+
|
|
71
|
+
Throws when the repo itself cannot be read or is not signed, rather than answering false: that
|
|
72
|
+
is a broken installation, not a rejected machine, and the two deserve different handling. */
|
|
73
|
+
export type MachineVerdict = {
|
|
74
|
+
accepted: boolean;
|
|
75
|
+
reason: string;
|
|
76
|
+
};
|
|
77
|
+
export declare function isMachineAccepted(config: {
|
|
78
|
+
machineId: string;
|
|
79
|
+
ip: string;
|
|
80
|
+
domain?: string;
|
|
81
|
+
}): Promise<MachineVerdict>;
|