@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,39 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ShareTokenService = exports.ShareTokenRecordSchema = exports.ShareTokenScopeSchema = exports.SHARE_TOKEN_MAX_DEVICES = exports.SHARE_TOKEN_TTL_DEFAULT_SEC = exports.SHARE_TOKEN_TTL_MAX_SEC = exports.SHARE_TOKEN_TTL_MIN_SEC = exports.SHARE_TOKEN_PREFIX = void 0;
|
|
37
1
|
/**
|
|
38
2
|
* ShareTokenService — scoped, TTL'd VIEW tokens for standalone share links
|
|
39
3
|
* (grid rework R6: the embed page opened by a third party authenticates with
|
|
@@ -58,9 +22,10 @@ exports.ShareTokenService = exports.ShareTokenRecordSchema = exports.ShareTokenS
|
|
|
58
22
|
* live in, reached directly instead of over the settings-store cap since
|
|
59
23
|
* this service is hub-resident). Collection: `share_view_tokens`.
|
|
60
24
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
25
|
+
import * as crypto from 'node:crypto';
|
|
26
|
+
import { z } from 'zod';
|
|
27
|
+
import { SHARE_VIEW_KINDS, userError } from '@camstack/types';
|
|
28
|
+
import { coreAuthRecordKinds } from './record-kinds.js';
|
|
64
29
|
/**
|
|
65
30
|
* @durable class=config owner=core-auth
|
|
66
31
|
* write="a user mints a share link; and a best-effort lastUsedAt touch on every successful validation"
|
|
@@ -91,12 +56,12 @@ const SHARE_TOKENS_INDEXES = [
|
|
|
91
56
|
{ name: 'idx_share_view_tokens_user', columns: ['userId'] },
|
|
92
57
|
];
|
|
93
58
|
/** Wire prefix — `csv_` = CamStack Share View (cf. `cst_` scoped tokens). */
|
|
94
|
-
|
|
59
|
+
export const SHARE_TOKEN_PREFIX = 'csv_';
|
|
95
60
|
// ── TTL / scope bounds (enforced at mint, re-checked by the router schema) ──
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
61
|
+
export const SHARE_TOKEN_TTL_MIN_SEC = 60;
|
|
62
|
+
export const SHARE_TOKEN_TTL_MAX_SEC = 30 * 24 * 60 * 60; // 30 days
|
|
63
|
+
export const SHARE_TOKEN_TTL_DEFAULT_SEC = 7 * 24 * 60 * 60; // 7 days
|
|
64
|
+
export const SHARE_TOKEN_MAX_DEVICES = 64;
|
|
100
65
|
/**
|
|
101
66
|
* What a share token is allowed to see. Keyed on `kind` so future share
|
|
102
67
|
* surfaces (single-camera view, recording clip, …) extend the set without
|
|
@@ -115,9 +80,9 @@ exports.SHARE_TOKEN_MAX_DEVICES = 64;
|
|
|
115
80
|
* Neither kind is a superset of the other — an events link cannot open a
|
|
116
81
|
* WebRTC session, and a grid link cannot read a track.
|
|
117
82
|
*/
|
|
118
|
-
|
|
119
|
-
kind:
|
|
120
|
-
deviceIds:
|
|
83
|
+
export const ShareTokenScopeSchema = z.object({
|
|
84
|
+
kind: z.enum(SHARE_VIEW_KINDS),
|
|
85
|
+
deviceIds: z.array(z.number().int().nonnegative()).min(1).max(SHARE_TOKEN_MAX_DEVICES),
|
|
121
86
|
/**
|
|
122
87
|
* TALK-BACK, opt-in at mint time. Absent means OFF, and that is the whole
|
|
123
88
|
* point: a share link is handed to third parties, so the difference between
|
|
@@ -133,27 +98,50 @@ exports.ShareTokenScopeSchema = zod_1.z.object({
|
|
|
133
98
|
* It widens WHAT may be called, never WHICH cameras — `deviceIds` still
|
|
134
99
|
* gates every talk call.
|
|
135
100
|
*/
|
|
136
|
-
talk:
|
|
101
|
+
talk: z.boolean().optional(),
|
|
137
102
|
});
|
|
138
103
|
/** Persisted record — never leaves the server with `tokenHash` attached. */
|
|
139
|
-
|
|
140
|
-
id:
|
|
104
|
+
export const ShareTokenRecordSchema = z.object({
|
|
105
|
+
id: z.string(),
|
|
141
106
|
/** The user that minted the share link (owner — may revoke it). */
|
|
142
|
-
userId:
|
|
143
|
-
tokenHash:
|
|
107
|
+
userId: z.string(),
|
|
108
|
+
tokenHash: z.string(),
|
|
144
109
|
/** First 12 chars of the raw token — display/audit label only. */
|
|
145
|
-
tokenPrefix:
|
|
146
|
-
scope:
|
|
147
|
-
createdAt:
|
|
110
|
+
tokenPrefix: z.string(),
|
|
111
|
+
scope: ShareTokenScopeSchema,
|
|
112
|
+
createdAt: z.number(),
|
|
148
113
|
/** Epoch ms — or `null` for a never-expiring token (explicit choice at mint). */
|
|
149
|
-
expiresAt:
|
|
150
|
-
lastUsedAt:
|
|
114
|
+
expiresAt: z.number().nullable(),
|
|
115
|
+
lastUsedAt: z.number().optional(),
|
|
151
116
|
});
|
|
152
117
|
function parseShareToken(data) {
|
|
153
|
-
const parsed =
|
|
118
|
+
const parsed = ShareTokenRecordSchema.safeParse(data);
|
|
154
119
|
return parsed.success ? parsed.data : null;
|
|
155
120
|
}
|
|
156
|
-
|
|
121
|
+
function recordToBody(record) {
|
|
122
|
+
const { id: _id, ...body } = record;
|
|
123
|
+
return body;
|
|
124
|
+
}
|
|
125
|
+
function rowToRecord(id, body) {
|
|
126
|
+
return ShareTokenRecordSchema.safeParse({ id, ...body }).data ?? null;
|
|
127
|
+
}
|
|
128
|
+
async function readAllShareTokenRows(kind, where) {
|
|
129
|
+
const out = [];
|
|
130
|
+
let cursor;
|
|
131
|
+
for (let page = 0; page < 100; page += 1) {
|
|
132
|
+
const answer = await kind.query({
|
|
133
|
+
...(where === undefined ? {} : { where }),
|
|
134
|
+
limit: 1000,
|
|
135
|
+
...(cursor === undefined ? {} : { cursor }),
|
|
136
|
+
});
|
|
137
|
+
out.push(...answer.records);
|
|
138
|
+
if (answer.nextCursor === null)
|
|
139
|
+
return out;
|
|
140
|
+
cursor = answer.nextCursor;
|
|
141
|
+
}
|
|
142
|
+
throw new Error('share-view-tokens: row count exceeds pagination bound');
|
|
143
|
+
}
|
|
144
|
+
export class ShareTokenService {
|
|
157
145
|
getStore;
|
|
158
146
|
logger;
|
|
159
147
|
/**
|
|
@@ -162,9 +150,59 @@ class ShareTokenService {
|
|
|
162
150
|
* the sqlite builtin registers after this service is constructed).
|
|
163
151
|
*/
|
|
164
152
|
collectionDeclared = false;
|
|
165
|
-
|
|
153
|
+
resolveKind;
|
|
154
|
+
constructor(getStore, logger = null, resolveKind = () => null) {
|
|
166
155
|
this.getStore = getStore;
|
|
167
156
|
this.logger = logger;
|
|
157
|
+
this.resolveKind = resolveKind;
|
|
158
|
+
}
|
|
159
|
+
/** Hub wiring after `records.forOwner('core-auth').declare(...)`. */
|
|
160
|
+
bindShareTokensKind(resolver) {
|
|
161
|
+
this.resolveKind = resolver;
|
|
162
|
+
this.collectionDeclared = true;
|
|
163
|
+
}
|
|
164
|
+
kind() {
|
|
165
|
+
return this.resolveKind();
|
|
166
|
+
}
|
|
167
|
+
async findById(id) {
|
|
168
|
+
const kind = this.kind();
|
|
169
|
+
if (kind !== null) {
|
|
170
|
+
const row = await kind.get(id);
|
|
171
|
+
return row === null ? null : rowToRecord(row.id, row.data);
|
|
172
|
+
}
|
|
173
|
+
const results = await (await this.store()).query({
|
|
174
|
+
collection: SHARE_TOKENS_COLLECTION,
|
|
175
|
+
filter: { where: { id } },
|
|
176
|
+
});
|
|
177
|
+
const first = results[0];
|
|
178
|
+
return first === undefined ? null : parseShareToken(first.data);
|
|
179
|
+
}
|
|
180
|
+
async persistRecord(record) {
|
|
181
|
+
const kind = this.kind();
|
|
182
|
+
if (kind !== null) {
|
|
183
|
+
const parsed = coreAuthRecordKinds['share-view-tokens'].schema.safeParse(recordToBody(record));
|
|
184
|
+
if (!parsed.success)
|
|
185
|
+
throw new Error(parsed.error.message);
|
|
186
|
+
await kind.put({
|
|
187
|
+
id: record.id,
|
|
188
|
+
expiresAt: record.expiresAt ?? undefined,
|
|
189
|
+
data: parsed.data,
|
|
190
|
+
});
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
await (await this.store()).update({
|
|
194
|
+
collection: SHARE_TOKENS_COLLECTION,
|
|
195
|
+
id: record.id,
|
|
196
|
+
data: { ...record },
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async deleteById(id) {
|
|
200
|
+
const kind = this.kind();
|
|
201
|
+
if (kind !== null) {
|
|
202
|
+
await kind.delete(id);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
await (await this.store()).delete({ collection: SHARE_TOKENS_COLLECTION, key: id });
|
|
168
206
|
}
|
|
169
207
|
/**
|
|
170
208
|
* Resolve the backend AND ensure `share_view_tokens` is declared before
|
|
@@ -174,6 +212,13 @@ class ShareTokenService {
|
|
|
174
212
|
* rows keep working with no migration.
|
|
175
213
|
*/
|
|
176
214
|
async store() {
|
|
215
|
+
if (this.kind() !== null) {
|
|
216
|
+
const store = this.getStore();
|
|
217
|
+
if (!store) {
|
|
218
|
+
throw new Error('Share tokens unavailable — settings backend not ready');
|
|
219
|
+
}
|
|
220
|
+
return store;
|
|
221
|
+
}
|
|
177
222
|
const store = this.getStore();
|
|
178
223
|
if (!store) {
|
|
179
224
|
throw new Error('Share tokens unavailable — settings backend not ready');
|
|
@@ -199,16 +244,16 @@ class ShareTokenService {
|
|
|
199
244
|
* Returns the RAW token exactly once; only its hash is persisted.
|
|
200
245
|
*/
|
|
201
246
|
async create(input) {
|
|
202
|
-
const scope =
|
|
203
|
-
const ttlSec = input.ttlSec ??
|
|
247
|
+
const scope = ShareTokenScopeSchema.parse(input.scope);
|
|
248
|
+
const ttlSec = input.ttlSec ?? SHARE_TOKEN_TTL_DEFAULT_SEC;
|
|
204
249
|
if (ttlSec !== 'never' &&
|
|
205
250
|
(!Number.isInteger(ttlSec) ||
|
|
206
|
-
ttlSec <
|
|
207
|
-
ttlSec >
|
|
251
|
+
ttlSec < SHARE_TOKEN_TTL_MIN_SEC ||
|
|
252
|
+
ttlSec > SHARE_TOKEN_TTL_MAX_SEC)) {
|
|
208
253
|
throw new Error(`Share token TTL out of bounds — got ${ttlSec}s, allowed ` +
|
|
209
|
-
`[${
|
|
254
|
+
`[${SHARE_TOKEN_TTL_MIN_SEC}s, ${SHARE_TOKEN_TTL_MAX_SEC}s] or 'never'`);
|
|
210
255
|
}
|
|
211
|
-
const rawToken = `${
|
|
256
|
+
const rawToken = `${SHARE_TOKEN_PREFIX}${crypto.randomBytes(32).toString('hex')}`;
|
|
212
257
|
const now = Date.now();
|
|
213
258
|
const record = {
|
|
214
259
|
id: crypto.randomUUID(),
|
|
@@ -219,10 +264,23 @@ class ShareTokenService {
|
|
|
219
264
|
createdAt: now,
|
|
220
265
|
expiresAt: ttlSec === 'never' ? null : now + ttlSec * 1000,
|
|
221
266
|
};
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
267
|
+
const kind = this.kind();
|
|
268
|
+
if (kind !== null) {
|
|
269
|
+
const parsed = coreAuthRecordKinds['share-view-tokens'].schema.safeParse(recordToBody(record));
|
|
270
|
+
if (!parsed.success)
|
|
271
|
+
throw new Error(parsed.error.message);
|
|
272
|
+
await kind.put({
|
|
273
|
+
id: record.id,
|
|
274
|
+
expiresAt: record.expiresAt ?? undefined,
|
|
275
|
+
data: parsed.data,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
await (await this.store()).insert({
|
|
280
|
+
collection: SHARE_TOKENS_COLLECTION,
|
|
281
|
+
record: { id: record.id, data: { ...record } },
|
|
282
|
+
});
|
|
283
|
+
}
|
|
226
284
|
this.logger?.info('Share token minted', {
|
|
227
285
|
meta: {
|
|
228
286
|
id: record.id,
|
|
@@ -240,18 +298,25 @@ class ShareTokenService {
|
|
|
240
298
|
* Never throws on bad input — the auth boundary treats `null` as 401.
|
|
241
299
|
*/
|
|
242
300
|
async validate(rawToken) {
|
|
243
|
-
if (!rawToken.startsWith(
|
|
301
|
+
if (!rawToken.startsWith(SHARE_TOKEN_PREFIX))
|
|
244
302
|
return null;
|
|
245
303
|
const tokenHash = crypto.createHash('sha256').update(rawToken).digest('hex');
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
304
|
+
const kind = this.kind();
|
|
305
|
+
let record = null;
|
|
306
|
+
if (kind !== null) {
|
|
307
|
+
const page = await kind.query({ where: { tokenHash }, limit: 1 });
|
|
308
|
+
const row = page.records[0];
|
|
309
|
+
record = row === undefined ? null : rowToRecord(row.id, row.data);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
const results = await (await this.store()).query({
|
|
313
|
+
collection: SHARE_TOKENS_COLLECTION,
|
|
314
|
+
filter: { where: { tokenHash } },
|
|
315
|
+
});
|
|
316
|
+
const first = results[0];
|
|
317
|
+
record = first === undefined ? null : parseShareToken(first.data);
|
|
318
|
+
}
|
|
319
|
+
if (record === null)
|
|
255
320
|
return null;
|
|
256
321
|
// `expiresAt: null` = never expires (explicit mint-time choice);
|
|
257
322
|
// revocation remains the kill switch for those.
|
|
@@ -270,42 +335,30 @@ class ShareTokenService {
|
|
|
270
335
|
*/
|
|
271
336
|
async extend(input) {
|
|
272
337
|
if (!Number.isInteger(input.ttlSec) ||
|
|
273
|
-
input.ttlSec <
|
|
274
|
-
input.ttlSec >
|
|
338
|
+
input.ttlSec < SHARE_TOKEN_TTL_MIN_SEC ||
|
|
339
|
+
input.ttlSec > SHARE_TOKEN_TTL_MAX_SEC) {
|
|
275
340
|
throw new Error(`Share token TTL out of bounds — got ${input.ttlSec}s, allowed ` +
|
|
276
|
-
`[${
|
|
277
|
-
}
|
|
278
|
-
const results = await (await this.store()).query({
|
|
279
|
-
collection: SHARE_TOKENS_COLLECTION,
|
|
280
|
-
filter: { where: { id: input.id } },
|
|
281
|
-
});
|
|
282
|
-
const first = results[0];
|
|
283
|
-
if (!first) {
|
|
284
|
-
throw (0, types_1.userError)('auth.share-token-not-found', { id: input.id }, `Share token not found: ${input.id}`);
|
|
341
|
+
`[${SHARE_TOKEN_TTL_MIN_SEC}s, ${SHARE_TOKEN_TTL_MAX_SEC}s]`);
|
|
285
342
|
}
|
|
286
|
-
const record =
|
|
287
|
-
if (
|
|
288
|
-
throw
|
|
343
|
+
const record = await this.findById(input.id);
|
|
344
|
+
if (record === null) {
|
|
345
|
+
throw userError('auth.share-token-not-found', { id: input.id }, `Share token not found: ${input.id}`);
|
|
289
346
|
}
|
|
290
347
|
if (!input.callerIsAdmin && record.userId !== input.callerUserId) {
|
|
291
|
-
throw
|
|
348
|
+
throw userError('auth.share-owner-only-extend', undefined, 'Only the token owner or an admin can extend a share token');
|
|
292
349
|
}
|
|
293
350
|
if (record.expiresAt === null) {
|
|
294
|
-
throw
|
|
351
|
+
throw userError('auth.share-never-expiring-extend', undefined, 'A never-expiring share token cannot be extended');
|
|
295
352
|
}
|
|
296
353
|
const now = Date.now();
|
|
297
354
|
if (now > record.expiresAt) {
|
|
298
|
-
throw
|
|
355
|
+
throw userError('server.share-token-expired', { id: String(input.id) }, `Share token expired: ${input.id}`);
|
|
299
356
|
}
|
|
300
357
|
const updated = {
|
|
301
358
|
...record,
|
|
302
359
|
expiresAt: now + input.ttlSec * 1000,
|
|
303
360
|
};
|
|
304
|
-
await
|
|
305
|
-
collection: SHARE_TOKENS_COLLECTION,
|
|
306
|
-
id: record.id,
|
|
307
|
-
data: { ...updated },
|
|
308
|
-
});
|
|
361
|
+
await this.persistRecord(updated);
|
|
309
362
|
this.logger?.info('Share token extended', {
|
|
310
363
|
meta: {
|
|
311
364
|
id: updated.id,
|
|
@@ -321,23 +374,13 @@ class ShareTokenService {
|
|
|
321
374
|
* permission mismatch so the router surfaces a FORBIDDEN.
|
|
322
375
|
*/
|
|
323
376
|
async revoke(input) {
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
filter: { where: { id: input.id } },
|
|
327
|
-
});
|
|
328
|
-
const first = results[0];
|
|
329
|
-
if (!first)
|
|
377
|
+
const record = await this.findById(input.id);
|
|
378
|
+
if (record === null)
|
|
330
379
|
return false;
|
|
331
|
-
const record = parseShareToken(first.data);
|
|
332
|
-
if (!record) {
|
|
333
|
-
// Corrupt record — delete it regardless (it can never validate).
|
|
334
|
-
await (await this.store()).delete({ collection: SHARE_TOKENS_COLLECTION, key: input.id });
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
380
|
if (!input.callerIsAdmin && record.userId !== input.callerUserId) {
|
|
338
|
-
throw
|
|
381
|
+
throw userError('auth.share-owner-only-revoke', undefined, 'Only the token owner or an admin can revoke a share token');
|
|
339
382
|
}
|
|
340
|
-
await
|
|
383
|
+
await this.deleteById(input.id);
|
|
341
384
|
this.logger?.info('Share token revoked', {
|
|
342
385
|
meta: { id: record.id, byUserId: input.callerUserId },
|
|
343
386
|
});
|
|
@@ -345,6 +388,13 @@ class ShareTokenService {
|
|
|
345
388
|
}
|
|
346
389
|
/** Every share token minted by `userId`, expired ones included. */
|
|
347
390
|
async listForUser(userId) {
|
|
391
|
+
const kind = this.kind();
|
|
392
|
+
if (kind !== null) {
|
|
393
|
+
const rows = await readAllShareTokenRows(kind, { userId });
|
|
394
|
+
return rows
|
|
395
|
+
.map((row) => rowToRecord(row.id, row.data))
|
|
396
|
+
.filter((r) => r !== null);
|
|
397
|
+
}
|
|
348
398
|
const results = await (await this.store()).query({
|
|
349
399
|
collection: SHARE_TOKENS_COLLECTION,
|
|
350
400
|
filter: { where: { userId } },
|
|
@@ -353,6 +403,13 @@ class ShareTokenService {
|
|
|
353
403
|
}
|
|
354
404
|
/** All share tokens (admin listing). */
|
|
355
405
|
async listAll() {
|
|
406
|
+
const kind = this.kind();
|
|
407
|
+
if (kind !== null) {
|
|
408
|
+
const rows = await readAllShareTokenRows(kind);
|
|
409
|
+
return rows
|
|
410
|
+
.map((row) => rowToRecord(row.id, row.data))
|
|
411
|
+
.filter((r) => r !== null);
|
|
412
|
+
}
|
|
356
413
|
const results = await (await this.store()).query({
|
|
357
414
|
collection: SHARE_TOKENS_COLLECTION,
|
|
358
415
|
filter: {},
|
|
@@ -360,11 +417,6 @@ class ShareTokenService {
|
|
|
360
417
|
return results.map((r) => parseShareToken(r.data)).filter((r) => r !== null);
|
|
361
418
|
}
|
|
362
419
|
async touchLastUsed(record) {
|
|
363
|
-
await (
|
|
364
|
-
collection: SHARE_TOKENS_COLLECTION,
|
|
365
|
-
id: record.id,
|
|
366
|
-
data: { ...record, lastUsedAt: Date.now() },
|
|
367
|
-
});
|
|
420
|
+
await this.persistRecord({ ...record, lastUsedAt: Date.now() });
|
|
368
421
|
}
|
|
369
422
|
}
|
|
370
|
-
exports.ShareTokenService = ShareTokenService;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* CapabilityService — NestJS-injectable wrapper around the CapabilityRegistry.
|
|
4
3
|
*
|
|
5
4
|
* Server services inject this instead of accessing the registry directly.
|
|
6
5
|
* The registry reference is set once during boot by AddonRegistryService.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
exports.CapabilityService = void 0;
|
|
10
|
-
class CapabilityService {
|
|
7
|
+
export class CapabilityService {
|
|
11
8
|
registry = null;
|
|
12
9
|
/** Called once during boot by AddonRegistryService to wire the registry */
|
|
13
10
|
setRegistry(registry) {
|
|
@@ -55,4 +52,3 @@ class CapabilityService {
|
|
|
55
52
|
return this.registry?.resolveCollectionForDevice(capability, deviceId) ?? [];
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
|
-
exports.CapabilityService = CapabilityService;
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RUNTIME_DEFAULTS = exports.bootstrapSchema = void 0;
|
|
4
1
|
// Re-export from @camstack/system
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "bootstrapSchema", { enumerable: true, get: function () { return system_1.bootstrapSchema; } });
|
|
7
|
-
Object.defineProperty(exports, "RUNTIME_DEFAULTS", { enumerable: true, get: function () { return system_1.RUNTIME_DEFAULTS; } });
|
|
2
|
+
export { bootstrapSchema, RUNTIME_DEFAULTS } from '@camstack/system';
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ConfigService = void 0;
|
|
4
|
-
const system_1 = require("@camstack/system");
|
|
5
|
-
class ConfigService extends system_1.ConfigManager {
|
|
1
|
+
import { ConfigManager } from '@camstack/system';
|
|
2
|
+
export class ConfigService extends ConfigManager {
|
|
6
3
|
}
|
|
7
|
-
exports.ConfigService = ConfigService;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EventBusService = void 0;
|
|
4
|
-
const system_1 = require("@camstack/system");
|
|
1
|
+
import { getBrokerEventBus } from '@camstack/system';
|
|
5
2
|
/**
|
|
6
3
|
* Hub-side event bus. Pre-broker boot the service buffers nothing —
|
|
7
4
|
* subscribers / emits are no-ops until `attachBroker` lands the
|
|
@@ -19,7 +16,7 @@ const system_1 = require("@camstack/system");
|
|
|
19
16
|
* `systemEvents.subscribe`, which is enough for the operator to see
|
|
20
17
|
* continuity across page reloads.
|
|
21
18
|
*/
|
|
22
|
-
class EventBusService {
|
|
19
|
+
export class EventBusService {
|
|
23
20
|
broker = null;
|
|
24
21
|
inner = null;
|
|
25
22
|
// Used only as a loose ring buffer for the very first events emitted
|
|
@@ -41,7 +38,7 @@ class EventBusService {
|
|
|
41
38
|
// addon runners + remote agents leave `retainRecent` false: their events
|
|
42
39
|
// are one-shot (fire-and-forget), fanned out to local subscribers but never
|
|
43
40
|
// accumulated, so their heap can't grow an unbounded recent[] backlog.
|
|
44
|
-
const inner =
|
|
41
|
+
const inner = getBrokerEventBus(broker, { retainRecent: true });
|
|
45
42
|
this.inner = inner;
|
|
46
43
|
// Replay deferred subscriptions onto the real bus.
|
|
47
44
|
for (const sub of this.deferredSubs) {
|
|
@@ -85,4 +82,3 @@ class EventBusService {
|
|
|
85
82
|
return this.inner?.getRecent(filter, limit) ?? [];
|
|
86
83
|
}
|
|
87
84
|
}
|
|
88
|
-
exports.EventBusService = EventBusService;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.FeatureService = void 0;
|
|
4
|
-
const system_1 = require("@camstack/system");
|
|
5
|
-
class FeatureService extends system_1.FeatureManager {
|
|
1
|
+
import { FeatureManager } from '@camstack/system';
|
|
2
|
+
export class FeatureService extends FeatureManager {
|
|
6
3
|
}
|
|
7
|
-
exports.FeatureService = FeatureService;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Process-wide singleton holder for the lifecycle job runner.
|
|
4
3
|
*
|
|
@@ -8,19 +7,15 @@
|
|
|
8
7
|
* at boot (from the `AddonPackageService` + event bus, wired in `manual-boot`)
|
|
9
8
|
* and exposes it to every consumer.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
exports.initLifecycleRunner = initLifecycleRunner;
|
|
13
|
-
exports.getLifecycleRunner = getLifecycleRunner;
|
|
14
|
-
exports.__resetLifecycleRunnerForTests = __resetLifecycleRunnerForTests;
|
|
15
|
-
const lifecycle_job_runner_js_1 = require("../../api/core/lifecycle-job-runner.js");
|
|
10
|
+
import { createLifecycleJobRunner, } from '../../api/core/lifecycle-job-runner.js';
|
|
16
11
|
let instance = null;
|
|
17
12
|
/**
|
|
18
13
|
* Build the runner once. Idempotent: a second call returns the already-built
|
|
19
14
|
* instance and ignores the new deps (it does NOT rebuild).
|
|
20
15
|
*/
|
|
21
|
-
function initLifecycleRunner(deps) {
|
|
16
|
+
export function initLifecycleRunner(deps) {
|
|
22
17
|
if (instance === null) {
|
|
23
|
-
instance =
|
|
18
|
+
instance = createLifecycleJobRunner(deps);
|
|
24
19
|
}
|
|
25
20
|
return instance;
|
|
26
21
|
}
|
|
@@ -28,13 +23,13 @@ function initLifecycleRunner(deps) {
|
|
|
28
23
|
* Return the process-wide runner. Throws if `initLifecycleRunner` has not been
|
|
29
24
|
* called yet (boot wiring is expected to init it before any consumer runs).
|
|
30
25
|
*/
|
|
31
|
-
function getLifecycleRunner() {
|
|
26
|
+
export function getLifecycleRunner() {
|
|
32
27
|
if (instance === null) {
|
|
33
28
|
throw new Error('lifecycle runner not initialized — call initLifecycleRunner(deps) at boot before use');
|
|
34
29
|
}
|
|
35
30
|
return instance;
|
|
36
31
|
}
|
|
37
32
|
/** Test-only: reset the singleton between specs. */
|
|
38
|
-
function __resetLifecycleRunnerForTests() {
|
|
33
|
+
export function __resetLifecycleRunnerForTests() {
|
|
39
34
|
instance = null;
|
|
40
35
|
}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LifecycleStateMachine = void 0;
|
|
4
1
|
// Re-export from @camstack/system — LifecycleStateMachine is already a plain class
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "LifecycleStateMachine", { enumerable: true, get: function () { return system_1.LifecycleStateMachine; } });
|
|
2
|
+
export { LifecycleStateMachine } from '@camstack/system';
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogRingBuffer = void 0;
|
|
4
1
|
// Re-export from @camstack/system
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "LogRingBuffer", { enumerable: true, get: function () { return system_1.LogRingBuffer; } });
|
|
2
|
+
export { LogRingBuffer } from '@camstack/system';
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.LoggingService = void 0;
|
|
4
|
-
const system_1 = require("@camstack/system");
|
|
5
|
-
const types_1 = require("@camstack/types");
|
|
1
|
+
import { LogManager } from '@camstack/system';
|
|
2
|
+
import { EventCategory } from '@camstack/types';
|
|
6
3
|
/** Baseline tags every hub-local logger gets, so console output never
|
|
7
4
|
* falls back to `?` for the agent slot. Hub-local addons already
|
|
8
5
|
* re-tag with their addonId; this ensures non-addon scopes (core
|
|
@@ -13,7 +10,7 @@ const types_1 = require("@camstack/types");
|
|
|
13
10
|
* forked workers via `$hub.log` carry their own `tags.pid` which
|
|
14
11
|
* wins over this baseline (right-biased merge in `writeFromWorker`). */
|
|
15
12
|
const HUB_BASELINE_TAGS = { agentId: 'hub', nodeId: 'hub', pid: process.pid };
|
|
16
|
-
class LoggingService extends
|
|
13
|
+
export class LoggingService extends LogManager {
|
|
17
14
|
/**
|
|
18
15
|
* Device-name cache consulted by the formatter when a log line
|
|
19
16
|
* carries `tags.deviceId` but no explicit `deviceName`. Populated
|
|
@@ -77,7 +74,7 @@ class LoggingService extends system_1.LogManager {
|
|
|
77
74
|
*/
|
|
78
75
|
attachDeviceNameStream(eventBus) {
|
|
79
76
|
const selfLogger = this.createLogger('logging').withTags({ addonId: 'logging' });
|
|
80
|
-
eventBus.subscribe({ category:
|
|
77
|
+
eventBus.subscribe({ category: EventCategory.DeviceRegistered }, (event) => {
|
|
81
78
|
const data = event.data;
|
|
82
79
|
if (data && typeof data.deviceId === 'number') {
|
|
83
80
|
this.upsertDeviceName(data.deviceId, data.name);
|
|
@@ -90,7 +87,7 @@ class LoggingService extends system_1.LogManager {
|
|
|
90
87
|
});
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
|
-
eventBus.subscribe({ category:
|
|
90
|
+
eventBus.subscribe({ category: EventCategory.DeviceUnregistered }, (event) => {
|
|
94
91
|
const data = event.data;
|
|
95
92
|
if (data && typeof data.deviceId === 'number')
|
|
96
93
|
this.removeDeviceName(data.deviceId);
|
|
@@ -137,4 +134,3 @@ class LoggingService extends system_1.LogManager {
|
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
}
|
|
140
|
-
exports.LoggingService = LoggingService;
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ScopedLogger = void 0;
|
|
4
1
|
// Re-export from @camstack/system
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "ScopedLogger", { enumerable: true, get: function () { return system_1.ScopedLogger; } });
|
|
2
|
+
export { ScopedLogger } from '@camstack/system';
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterAgentAuthoritativeRecords = filterAgentAuthoritativeRecords;
|
|
4
1
|
const VALID_STATES = new Set(['starting', 'ready', 'down']);
|
|
5
2
|
const VALID_SCOPE_TYPES = new Set(['global', 'node', 'device']);
|
|
6
3
|
/** Structural validation for a record received from a remote node. */
|
|
@@ -27,7 +24,7 @@ function isWellFormedRecord(value) {
|
|
|
27
24
|
* Keep only the records `agentNodeId` is authoritative for, dropping
|
|
28
25
|
* malformed entries. See module doc for why this filter must exist.
|
|
29
26
|
*/
|
|
30
|
-
function filterAgentAuthoritativeRecords(records, agentNodeId) {
|
|
27
|
+
export function filterAgentAuthoritativeRecords(records, agentNodeId) {
|
|
31
28
|
if (!Array.isArray(records))
|
|
32
29
|
return [];
|
|
33
30
|
return records.filter((record) => {
|