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.
Files changed (40) hide show
  1. package/index.d.ts +4 -51
  2. package/package.json +1 -1
  3. package/security/authorizedKeys/authorizedKeys.d.ts +37 -0
  4. package/security/authorizedKeys/daemon/changes.d.ts +17 -0
  5. package/security/authorizedKeys/daemon/git.d.ts +35 -0
  6. package/security/authorizedKeys/daemon/notify.d.ts +8 -0
  7. package/security/authorizedKeys/daemon/paths.d.ts +15 -0
  8. package/security/authorizedKeys/daemon/repoFiles.d.ts +25 -0
  9. package/security/authorizedKeys/daemon/revocation.d.ts +74 -0
  10. package/security/authorizedKeys/daemon/sessions.d.ts +19 -0
  11. package/security/authorizedKeys/daemon/state.d.ts +67 -0
  12. package/security/authorizedKeys/daemon/trust.d.ts +20 -0
  13. package/security/authorizedKeys/keysRepo.d.ts +10 -0
  14. package/security/authorizedKeys/revokeSource.d.ts +13 -0
  15. package/security/authorizedKeys/sources.d.ts +17 -0
  16. package/security/helpers/paths.d.ts +4 -0
  17. package/security/helpers/spawn.d.ts +16 -0
  18. package/security/keys/deriveKey.d.ts +16 -0
  19. package/security/keys/sshKeyFile.d.ts +18 -0
  20. package/security/machines/addMachine.ts +76 -24
  21. package/security/machines/dist/addMachine.ts.cache +6 -5
  22. package/security/machines/dist/machines.ts.cache +80 -13
  23. package/security/machines/machines.d.ts +81 -0
  24. package/security/machines/machines.ts +89 -14
  25. package/security/notifications/discord.d.ts +36 -0
  26. package/security/signedFiles/manifest.d.ts +44 -0
  27. package/storage/remoteStorage/ArchivesRemote.ts +8 -10
  28. package/storage/remoteStorage/accessPage.tsx +13 -90
  29. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +11 -12
  30. package/storage/remoteStorage/dist/serverConfig.ts.cache +7 -49
  31. package/storage/remoteStorage/dist/storageController.ts.cache +33 -114
  32. package/storage/remoteStorage/serverConfig.d.ts +0 -10
  33. package/storage/remoteStorage/serverConfig.ts +6 -48
  34. package/storage/remoteStorage/storageController.d.ts +4 -36
  35. package/storage/remoteStorage/storageController.ts +40 -126
  36. package/storage/remoteStorage/storageServer.ts +1 -8
  37. package/storage/remoteStorage/storageServerCli.ts +14 -0
  38. package/storage/remoteStorage/grantAccess.js +0 -4
  39. package/storage/remoteStorage/grantAccessCli.d.ts +0 -1
  40. 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 USAGE = `Usage: yarn addmachine <domain> [ip]
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 no ip it adds this machine, with its own addresses. With an ip it asks that machine over ssh
14
- for its identity under that domain, gives it one if it has none, and adds it under that address.
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. Nothing is signed or pushed here. Run "yarn signfiles git" in that repo afterwards, or no
18
- machine will believe any of it.`;
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
- export async function main() {
21
- let argv = process.argv.slice(2);
22
- if (!argv.length || argv.length > 2) {
23
- throw new Error(`Expected a domain and optionally an ip, was ${argv.length} argument(s)\n${USAGE}`);
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
- let [domain, host = ""] = argv;
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 identity: Identity;
31
- let addresses: string[];
32
- if (!host) {
33
- let found = await localIdentity(domain);
34
- if (!found) {
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
- identity = found;
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 === identity.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: identity.machineId, ips: [...added], addedAt: "" });
110
+ machines.push({ machineId, ips: [...added], addedAt: "" });
70
111
  }
71
112
  await setMachines({ repoPath, machines });
72
113
 
73
- console.log(`\nTrusting machine ${identity.machineId}`);
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/${identity.machineId}.json: ${added.join(", ")}`);
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 ${identity.fullDomain}`);
121
+ console.log(` identity ${describe}`);
81
122
  console.log(` in ${repoPath}`);
