@trillboards/edge-sdk 0.2.21 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/macos/scripts/setup-litertlm.sh +30 -0
- package/deploy/windows/build-windows.ps1 +1 -0
- package/deploy/windows/e2e/test-enterprise-trust-store.ps1 +341 -0
- package/deploy/windows/enroll-connector.ps1 +169 -0
- package/deploy/windows/installer.nsi +102 -6
- package/deploy/windows/run-connector.ps1 +30 -0
- package/deploy/windows/setup-litertlm.ps1 +49 -1
- package/dist/AudienceAnalyzeClient.d.ts +32 -1
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -1
- package/dist/AudienceAnalyzeClient.js +34 -5
- package/dist/AudienceAnalyzeClient.js.map +1 -1
- package/dist/CloudSensingManager.d.ts +30 -0
- package/dist/CloudSensingManager.d.ts.map +1 -1
- package/dist/CloudSensingManager.js +61 -1
- package/dist/CloudSensingManager.js.map +1 -1
- package/dist/ConnectorCameraClient.d.ts +79 -0
- package/dist/ConnectorCameraClient.d.ts.map +1 -0
- package/dist/ConnectorCameraClient.js +114 -0
- package/dist/ConnectorCameraClient.js.map +1 -0
- package/dist/EdgeAgent.js +1 -1
- package/dist/EnrollClient.d.ts +81 -0
- package/dist/EnrollClient.d.ts.map +1 -0
- package/dist/EnrollClient.js +97 -0
- package/dist/EnrollClient.js.map +1 -0
- package/dist/cli.d.ts +49 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +392 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnose.d.ts +37 -4
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +155 -6
- package/dist/diagnose.js.map +1 -1
- package/dist/enterpriseNetwork.d.ts +130 -0
- package/dist/enterpriseNetwork.d.ts.map +1 -0
- package/dist/enterpriseNetwork.js +568 -0
- package/dist/enterpriseNetwork.js.map +1 -0
- package/dist/enterpriseProxy.d.ts +73 -0
- package/dist/enterpriseProxy.d.ts.map +1 -0
- package/dist/enterpriseProxy.js +406 -0
- package/dist/enterpriseProxy.js.map +1 -0
- package/dist/enterpriseTrust.d.ts +188 -0
- package/dist/enterpriseTrust.d.ts.map +1 -0
- package/dist/enterpriseTrust.js +615 -0
- package/dist/enterpriseTrust.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/localNetworkAccess.d.ts +166 -0
- package/dist/localNetworkAccess.d.ts.map +1 -0
- package/dist/localNetworkAccess.js +490 -0
- package/dist/localNetworkAccess.js.map +1 -0
- package/dist/sensingRunMode.d.ts +36 -0
- package/dist/sensingRunMode.d.ts.map +1 -1
- package/dist/sensingRunMode.js +63 -1
- package/dist/sensingRunMode.js.map +1 -1
- package/dist/transportFailure.d.ts +118 -0
- package/dist/transportFailure.d.ts.map +1 -0
- package/dist/transportFailure.js +267 -0
- package/dist/transportFailure.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Install: npm install @trillboards/edge-sdk
|
|
4
4
|
// Run: npx trillboards-edge start --config trillboards.config.json
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.CropViewProvider = exports.SharedFrameSource = exports.isCloudEscalationEnabled = exports.CloudEscalationPolicy = exports.motionSignature = exports.downscaleRgbaToGrey = exports.decodeGreyFrame = exports.isChangeCandidate = exports.SceneChangeDetector = exports.MotionGate = exports.DEFAULT_CANDIDATE_TTL_MS = exports.VlmCandidateBuffer = exports.VlmAdmissionGate = exports.shouldAttemptRecorderAddressRecovery = exports.rewriteStreamHost = exports.normalizeMacAddress = exports.lookupMacAddress = exports.RecorderAddressRecovery = exports.resolveFeeds = exports.classifyRtspFailureClass = exports.buildTiledCameras = exports.buildSensingLoops = exports.CloudSensingManager = exports.defaultHttpPoster = exports.AudienceAnalyzeClient = exports.runDiagnose = exports.runInit = exports.CommandRouter = exports.resolveConfig = exports.loadConfig = exports.EdgeAgent = void 0;
|
|
6
|
+
exports.CropViewProvider = exports.SharedFrameSource = exports.isCloudEscalationEnabled = exports.CloudEscalationPolicy = exports.motionSignature = exports.downscaleRgbaToGrey = exports.decodeGreyFrame = exports.isChangeCandidate = exports.SceneChangeDetector = exports.MotionGate = exports.DEFAULT_CANDIDATE_TTL_MS = exports.VlmCandidateBuffer = exports.VlmAdmissionGate = exports.shouldAttemptRecorderAddressRecovery = exports.rewriteStreamHost = exports.normalizeMacAddress = exports.lookupMacAddress = exports.RecorderAddressRecovery = exports.resolveFeeds = exports.classifyRtspFailureClass = exports.buildTiledCameras = exports.buildSensingLoops = exports.CloudSensingManager = exports.defaultHttpPoster = exports.AudienceAnalyzeClient = exports.LOCAL_NETWORK_DENIED_SUMMARY = exports.LOCAL_NETWORK_DENIED_SUGGESTION = exports.decideLocalNetworkVerdict = exports.probeLocalNetworkAccess = exports.describeProxy = exports.resolveProxyForUrl = exports.describeTrustAnchors = exports.resolveTrustAnchors = exports.isTrustFailure = exports.formatTransportFailure = exports.classifyTransportError = exports.TransportFailure = exports.EnterpriseHttpsAgent = exports.resetEnterpriseNetworkCaches = exports.diagnoseTransportError = exports.getEnterpriseAgent = exports.describeNetworkPosture = exports.installEnterpriseNetworking = exports.runDiagnose = exports.runInit = exports.CommandRouter = exports.resolveConfig = exports.loadConfig = exports.EdgeAgent = void 0;
|
|
7
7
|
var EdgeAgent_1 = require("./EdgeAgent");
|
|
8
8
|
Object.defineProperty(exports, "EdgeAgent", { enumerable: true, get: function () { return EdgeAgent_1.EdgeAgent; } });
|
|
9
9
|
var config_1 = require("./config");
|
|
@@ -15,6 +15,34 @@ var init_1 = require("./init");
|
|
|
15
15
|
Object.defineProperty(exports, "runInit", { enumerable: true, get: function () { return init_1.runInit; } });
|
|
16
16
|
var diagnose_1 = require("./diagnose");
|
|
17
17
|
Object.defineProperty(exports, "runDiagnose", { enumerable: true, get: function () { return diagnose_1.runDiagnose; } });
|
|
18
|
+
// Enterprise networking: the machine's TLS trust store + the machine's proxy.
|
|
19
|
+
// Exported so an embedder that does not run our CLI can install the same
|
|
20
|
+
// posture, and so the failure classification is reusable rather than re-derived.
|
|
21
|
+
var enterpriseNetwork_1 = require("./enterpriseNetwork");
|
|
22
|
+
Object.defineProperty(exports, "installEnterpriseNetworking", { enumerable: true, get: function () { return enterpriseNetwork_1.installEnterpriseNetworking; } });
|
|
23
|
+
Object.defineProperty(exports, "describeNetworkPosture", { enumerable: true, get: function () { return enterpriseNetwork_1.describeNetworkPosture; } });
|
|
24
|
+
Object.defineProperty(exports, "getEnterpriseAgent", { enumerable: true, get: function () { return enterpriseNetwork_1.getEnterpriseAgent; } });
|
|
25
|
+
Object.defineProperty(exports, "diagnoseTransportError", { enumerable: true, get: function () { return enterpriseNetwork_1.diagnoseTransportError; } });
|
|
26
|
+
Object.defineProperty(exports, "resetEnterpriseNetworkCaches", { enumerable: true, get: function () { return enterpriseNetwork_1.resetEnterpriseNetworkCaches; } });
|
|
27
|
+
Object.defineProperty(exports, "EnterpriseHttpsAgent", { enumerable: true, get: function () { return enterpriseNetwork_1.EnterpriseHttpsAgent; } });
|
|
28
|
+
var transportFailure_1 = require("./transportFailure");
|
|
29
|
+
Object.defineProperty(exports, "TransportFailure", { enumerable: true, get: function () { return transportFailure_1.TransportFailure; } });
|
|
30
|
+
Object.defineProperty(exports, "classifyTransportError", { enumerable: true, get: function () { return transportFailure_1.classifyTransportError; } });
|
|
31
|
+
Object.defineProperty(exports, "formatTransportFailure", { enumerable: true, get: function () { return transportFailure_1.formatTransportFailure; } });
|
|
32
|
+
Object.defineProperty(exports, "isTrustFailure", { enumerable: true, get: function () { return transportFailure_1.isTrustFailure; } });
|
|
33
|
+
var enterpriseTrust_1 = require("./enterpriseTrust");
|
|
34
|
+
Object.defineProperty(exports, "resolveTrustAnchors", { enumerable: true, get: function () { return enterpriseTrust_1.resolveTrustAnchors; } });
|
|
35
|
+
Object.defineProperty(exports, "describeTrustAnchors", { enumerable: true, get: function () { return enterpriseTrust_1.describeTrustAnchors; } });
|
|
36
|
+
var enterpriseProxy_1 = require("./enterpriseProxy");
|
|
37
|
+
Object.defineProperty(exports, "resolveProxyForUrl", { enumerable: true, get: function () { return enterpriseProxy_1.resolveProxyForUrl; } });
|
|
38
|
+
Object.defineProperty(exports, "describeProxy", { enumerable: true, get: function () { return enterpriseProxy_1.describeProxy; } });
|
|
39
|
+
// macOS Local Network (TCC) detection — why a LAN camera can be unreachable
|
|
40
|
+
// for a reason that has nothing to do with the camera.
|
|
41
|
+
var localNetworkAccess_1 = require("./localNetworkAccess");
|
|
42
|
+
Object.defineProperty(exports, "probeLocalNetworkAccess", { enumerable: true, get: function () { return localNetworkAccess_1.probeLocalNetworkAccess; } });
|
|
43
|
+
Object.defineProperty(exports, "decideLocalNetworkVerdict", { enumerable: true, get: function () { return localNetworkAccess_1.decideLocalNetworkVerdict; } });
|
|
44
|
+
Object.defineProperty(exports, "LOCAL_NETWORK_DENIED_SUGGESTION", { enumerable: true, get: function () { return localNetworkAccess_1.LOCAL_NETWORK_DENIED_SUGGESTION; } });
|
|
45
|
+
Object.defineProperty(exports, "LOCAL_NETWORK_DENIED_SUMMARY", { enumerable: true, get: function () { return localNetworkAccess_1.LOCAL_NETWORK_DENIED_SUMMARY; } });
|
|
18
46
|
// Cloud-sensing mode: RTSP frame → cloud-VLM POST (no local ONNX), multi-channel.
|
|
19
47
|
var AudienceAnalyzeClient_1 = require("./AudienceAnalyzeClient");
|
|
20
48
|
Object.defineProperty(exports, "AudienceAnalyzeClient", { enumerable: true, get: function () { return AudienceAnalyzeClient_1.AudienceAnalyzeClient; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,6CAA6C;AAC7C,mEAAmE;;;AAEnE,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAElB,mCAAqD;AAA5C,oGAAA,UAAU,OAAA;AAAE,uGAAA,aAAa,OAAA;AAClC,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAEtB,+BAAiC;AAAxB,+FAAA,OAAO,OAAA;AAChB,uCAAyC;AAAhC,uGAAA,WAAW,OAAA;AAGpB,kFAAkF;AAClF,iEAAmF;AAA1E,8HAAA,qBAAqB,OAAA;AAAE,0HAAA,iBAAiB,OAAA;AAWjD,6DAM+B;AAL7B,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,mHAAA,YAAY,OAAA;AAEd,qEAMmC;AALjC,kIAAA,uBAAuB,OAAA;AACvB,2HAAA,gBAAgB,OAAA;AAChB,8HAAA,mBAAmB,OAAA;AACnB,4HAAA,iBAAiB,OAAA;AACjB,+IAAA,oCAAoC,OAAA;AAStC,+DAA+D;AAC/D,6EAA6E;AAC7E,uBAAuB;AACvB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAMzB,wEAAwE;AACxE,sEAAsE;AACtE,2DAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,8HAAA,wBAAwB,OAAA;AAQrD,6DAO+B;AAN7B,iHAAA,UAAU,OAAA;AACV,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,sHAAA,eAAe,OAAA;AACf,0HAAA,mBAAmB,OAAA;AACnB,sHAAA,eAAe,OAAA;AAajB,sEAAsE;AACtE,8EAA8E;AAC9E,uDAAuD;AACvD,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,+CAA0D;AAAjD,wHAAA,wBAAwB,OAAA;AASjC,+EAA+E;AAC/E,mEAAmE;AACnE,+CAAqE;AAA5D,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,6CAA6C;AAC7C,mEAAmE;;;AAEnE,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAElB,mCAAqD;AAA5C,oGAAA,UAAU,OAAA;AAAE,uGAAA,aAAa,OAAA;AAClC,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAEtB,+BAAiC;AAAxB,+FAAA,OAAO,OAAA;AAChB,uCAAyC;AAAhC,uGAAA,WAAW,OAAA;AAGpB,8EAA8E;AAC9E,yEAAyE;AACzE,iFAAiF;AACjF,yDAO6B;AAN3B,gIAAA,2BAA2B,OAAA;AAC3B,2HAAA,sBAAsB,OAAA;AACtB,uHAAA,kBAAkB,OAAA;AAClB,2HAAA,sBAAsB,OAAA;AACtB,iIAAA,4BAA4B,OAAA;AAC5B,yHAAA,oBAAoB,OAAA;AAGtB,uDAK4B;AAJ1B,oHAAA,gBAAgB,OAAA;AAChB,0HAAA,sBAAsB,OAAA;AACtB,0HAAA,sBAAsB,OAAA;AACtB,kHAAA,cAAc,OAAA;AAGhB,qDAA8E;AAArE,sHAAA,mBAAmB,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAElD,qDAAsE;AAA7D,qHAAA,kBAAkB,OAAA;AAAE,gHAAA,aAAa,OAAA;AAE1C,4EAA4E;AAC5E,uDAAuD;AACvD,2DAK8B;AAJ5B,6HAAA,uBAAuB,OAAA;AACvB,+HAAA,yBAAyB,OAAA;AACzB,qIAAA,+BAA+B,OAAA;AAC/B,kIAAA,4BAA4B,OAAA;AAS9B,kFAAkF;AAClF,iEAAmF;AAA1E,8HAAA,qBAAqB,OAAA;AAAE,0HAAA,iBAAiB,OAAA;AAWjD,6DAM+B;AAL7B,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,mHAAA,YAAY,OAAA;AAEd,qEAMmC;AALjC,kIAAA,uBAAuB,OAAA;AACvB,2HAAA,gBAAgB,OAAA;AAChB,8HAAA,mBAAmB,OAAA;AACnB,4HAAA,iBAAiB,OAAA;AACjB,+IAAA,oCAAoC,OAAA;AAStC,+DAA+D;AAC/D,6EAA6E;AAC7E,uBAAuB;AACvB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAMzB,wEAAwE;AACxE,sEAAsE;AACtE,2DAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,8HAAA,wBAAwB,OAAA;AAQrD,6DAO+B;AAN7B,iHAAA,UAAU,OAAA;AACV,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,sHAAA,eAAe,OAAA;AACf,0HAAA,mBAAmB,OAAA;AACnB,sHAAA,eAAe,OAAA;AAajB,sEAAsE;AACtE,8EAA8E;AAC9E,uDAAuD;AACvD,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,+CAA0D;AAAjD,wHAAA,wBAAwB,OAAA;AASjC,+EAA+E;AAC/E,mEAAmE;AACnE,+CAAqE;AAA5D,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* macOS **Local Network** (TCC) access detection.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this file exists
|
|
5
|
+
*
|
|
6
|
+
* On macOS 15+ every process that talks to a private-IP LAN host is gated by
|
|
7
|
+
* the *Local Network* privacy grant. The connector's whole camera surface is
|
|
8
|
+
* LAN traffic — ONVIF WS-Discovery multicast, the subnet TCP sweep, and RTSP
|
|
9
|
+
* frame capture — so a missing grant takes every camera offline at once.
|
|
10
|
+
*
|
|
11
|
+
* The failure it produces is not silence, it is **misattribution**: ffmpeg
|
|
12
|
+
* reports "no route to host", `classifyRtspFailureClass` maps that to
|
|
13
|
+
* `rtsp_unreachable`, and the portal tells the operator to check that their
|
|
14
|
+
* camera and connector are on the same network. They are. The fix is a
|
|
15
|
+
* checkbox in System Settings that nobody was told to tick.
|
|
16
|
+
*
|
|
17
|
+
* ## What macOS actually exposes — measured, not assumed
|
|
18
|
+
*
|
|
19
|
+
* Measured on macOS 26.5.2 (arm64) on 2026-08-14:
|
|
20
|
+
*
|
|
21
|
+
* - The grant is **not readable**. `kTCCServiceLocalNetwork` does not exist in
|
|
22
|
+
* `tccd`'s service table (positive control: `kTCCServiceCamera` is present),
|
|
23
|
+
* there is no row in either TCC.db, and `tccutil` cannot address it. The
|
|
24
|
+
* decision is owned by `nehelper` (`com.apple.network.localnetworkdecision`)
|
|
25
|
+
* and is not exposed to a client process by any public or file-level means.
|
|
26
|
+
* **So the state must be inferred from behaviour.**
|
|
27
|
+
*
|
|
28
|
+
* - Denial has a sharp, specific signature. The *same* binary, same machine,
|
|
29
|
+
* same network, same minute, differing only in who launched it:
|
|
30
|
+
*
|
|
31
|
+
* | operation | LAN allowed | LAN denied |
|
|
32
|
+
* |----------------------------------|----------------------|----------------------|
|
|
33
|
+
* | `sendto` 239.255.255.250:3702 | sent | **EHOSTUNREACH, 0 ms** |
|
|
34
|
+
* | `connect` gateway:80 (host up) | connected, 4 ms | **EHOSTUNREACH, 1 ms** |
|
|
35
|
+
* | `connect` gateway:9 (port shut) | ECONNREFUSED, 1005 ms| **EHOSTUNREACH, 0 ms** |
|
|
36
|
+
* | `connect` 192.168.0.222 (no host)| timeout, 3004 ms | timeout, 3193 ms |
|
|
37
|
+
* | `connect` 127.0.0.1 (loopback) | connected | connected |
|
|
38
|
+
*
|
|
39
|
+
* Two things in that table are the entire design:
|
|
40
|
+
*
|
|
41
|
+
* 1. **The absent host times out in BOTH states.** A probe that only tries the
|
|
42
|
+
* camera can never tell "denied" from "the NVR is off", because they look
|
|
43
|
+
* identical. That is precisely the bug, so a probe that reproduces it is
|
|
44
|
+
* worthless.
|
|
45
|
+
*
|
|
46
|
+
* 2. **Multicast `sendto` is the clean discriminator.** An empty network
|
|
47
|
+
* segment still *accepts* a multicast send — nothing answers, but the send
|
|
48
|
+
* succeeds. Only the TCC gate makes `sendto` itself fail. And an immediate
|
|
49
|
+
* `EHOSTUNREACH` toward an address on the machine's own directly-connected
|
|
50
|
+
* subnet cannot come from routing: the kernel has a connected route there by
|
|
51
|
+
* construction, and a missing host shows up as an ARP timeout instead.
|
|
52
|
+
*
|
|
53
|
+
* Loopback is deliberately only a control, never evidence: it is never gated,
|
|
54
|
+
* so it succeeds in both states and separates nothing.
|
|
55
|
+
*
|
|
56
|
+
* ## Why NOT the default gateway
|
|
57
|
+
*
|
|
58
|
+
* The obvious probe — `route -n get default` — is wrong, and measurably so.
|
|
59
|
+
* On the test machine the default route is a Tailscale `utun` interface, and
|
|
60
|
+
* under a denied grant that endpoint answered `ECONNREFUSED` in the same run
|
|
61
|
+
* where the real LAN returned `EHOSTUNREACH`. A VPN default route is not a LAN
|
|
62
|
+
* host and is not gated, so probing it reports "the LAN is fine" every time and
|
|
63
|
+
* sends the operator straight back to debugging the recorder. Probe targets are
|
|
64
|
+
* therefore derived from the machine's **own directly-connected IPv4 subnets**
|
|
65
|
+
* via `os.networkInterfaces()`, never from the default route.
|
|
66
|
+
*
|
|
67
|
+
* ## Failing safe
|
|
68
|
+
*
|
|
69
|
+
* Every ambiguous outcome resolves to `unknown`, never to `denied`. Positive
|
|
70
|
+
* evidence that the LAN is reachable (a completed connect, or an RST) vetoes a
|
|
71
|
+
* denial verdict outright. Claiming a permission problem that isn't there sends
|
|
72
|
+
* the operator to the wrong place just as surely as the bug this replaces.
|
|
73
|
+
*/
|
|
74
|
+
import * as os from 'os';
|
|
75
|
+
export type LocalNetworkVerdict =
|
|
76
|
+
/** Proven reachable: something on the local subnet answered (accept or RST). */
|
|
77
|
+
'granted'
|
|
78
|
+
/** Proven blocked above the routing layer: the TCC grant is missing. */
|
|
79
|
+
| 'denied'
|
|
80
|
+
/** Not assessable — no LAN, all targets silent, or contradictory evidence. */
|
|
81
|
+
| 'unknown'
|
|
82
|
+
/** Platform has no Local Network gate at all (everything except darwin). */
|
|
83
|
+
| 'not_applicable';
|
|
84
|
+
export interface LocalNetworkProbeEvidence {
|
|
85
|
+
/** `sendto` to the WS-Discovery group: did the kernel accept the datagram? */
|
|
86
|
+
multicastSend: 'sent' | 'blocked' | 'error' | 'skipped';
|
|
87
|
+
/** errno from the multicast attempt, when it failed. */
|
|
88
|
+
multicastErrorCode?: string;
|
|
89
|
+
/** Any same-subnet TCP target that accepted or actively refused us. */
|
|
90
|
+
reachableTarget?: string;
|
|
91
|
+
/** Any same-subnet TCP target that failed instantly with a blocked errno. */
|
|
92
|
+
blockedTarget?: string;
|
|
93
|
+
/** Same-subnet TCP targets that simply went silent (absent host, or empty LAN). */
|
|
94
|
+
silentTargets: string[];
|
|
95
|
+
/** Loopback control — sockets working at all. Never used as LAN evidence. */
|
|
96
|
+
loopbackUsable: boolean;
|
|
97
|
+
/** Directly-connected IPv4 subnets discovered from the interface list. */
|
|
98
|
+
subnets: string[];
|
|
99
|
+
}
|
|
100
|
+
export interface LocalNetworkProbeResult {
|
|
101
|
+
verdict: LocalNetworkVerdict;
|
|
102
|
+
/** One line, safe to log and to show support. */
|
|
103
|
+
reason: string;
|
|
104
|
+
evidence: LocalNetworkProbeEvidence;
|
|
105
|
+
}
|
|
106
|
+
export interface LocalNetworkProbeOptions {
|
|
107
|
+
/**
|
|
108
|
+
* Extra LAN hosts to probe — normally the configured camera/recorder hosts.
|
|
109
|
+
* Only those on a directly-connected subnet are used; a routed host tells us
|
|
110
|
+
* nothing, because a routed destination legitimately has no connected route.
|
|
111
|
+
*/
|
|
112
|
+
extraHosts?: string[];
|
|
113
|
+
/** Per-target TCP timeout. */
|
|
114
|
+
tcpTimeoutMs?: number;
|
|
115
|
+
/** Injection seam for tests. */
|
|
116
|
+
platform?: NodeJS.Platform;
|
|
117
|
+
/** Injection seam for tests. */
|
|
118
|
+
networkInterfaces?: () => NodeJS.Dict<os.NetworkInterfaceInfo[]>;
|
|
119
|
+
/**
|
|
120
|
+
* Injection seam. Exists so the `denied` branch can be driven end to end from
|
|
121
|
+
* the socket outcomes actually recorded on a blocked Mac — the OS state that
|
|
122
|
+
* produces them cannot be re-induced on demand (see the header table).
|
|
123
|
+
*/
|
|
124
|
+
tcpProbeImpl?: (host: string, port: number, timeoutMs: number) => Promise<TcpProbeOutcome>;
|
|
125
|
+
/** Injection seam — see `tcpProbeImpl`. */
|
|
126
|
+
multicastProbeImpl?: (interfaceAddress?: string) => Promise<MulticastProbeOutcome>;
|
|
127
|
+
}
|
|
128
|
+
export interface TcpProbeOutcome {
|
|
129
|
+
target: string;
|
|
130
|
+
outcome: 'reachable' | 'blocked' | 'silent';
|
|
131
|
+
code?: string;
|
|
132
|
+
elapsedMs: number;
|
|
133
|
+
}
|
|
134
|
+
export interface MulticastProbeOutcome {
|
|
135
|
+
result: 'sent' | 'blocked' | 'error';
|
|
136
|
+
code?: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Decide whether this process can reach the local network.
|
|
140
|
+
*
|
|
141
|
+
* Never throws, never rejects. Ambiguity always resolves toward `unknown`.
|
|
142
|
+
*/
|
|
143
|
+
export declare function probeLocalNetworkAccess(options?: LocalNetworkProbeOptions): Promise<LocalNetworkProbeResult>;
|
|
144
|
+
/**
|
|
145
|
+
* The verdict rule, isolated from all I/O.
|
|
146
|
+
*
|
|
147
|
+
* Split out so it can be driven from the socket outcomes *recorded on a Mac
|
|
148
|
+
* that was actually blocked*. The OS-level denial could not be re-induced on
|
|
149
|
+
* demand after it cleared, so replaying the measured evidence through this
|
|
150
|
+
* exact function is the only way the `denied` branch gets tested against real
|
|
151
|
+
* data rather than against an invented signature.
|
|
152
|
+
*/
|
|
153
|
+
export declare function decideLocalNetworkVerdict(evidence: LocalNetworkProbeEvidence): {
|
|
154
|
+
verdict: LocalNetworkVerdict;
|
|
155
|
+
reason: string;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* The operator-facing instruction for a denied grant.
|
|
159
|
+
*
|
|
160
|
+
* Names the pane and says plainly that a human has to be at the machine, because
|
|
161
|
+
* the one thing that cannot be automated here is the only thing that fixes it.
|
|
162
|
+
*/
|
|
163
|
+
export declare const LOCAL_NETWORK_DENIED_SUGGESTION: string;
|
|
164
|
+
/** Same message, one line, for a log or a health beacon. */
|
|
165
|
+
export declare const LOCAL_NETWORK_DENIED_SUMMARY: string;
|
|
166
|
+
//# sourceMappingURL=localNetworkAccess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localNetworkAccess.d.ts","sourceRoot":"","sources":["../src/localNetworkAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AAIH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAuBzB,MAAM,MAAM,mBAAmB;AAC7B,gFAAgF;AAC9E,SAAS;AACX,wEAAwE;GACtE,QAAQ;AACV,8EAA8E;GAC5E,SAAS;AACX,4EAA4E;GAC1E,gBAAgB,CAAC;AAErB,MAAM,WAAW,yBAAyB;IACxC,8EAA8E;IAC9E,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACxD,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,cAAc,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,yBAAyB,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACjE;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3F,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAgPD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CAoElC;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,yBAAyB,GAClC;IAAE,OAAO,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoDlD;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,QAGoB,CAAC;AAEjE,4DAA4D;AAC5D,eAAO,MAAM,4BAA4B,QAEiB,CAAC"}
|