@camstack/server 1.2.594 → 1.2.595
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/dist/addon-root-inventory.js +50 -11
- package/dist/agent/addon-scan.js +44 -6
- package/dist/agent/agent-addon-runtime.js +8 -3
- package/dist/agent/agent-addon-updates.js +52 -12
- package/dist/agent/agent-cap-dispatch-service.js +5 -3
- package/dist/agent/agent-config.js +42 -7
- package/dist/agent/agent-deploy-swap.js +41 -5
- package/dist/agent/agent-group-runner.js +47 -8
- package/dist/agent/agent-http-auth.js +22 -10
- package/dist/agent/agent-http.js +113 -64
- package/dist/agent/agent-hub-addon-update.js +16 -10
- package/dist/agent/agent-hub-registration.js +7 -4
- package/dist/agent/agent-infra-capabilities.js +9 -5
- package/dist/agent/agent-json-file.js +42 -5
- package/dist/agent/agent-mesh-gate.js +8 -5
- package/dist/agent/agent-node-certificates.js +28 -25
- package/dist/agent/agent-pairing-local.js +47 -10
- package/dist/agent/agent-pairing-routes.js +20 -16
- package/dist/agent/agent-pairing-store.js +58 -18
- package/dist/agent/agent-reconnect.js +4 -1
- package/dist/agent/agent-service.js +71 -35
- package/dist/agent/agent-sniffing-listener.js +48 -11
- package/dist/agent/agent-undeploy.js +41 -5
- package/dist/agent/agent-update-routes.js +19 -14
- package/dist/agent/agent-update-service.js +80 -38
- package/dist/agent/apply-model-distribution.js +4 -1
- package/dist/agent/apply-stage-dev-uploads.js +9 -6
- package/dist/agent/derive-hub-url.js +8 -3
- package/dist/agent/fetch-bundle-from-hub.js +9 -6
- package/dist/agent/hubs-found.js +43 -6
- package/dist/agent/infra-boot-guard.js +4 -1
- package/dist/agent/infra-boot-plan.js +6 -2
- package/dist/agent/main.js +183 -148
- package/dist/agent/register-agent-cap-dispatch.js +6 -3
- package/dist/agent/serial-queue.js +7 -2
- package/dist/agent-status-page.js +4 -1
- package/dist/api/addon-upload.js +61 -22
- package/dist/api/agent-addon-delivery.js +11 -6
- package/dist/api/auth-whoami.js +4 -1
- package/dist/api/backup-download-pump.js +9 -5
- package/dist/api/backup-download.js +10 -7
- package/dist/api/core/addon-settings.router.js +19 -16
- package/dist/api/core/agent-pairing.router.js +79 -76
- package/dist/api/core/agents.router.js +24 -21
- package/dist/api/core/auth-admin-tokens.procedures.js +52 -48
- package/dist/api/core/auth-device-cert.procedures.js +67 -62
- package/dist/api/core/auth-limits.js +25 -16
- package/dist/api/core/auth-reauth.procedures.js +37 -32
- package/dist/api/core/auth-revoke-credentials.procedures.js +26 -22
- package/dist/api/core/auth-sessions.procedures.js +56 -52
- package/dist/api/core/auth.router.js +304 -300
- package/dist/api/core/cap-providers.js +121 -74
- package/dist/api/core/capabilities.router.js +37 -34
- package/dist/api/core/capability-preference-writes.js +17 -10
- package/dist/api/core/certificates.router.js +109 -106
- package/dist/api/core/cluster-nodes.router.js +18 -15
- package/dist/api/core/collection-preference.js +6 -2
- package/dist/api/core/event-bus-proxy.router.js +37 -34
- package/dist/api/core/failure-contributions.js +8 -4
- package/dist/api/core/hwaccel.router.js +20 -17
- package/dist/api/core/integration-secrets.js +12 -8
- package/dist/api/core/lifecycle-job-runner.js +49 -13
- package/dist/api/core/live-events.router.js +32 -29
- package/dist/api/core/load-contributions.js +8 -4
- package/dist/api/core/logging-settings.js +43 -30
- package/dist/api/core/logs.router.js +43 -40
- package/dist/api/core/notifications.router.js +18 -15
- package/dist/api/core/public-event-filter.js +8 -4
- package/dist/api/core/repl.router.js +21 -18
- package/dist/api/core/request-census-settings.js +16 -11
- package/dist/api/core/server-management.provider.js +4 -1
- package/dist/api/core/server-name.js +17 -9
- package/dist/api/core/site-location.js +24 -16
- package/dist/api/core/stream-probe.router.js +24 -21
- package/dist/api/core/system-events.router.js +26 -23
- package/dist/api/cors/cors-policy.js +29 -20
- package/dist/api/cors/register-cors-policy.js +14 -9
- package/dist/api/deploy-stage-registry.js +10 -6
- package/dist/api/dev-uploads-bundle.js +50 -12
- package/dist/api/health/adaptive-probe.routes.js +13 -9
- package/dist/api/health/health.routes.js +13 -8
- package/dist/api/hub-cluster-url.js +9 -3
- package/dist/api/model-distributor.js +50 -12
- package/dist/api/oauth2/consent-page.js +13 -10
- package/dist/api/oauth2/oauth2-routes.js +25 -17
- package/dist/api/oauth2/private-host.js +4 -1
- package/dist/api/server-upload-propagate.js +51 -15
- package/dist/api/server-upload.js +50 -13
- package/dist/api/sse-no-compression.js +4 -1
- package/dist/api/static/frame-policy.js +9 -4
- package/dist/api/static/precompressed-asset.js +57 -15
- package/dist/api/static/spa-mount.js +47 -8
- package/dist/api/static/spa-static.js +12 -5
- package/dist/api/tarball-manifest.js +44 -7
- package/dist/api/trpc/cap-mount-helpers.js +12 -7
- package/dist/api/trpc/cap-route-error-formatter.js +13 -10
- package/dist/api/trpc/cap-router-runtime.js +51 -40
- package/dist/api/trpc/client-ip.js +20 -9
- package/dist/api/trpc/core-cap-bridge.js +42 -32
- package/dist/api/trpc/device-collection-dispatch.js +27 -23
- package/dist/api/trpc/device-config-secret-redaction.js +40 -24
- package/dist/api/trpc/generated-cap-mounts.js +222 -218
- package/dist/api/trpc/generated-cap-routers.js +4856 -4676
- package/dist/api/trpc/http-request-census-hook.js +11 -8
- package/dist/api/trpc/http-request-census.js +41 -34
- package/dist/api/trpc/http-request-census.singleton.js +8 -4
- package/dist/api/trpc/localized-schema-paths.js +4 -1
- package/dist/api/trpc/principal-visibility.js +22 -14
- package/dist/api/trpc/remote-addon-update-grant.js +4 -1
- package/dist/api/trpc/scope-access.js +15 -10
- package/dist/api/trpc/server-provided-caps.js +7 -3
- package/dist/api/trpc/share-view-access.js +14 -6
- package/dist/api/trpc/trpc-error-device-tags.js +6 -3
- package/dist/api/trpc/trpc-error-principal.js +6 -2
- package/dist/api/trpc/trpc.context.js +25 -20
- package/dist/api/trpc/trpc.middleware.js +46 -38
- package/dist/api/trpc/trpc.router.js +99 -58
- package/dist/api/trpc/user-error.js +8 -5
- package/dist/api/trpc/ws-request-census.js +24 -17
- package/dist/api/trpc/ws-slow-consumer-guard.js +16 -11
- package/dist/api/upload-auth.js +9 -5
- package/dist/auth/addon-route-jwt-gate.js +7 -4
- package/dist/auth/addon-route-share-gate.js +12 -7
- package/dist/auth/app-confirm-page.js +22 -17
- package/dist/auth/app-confirm-routes.js +31 -26
- package/dist/auth/app-confirmations.js +44 -7
- package/dist/auth/app-page-shell.js +30 -17
- package/dist/auth/app-page-strings.js +17 -11
- package/dist/auth/app-passkey-page.js +21 -16
- package/dist/auth/app-passkey-routes.js +41 -37
- package/dist/auth/app-refused-route.js +18 -13
- package/dist/auth/auth-network-policy.js +15 -11
- package/dist/auth/auth-provider-gate.js +9 -4
- package/dist/auth/auth-rate-limit.js +7 -3
- package/dist/auth/client-address.js +9 -6
- package/dist/auth/device-enroll-proofs.js +43 -6
- package/dist/auth/external-link-intents.js +7 -3
- package/dist/auth/hub-sessions.js +12 -6
- package/dist/auth/native-link-completions.js +11 -7
- package/dist/auth/native-return.js +13 -9
- package/dist/auth/passkey-provider.js +32 -26
- package/dist/auth/second-factors.js +10 -6
- package/dist/auth/session-connections.js +12 -6
- package/dist/auth/session-cookie.js +23 -12
- package/dist/auth/session-lifetimes.js +12 -8
- package/dist/auth/session-mint.js +11 -4
- package/dist/auth/sso-finish-app.js +16 -13
- package/dist/auth/sso-finish-deps.js +27 -21
- package/dist/auth/sso-finish.js +38 -28
- package/dist/auth/sso-routes.js +25 -22
- package/dist/auth/used-bridge-ids.js +5 -1
- package/dist/boot/boot-config.js +55 -16
- package/dist/boot/init-sequence.js +4 -1
- package/dist/boot/integration-id-backfill.js +8 -3
- package/dist/boot/platform-keychain-key.js +42 -5
- package/dist/boot/post-boot.service.js +18 -14
- package/dist/boot/reconcile-lifecycle-jobs.js +6 -3
- package/dist/boot/retired-public-url-env.js +8 -4
- package/dist/bootstrap-packages.js +4 -1
- package/dist/closure-node-modules.js +38 -2
- package/dist/core/addon/addon-call-gateway.js +5 -1
- package/dist/core/addon/addon-package.service.js +123 -83
- package/dist/core/addon/addon-process-view.js +6 -2
- package/dist/core/addon/addon-realign-plan.js +4 -1
- package/dist/core/addon/addon-registry.service.js +187 -146
- package/dist/core/addon/addon-row-manifest.js +4 -1
- package/dist/core/addon/addon-search.service.js +7 -3
- package/dist/core/addon/addon-settings-provider.js +3 -1
- package/dist/core/addon/addon-uninstall.js +11 -4
- package/dist/core/addon/addon.tokens.js +5 -2
- package/dist/core/addon/device-meta-mirror.js +13 -8
- package/dist/core/addon/forked-custom-actions.js +11 -6
- package/dist/core/addon/integration-visibility.js +6 -3
- package/dist/core/addon/materialize-route-path.js +4 -1
- package/dist/core/addon/package-dir-utils.js +45 -8
- package/dist/core/addon/prune-misplaced-addons.js +43 -5
- package/dist/core/addon/runner-convergence.js +4 -1
- package/dist/core/addon/runner-serialization.js +4 -1
- package/dist/core/addon/runner-spawn-fanout.js +8 -3
- package/dist/core/addon/settings-door-wiring.js +8 -5
- package/dist/core/addon/single-flight-refresh.js +4 -1
- package/dist/core/addon-bridge/addon-bridge.service.js +44 -7
- package/dist/core/addon-pages/addon-pages.service.js +40 -3
- package/dist/core/addon-widgets/addon-widgets.service.js +42 -4
- package/dist/core/agent/agent-addon-backfill.js +17 -9
- package/dist/core/agent/agent-delivery-ledger.js +7 -3
- package/dist/core/agent/agent-liveness-event.js +6 -2
- package/dist/core/agent/agent-pairing-http.js +45 -41
- package/dist/core/agent/agent-registry.service.js +89 -50
- package/dist/core/agent/cluster-node-history-mirror.js +7 -3
- package/dist/core/agent/cluster-node-history-store.js +35 -31
- package/dist/core/agent/hub-agent-pairing.js +5 -1
- package/dist/core/agent/node-certificates-client.js +6 -3
- package/dist/core/agent/node-directory.js +4 -1
- package/dist/core/app-links/well-known-app-links.js +6 -2
- package/dist/core/auth/auth.service.js +8 -3
- package/dist/core/auth/handoff-code.service.js +49 -11
- package/dist/core/auth/record-kinds.js +19 -16
- package/dist/core/auth/share-token.service.js +79 -42
- package/dist/core/capability/capability.service.js +5 -1
- package/dist/core/config/config.schema.js +6 -1
- package/dist/core/config/config.service.js +6 -2
- package/dist/core/events/event-bus.service.js +7 -3
- package/dist/core/feature/feature.service.js +6 -2
- package/dist/core/lifecycle/lifecycle-runner.singleton.js +10 -5
- package/dist/core/lifecycle/lifecycle-state-machine.js +5 -1
- package/dist/core/logging/log-ring-buffer.js +5 -1
- package/dist/core/logging/logging.service.js +9 -5
- package/dist/core/logging/scoped-logger.js +5 -1
- package/dist/core/moleculer/agent-readiness-pull.js +4 -1
- package/dist/core/moleculer/agent-registration-request.js +7 -3
- package/dist/core/moleculer/cap-call-fn.js +7 -4
- package/dist/core/moleculer/cap-route-authority.js +8 -3
- package/dist/core/moleculer/hub-mesh-guard.js +9 -5
- package/dist/core/moleculer/moleculer.service.js +86 -79
- package/dist/core/network/network-quality.service.js +6 -2
- package/dist/core/notification/notification-wrapper.service.js +7 -3
- package/dist/core/notification/toast-wrapper.service.js +7 -3
- package/dist/core/provider/provider.tokens.js +4 -1
- package/dist/core/repl/repl-engine.service.js +8 -4
- package/dist/core/runner-health/runner-boot-check.js +15 -7
- package/dist/core/runner-health/update-preflight.js +14 -9
- package/dist/core/server-update/server-update.service.js +49 -12
- package/dist/core/server-update/system-apply-closure-patches.js +42 -6
- package/dist/core/server-update/system-ensure-prebuilds.js +6 -3
- package/dist/core/server-update/system-exec-npm.js +5 -2
- package/dist/core/storage/fs-storage-backend.js +5 -1
- package/dist/core/storage/storage-location-manager.js +5 -1
- package/dist/core/storage/storage.service.js +6 -2
- package/dist/core/streaming/ffmpeg-stream-info.js +8 -3
- package/dist/core/streaming/stream-probe.service.js +16 -12
- package/dist/core/streaming/ttl-cache.js +5 -1
- package/dist/core/topology/topology-emitter.service.js +23 -19
- package/dist/core/update-availability-emitter.js +7 -3
- package/dist/core/update-availability-store.js +45 -8
- package/dist/core/updates/agent-installed-packages.js +9 -5
- package/dist/core/updates/restart-marker.js +8 -3
- package/dist/core/updates/update-check-scheduler.js +18 -13
- package/dist/core/updates/wrapper-update-checker.js +7 -3
- package/dist/first-boot-addon-plan.js +6 -2
- package/dist/framework-nodepath.js +38 -2
- package/dist/i18n/request-lang.js +11 -7
- package/dist/launcher.js +65 -30
- package/dist/lifecycle-journal-path.js +38 -2
- package/dist/main.js +324 -286
- package/dist/manual-boot.js +156 -117
- package/dist/node-role.js +4 -1
- package/dist/package-inventory.js +48 -7
- package/dist/pending-restore.js +43 -7
- package/dist/single-copy-cleanup-runner.js +45 -9
- package/dist/single-copy-cleanup.js +15 -7
- package/dist/sqlite-restore.js +48 -9
- package/dist/starter.js +39 -4
- package/dist/ui-serving/lazy-ui-serving.js +39 -3
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* The seam that feeds {@link HttpRequestCensus} from a live tRPC request.
|
|
3
4
|
*
|
|
@@ -25,9 +26,11 @@
|
|
|
25
26
|
* ever moves below a field access, that test fails instead of the hub paying
|
|
26
27
|
* for a diagnostic nobody switched on.
|
|
27
28
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.recordTrpcHttpRequest = recordTrpcHttpRequest;
|
|
31
|
+
const client_ip_js_1 = require("./client-ip.js");
|
|
32
|
+
const http_request_census_js_1 = require("./http-request-census.js");
|
|
33
|
+
const trpc_error_principal_js_1 = require("./trpc-error-principal.js");
|
|
31
34
|
/**
|
|
32
35
|
* Count one tRPC HTTP request against `census`.
|
|
33
36
|
*
|
|
@@ -35,20 +38,20 @@ import { describeTrpcPrincipal } from './trpc-error-principal.js';
|
|
|
35
38
|
* `describeTrpcPrincipal`, the same function the tRPC error log already uses -
|
|
36
39
|
* a username and a credential KIND, never a token and never a header.
|
|
37
40
|
*/
|
|
38
|
-
|
|
41
|
+
function recordTrpcHttpRequest(census, req, user) {
|
|
39
42
|
if (!census.armed)
|
|
40
43
|
return;
|
|
41
44
|
if (req === undefined)
|
|
42
45
|
return;
|
|
43
46
|
const url = typeof req.url === 'string' ? req.url : '';
|
|
44
|
-
const procedures = parseTrpcProcedures(url, headerValue(req, 'content-type'));
|
|
47
|
+
const procedures = (0, http_request_census_js_1.parseTrpcProcedures)(url, headerValue(req, 'content-type'));
|
|
45
48
|
if (procedures.length === 0)
|
|
46
49
|
return;
|
|
47
50
|
census.observeHttpRequest({
|
|
48
51
|
procedures,
|
|
49
|
-
userAgent: extractUserAgent(req),
|
|
50
|
-
ip: extractClientIp(req),
|
|
51
|
-
principal: describeTrpcPrincipal(user),
|
|
52
|
+
userAgent: (0, client_ip_js_1.extractUserAgent)(req),
|
|
53
|
+
ip: (0, client_ip_js_1.extractClientIp)(req),
|
|
54
|
+
principal: (0, trpc_error_principal_js_1.describeTrpcPrincipal)(user),
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
/** First value of a possibly-repeated header, or `null`. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* WHO is calling the hub, and OVER WHICH PLANE - measured at the transport,
|
|
3
4
|
* never inferred.
|
|
@@ -104,8 +105,13 @@
|
|
|
104
105
|
* request. Stale timers are neutralised by a generation counter instead of
|
|
105
106
|
* being cleared, so no timer handle has to be stored or typed.
|
|
106
107
|
*/
|
|
108
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
109
|
+
exports.HttpRequestCensus = exports.UNKNOWN = exports.PROCEDURE_OVERFLOW = exports.BATCH_OVERFLOW_PROCEDURE = exports.MAX_BATCH_PROCEDURES = exports.USER_AGENT_MAX_CHARS = exports.MAX_PROCEDURES = exports.MAX_GROUPS = exports.MIN_REPORT_EVERY_MS = exports.DEFAULT_REPORT_EVERY_MS = exports.MIN_WINDOW_MS = exports.MAX_WINDOW_MS = exports.TRPC_URL_PREFIX = void 0;
|
|
110
|
+
exports.zeroPlaneCounts = zeroPlaneCounts;
|
|
111
|
+
exports.shortenUserAgent = shortenUserAgent;
|
|
112
|
+
exports.parseTrpcProcedures = parseTrpcProcedures;
|
|
107
113
|
/** Route prefix the tRPC plugin is registered under (`main.ts`). */
|
|
108
|
-
|
|
114
|
+
exports.TRPC_URL_PREFIX = '/trpc/';
|
|
109
115
|
/**
|
|
110
116
|
* Longest window the census may be armed for.
|
|
111
117
|
*
|
|
@@ -115,11 +121,11 @@ export const TRPC_URL_PREFIX = '/trpc/';
|
|
|
115
121
|
* was already running. Ten minutes is not enough room for a container
|
|
116
122
|
* recreation plus a cold boot.
|
|
117
123
|
*/
|
|
118
|
-
|
|
124
|
+
exports.MAX_WINDOW_MS = 30 * 60_000;
|
|
119
125
|
/** Shortest useful window. Anything below this cannot contain a boot. */
|
|
120
|
-
|
|
126
|
+
exports.MIN_WINDOW_MS = 1_000;
|
|
121
127
|
/** Default cadence of the aggregated report line. */
|
|
122
|
-
|
|
128
|
+
exports.DEFAULT_REPORT_EVERY_MS = 30_000;
|
|
123
129
|
/**
|
|
124
130
|
* Floor on the report cadence.
|
|
125
131
|
*
|
|
@@ -127,7 +133,7 @@ export const DEFAULT_REPORT_EVERY_MS = 30_000;
|
|
|
127
133
|
* would be 41 lines a second, which is itself an incident - and a cadence an
|
|
128
134
|
* operator could set to 100 ms would reproduce that with an aggregate.
|
|
129
135
|
*/
|
|
130
|
-
|
|
136
|
+
exports.MIN_REPORT_EVERY_MS = 5_000;
|
|
131
137
|
/**
|
|
132
138
|
* Bound on distinct `(procedure, ua, ip, principal)` groups held in memory.
|
|
133
139
|
*
|
|
@@ -136,27 +142,27 @@ export const MIN_REPORT_EVERY_MS = 5_000;
|
|
|
136
142
|
* COUNTED, never dropped silently - the totals stay exact, which is what the
|
|
137
143
|
* negative proof rests on.
|
|
138
144
|
*/
|
|
139
|
-
|
|
145
|
+
exports.MAX_GROUPS = 500;
|
|
140
146
|
/**
|
|
141
147
|
* Bound on distinct procedure names. The router's procedure set is closed and
|
|
142
148
|
* far below this; the bound exists so a garbage path cannot grow the map.
|
|
143
149
|
* Names beyond it fold into {@link PROCEDURE_OVERFLOW} rather than vanishing.
|
|
144
150
|
*/
|
|
145
|
-
|
|
151
|
+
exports.MAX_PROCEDURES = 500;
|
|
146
152
|
/** User-agent prefix kept in a group key. Full UA strings are long and their
|
|
147
153
|
* tail is build metadata that splits one client into many rows. */
|
|
148
|
-
|
|
154
|
+
exports.USER_AGENT_MAX_CHARS = 80;
|
|
149
155
|
/** Bound on procedures counted from one batched URL. tRPC's own `maxBatchSize`
|
|
150
156
|
* guards the router; this guards the census against a URL that never reaches
|
|
151
157
|
* a procedure at all. */
|
|
152
|
-
|
|
158
|
+
exports.MAX_BATCH_PROCEDURES = 200;
|
|
153
159
|
/** Synthetic name for batch entries beyond {@link MAX_BATCH_PROCEDURES}. */
|
|
154
|
-
|
|
160
|
+
exports.BATCH_OVERFLOW_PROCEDURE = '(batch-overflow)';
|
|
155
161
|
/** Synthetic name for procedures beyond {@link MAX_PROCEDURES}. */
|
|
156
|
-
|
|
162
|
+
exports.PROCEDURE_OVERFLOW = '(procedure-overflow)';
|
|
157
163
|
/** Placeholder used when a request carries no such signal. Never blank: an
|
|
158
164
|
* empty field reads as a logging defect rather than as an absent header. */
|
|
159
|
-
|
|
165
|
+
exports.UNKNOWN = 'unknown';
|
|
160
166
|
/** Group-key field separator. A character that cannot appear in a tRPC
|
|
161
167
|
* procedure path, so two different tuples can never collide into one row. */
|
|
162
168
|
const KEY_SEPARATOR = ' | ';
|
|
@@ -167,7 +173,7 @@ const KEY_SEPARATOR = ' | ';
|
|
|
167
173
|
* this literal fail to compile until it is given a counter. That is what keeps
|
|
168
174
|
* "a plane is never silently absent" from being a comment nobody enforces.
|
|
169
175
|
*/
|
|
170
|
-
|
|
176
|
+
function zeroPlaneCounts() {
|
|
171
177
|
return { http: 0, ws: 0, mesh: 0, unknown: 0 };
|
|
172
178
|
}
|
|
173
179
|
/** Frozen view of a mutable plane counter, for the wire. */
|
|
@@ -187,15 +193,15 @@ function defaultSchedule(fn, ms) {
|
|
|
187
193
|
* Exported because the truncation is part of the group KEY: a spec that builds
|
|
188
194
|
* an expected key by hand must use the same rule, or it pins the wrong thing.
|
|
189
195
|
*/
|
|
190
|
-
|
|
196
|
+
function shortenUserAgent(ua) {
|
|
191
197
|
if (ua === null)
|
|
192
|
-
return UNKNOWN;
|
|
198
|
+
return exports.UNKNOWN;
|
|
193
199
|
const trimmed = ua.trim();
|
|
194
200
|
if (trimmed.length === 0)
|
|
195
|
-
return UNKNOWN;
|
|
196
|
-
if (trimmed.length <= USER_AGENT_MAX_CHARS)
|
|
201
|
+
return exports.UNKNOWN;
|
|
202
|
+
if (trimmed.length <= exports.USER_AGENT_MAX_CHARS)
|
|
197
203
|
return trimmed;
|
|
198
|
-
return `${trimmed.slice(0, USER_AGENT_MAX_CHARS)}~`;
|
|
204
|
+
return `${trimmed.slice(0, exports.USER_AGENT_MAX_CHARS)}~`;
|
|
199
205
|
}
|
|
200
206
|
/**
|
|
201
207
|
* The procedures one tRPC HTTP request invokes.
|
|
@@ -214,15 +220,15 @@ export function shortenUserAgent(ua) {
|
|
|
214
220
|
* Returns `[]` for a URL that is not under the tRPC prefix, and for the bare
|
|
215
221
|
* prefix with no path.
|
|
216
222
|
*/
|
|
217
|
-
|
|
223
|
+
function parseTrpcProcedures(url, contentType) {
|
|
218
224
|
const queryAt = url.indexOf('?');
|
|
219
225
|
const pathname = queryAt === -1 ? url : url.slice(0, queryAt);
|
|
220
226
|
const query = queryAt === -1 ? '' : url.slice(queryAt + 1);
|
|
221
|
-
if (!pathname.startsWith(TRPC_URL_PREFIX))
|
|
227
|
+
if (!pathname.startsWith(exports.TRPC_URL_PREFIX))
|
|
222
228
|
return [];
|
|
223
229
|
// The plugin route is `/trpc/:path` - one segment. Anything after a further
|
|
224
230
|
// `/` is not part of the procedure path.
|
|
225
|
-
const rest = pathname.slice(TRPC_URL_PREFIX.length);
|
|
231
|
+
const rest = pathname.slice(exports.TRPC_URL_PREFIX.length);
|
|
226
232
|
const slashAt = rest.indexOf('/');
|
|
227
233
|
const rawPath = slashAt === -1 ? rest : rest.slice(0, slashAt);
|
|
228
234
|
if (rawPath.length === 0)
|
|
@@ -238,14 +244,14 @@ export function parseTrpcProcedures(url, contentType) {
|
|
|
238
244
|
const name = part.trim();
|
|
239
245
|
if (name.length === 0)
|
|
240
246
|
continue;
|
|
241
|
-
if (out.length >= MAX_BATCH_PROCEDURES) {
|
|
247
|
+
if (out.length >= exports.MAX_BATCH_PROCEDURES) {
|
|
242
248
|
overflowed = true;
|
|
243
249
|
continue;
|
|
244
250
|
}
|
|
245
251
|
out.push(name);
|
|
246
252
|
}
|
|
247
253
|
if (overflowed)
|
|
248
|
-
out.push(BATCH_OVERFLOW_PROCEDURE);
|
|
254
|
+
out.push(exports.BATCH_OVERFLOW_PROCEDURE);
|
|
249
255
|
return out;
|
|
250
256
|
}
|
|
251
257
|
/** `decodeURIComponent` throws on a malformed escape. A garbage path is still
|
|
@@ -292,7 +298,7 @@ function hasBatchFlag(query) {
|
|
|
292
298
|
*
|
|
293
299
|
* Disarmed it is one boolean read at every call site and nothing else.
|
|
294
300
|
*/
|
|
295
|
-
|
|
301
|
+
class HttpRequestCensus {
|
|
296
302
|
now;
|
|
297
303
|
schedule;
|
|
298
304
|
/** The ONLY thing a disarmed request path reads. */
|
|
@@ -303,7 +309,7 @@ export class HttpRequestCensus {
|
|
|
303
309
|
armedAt = 0;
|
|
304
310
|
closedAt = 0;
|
|
305
311
|
currentWindowMs = 0;
|
|
306
|
-
currentReportEveryMs = DEFAULT_REPORT_EVERY_MS;
|
|
312
|
+
currentReportEveryMs = exports.DEFAULT_REPORT_EVERY_MS;
|
|
307
313
|
httpRequests = 0;
|
|
308
314
|
batchedRequests = 0;
|
|
309
315
|
procedureCalls = 0;
|
|
@@ -338,9 +344,9 @@ export class HttpRequestCensus {
|
|
|
338
344
|
* Re-arming CLEARS the counts and restarts the window: two overlapping
|
|
339
345
|
* measurements in one table is a table nobody can divide by a duration.
|
|
340
346
|
*/
|
|
341
|
-
arm(windowMs, reportEveryMs = DEFAULT_REPORT_EVERY_MS) {
|
|
342
|
-
const clampedWindow = clamp(windowMs, MIN_WINDOW_MS, MAX_WINDOW_MS);
|
|
343
|
-
const clampedReport = clamp(reportEveryMs, MIN_REPORT_EVERY_MS, clampedWindow);
|
|
347
|
+
arm(windowMs, reportEveryMs = exports.DEFAULT_REPORT_EVERY_MS) {
|
|
348
|
+
const clampedWindow = clamp(windowMs, exports.MIN_WINDOW_MS, exports.MAX_WINDOW_MS);
|
|
349
|
+
const clampedReport = clamp(reportEveryMs, exports.MIN_REPORT_EVERY_MS, clampedWindow);
|
|
344
350
|
this.reset();
|
|
345
351
|
this.generation += 1;
|
|
346
352
|
this.isArmed = true;
|
|
@@ -395,7 +401,7 @@ export class HttpRequestCensus {
|
|
|
395
401
|
if (observation.procedures.length === 0)
|
|
396
402
|
return;
|
|
397
403
|
const userAgent = shortenUserAgent(observation.userAgent);
|
|
398
|
-
const ip = observation.ip ?? UNKNOWN;
|
|
404
|
+
const ip = observation.ip ?? exports.UNKNOWN;
|
|
399
405
|
const { plane, kind, principal } = observation;
|
|
400
406
|
for (const procedure of observation.procedures) {
|
|
401
407
|
if (kind === 'subscription')
|
|
@@ -414,7 +420,7 @@ export class HttpRequestCensus {
|
|
|
414
420
|
group.calls += 1;
|
|
415
421
|
continue;
|
|
416
422
|
}
|
|
417
|
-
if (this.byGroup.size >= MAX_GROUPS) {
|
|
423
|
+
if (this.byGroup.size >= exports.MAX_GROUPS) {
|
|
418
424
|
this.unattributedCalls += 1;
|
|
419
425
|
continue;
|
|
420
426
|
}
|
|
@@ -460,7 +466,7 @@ export class HttpRequestCensus {
|
|
|
460
466
|
this.subscriptionStops += count;
|
|
461
467
|
}
|
|
462
468
|
/** Everything the window measured, busiest first. */
|
|
463
|
-
snapshot(limit = MAX_GROUPS) {
|
|
469
|
+
snapshot(limit = exports.MAX_GROUPS) {
|
|
464
470
|
const elapsedMs = this.elapsedMs();
|
|
465
471
|
const perMin = (calls) => elapsedMs === 0 ? 0 : Math.round((calls * 60_000) / elapsedMs);
|
|
466
472
|
const procedures = [...this.byProcedure.entries()]
|
|
@@ -561,10 +567,10 @@ export class HttpRequestCensus {
|
|
|
561
567
|
bumpCount(existing, plane, kind);
|
|
562
568
|
return;
|
|
563
569
|
}
|
|
564
|
-
if (this.byProcedure.size >= MAX_PROCEDURES) {
|
|
565
|
-
const overflow = this.byProcedure.get(PROCEDURE_OVERFLOW) ?? newCount();
|
|
570
|
+
if (this.byProcedure.size >= exports.MAX_PROCEDURES) {
|
|
571
|
+
const overflow = this.byProcedure.get(exports.PROCEDURE_OVERFLOW) ?? newCount();
|
|
566
572
|
bumpCount(overflow, plane, kind);
|
|
567
|
-
this.byProcedure.set(PROCEDURE_OVERFLOW, overflow);
|
|
573
|
+
this.byProcedure.set(exports.PROCEDURE_OVERFLOW, overflow);
|
|
568
574
|
return;
|
|
569
575
|
}
|
|
570
576
|
const fresh = newCount();
|
|
@@ -603,6 +609,7 @@ export class HttpRequestCensus {
|
|
|
603
609
|
}, this.currentReportEveryMs);
|
|
604
610
|
}
|
|
605
611
|
}
|
|
612
|
+
exports.HttpRequestCensus = HttpRequestCensus;
|
|
606
613
|
/** Per-procedure rows carried on one report line. The router's procedure set
|
|
607
614
|
* is small; this is a guard against a garbage path, not a real cut. */
|
|
608
615
|
const REPORTED_PROCEDURES = 40;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Process-wide holder for the HTTP request census.
|
|
3
4
|
*
|
|
@@ -10,14 +11,17 @@
|
|
|
10
11
|
* Same idiom as `lifecycle-runner.singleton.ts`, minus the init step: this one
|
|
11
12
|
* has no dependencies, so the first reader creates it disarmed.
|
|
12
13
|
*/
|
|
13
|
-
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getHttpRequestCensus = getHttpRequestCensus;
|
|
16
|
+
exports.__resetHttpRequestCensusForTests = __resetHttpRequestCensusForTests;
|
|
17
|
+
const http_request_census_js_1 = require("./http-request-census.js");
|
|
14
18
|
let instance = null;
|
|
15
19
|
/** The process-wide census. Created disarmed on first use. */
|
|
16
|
-
|
|
17
|
-
instance ??= new HttpRequestCensus();
|
|
20
|
+
function getHttpRequestCensus() {
|
|
21
|
+
instance ??= new http_request_census_js_1.HttpRequestCensus();
|
|
18
22
|
return instance;
|
|
19
23
|
}
|
|
20
24
|
/** Test-only: drop the instance so a spec starts from a disarmed census. */
|
|
21
|
-
|
|
25
|
+
function __resetHttpRequestCensusForTests() {
|
|
22
26
|
instance = null;
|
|
23
27
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LOCALIZED_SCHEMA_PATHS = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* The tRPC methods whose answer carries a settings schema (`ConfigUISchema`
|
|
3
6
|
* or `ConfigUISchemaWithValues`) - the ONLY places the hub swaps a `labelKey`
|
|
@@ -8,7 +11,7 @@
|
|
|
8
11
|
* A new cap method that returns a schema is added HERE (and nowhere else): a
|
|
9
12
|
* schema served from a path not listed simply stays English.
|
|
10
13
|
*/
|
|
11
|
-
|
|
14
|
+
exports.LOCALIZED_SCHEMA_PATHS = new Set([
|
|
12
15
|
'addonSettings.getGlobalSettings',
|
|
13
16
|
'addonSettings.getIntegrationSettings',
|
|
14
17
|
'addonSettings.getDeviceSettings',
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.callerCanViewDevice = callerCanViewDevice;
|
|
4
|
+
exports.isBroadEventViewer = isBroadEventViewer;
|
|
5
|
+
exports.filterViewableDeviceIds = filterViewableDeviceIds;
|
|
6
|
+
exports.hasUnrestrictedDeviceView = hasUnrestrictedDeviceView;
|
|
7
|
+
exports.projectListAllForPrincipal = projectListAllForPrincipal;
|
|
8
|
+
exports.scopedEventVisibility = scopedEventVisibility;
|
|
1
9
|
/**
|
|
2
10
|
* Non-admin principal device visibility — the shared answer to "which cameras
|
|
3
11
|
* may this scoped caller see?", reused by two hotfixes:
|
|
@@ -19,10 +27,10 @@
|
|
|
19
27
|
* Pure module — no tRPC machinery — so the spec exercises it directly (same
|
|
20
28
|
* pattern as `scope-access.ts` / `share-view-access.ts`).
|
|
21
29
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const system_1 = require("@camstack/system");
|
|
31
|
+
const types_1 = require("@camstack/types");
|
|
32
|
+
const scope_access_js_1 = require("./scope-access.js");
|
|
33
|
+
const share_view_access_js_1 = require("./share-view-access.js");
|
|
26
34
|
/**
|
|
27
35
|
* Canonical "view this camera" probe. `snapshot.getSnapshot` is a device-scope,
|
|
28
36
|
* `view`-access method every viewer surface needs (the grid-embed cold-start
|
|
@@ -32,7 +40,7 @@ import { projectListAllForDeviceIds } from './share-view-access.js';
|
|
|
32
40
|
*/
|
|
33
41
|
const DEVICE_VIEW_PROBE = 'snapshot.getSnapshot';
|
|
34
42
|
function assertProbeExists() {
|
|
35
|
-
const meta = METHOD_ACCESS_MAP[DEVICE_VIEW_PROBE];
|
|
43
|
+
const meta = system_1.METHOD_ACCESS_MAP[DEVICE_VIEW_PROBE];
|
|
36
44
|
if (!meta || meta.capScope !== 'device' || meta.access !== 'view') {
|
|
37
45
|
throw new Error(`principal-visibility: probe '${DEVICE_VIEW_PROBE}' is not a device-scope view method ` +
|
|
38
46
|
`(codegen drift). Pick another canonical camera-view method.`);
|
|
@@ -44,8 +52,8 @@ assertProbeExists();
|
|
|
44
52
|
* `device:[parent]` → child inheritance through the ancestor walk, exactly as
|
|
45
53
|
* the per-camera middleware does.
|
|
46
54
|
*/
|
|
47
|
-
|
|
48
|
-
return checkScopeAccess(scopes, DEVICE_VIEW_PROBE, { deviceId }, lookup).ok;
|
|
55
|
+
function callerCanViewDevice(scopes, deviceId, lookup) {
|
|
56
|
+
return (0, scope_access_js_1.checkScopeAccess)(scopes, DEVICE_VIEW_PROBE, { deviceId }, lookup).ok;
|
|
49
57
|
}
|
|
50
58
|
/**
|
|
51
59
|
* A scoped principal sees the WHOLE event/telemetry firehose when it holds any
|
|
@@ -60,7 +68,7 @@ export function callerCanViewDevice(scopes, deviceId, lookup) {
|
|
|
60
68
|
* does not satisfy) would blank a surface they are entitled to. Availability and
|
|
61
69
|
* security both point the same way here — broad grant, broad stream.
|
|
62
70
|
*/
|
|
63
|
-
|
|
71
|
+
function isBroadEventViewer(scopes) {
|
|
64
72
|
return scopes.some((s) => s.type === 'category' && s.access.includes('view'));
|
|
65
73
|
}
|
|
66
74
|
/**
|
|
@@ -68,7 +76,7 @@ export function isBroadEventViewer(scopes) {
|
|
|
68
76
|
* share minting: an admin passes `isAdmin` and skips this; a non-admin gets the
|
|
69
77
|
* intersection, and the router refuses when it is empty.
|
|
70
78
|
*/
|
|
71
|
-
|
|
79
|
+
function filterViewableDeviceIds(scopes, requested, lookup) {
|
|
72
80
|
return requested.filter((id) => callerCanViewDevice(scopes, id, lookup));
|
|
73
81
|
}
|
|
74
82
|
/** The device identity an event is attributable to, or null when it carries
|
|
@@ -96,7 +104,7 @@ function eventDeviceId(evt) {
|
|
|
96
104
|
* `category:device[view]` grant, or a device grant with an `all` selector.
|
|
97
105
|
* Such a caller enumerates the fleet unprojected, exactly as before.
|
|
98
106
|
*/
|
|
99
|
-
|
|
107
|
+
function hasUnrestrictedDeviceView(isAdmin, scopes) {
|
|
100
108
|
if (isAdmin)
|
|
101
109
|
return true;
|
|
102
110
|
return scopes.some((s) => s.access.includes('view') &&
|
|
@@ -118,11 +126,11 @@ export function hasUnrestrictedDeviceView(isAdmin, scopes) {
|
|
|
118
126
|
*
|
|
119
127
|
* A caller with unrestricted reach is returned the payload untouched.
|
|
120
128
|
*/
|
|
121
|
-
|
|
129
|
+
function projectListAllForPrincipal(data, isAdmin, scopes, fleet) {
|
|
122
130
|
if (hasUnrestrictedDeviceView(isAdmin, scopes))
|
|
123
131
|
return data;
|
|
124
|
-
const viewable = resolveViewableDeviceIds(scopes, fleet, 'view');
|
|
125
|
-
return projectListAllForDeviceIds(data, viewable);
|
|
132
|
+
const viewable = (0, types_1.resolveViewableDeviceIds)(scopes, fleet, 'view');
|
|
133
|
+
return (0, share_view_access_js_1.projectListAllForDeviceIds)(data, viewable);
|
|
126
134
|
}
|
|
127
135
|
/**
|
|
128
136
|
* Build the event-stream predicate for a NON-share principal (F0.5).
|
|
@@ -136,7 +144,7 @@ export function projectListAllForPrincipal(data, isAdmin, scopes, fleet) {
|
|
|
136
144
|
* Share-view (`csv_*`) principals are NOT handled here — they keep their own,
|
|
137
145
|
* stricter `liveEventInShareScope` filter, applied by the routers first.
|
|
138
146
|
*/
|
|
139
|
-
|
|
147
|
+
function scopedEventVisibility(user, lookup) {
|
|
140
148
|
if (user.isAdmin)
|
|
141
149
|
return null;
|
|
142
150
|
const scopes = user.scopes ?? [];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* The scoped grant that lets an agent update an addon on ITS OWN node (D842).
|
|
3
4
|
*
|
|
@@ -18,6 +19,8 @@
|
|
|
18
19
|
*
|
|
19
20
|
* Every decision, allowed or refused, is written to the auth audit trail.
|
|
20
21
|
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.authorizeRemoteUpdatePackage = authorizeRemoteUpdatePackage;
|
|
21
24
|
function readRequest(input) {
|
|
22
25
|
if (input === null || typeof input !== 'object')
|
|
23
26
|
return null;
|
|
@@ -67,7 +70,7 @@ function decide(callerNodeId, input, deps) {
|
|
|
67
70
|
return { allowed: true, reason: null, detail };
|
|
68
71
|
}
|
|
69
72
|
/** Decide, audit, and return the decision. */
|
|
70
|
-
|
|
73
|
+
async function authorizeRemoteUpdatePackage(callerNodeId, input, deps) {
|
|
71
74
|
const { allowed, reason, detail } = decide(callerNodeId, input, deps);
|
|
72
75
|
await deps.audit({
|
|
73
76
|
action: allowed ? 'agent-addon-update' : 'agent-addon-update-refused',
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEVICE_ENUMERATION_METHODS = void 0;
|
|
4
|
+
exports.referencedDeviceIds = referencedDeviceIds;
|
|
5
|
+
exports.checkScopeAccess = checkScopeAccess;
|
|
1
6
|
/**
|
|
2
7
|
* Pure scope-access matcher.
|
|
3
8
|
*
|
|
@@ -24,8 +29,8 @@
|
|
|
24
29
|
* method's required `access` flavour.
|
|
25
30
|
* 4. No matching scope → FORBIDDEN with a human-readable reason.
|
|
26
31
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
const system_1 = require("@camstack/system");
|
|
33
|
+
const types_1 = require("@camstack/types");
|
|
29
34
|
/**
|
|
30
35
|
* Pull `deviceId` off a tRPC request input. Device-scope cap methods
|
|
31
36
|
* uniformly take `{deviceId: number, ...}` per the DeviceProxy contract,
|
|
@@ -63,13 +68,13 @@ function candidateMetas(deviceId, lookup) {
|
|
|
63
68
|
* the device, or — when the grant inherits at this access — a match on an
|
|
64
69
|
* ancestor. */
|
|
65
70
|
function deviceScopeCovers(scope, access, candidates) {
|
|
66
|
-
const inherit = scopeInherits(scope, access);
|
|
71
|
+
const inherit = (0, types_1.scopeInherits)(scope, access);
|
|
67
72
|
return candidates.some((cand, index) => {
|
|
68
73
|
// index 0 is the device itself (always eligible); ancestors only when the
|
|
69
74
|
// grant inherits.
|
|
70
75
|
if (index > 0 && !inherit)
|
|
71
76
|
return false;
|
|
72
|
-
return deviceSelectorMatches(scope.selector, cand);
|
|
77
|
+
return (0, types_1.deviceSelectorMatches)(scope.selector, cand);
|
|
73
78
|
});
|
|
74
79
|
}
|
|
75
80
|
/** Render a device selector for the human-readable denial reason. */
|
|
@@ -97,7 +102,7 @@ function describeSelector(scope) {
|
|
|
97
102
|
* one-camera token. The pairing is asserted by
|
|
98
103
|
* `scoped-list-projection.spec.ts`.
|
|
99
104
|
*/
|
|
100
|
-
|
|
105
|
+
exports.DEVICE_ENUMERATION_METHODS = new Set(['deviceManager.listAll']);
|
|
101
106
|
/**
|
|
102
107
|
* Every deviceId a request NAMES, per the codegen'd
|
|
103
108
|
* {@link METHOD_DEVICE_SELECTORS}. Absent / null / malformed values are
|
|
@@ -108,8 +113,8 @@ export const DEVICE_ENUMERATION_METHODS = new Set(['deviceManager.listAll']);
|
|
|
108
113
|
* on a device-scoped path has to say WHICH camera
|
|
109
114
|
* (`trpc-error-device-tags.ts`).
|
|
110
115
|
*/
|
|
111
|
-
|
|
112
|
-
const fields = METHOD_DEVICE_SELECTORS[path];
|
|
116
|
+
function referencedDeviceIds(path, input) {
|
|
117
|
+
const fields = types_1.METHOD_DEVICE_SELECTORS[path];
|
|
113
118
|
if (!fields || input === null || typeof input !== 'object')
|
|
114
119
|
return [];
|
|
115
120
|
const out = [];
|
|
@@ -184,8 +189,8 @@ function deviceRefsSatisfied(scopes, path, input, access, lookup) {
|
|
|
184
189
|
}
|
|
185
190
|
return { ok: true };
|
|
186
191
|
}
|
|
187
|
-
|
|
188
|
-
const meta = METHOD_ACCESS_MAP[path];
|
|
192
|
+
function checkScopeAccess(scopes, path, input, lookup) {
|
|
193
|
+
const meta = system_1.METHOD_ACCESS_MAP[path];
|
|
189
194
|
if (!meta) {
|
|
190
195
|
return { ok: false, reason: `Unknown method '${path}' — codegen drift` };
|
|
191
196
|
}
|
|
@@ -221,7 +226,7 @@ export function checkScopeAccess(scopes, path, input, lookup) {
|
|
|
221
226
|
targetMatches =
|
|
222
227
|
refs.length > 0
|
|
223
228
|
? refs.every((id) => deviceScopeCovers(s, meta.access, candidateMetas(id, lookup)))
|
|
224
|
-
: DEVICE_ENUMERATION_METHODS.has(path);
|
|
229
|
+
: exports.DEVICE_ENUMERATION_METHODS.has(path);
|
|
225
230
|
break;
|
|
226
231
|
}
|
|
227
232
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* The capabilities the SERVER provides — routers mounted from
|
|
3
4
|
* `buildServerProviders` (`trpc.router.ts`) rather than from an addon.
|
|
@@ -13,11 +14,14 @@
|
|
|
13
14
|
* provided the cap, no addon did, and the bridge list had been copied by
|
|
14
15
|
* hand before the cap existed.
|
|
15
16
|
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ADDON_BACKED_SERVER_CAP_NAMES = exports.HUB_SERVICE_CAP_NAMES = void 0;
|
|
19
|
+
exports.capNameToNamespace = capNameToNamespace;
|
|
16
20
|
/**
|
|
17
21
|
* Caps served by a hub SERVICE. No addon ever registers a provider for them,
|
|
18
22
|
* so a forked runner can reach them only over the `$core-caps` bridge.
|
|
19
23
|
*/
|
|
20
|
-
|
|
24
|
+
exports.HUB_SERVICE_CAP_NAMES = [
|
|
21
25
|
'network-quality',
|
|
22
26
|
'system',
|
|
23
27
|
'toast',
|
|
@@ -33,8 +37,8 @@ export const HUB_SERVICE_CAP_NAMES = [
|
|
|
33
37
|
* cap; a resolver miss means the addon is down, not that the bridge should
|
|
34
38
|
* answer — so they are deliberately NOT bridged.
|
|
35
39
|
*/
|
|
36
|
-
|
|
40
|
+
exports.ADDON_BACKED_SERVER_CAP_NAMES = ['webrtc-session'];
|
|
37
41
|
/** kebab-case cap name → the camelCase appRouter namespace it is mounted as. */
|
|
38
|
-
|
|
42
|
+
function capNameToNamespace(capName) {
|
|
39
43
|
return capName.replace(/-([a-z])/g, (_m, c) => c.toUpperCase());
|
|
40
44
|
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SHARE_SCOPE_PROJECTED_METHODS = void 0;
|
|
4
|
+
exports.checkShareViewAccess = checkShareViewAccess;
|
|
5
|
+
exports.projectListAllForShareScope = projectListAllForShareScope;
|
|
6
|
+
exports.projectListAllForDeviceIds = projectListAllForDeviceIds;
|
|
7
|
+
exports.projectShareScopeRows = projectShareScopeRows;
|
|
8
|
+
exports.liveEventInShareScope = liveEventInShareScope;
|
|
1
9
|
/**
|
|
2
10
|
* Methods callable WITHOUT a per-device check — their input carries no
|
|
3
11
|
* deviceId. `live.onEvent` is here because its input is only a category;
|
|
@@ -127,7 +135,7 @@ function checkEventsViewAccess(scope, path, input) {
|
|
|
127
135
|
}
|
|
128
136
|
return { ok: false, reason: `'${path}' is not available to share-view tokens` };
|
|
129
137
|
}
|
|
130
|
-
|
|
138
|
+
function checkShareViewAccess(scope, path, input) {
|
|
131
139
|
if (scope.kind === 'events-view') {
|
|
132
140
|
return checkEventsViewAccess(scope, path, input);
|
|
133
141
|
}
|
|
@@ -166,7 +174,7 @@ export function checkShareViewAccess(scope, path, input) {
|
|
|
166
174
|
* onto the whitelisted row (never the raw device — fail closed on fields).
|
|
167
175
|
* Non-array payloads pass through untouched (the route errored upstream).
|
|
168
176
|
*/
|
|
169
|
-
|
|
177
|
+
function projectListAllForShareScope(data, scope) {
|
|
170
178
|
return projectListAllForDeviceIds(data, new Set(scope.deviceIds));
|
|
171
179
|
}
|
|
172
180
|
/**
|
|
@@ -179,7 +187,7 @@ export function projectListAllForShareScope(data, scope) {
|
|
|
179
187
|
* would be two chances to forget `config` — which carries the camera
|
|
180
188
|
* credentials in plaintext.
|
|
181
189
|
*/
|
|
182
|
-
|
|
190
|
+
function projectListAllForDeviceIds(data, allowed) {
|
|
183
191
|
if (!Array.isArray(data))
|
|
184
192
|
return data;
|
|
185
193
|
const rows = [];
|
|
@@ -227,7 +235,7 @@ export function projectListAllForDeviceIds(data, allowed) {
|
|
|
227
235
|
* Anything that is not a row payload passes through untouched (the route
|
|
228
236
|
* errored upstream, and rewriting an error into `[]` would hide it).
|
|
229
237
|
*/
|
|
230
|
-
|
|
238
|
+
function projectShareScopeRows(data, scope) {
|
|
231
239
|
const allowed = new Set(scope.deviceIds);
|
|
232
240
|
const keep = (row) => {
|
|
233
241
|
if (row === null || typeof row !== 'object')
|
|
@@ -248,7 +256,7 @@ export function projectShareScopeRows(data, scope) {
|
|
|
248
256
|
/** Paths whose RESPONSE must be cut to the share scope before it leaves the
|
|
249
257
|
* server. Kept beside the enumeration so a method added to one and forgotten
|
|
250
258
|
* in the other is visible in a single file. */
|
|
251
|
-
|
|
259
|
+
exports.SHARE_SCOPE_PROJECTED_METHODS = new Set([
|
|
252
260
|
'pipelineAnalytics.listRecentTracks',
|
|
253
261
|
'pipelineAnalytics.listEventKindsBatch',
|
|
254
262
|
'pipelineAnalytics.searchObjectEvents',
|
|
@@ -261,7 +269,7 @@ export const SHARE_SCOPE_PROJECTED_METHODS = new Set([
|
|
|
261
269
|
* • `data.deviceId` — addon-sourced per-device telemetry
|
|
262
270
|
* (e.g. `pipeline.camera-metrics-snapshot`).
|
|
263
271
|
*/
|
|
264
|
-
|
|
272
|
+
function liveEventInShareScope(evt, allowedDeviceIds) {
|
|
265
273
|
const sourceId = evt.source?.id;
|
|
266
274
|
if (typeof sourceId === 'number' && allowedDeviceIds.has(sourceId))
|
|
267
275
|
return true;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* A tRPC error line about a camera has to say WHICH camera.
|
|
3
4
|
*
|
|
@@ -20,16 +21,18 @@
|
|
|
20
21
|
* one call, not N events. `deviceCount` is what tells a reader the line is
|
|
21
22
|
* about a batch rather than a single camera.
|
|
22
23
|
*/
|
|
23
|
-
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.trpcErrorDeviceTags = trpcErrorDeviceTags;
|
|
26
|
+
const scope_access_js_1 = require("./scope-access.js");
|
|
24
27
|
/**
|
|
25
28
|
* Device tags for a tRPC error line. Returns `{}` — never a partial or a
|
|
26
29
|
* placeholder id — when the path names no device: a system-scope call is not
|
|
27
30
|
* "about device 0".
|
|
28
31
|
*/
|
|
29
|
-
|
|
32
|
+
function trpcErrorDeviceTags(path, input) {
|
|
30
33
|
if (path === undefined)
|
|
31
34
|
return {};
|
|
32
|
-
const ids = referencedDeviceIds(path, input);
|
|
35
|
+
const ids = (0, scope_access_js_1.referencedDeviceIds)(path, input);
|
|
33
36
|
const first = ids[0];
|
|
34
37
|
if (first === undefined)
|
|
35
38
|
return {};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readCredentialIdentity = readCredentialIdentity;
|
|
4
|
+
exports.describeTrpcPrincipal = describeTrpcPrincipal;
|
|
1
5
|
/**
|
|
2
6
|
* Read the credential's self-description off verified claims.
|
|
3
7
|
*
|
|
@@ -11,7 +15,7 @@
|
|
|
11
15
|
* that a future token type could carry one meaning something else entirely, and
|
|
12
16
|
* mislabelling a principal in a security log is worse than not labelling it.
|
|
13
17
|
*/
|
|
14
|
-
|
|
18
|
+
function readCredentialIdentity(claims) {
|
|
15
19
|
const kind = Reflect.get(claims, 'kind');
|
|
16
20
|
if (kind !== 'sso-bridge')
|
|
17
21
|
return {};
|
|
@@ -34,7 +38,7 @@ export function readCredentialIdentity(claims) {
|
|
|
34
38
|
* apocaliss92 (oauth-access session=910a6179-…)
|
|
35
39
|
* apocaliss92 (session)
|
|
36
40
|
*/
|
|
37
|
-
|
|
41
|
+
function describeTrpcPrincipal(user) {
|
|
38
42
|
// Never blank: an empty field reads as a logging defect rather than as an
|
|
39
43
|
// unauthenticated request, and the two need different fixes.
|
|
40
44
|
if (!user)
|