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