@phigon/observer 8.1.0 → 8.3.0

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 (309) hide show
  1. package/README.md +244 -18
  2. package/dist/bin/guardian-runner-darwin-amd64 +0 -0
  3. package/dist/bin/guardian-runner-darwin-arm64 +0 -0
  4. package/dist/bin/guardian-runner-linux-amd64 +0 -0
  5. package/dist/bin/guardian-runner-linux-arm64 +0 -0
  6. package/dist/bin/guardian-runner-windows-amd64.exe +0 -0
  7. package/dist/bin/guardian-runner-windows-arm64.exe +0 -0
  8. package/dist/src/abortable-delay.d.ts +10 -0
  9. package/dist/src/abortable-delay.d.ts.map +1 -0
  10. package/dist/src/abortable-delay.js +21 -0
  11. package/dist/src/abortable-delay.js.map +1 -0
  12. package/dist/src/action-policy.d.ts.map +1 -1
  13. package/dist/src/action-policy.js +4 -2
  14. package/dist/src/action-policy.js.map +1 -1
  15. package/dist/src/activity/adapters/claude.d.ts.map +1 -1
  16. package/dist/src/activity/adapters/claude.js +28 -2
  17. package/dist/src/activity/adapters/claude.js.map +1 -1
  18. package/dist/src/activity/adapters/cline-task.d.ts +7 -0
  19. package/dist/src/activity/adapters/cline-task.d.ts.map +1 -0
  20. package/dist/src/activity/adapters/cline-task.js +197 -0
  21. package/dist/src/activity/adapters/cline-task.js.map +1 -0
  22. package/dist/src/activity/adapters/cline.d.ts +3 -0
  23. package/dist/src/activity/adapters/cline.d.ts.map +1 -0
  24. package/dist/src/activity/adapters/cline.js +102 -0
  25. package/dist/src/activity/adapters/cline.js.map +1 -0
  26. package/dist/src/activity/adapters/codex.d.ts.map +1 -1
  27. package/dist/src/activity/adapters/codex.js +76 -0
  28. package/dist/src/activity/adapters/codex.js.map +1 -1
  29. package/dist/src/activity/adapters/copilot-chat.d.ts +3 -0
  30. package/dist/src/activity/adapters/copilot-chat.d.ts.map +1 -0
  31. package/dist/src/activity/adapters/copilot-chat.js +176 -0
  32. package/dist/src/activity/adapters/copilot-chat.js.map +1 -0
  33. package/dist/src/activity/adapters/copilot.d.ts +2 -1
  34. package/dist/src/activity/adapters/copilot.d.ts.map +1 -1
  35. package/dist/src/activity/adapters/copilot.js +173 -2
  36. package/dist/src/activity/adapters/copilot.js.map +1 -1
  37. package/dist/src/activity/adapters/cursor.d.ts +3 -0
  38. package/dist/src/activity/adapters/cursor.d.ts.map +1 -0
  39. package/dist/src/activity/adapters/cursor.js +86 -0
  40. package/dist/src/activity/adapters/cursor.js.map +1 -0
  41. package/dist/src/activity/adapters/factory-droid.d.ts +3 -0
  42. package/dist/src/activity/adapters/factory-droid.d.ts.map +1 -0
  43. package/dist/src/activity/adapters/factory-droid.js +126 -0
  44. package/dist/src/activity/adapters/factory-droid.js.map +1 -0
  45. package/dist/src/activity/adapters/gemini.d.ts +3 -0
  46. package/dist/src/activity/adapters/gemini.d.ts.map +1 -0
  47. package/dist/src/activity/adapters/gemini.js +177 -0
  48. package/dist/src/activity/adapters/gemini.js.map +1 -0
  49. package/dist/src/activity/adapters/goose.d.ts +3 -0
  50. package/dist/src/activity/adapters/goose.d.ts.map +1 -0
  51. package/dist/src/activity/adapters/goose.js +116 -0
  52. package/dist/src/activity/adapters/goose.js.map +1 -0
  53. package/dist/src/activity/adapters/kiro.d.ts +3 -0
  54. package/dist/src/activity/adapters/kiro.d.ts.map +1 -0
  55. package/dist/src/activity/adapters/kiro.js +47 -0
  56. package/dist/src/activity/adapters/kiro.js.map +1 -0
  57. package/dist/src/activity/adapters/openai-compatible.d.ts.map +1 -1
  58. package/dist/src/activity/adapters/openai-compatible.js +9 -1
  59. package/dist/src/activity/adapters/openai-compatible.js.map +1 -1
  60. package/dist/src/activity/adapters/opencode.d.ts.map +1 -1
  61. package/dist/src/activity/adapters/opencode.js +108 -1
  62. package/dist/src/activity/adapters/opencode.js.map +1 -1
  63. package/dist/src/activity/adapters/zed.d.ts +3 -0
  64. package/dist/src/activity/adapters/zed.d.ts.map +1 -0
  65. package/dist/src/activity/adapters/zed.js +134 -0
  66. package/dist/src/activity/adapters/zed.js.map +1 -0
  67. package/dist/src/activity/collector.d.ts +43 -1
  68. package/dist/src/activity/collector.d.ts.map +1 -1
  69. package/dist/src/activity/collector.js +490 -77
  70. package/dist/src/activity/collector.js.map +1 -1
  71. package/dist/src/activity/goose-sqlite-source.d.ts +33 -0
  72. package/dist/src/activity/goose-sqlite-source.d.ts.map +1 -0
  73. package/dist/src/activity/goose-sqlite-source.js +274 -0
  74. package/dist/src/activity/goose-sqlite-source.js.map +1 -0
  75. package/dist/src/activity/index.d.ts +3 -0
  76. package/dist/src/activity/index.d.ts.map +1 -1
  77. package/dist/src/activity/index.js +3 -0
  78. package/dist/src/activity/index.js.map +1 -1
  79. package/dist/src/activity/ingest.d.ts +9 -0
  80. package/dist/src/activity/ingest.d.ts.map +1 -1
  81. package/dist/src/activity/ingest.js +94 -4
  82. package/dist/src/activity/ingest.js.map +1 -1
  83. package/dist/src/activity/json-document-source.d.ts +151 -0
  84. package/dist/src/activity/json-document-source.d.ts.map +1 -0
  85. package/dist/src/activity/json-document-source.js +586 -0
  86. package/dist/src/activity/json-document-source.js.map +1 -0
  87. package/dist/src/activity/native-capabilities.d.ts.map +1 -1
  88. package/dist/src/activity/native-capabilities.js +8 -12
  89. package/dist/src/activity/native-capabilities.js.map +1 -1
  90. package/dist/src/activity/normalize.d.ts.map +1 -1
  91. package/dist/src/activity/normalize.js +64 -6
  92. package/dist/src/activity/normalize.js.map +1 -1
  93. package/dist/src/activity/opencode-message-tables.d.ts +87 -0
  94. package/dist/src/activity/opencode-message-tables.d.ts.map +1 -0
  95. package/dist/src/activity/opencode-message-tables.js +546 -0
  96. package/dist/src/activity/opencode-message-tables.js.map +1 -0
  97. package/dist/src/activity/opencode-sqlite-source.d.ts +7 -0
  98. package/dist/src/activity/opencode-sqlite-source.d.ts.map +1 -1
  99. package/dist/src/activity/opencode-sqlite-source.js +154 -63
  100. package/dist/src/activity/opencode-sqlite-source.js.map +1 -1
  101. package/dist/src/activity/source-reader.d.ts +60 -4
  102. package/dist/src/activity/source-reader.d.ts.map +1 -1
  103. package/dist/src/activity/source-reader.js +593 -75
  104. package/dist/src/activity/source-reader.js.map +1 -1
  105. package/dist/src/activity/sqlite-connections.d.ts +77 -0
  106. package/dist/src/activity/sqlite-connections.d.ts.map +1 -0
  107. package/dist/src/activity/sqlite-connections.js +220 -0
  108. package/dist/src/activity/sqlite-connections.js.map +1 -0
  109. package/dist/src/activity/zed-sqlite-source.d.ts +65 -0
  110. package/dist/src/activity/zed-sqlite-source.d.ts.map +1 -0
  111. package/dist/src/activity/zed-sqlite-source.js +547 -0
  112. package/dist/src/activity/zed-sqlite-source.js.map +1 -0
  113. package/dist/src/agent-action-executor.d.ts +18 -1
  114. package/dist/src/agent-action-executor.d.ts.map +1 -1
  115. package/dist/src/agent-action-executor.js +113 -58
  116. package/dist/src/agent-action-executor.js.map +1 -1
  117. package/dist/src/agentic-guardian.d.ts.map +1 -1
  118. package/dist/src/agentic-guardian.js +6 -5
  119. package/dist/src/agentic-guardian.js.map +1 -1
  120. package/dist/src/atomic-replace.d.ts +7 -0
  121. package/dist/src/atomic-replace.d.ts.map +1 -1
  122. package/dist/src/atomic-replace.js +28 -3
  123. package/dist/src/atomic-replace.js.map +1 -1
  124. package/dist/src/bridge-journal.d.ts +32 -0
  125. package/dist/src/bridge-journal.d.ts.map +1 -0
  126. package/dist/src/bridge-journal.js +113 -0
  127. package/dist/src/bridge-journal.js.map +1 -0
  128. package/dist/src/cli.d.ts +7 -1
  129. package/dist/src/cli.d.ts.map +1 -1
  130. package/dist/src/cli.js +534 -50
  131. package/dist/src/cli.js.map +1 -1
  132. package/dist/src/collection-notice.d.ts +34 -0
  133. package/dist/src/collection-notice.d.ts.map +1 -0
  134. package/dist/src/collection-notice.js +73 -0
  135. package/dist/src/collection-notice.js.map +1 -0
  136. package/dist/src/config.d.ts +39 -0
  137. package/dist/src/config.d.ts.map +1 -1
  138. package/dist/src/config.js +187 -36
  139. package/dist/src/config.js.map +1 -1
  140. package/dist/src/connection-config.d.ts.map +1 -1
  141. package/dist/src/connection-config.js +5 -0
  142. package/dist/src/connection-config.js.map +1 -1
  143. package/dist/src/content-redaction.d.ts +17 -1
  144. package/dist/src/content-redaction.d.ts.map +1 -1
  145. package/dist/src/content-redaction.js +51 -3
  146. package/dist/src/content-redaction.js.map +1 -1
  147. package/dist/src/credential-store.d.ts +20 -1
  148. package/dist/src/credential-store.d.ts.map +1 -1
  149. package/dist/src/credential-store.js +29 -4
  150. package/dist/src/credential-store.js.map +1 -1
  151. package/dist/src/custom-agent-registry.d.ts.map +1 -1
  152. package/dist/src/custom-agent-registry.js +2 -1
  153. package/dist/src/custom-agent-registry.js.map +1 -1
  154. package/dist/src/discovery/adapters/generic.d.ts.map +1 -1
  155. package/dist/src/discovery/adapters/generic.js +160 -2
  156. package/dist/src/discovery/adapters/generic.js.map +1 -1
  157. package/dist/src/discovery/engine.d.ts +7 -1
  158. package/dist/src/discovery/engine.d.ts.map +1 -1
  159. package/dist/src/discovery/engine.js +21 -16
  160. package/dist/src/discovery/engine.js.map +1 -1
  161. package/dist/src/discovery/known-agent.d.ts +7 -0
  162. package/dist/src/discovery/known-agent.d.ts.map +1 -1
  163. package/dist/src/discovery/known-agent.js +9 -4
  164. package/dist/src/discovery/known-agent.js.map +1 -1
  165. package/dist/src/discovery/system-evidence.d.ts +40 -1
  166. package/dist/src/discovery/system-evidence.d.ts.map +1 -1
  167. package/dist/src/discovery/system-evidence.js +189 -16
  168. package/dist/src/discovery/system-evidence.js.map +1 -1
  169. package/dist/src/doctor-check.d.ts +51 -0
  170. package/dist/src/doctor-check.d.ts.map +1 -0
  171. package/dist/src/doctor-check.js +174 -0
  172. package/dist/src/doctor-check.js.map +1 -0
  173. package/dist/src/enroll.d.ts +86 -0
  174. package/dist/src/enroll.d.ts.map +1 -0
  175. package/dist/src/enroll.js +245 -0
  176. package/dist/src/enroll.js.map +1 -0
  177. package/dist/src/entry.d.ts +3 -0
  178. package/dist/src/entry.d.ts.map +1 -0
  179. package/dist/src/entry.js +14 -0
  180. package/dist/src/entry.js.map +1 -0
  181. package/dist/src/event-queue.d.ts +13 -1
  182. package/dist/src/event-queue.d.ts.map +1 -1
  183. package/dist/src/event-queue.js +137 -42
  184. package/dist/src/event-queue.js.map +1 -1
  185. package/dist/src/event-spool.d.ts +61 -3
  186. package/dist/src/event-spool.d.ts.map +1 -1
  187. package/dist/src/event-spool.js +341 -44
  188. package/dist/src/event-spool.js.map +1 -1
  189. package/dist/src/generated/phigon/v1/identity_pb.d.ts +7 -0
  190. package/dist/src/generated/phigon/v1/identity_pb.d.ts.map +1 -1
  191. package/dist/src/generated/phigon/v1/identity_pb.js +1 -1
  192. package/dist/src/generated/phigon/v1/identity_pb.js.map +1 -1
  193. package/dist/src/guardian-containment.d.ts +2 -6
  194. package/dist/src/guardian-containment.d.ts.map +1 -1
  195. package/dist/src/guardian-containment.js +12 -63
  196. package/dist/src/guardian-containment.js.map +1 -1
  197. package/dist/src/guardian-decision-journal.d.ts.map +1 -1
  198. package/dist/src/guardian-decision-journal.js +4 -19
  199. package/dist/src/guardian-decision-journal.js.map +1 -1
  200. package/dist/src/guardian-managed-exec.d.ts.map +1 -1
  201. package/dist/src/guardian-managed-exec.js +6 -18
  202. package/dist/src/guardian-managed-exec.js.map +1 -1
  203. package/dist/src/guardian-model-bridge.d.ts.map +1 -1
  204. package/dist/src/guardian-model-bridge.js +2 -1
  205. package/dist/src/guardian-model-bridge.js.map +1 -1
  206. package/dist/src/guardian-native.d.ts +0 -1
  207. package/dist/src/guardian-native.d.ts.map +1 -1
  208. package/dist/src/guardian-native.js +0 -6
  209. package/dist/src/guardian-native.js.map +1 -1
  210. package/dist/src/guardian-process-monitor.d.ts +4 -0
  211. package/dist/src/guardian-process-monitor.d.ts.map +1 -1
  212. package/dist/src/guardian-process-monitor.js +82 -26
  213. package/dist/src/guardian-process-monitor.js.map +1 -1
  214. package/dist/src/health.d.ts +19 -1
  215. package/dist/src/health.d.ts.map +1 -1
  216. package/dist/src/health.js +22 -1
  217. package/dist/src/health.js.map +1 -1
  218. package/dist/src/historical-identity-store.d.ts +8 -1
  219. package/dist/src/historical-identity-store.d.ts.map +1 -1
  220. package/dist/src/historical-identity-store.js +28 -10
  221. package/dist/src/historical-identity-store.js.map +1 -1
  222. package/dist/src/index.d.ts +2 -0
  223. package/dist/src/index.d.ts.map +1 -1
  224. package/dist/src/index.js +2 -0
  225. package/dist/src/index.js.map +1 -1
  226. package/dist/src/installation.d.ts +2 -0
  227. package/dist/src/installation.d.ts.map +1 -1
  228. package/dist/src/installation.js +6 -3
  229. package/dist/src/installation.js.map +1 -1
  230. package/dist/src/instance-lock.d.ts +45 -0
  231. package/dist/src/instance-lock.d.ts.map +1 -0
  232. package/dist/src/instance-lock.js +243 -0
  233. package/dist/src/instance-lock.js.map +1 -0
  234. package/dist/src/machine-command-executor.d.ts +22 -7
  235. package/dist/src/machine-command-executor.d.ts.map +1 -1
  236. package/dist/src/machine-command-executor.js +80 -19
  237. package/dist/src/machine-command-executor.js.map +1 -1
  238. package/dist/src/node-version.d.ts +8 -0
  239. package/dist/src/node-version.d.ts.map +1 -0
  240. package/dist/src/node-version.js +17 -0
  241. package/dist/src/node-version.js.map +1 -0
  242. package/dist/src/observer-log.d.ts +50 -0
  243. package/dist/src/observer-log.d.ts.map +1 -0
  244. package/dist/src/observer-log.js +141 -0
  245. package/dist/src/observer-log.js.map +1 -0
  246. package/dist/src/pair.d.ts +68 -1
  247. package/dist/src/pair.d.ts.map +1 -1
  248. package/dist/src/pair.js +204 -65
  249. package/dist/src/pair.js.map +1 -1
  250. package/dist/src/private-directory.d.ts +10 -0
  251. package/dist/src/private-directory.d.ts.map +1 -0
  252. package/dist/src/private-directory.js +66 -0
  253. package/dist/src/private-directory.js.map +1 -0
  254. package/dist/src/process-tree.d.ts +73 -0
  255. package/dist/src/process-tree.d.ts.map +1 -0
  256. package/dist/src/process-tree.js +256 -0
  257. package/dist/src/process-tree.js.map +1 -0
  258. package/dist/src/proxy.d.ts +68 -0
  259. package/dist/src/proxy.d.ts.map +1 -0
  260. package/dist/src/proxy.js +209 -0
  261. package/dist/src/proxy.js.map +1 -0
  262. package/dist/src/purge.d.ts +17 -0
  263. package/dist/src/purge.d.ts.map +1 -0
  264. package/dist/src/purge.js +84 -0
  265. package/dist/src/purge.js.map +1 -0
  266. package/dist/src/remove-machine.d.ts +5 -1
  267. package/dist/src/remove-machine.d.ts.map +1 -1
  268. package/dist/src/remove-machine.js +28 -14
  269. package/dist/src/remove-machine.js.map +1 -1
  270. package/dist/src/server-authority.d.ts +29 -0
  271. package/dist/src/server-authority.d.ts.map +1 -0
  272. package/dist/src/server-authority.js +106 -0
  273. package/dist/src/server-authority.js.map +1 -0
  274. package/dist/src/server-clock.d.ts +32 -0
  275. package/dist/src/server-clock.d.ts.map +1 -0
  276. package/dist/src/server-clock.js +72 -0
  277. package/dist/src/server-clock.js.map +1 -0
  278. package/dist/src/service-command.d.ts +20 -0
  279. package/dist/src/service-command.d.ts.map +1 -0
  280. package/dist/src/service-command.js +136 -0
  281. package/dist/src/service-command.js.map +1 -0
  282. package/dist/src/service.d.ts +98 -0
  283. package/dist/src/service.d.ts.map +1 -0
  284. package/dist/src/service.js +472 -0
  285. package/dist/src/service.js.map +1 -0
  286. package/dist/src/stream-client.d.ts +21 -1
  287. package/dist/src/stream-client.d.ts.map +1 -1
  288. package/dist/src/stream-client.js +137 -24
  289. package/dist/src/stream-client.js.map +1 -1
  290. package/dist/src/stream-state.d.ts +2 -0
  291. package/dist/src/stream-state.d.ts.map +1 -1
  292. package/dist/src/stream-state.js +5 -2
  293. package/dist/src/stream-state.js.map +1 -1
  294. package/dist/src/system-inspection.d.ts +78 -0
  295. package/dist/src/system-inspection.d.ts.map +1 -0
  296. package/dist/src/system-inspection.js +281 -0
  297. package/dist/src/system-inspection.js.map +1 -0
  298. package/dist/src/update.d.ts.map +1 -1
  299. package/dist/src/update.js +9 -3
  300. package/dist/src/update.js.map +1 -1
  301. package/dist/src/user-notices.d.ts +64 -0
  302. package/dist/src/user-notices.d.ts.map +1 -0
  303. package/dist/src/user-notices.js +141 -0
  304. package/dist/src/user-notices.js.map +1 -0
  305. package/package.json +7 -7
  306. package/dist/src/windows-process.d.ts +0 -7
  307. package/dist/src/windows-process.d.ts.map +0 -1
  308. package/dist/src/windows-process.js +0 -18
  309. package/dist/src/windows-process.js.map +0 -1