82
- console.log(`\nNothing believes this until it is signed. In that repo, run:`);
83
- console.log(`\`\`\`\nyarn signfiles git\n\`\`\``);
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, machines_1.resolveKeysRepo)();
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.machineState)({ repoPath });
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.machineState)({ repoPath, machines });
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkTWFjaGluZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFkZE1hY2hpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhDQUE4QztBQUM5QyxvREFBb0Q7QUFDcEQseUNBQXlHO0FBQ3pHLHlDQUEyRDtBQUUzRCxNQUFNLEtBQUssR0FBRzs7Ozs7Ozs7OztnQ0FVa0IsQ0FBQztBQUUxQixLQUFLLFVBQVUsSUFBSTtJQUN0QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsK0NBQStDLElBQUksQ0FBQyxNQUFNLGlCQUFpQixLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDL0IsNkZBQTZGO0lBQzdGLHlDQUF5QztJQUN6QyxJQUFJLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxJQUFBLDBCQUFlLEdBQUUsQ0FBQztJQUUzQyxJQUFJLFFBQWtCLENBQUM7SUFDdkIsSUFBSSxTQUFtQixDQUFDO0lBQ3hCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNSLElBQUksS0FBSyxHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQ1gsNEJBQTRCLE1BQU0sT0FBTyxZQUFFLENBQUMsT0FBTyxFQUFFLDRCQUE0QjtrQkFDL0UsV0FBVyxDQUFDLE1BQU0sSUFBQSx1QkFBWSxHQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFD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QUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO0lBQzlFLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0NBQW9DLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBaEVELG9CQWdFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCB7IGdldE93bklQcyB9IGZyb20gXCIuLi8uLi9taXNjL293bklQc1wiO1xuaW1wb3J0IHsgZGVzY3JpYmVIb3N0IH0gZnJvbSBcIi4uL2hlbHBlcnMvcmVtb3RlU1NIXCI7XG5pbXBvcnQgeyBjcmVhdGVSZW1vdGVJZGVudGl0eSwgSWRlbnRpdHksIGxvY2FsRG9tYWlucywgbG9jYWxJZGVudGl0eSwgcmVtb3RlSWRlbnRpdHkgfSBmcm9tIFwiLi9pZGVudGl0eVwiO1xuaW1wb3J0IHsgbWFjaGluZVN0YXRlLCByZXNvbHZlS2V5c1JlcG8gfSBmcm9tIFwiLi9tYWNoaW5lc1wiO1xuXG5jb25zdCBVU0FHRSA9IGBVc2FnZTogeWFybiBhZGRtYWNoaW5lIDxkb21haW4+IFtpcF1cblxuVGhlIGRvbWFpbiBpcyByZXF1aXJlZDogYSBtYWNoaW5lIGhhcyBhIGRpZmZlcmVudCBpZGVudGl0eSwgYW5kIHNvIGEgZGlmZmVyZW50IG1hY2hpbmUgaWQsIHVuZGVyXG5ldmVyeSBkb21haW4gaXQgcnVucyB1bmRlciwgc28gdGhlcmUgaXMgbm8gc3VjaCB0aGluZyBhcyBcInRoaXMgbWFjaGluZVwiIHdpdGhvdXQgb25lLlxuXG5XaXRoIG5vIGlwIGl0IGFkZHMgdGhpcyBtYWNoaW5lLCB3aXRoIGl0cyBvd24gYWRkcmVzc2VzLiBXaXRoIGFuIGlwIGl0IGFza3MgdGhhdCBtYWNoaW5lIG92ZXIgc3NoXG5mb3IgaXRzIGlkZW50aXR5IHVuZGVyIHRoYXQgZG9tYWluLCBnaXZlcyBpdCBvbmUgaWYgaXQgaGFzIG5vbmUsIGFuZCBhZGRzIGl0IHVuZGVyIHRoYXQgYWRkcmVzcy5cblxuSXQgZWRpdHMgdGhlIGtleXMgcmVwbyB0aGlzIG1hY2hpbmUgcmVhZHMsIHdoZXJldmVyIHRoYXQgaXMsIG5vdCB3aGF0ZXZlciBkaXJlY3RvcnkgdGhpcyB3YXMgcnVuXG5mcm9tLiBOb3RoaW5nIGlzIHNpZ25lZCBvciBwdXNoZWQgaGVyZS4gUnVuIFwieWFybiBzaWduZmlsZXMgZ2l0XCIgaW4gdGhhdCByZXBvIGFmdGVyd2FyZHMsIG9yIG5vXG5tYWNoaW5lIHdpbGwgYmVsaWV2ZSBhbnkgb2YgaXQuYDtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gICAgbGV0IGFyZ3YgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG4gICAgaWYgKCFhcmd2Lmxlbmd0aCB8fCBhcmd2Lmxlbmd0aCA+IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhIGRvbWFpbiBhbmQgb3B0aW9uYWxseSBhbiBpcCwgd2FzICR7YXJndi5sZW5ndGh9IGFyZ3VtZW50KHMpXFxuJHtVU0FHRX1gKTtcbiAgICB9XG4gICAgbGV0IFtkb21haW4sIGhvc3QgPSBcIlwiXSA9IGFyZ3Y7XG4gICAgLy8gVGhlIHNhbWUgcmVwbyB0aGUgYWNjZXB0YW5jZSBjaGVjayByZWFkcy4gRWRpdGluZyBhbnl0aGluZyBlbHNlIHdvdWxkIHdyaXRlIGEgbWFjaGluZSBsaXN0XG4gICAgLy8gbm90aGluZyBvbiB0aGlzIG1hY2hpbmUgZXZlciBsb29rcyBhdC5cbiAgICBsZXQgeyByZXBvUGF0aCB9ID0gYXdhaXQgcmVzb2x2ZUtleXNSZXBvKCk7XG5cbiAgICBsZXQgaWRlbnRpdHk6IElkZW50aXR5O1xuICAgIGxldCBhZGRyZXNzZXM6IHN0cmluZ1tdO1xuICAgIGlmICghaG9zdCkge1xuICAgICAgICBsZXQgZm91bmQgPSBhd2FpdCBsb2NhbElkZW50aXR5KGRvbWFpbik7XG4gICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYW4gaWRlbnRpdHkgZm9yICR7ZG9tYWlufSBpbiAke29zLmhvbWVkaXIoKX0sIHRoaXMgbWFjaGluZSBoYXMgbm9uZS5cXG5gXG4gICAgICAgICAgICAgICAgKyBgSXQgaGFzOiAkeyhhd2FpdCBsb2NhbERvbWFpbnMoKSkuam9pbihcIiwgXCIpIHx8IFwibm8gaWRlbnRpdGllcyBhdCBhbGxcIn1cXG5gXG4gICAgICAgICAgICAgICAgKyBgT25lIGlzIGdlbmVyYXRlZCB0aGUgZmlyc3QgdGltZSBzb21ldGhpbmcgcnVucyBoZXJlIHVuZGVyIGEgZG9tYWluLCBzbyBydW4gdGhhdGBcbiAgICAgICAgICAgICAgICArIGAgZmlyc3QsIG9yIG5hbWUgYW5vdGhlciBtYWNoaW5lIHRvIGFkZCBpbnN0ZWFkLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWRlbnRpdHkgPSBmb3VuZDtcbiAgICAgICAgYWRkcmVzc2VzID0gYXdhaXQgZ2V0T3duSVBzKCk7XG4gICAgICAgIGlmICghYWRkcmVzc2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCB0aGlzIG1hY2hpbmUgdG8gaGF2ZSBhbiBhZGRyZXNzIGFueXRoaW5nIGVsc2UgY2FuIHNlZSwgaXQgaGFzIG5vbmVgKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vdGhpbmcgdGhlcmUgdW5kZXIgdGhpcyBkb21haW4gbWVhbnMgaXQgZ2V0cyBvbmUuIEl0cyBvd24gZnJvbSB0aGlzIHBvaW50IG9uOiB0aGUga2V5XG4gICAgICAgIC8vIGlzIHdyaXR0ZW4gdGhlcmUgYW5kIG5vdGhpbmcga2VlcHMgYSBjb3B5LlxuICAgICAgICBsZXQgZm91bmQgPSBhd2FpdCByZW1vdGVJZGVudGl0eShob3N0LCBkb21haW4pO1xuICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtkZXNjcmliZUhvc3QoaG9zdCl9IGhhcyBubyBpZGVudGl0eSBmb3IgJHtkb21haW59LCBnZW5lcmF0aW5nIG9uZWApO1xuICAgICAgICB9XG4gICAgICAgIGlkZW50aXR5ID0gZm91bmQgfHwgYXdhaXQgY3JlYXRlUmVtb3RlSWRlbnRpdHkoeyBob3N0LCBkb21haW4gfSk7XG4gICAgICAgIC8vIFRoZSBhZGRyZXNzIGl0IHdhcyBuYW1lZCBieSBpcyB0aGUgYWRkcmVzcyBpdCB0YWxrcyB0byB1cyBmcm9tLCB3aGljaCBpcyB0aGUgb25lIHRoaW5nXG4gICAgICAgIC8vIGl0IGNhbm5vdCBsaWUgYWJvdXQuXG4gICAgICAgIGFkZHJlc3NlcyA9IFtob3N0XTtcbiAgICB9XG5cbiAgICAvLyBUaGUgd2hvbGUgbGlzdCBpcyByZWFkIGFuZCB3cml0dGVuIGJhY2ssIGJlY2F1c2Ugc2V0dGluZyBpcyBieSB0aGUgc2V0OiB3cml0aW5nIHRoaXMgb25lXG4gICAgLy8gbWFjaGluZSBhbG9uZSB3b3VsZCByZW1vdmUgZXZlcnkgb3RoZXIgbWFjaGluZSBmcm9tIHRoZSByZXBvLlxuICAgIGxldCBtYWNoaW5lcyA9IGF3YWl0IG1hY2hpbmVTdGF0ZSh7IHJlcG9QYXRoIH0pO1xuICAgIGxldCBleGlzdGluZyA9IG1hY2hpbmVzLmZpbmQobWFjaGluZSA9PiBtYWNoaW5lLm1hY2hpbmVJZCA9PT0gaWRlbnRpdHkubWFjaGluZUlkKTtcbiAgICBsZXQgaXBzID0gWy4uLihleGlzdGluZz8uaXBzIHx8IFtdKV07XG4gICAgbGV0IGFkZGVkID0gYWRkcmVzc2VzLmZpbHRlcihhZGRyZXNzID0+ICFpcHMuaW5jbHVkZXMoYWRkcmVzcykpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgICBleGlzdGluZy5pcHMgPSBbLi4uaXBzLCAuLi5hZGRlZF07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbWFjaGluZXMucHVzaCh7IG1hY2hpbmVJZDogaWRlbnRpdHkubWFjaGluZUlkLCBpcHM6IFsuLi5hZGRlZF0sIGFkZGVkQXQ6IFwiXCIgfSk7XG4gICAgfVxuICAgIGF3YWl0IG1hY2hpbmVTdGF0ZSh7IHJlcG9QYXRoLCBtYWNoaW5lcyB9KTtcblxuICAgIGNvbnNvbGUubG9nKGBcXG5UcnVzdGluZyBtYWNoaW5lICR7aWRlbnRpdHkubWFjaGluZUlkfWApO1xuICAgIGNvbnNvbGUubG9nKGBBbGxvd2luZyBJUCAke1suLi5pcHMsIC4uLmFkZGVkXS5qb2luKFwiLCBcIil9YCk7XG4gICAgaWYgKGFkZGVkLmxlbmd0aCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgICBhZGRlZCB0byBtYWNoaW5lcy8ke2lkZW50aXR5Lm1hY2hpbmVJZH0uanNvbjogJHthZGRlZC5qb2luKFwiLCBcIil9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgYWxyZWFkeSBhbGxvd2VkIGZyb20gJHthZGRyZXNzZXMuam9pbihcIiwgXCIpfWApO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgICBpZGVudGl0eSAke2lkZW50aXR5LmZ1bGxEb21haW59YCk7XG4gICAgY29uc29sZS5sb2coYCAgaW4gJHtyZXBvUGF0aH1gKTtcbiAgICBjb25zb2xlLmxvZyhgXFxuTm90aGluZyBiZWxpZXZlcyB0aGlzIHVudGlsIGl0IGlzIHNpZ25lZC4gSW4gdGhhdCByZXBvLCBydW46YCk7XG4gICAgY29uc29sZS5sb2coYFxcYFxcYFxcYFxcbnlhcm4gc2lnbmZpbGVzIGdpdFxcblxcYFxcYFxcYGApO1xufVxuIl19
88
- /* _JS_SOURCE_HASH = "8b6a7e13912660fd6733b2585e4fec0865a5548fe5846ee6e23f46c506f83e34"; */
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
- /** Every machine a checkout lists. */
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 { repoPath, machines } = config;
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 { repoPath, sourceURL } = await (0, keysRepo_1.resolveKeysRepo)();
218
- // Unsigned, or signed over different contents, means the machine list is not evidence of
219
- // anything. Same gate the ssh keys go through.
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: "that machine is not trusted" };
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 = "4f49b3c9f4a58987204c92820f6aca5ff7cf73325e697e849445299f06638103"; */
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>;