@@ -0,0 +1,209 @@
1
+ import * as http from "node:http";
2
+ import * as https from "node:https";
3
+ /** The variable names, lowercase first: Node.js lets lowercase win. */
4
+ const variables = {
5
+ https: ["https_proxy", "HTTPS_PROXY"],
6
+ http: ["http_proxy", "HTTP_PROXY"],
7
+ noProxy: ["no_proxy", "NO_PROXY"],
8
+ };
9
+ function variable(environment, names) {
10
+ for (const name of names) {
11
+ const value = environment[name]?.trim();
12
+ if (value)
13
+ return value;
14
+ }
15
+ if (process.platform === "win32") {
16
+ // Windows names are case-insensitive, but a copied environment is not.
17
+ const wanted = names[0].toLowerCase();
18
+ const found = Object.entries(environment).find(([key]) => key.toLowerCase() === wanted)?.[1]?.trim();
19
+ if (found)
20
+ return found;
21
+ }
22
+ return undefined;
23
+ }
24
+ function proxyURL(value, name) {
25
+ if (value === undefined)
26
+ return undefined;
27
+ let url;
28
+ try {
29
+ // A bare host:port is read the way Node.js and curl read it.
30
+ url = new URL(/^[a-z][a-z0-9+.-]*:\/\//iu.test(value) ? value : `http://${value}`);
31
+ }
32
+ catch {
33
+ // Never echo the value: it can hold the proxy's password.
34
+ throw new Error(`${name} is not a valid proxy address. Use a form such as http://proxy.example.com:8080.`);
35
+ }
36
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
37
+ throw new Error(`${name} must be an http:// or https:// proxy address.`);
38
+ }
39
+ return url;
40
+ }
41
+ /** Reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY (either case) from `environment`. */
42
+ export function proxySettings(environment) {
43
+ const httpsProxy = proxyURL(variable(environment, variables.https), "HTTPS_PROXY");
44
+ const httpProxy = proxyURL(variable(environment, variables.http), "HTTP_PROXY");
45
+ return Object.freeze({
46
+ ...(httpsProxy === undefined ? {} : { https: httpsProxy }),
47
+ ...(httpProxy === undefined ? {} : { http: httpProxy }),
48
+ noProxy: variable(environment, variables.noProxy) ?? "",
49
+ });
50
+ }
51
+ function noProxyEntries(value) {
52
+ return value.split(/[,\s]+/u).filter(Boolean).map((entry) => {
53
+ // An IPv6 address carries a port only in brackets: [::1]:8443.
54
+ const withPort = /^(\[[^\]]+\]|[^:]+):(\d+)$/u.exec(entry);
55
+ const host = (withPort?.[1] ?? entry).toLowerCase().replace(/^\[|\]$/gu, "");
56
+ return { host, port: withPort === null ? 0 : Number(withPort[2]) };
57
+ });
58
+ }
59
+ /**
60
+ * The proxy `target` goes through, or undefined to connect directly. It
61
+ * follows Node.js: an entry matches its host and every host under it
62
+ * (`example.com`, `.example.com` and `*.example.com` all cover
63
+ * `a.example.com`), `*` matches everything, and `host:port` only that port.
64
+ */
65
+ export function proxyForUrl(target, settings) {
66
+ const proxy = target.protocol === "https:" ? settings.https ?? settings.http : settings.http;
67
+ if (proxy === undefined)
68
+ return undefined;
69
+ const host = target.hostname.toLowerCase().replace(/^\[|\]$/gu, "");
70
+ const port = Number(target.port || (target.protocol === "https:" ? 443 : 80));
71
+ for (const entry of noProxyEntries(settings.noProxy)) {
72
+ if (entry.host === "*")
73
+ return undefined;
74
+ if (entry.port !== 0 && entry.port !== port)
75
+ continue;
76
+ const suffix = entry.host.replace(/^\*?\./u, "");
77
+ if (host === suffix || host.endsWith(`.${suffix}`))
78
+ return undefined;
79
+ }
80
+ return proxy;
81
+ }
82
+ /**
83
+ * NO_PROXY in the form @grpc/grpc-js reads, which matches plain host name
84
+ * endings only: `*.example.com` and `.example.com` become `example.com`, and
85
+ * an entry for another port is left out because the stream cannot check
86
+ * ports.
87
+ */
88
+ export function grpcNoProxy(noProxy, streamPort) {
89
+ return noProxyEntries(noProxy)
90
+ .filter((entry) => entry.host !== "*" && (entry.port === 0 || entry.port === streamPort))
91
+ .map((entry) => entry.host.replace(/^\*?\./u, ""))
92
+ .join(",");
93
+ }
94
+ /** Whether NO_PROXY turns the proxy off for every host, which grpc-js cannot express. */
95
+ export function noProxyForAll(environment) {
96
+ const value = environment["no_grpc_proxy"] ?? variable(environment, variables.noProxy) ?? "";
97
+ return noProxyEntries(value).some((entry) => entry.host === "*");
98
+ }
99
+ /**
100
+ * Sends `fetch` (and `http`/`https` requests) through the proxy that
101
+ * `environment` names, and gives the telemetry stream the same proxy and
102
+ * NO_PROXY list. Does nothing when no proxy is set.
103
+ */
104
+ export function useProxyFromEnvironment(environment, options = {}) {
105
+ const settings = proxySettings(environment);
106
+ const proxy = settings.https ?? settings.http;
107
+ if (proxy === undefined)
108
+ return Object.freeze({ restore: () => undefined });
109
+ const notices = [];
110
+ const setGlobal = "setGlobalProxyFromEnv" in options
111
+ ? options.setGlobalProxyFromEnv
112
+ : http.setGlobalProxyFromEnv;
113
+ let restoreFetch = () => undefined;
114
+ if (typeof setGlobal === "function") {
115
+ restoreFetch = setGlobal({
116
+ ...(settings.https === undefined ? {} : { HTTPS_PROXY: settings.https.href }),
117
+ ...(settings.http === undefined ? {} : { HTTP_PROXY: settings.http.href }),
118
+ ...(settings.noProxy === "" ? {} : { NO_PROXY: settings.noProxy }),
119
+ });
120
+ }
121
+ else if (!(options.startedWithEnvProxy ?? startedWithEnvProxy())) {
122
+ notices.push(`This computer sets a proxy, but Node.js ${options.nodeVersion ?? process.versions.node} uses it ` +
123
+ "only when NODE_USE_ENV_PROXY=1 is set before the observer starts. Set it, or update Node.js to 24.14 or newer.");
124
+ }
125
+ // @grpc/grpc-js reads grpc_proxy, then https_proxy and http_proxy, in
126
+ // lowercase only, and supports only http:// proxies.
127
+ const target = options.processEnvironment ?? process.env;
128
+ const saved = new Map();
129
+ const assign = (name, value) => {
130
+ if (target[name] !== undefined && target[name] !== "")
131
+ return;
132
+ saved.set(name, target[name]);
133
+ target[name] = value;
134
+ };
135
+ const streamProxy = settings.https ?? settings.http;
136
+ if (streamProxy !== undefined && streamProxy.protocol === "http:") {
137
+ assign("grpc_proxy", streamProxy.href);
138
+ }
139
+ else if (streamProxy !== undefined && target["grpc_proxy"] === undefined) {
140
+ notices.push("The telemetry stream can use only an http:// proxy address, so it connects directly. " +
141
+ "Set grpc_proxy to an http:// proxy if direct connections are blocked.");
142
+ }
143
+ if (settings.noProxy !== "") {
144
+ const port = Number(options.streamUrl?.port || 443);
145
+ const list = grpcNoProxy(settings.noProxy, port);
146
+ if (list !== "")
147
+ assign("no_grpc_proxy", list);
148
+ }
149
+ return Object.freeze({
150
+ restore: () => {
151
+ restoreFetch();
152
+ for (const [name, value] of saved) {
153
+ if (value === undefined)
154
+ delete target[name];
155
+ else
156
+ target[name] = value;
157
+ }
158
+ saved.clear();
159
+ },
160
+ ...(notices.length === 0 ? {} : { notice: notices.join(" ") }),
161
+ });
162
+ }
163
+ function startedWithEnvProxy() {
164
+ return process.env["NODE_USE_ENV_PROXY"] === "1" ||
165
+ process.execArgv.includes("--use-env-proxy");
166
+ }
167
+ /**
168
+ * Opens a CONNECT tunnel through `proxy` to `host:port`, for a raw TLS
169
+ * connection that `fetch` does not cover. Messages name the proxy by host
170
+ * only, never with its credentials.
171
+ */
172
+ export async function connectThroughProxy(proxy, host, port, timeoutMs = 15_000) {
173
+ const authority = host.includes(":") ? `[${host}]:${port}` : `${host}:${port}`;
174
+ const credentials = proxy.username === ""
175
+ ? undefined
176
+ : Buffer.from(`${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`).toString("base64");
177
+ const request = (proxy.protocol === "https:" ? https : http).request({
178
+ host: proxy.hostname.replace(/^\[|\]$/gu, ""),
179
+ port: Number(proxy.port || (proxy.protocol === "https:" ? 443 : 80)),
180
+ method: "CONNECT",
181
+ path: authority,
182
+ agent: false,
183
+ headers: {
184
+ host: authority,
185
+ ...(credentials === undefined ? {} : { "proxy-authorization": `Basic ${credentials}` }),
186
+ },
187
+ });
188
+ return await new Promise((resolve, reject) => {
189
+ const timer = setTimeout(() => {
190
+ request.destroy();
191
+ reject(new Error(`The proxy ${proxy.host} did not answer in time.`));
192
+ }, timeoutMs);
193
+ request.once("connect", (response, socket) => {
194
+ clearTimeout(timer);
195
+ if (response.statusCode === 200) {
196
+ resolve(socket);
197
+ return;
198
+ }
199
+ socket.destroy();
200
+ reject(new Error(`The proxy ${proxy.host} refused to connect to ${authority} (HTTP ${response.statusCode}).`));
201
+ });
202
+ request.once("error", (error) => {
203
+ clearTimeout(timer);
204
+ reject(new Error(`Could not reach the proxy ${proxy.host}: ${error.message}`));
205
+ });
206
+ request.end();
207
+ });
208
+ }
209
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type PurgeResult = Readonly<{
2
+ /** Files and folders removed. */
3
+ removed: number;
4
+ /** Names left because the observer did not create them. */
5
+ leftBehind: readonly string[];
6
+ /** Whether the data directory itself was removed, being empty. */
7
+ directoryRemoved: boolean;
8
+ }>;
9
+ /**
10
+ * Removes every file the observer keeps in `dataDirectory`, then the
11
+ * directory when nothing else is in it. `keep` names files to leave for
12
+ * the caller to remove last, such as the lock it still holds.
13
+ */
14
+ export declare function purgeDataDirectory(dataDirectory: string, keep?: readonly string[]): Promise<PurgeResult>;
15
+ /** Removes the data directory when it is empty. */
16
+ export declare function removeEmptyDataDirectory(dataDirectory: string): Promise<boolean>;
17
+ //# sourceMappingURL=purge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purge.d.ts","sourceRoot":"","sources":["../../src/purge.ts"],"names":[],"mappings":"AA6CA,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,kEAAkE;IAClE,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE,SAAS,MAAM,EAAO,GAC3B,OAAO,CAAC,WAAW,CAAC,CAsBtB;AAED,mDAAmD;AACnD,wBAAsB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOtF"}
@@ -0,0 +1,84 @@
1
+ import { readdir, rm, rmdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Everything the observer itself writes in its data directory. A purge
5
+ * removes only these, so a data directory set to a folder that also holds
6
+ * other files (a home folder, say) loses nothing else.
7
+ */
8
+ const observerFiles = new Set([
9
+ "action-policy.json",
10
+ "activity-cursors.json",
11
+ "agent-action-receipts.json",
12
+ "collection-notice.json",
13
+ "custom-agents.json",
14
+ "historical-agent-identities.json",
15
+ "installation-id",
16
+ "machine-credential.json",
17
+ "observer.lock",
18
+ "server-ca.pem",
19
+ "service-settings.json",
20
+ "stream-state.json",
21
+ "telemetry-spool.jsonl",
22
+ "update-check.json",
23
+ ]);
24
+ const observerDirectories = new Set([
25
+ "bridges",
26
+ "damaged-spools",
27
+ "history-sync",
28
+ "logs",
29
+ "machine-operation-receipts",
30
+ "process-operation-claims",
31
+ "retired-pairings",
32
+ ]);
33
+ /** Temporary, corrupt and per-run files named after the ones above. */
34
+ function observerFile(name) {
35
+ if (observerFiles.has(name))
36
+ return true;
37
+ for (const file of observerFiles) {
38
+ if (name.startsWith(`${file}.`) && /\.(tmp|corrupt)$/u.test(name))
39
+ return true;
40
+ }
41
+ return /^guardian-lease-[0-9a-f-]{36}\.json$/u.test(name) ||
42
+ /^service-task-[0-9a-f-]{36}\.xml$/u.test(name);
43
+ }
44
+ /**
45
+ * Removes every file the observer keeps in `dataDirectory`, then the
46
+ * directory when nothing else is in it. `keep` names files to leave for
47
+ * the caller to remove last, such as the lock it still holds.
48
+ */
49
+ export async function purgeDataDirectory(dataDirectory, keep = []) {
50
+ let entries;
51
+ try {
52
+ entries = await readdir(dataDirectory);
53
+ }
54
+ catch (error) {
55
+ if (error.code === "ENOENT") {
56
+ return Object.freeze({ removed: 0, leftBehind: Object.freeze([]), directoryRemoved: true });
57
+ }
58
+ throw error;
59
+ }
60
+ let removed = 0;
61
+ const leftBehind = [];
62
+ for (const name of entries) {
63
+ if (keep.includes(name))
64
+ continue;
65
+ if (!observerFile(name) && !observerDirectories.has(name)) {
66
+ leftBehind.push(name);
67
+ continue;
68
+ }
69
+ await rm(join(dataDirectory, name), { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
70
+ removed++;
71
+ }
72
+ return Object.freeze({ removed, leftBehind: Object.freeze(leftBehind.sort()), directoryRemoved: false });
73
+ }
74
+ /** Removes the data directory when it is empty. */
75
+ export async function removeEmptyDataDirectory(dataDirectory) {
76
+ try {
77
+ await rmdir(dataDirectory);
78
+ return true;
79
+ }
80
+ catch (error) {
81
+ return error.code === "ENOENT";
82
+ }
83
+ }
84
+ //# sourceMappingURL=purge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purge.js","sourceRoot":"","sources":["../../src/purge.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,11 @@
1
1
  import type { ObserverConfig } from "./config.js";
2
2
  import type { StoredMachineCredential } from "./credential-store.js";
3
3
  export type RemoveMachineResult = Readonly<{
4
- status: "removed";
4
+ /**
5
+ * `already_removed`: an administrator had already removed this computer
6
+ * or revoked its key, so only the local cleanup was left to do.
7
+ */
8
+ status: "removed" | "already_removed";
5
9
  machineId: string;
6
10
  controlPlaneOrigin: string;
7
11
  credentialRemoved: true;
@@ -1 +1 @@
1
- {"version":3,"file":"remove-machine.d.ts","sourceRoot":"","sources":["../../src/remove-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,wBAAsB,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC;IACpD,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,uBAAuB,CAAC;IACpC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6DhC"}
1
+ {"version":3,"file":"remove-machine.d.ts","sourceRoot":"","sources":["../../src/remove-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC;;;OAGG;IACH,MAAM,EAAE,SAAS,GAAG,iBAAiB,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,wBAAsB,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC;IACpD,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,uBAAuB,CAAC;IACpC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoEhC"}
@@ -27,10 +27,18 @@ export async function removeMachine(options) {
27
27
  throw new Error(`Could not reach ${endpoint.origin}. The local credential was kept; ` +
28
28
  "check your connection and try again.");
29
29
  }
30
+ let alreadyRemoved = false;
30
31
  if (!response.ok) {
31
- throw new Error(await removalFailureMessage(response));
32
+ const failure = await removalFailure(response);
33
+ // The server no longer accepts this key: an administrator already
34
+ // removed the computer or revoked the key. Nothing is left to
35
+ // unregister, and the key is useless, so finish the local cleanup.
36
+ if (response.status !== 401 || failure.code !== "invalid_credential") {
37
+ throw new Error(failure.message);
38
+ }
39
+ alreadyRemoved = true;
32
40
  }
33
- if (response.status !== 204) {
41
+ else if (response.status !== 204) {
34
42
  throw new Error(`Control plane returned an unexpected machine-removal response ` +
35
43
  `(HTTP ${response.status}). The local credential was kept.`);
36
44
  }
@@ -44,34 +52,40 @@ export async function removeMachine(options) {
44
52
  "pairing again.");
45
53
  }
46
54
  return Object.freeze({
47
- status: "removed",
55
+ status: alreadyRemoved ? "already_removed" : "removed",
48
56
  machineId: options.credential.machineId,
49
57
  controlPlaneOrigin: configuredOrigin,
50
58
  credentialRemoved: true,
51
59
  });
52
60
  }
53
- async function removalFailureMessage(response) {
61
+ async function removalFailure(response) {
62
+ const fallback = `Machine removal failed with HTTP ${response.status}. ` +
63
+ "The local credential was kept.";
54
64
  try {
55
65
  const value = await response.json();
56
66
  if (typeof value === "object" &&
57
67
  value !== null &&
58
68
  "error" in value &&
59
69
  typeof value.error === "object" &&
60
- value.error !== null &&
61
- "message" in value.error &&
62
- typeof value.error.message === "string") {
63
- const message = value.error.message.trim();
64
- if (message.length > 0 &&
65
- Buffer.byteLength(message, "utf8") <= 512 &&
66
- !/[\u0000-\u001f\u007f]/u.test(message)) {
67
- return `${message} The local credential was kept.`;
70
+ value.error !== null) {
71
+ const error = value.error;
72
+ const code = "code" in error && typeof error.code === "string"
73
+ ? { code: error.code }
74
+ : {};
75
+ if ("message" in error && typeof error.message === "string") {
76
+ const message = error.message.trim();
77
+ if (message.length > 0 &&
78
+ Buffer.byteLength(message, "utf8") <= 512 &&
79
+ !/[\u0000-\u001f\u007f]/u.test(message)) {
80
+ return { ...code, message: `${message} The local credential was kept.` };
81
+ }
68
82
  }
83
+ return { ...code, message: fallback };
69
84
  }
70
85
  }
71
86
  catch {
72
87
  // The status code is still useful and does not expose the credential.
73
88
  }
74
- return `Machine removal failed with HTTP ${response.status}. ` +
75
- "The local credential was kept.";
89
+ return { message: fallback };
76
90
  }
77
91
  //# sourceMappingURL=remove-machine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove-machine.js","sourceRoot":"","sources":["../../src/remove-machine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remove-machine.js","sourceRoot":"","sources":["../../src/remove-machine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import * as tls from "node:tls";
2
+ /**
3
+ * A company's own Phigon server (run by the Phigon app) signs its HTTPS
4
+ * certificate with an authority of its own. The pairing command carries
5
+ * that authority's SHA-256 fingerprint; pairing pins it here, and every
6
+ * later HTTPS and gRPC connection trusts it.
7
+ */
8
+ export declare const SERVER_AUTHORITY_FILE = "server-ca.pem";
9
+ export declare function serverAuthorityPath(dataDirectory: string): string;
10
+ /** Reads `--server-ca-sha256`: 64 hex characters, with or without colons. */
11
+ export declare function parseAuthorityFingerprint(value: string): string;
12
+ /** Adds an authority to the ones this process trusts for HTTPS and gRPC. */
13
+ export declare function trustAuthority(pem: string): void;
14
+ /** Trusts the authority saved when this computer paired, and returns its file. */
15
+ export declare function trustSavedAuthority(dataDirectory: string): string | undefined;
16
+ export declare function forgetServerAuthority(dataDirectory: string): Promise<void>;
17
+ type Connect = (options: tls.ConnectionOptions, listener: () => void) => tls.TLSSocket;
18
+ /**
19
+ * Finds the certificate in the server's chain whose SHA-256 matches the
20
+ * pinned fingerprint, saves it and trusts it. Nothing is sent to the server
21
+ * on this connection; the requests that follow are verified normally,
22
+ * including the server's name, against the pinned authority. Behind a
23
+ * proxy (`options.proxy`), the chain is read through a CONNECT tunnel.
24
+ */
25
+ export declare function pinServerAuthority(url: URL, fingerprint: string, dataDirectory: string, connect?: Connect, options?: Readonly<{
26
+ proxy?: URL | undefined;
27
+ }>): Promise<string>;
28
+ export {};
29
+ //# sourceMappingURL=server-authority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-authority.d.ts","sourceRoot":"","sources":["../../src/server-authority.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAGhC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAIrD,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/D;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQhD;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK7E;AAED,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;AAED,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,GAAG,CAAC,SAAS,CAAC;AAEvF;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,OAAqB,EAC9B,OAAO,GAAE,QAAQ,CAAC;IAAE,KAAK,CAAC,EAAE,GAAG,GAAG,SAAS,CAAA;CAAE,CAAM,GAClD,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
@@ -0,0 +1,106 @@
1
+ import { createHash, X509Certificate } from "node:crypto";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { rm, writeFile } from "node:fs/promises";
4
+ import { isIP } from "node:net";
5
+ import { join } from "node:path";
6
+ import * as tls from "node:tls";
7
+ import { connectThroughProxy } from "./proxy.js";
8
+ /**
9
+ * A company's own Phigon server (run by the Phigon app) signs its HTTPS
10
+ * certificate with an authority of its own. The pairing command carries
11
+ * that authority's SHA-256 fingerprint; pairing pins it here, and every
12
+ * later HTTPS and gRPC connection trusts it.
13
+ */
14
+ export const SERVER_AUTHORITY_FILE = "server-ca.pem";
15
+ const FINGERPRINT = /^[0-9a-f]{64}$/u;
16
+ export function serverAuthorityPath(dataDirectory) {
17
+ return join(dataDirectory, SERVER_AUTHORITY_FILE);
18
+ }
19
+ /** Reads `--server-ca-sha256`: 64 hex characters, with or without colons. */
20
+ export function parseAuthorityFingerprint(value) {
21
+ const normalized = value.trim().toLowerCase().replace(/:/gu, "");
22
+ if (!FINGERPRINT.test(normalized)) {
23
+ throw new Error("--server-ca-sha256 must be the 64-character fingerprint from the Connect machine dialog.");
24
+ }
25
+ return normalized;
26
+ }
27
+ /** Adds an authority to the ones this process trusts for HTTPS and gRPC. */
28
+ export function trustAuthority(pem) {
29
+ if (typeof tls.setDefaultCACertificates !== "function" || typeof tls.getCACertificates !== "function") {
30
+ throw new Error("Connecting to a company's own Phigon server needs Node.js 24.5 or newer. Update Node.js and try again.");
31
+ }
32
+ const current = tls.getCACertificates("default");
33
+ if (!current.some((certificate) => sameCertificate(certificate, pem))) {
34
+ tls.setDefaultCACertificates([...current, pem]);
35
+ }
36
+ }
37
+ /** Trusts the authority saved when this computer paired, and returns its file. */
38
+ export function trustSavedAuthority(dataDirectory) {
39
+ const file = serverAuthorityPath(dataDirectory);
40
+ if (!existsSync(file))
41
+ return undefined;
42
+ trustAuthority(readFileSync(file, "utf8"));
43
+ return file;
44
+ }
45
+ export async function forgetServerAuthority(dataDirectory) {
46
+ await rm(serverAuthorityPath(dataDirectory), { force: true });
47
+ }
48
+ /**
49
+ * Finds the certificate in the server's chain whose SHA-256 matches the
50
+ * pinned fingerprint, saves it and trusts it. Nothing is sent to the server
51
+ * on this connection; the requests that follow are verified normally,
52
+ * including the server's name, against the pinned authority. Behind a
53
+ * proxy (`options.proxy`), the chain is read through a CONNECT tunnel.
54
+ */
55
+ export async function pinServerAuthority(url, fingerprint, dataDirectory, connect = tls.connect, options = {}) {
56
+ if (url.protocol !== "https:") {
57
+ throw new Error("--server-ca-sha256 needs an https:// control plane URL.");
58
+ }
59
+ const tunnel = options.proxy === undefined
60
+ ? undefined
61
+ : await connectThroughProxy(options.proxy, url.hostname.replace(/^\[|\]$/gu, ""), Number(url.port || 443));
62
+ const chain = await peerChain(url, connect, tunnel);
63
+ const match = chain.find((raw) => createHash("sha256").update(raw).digest("hex") === fingerprint);
64
+ if (match === undefined) {
65
+ throw new Error("The server's certificate does not match the fingerprint in the pairing command. Check that this computer is on the right network and that you copied the whole command.");
66
+ }
67
+ const pem = new X509Certificate(match).toString();
68
+ trustAuthority(pem);
69
+ const file = serverAuthorityPath(dataDirectory);
70
+ await writeFile(file, pem, { mode: 0o600 });
71
+ return file;
72
+ }
73
+ function peerChain(url, connect, tunnel) {
74
+ const host = url.hostname.replace(/^\[|\]$/gu, "");
75
+ const port = Number(url.port || 443);
76
+ return new Promise((resolve, reject) => {
77
+ const socket = connect({
78
+ ...(tunnel === undefined ? { host, port } : { socket: tunnel }),
79
+ ...(isIP(host) ? {} : { servername: host }),
80
+ // Only to read the chain; the fingerprint decides what is trusted.
81
+ rejectUnauthorized: false,
82
+ timeout: 15_000,
83
+ }, () => {
84
+ const chain = [];
85
+ const seen = new Set();
86
+ let certificate = socket.getPeerCertificate(true);
87
+ while (certificate?.raw && !seen.has(certificate.fingerprint256)) {
88
+ seen.add(certificate.fingerprint256);
89
+ chain.push(certificate.raw);
90
+ certificate = certificate.issuerCertificate;
91
+ }
92
+ socket.end();
93
+ resolve(chain);
94
+ });
95
+ socket.once("error", (error) => reject(new Error(`Could not reach ${url.host}: ${error.message}`)));
96
+ socket.once("timeout", () => {
97
+ socket.destroy();
98
+ reject(new Error(`Connecting to ${url.host} timed out. Check that this computer can reach it on the network.`));
99
+ });
100
+ });
101
+ }
102
+ function sameCertificate(a, b) {
103
+ const strip = (pem) => pem.replace(/\s+/gu, "");
104
+ return strip(a) === strip(b);
105
+ }
106
+ //# sourceMappingURL=server-authority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-authority.js","sourceRoot":"","sources":["../../src/server-authority.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The server's idea of the time, estimated from the times it stamps on the
3
+ * stream (acknowledgements and policies). Remote commands carry an expiry in
4
+ * server time, so judging it by a computer clock that is a few minutes off
5
+ * would reject or extend every command.
6
+ *
7
+ * Each sample is the server's stamp minus the local time it arrived, which
8
+ * is the true offset less the one-way network delay: well under a second,
9
+ * against command windows of minutes. The estimate is the median of recent
10
+ * samples, so one odd stamp does not move it, and it is bounded so a broken
11
+ * stamp cannot move the clock arbitrarily far.
12
+ */
13
+ export declare class ServerClock {
14
+ #private;
15
+ constructor(options?: Readonly<{
16
+ now?: () => number;
17
+ /** The largest correction applied; larger offsets are clamped to it. */
18
+ maxCorrectionMs?: number;
19
+ /** Skews at least this large are reported. */
20
+ largeSkewMs?: number;
21
+ onLargeSkew?: (offsetMs: number) => void;
22
+ }>);
23
+ /** Records a server timestamp that arrived just now. */
24
+ observe(serverTime: Date): void;
25
+ /** How far the server's clock is ahead of this computer's, as applied. */
26
+ offsetMs(): number;
27
+ /** The current time on the server's clock, in epoch milliseconds. */
28
+ now(): number;
29
+ }
30
+ /** A plain-English description of a clock skew, for status messages. */
31
+ export declare function describeClockSkew(offsetMs: number): string;
32
+ //# sourceMappingURL=server-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-clock.d.ts","sourceRoot":"","sources":["../../src/server-clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,WAAW;;gBAUV,OAAO,GAAE,QAAQ,CAAC;QAC5B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;QACnB,wEAAwE;QACxE,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,8CAA8C;QAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KAC1C,CAAM;IAOP,wDAAwD;IACxD,OAAO,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI;IAuB/B,0EAA0E;IAC1E,QAAQ,IAAI,MAAM;IAIlB,qEAAqE;IACrE,GAAG,IAAI,MAAM;CAGd;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO1D"}