@camstack/system 1.2.378 → 1.2.379
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-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/addon-utils.js +1 -1
- package/dist/addon-utils.mjs +1 -1
- package/dist/auth/auth-manager.d.ts +10 -2
- package/dist/auth/jwt-signing-key.d.ts +42 -0
- package/dist/auth/user-manager.d.ts +19 -19
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +34 -4
- package/dist/builtins/keychain/index.mjs +34 -4
- package/dist/builtins/keychain/keychain-service.d.ts +14 -2
- package/dist/builtins/keychain/system-held-secrets.d.ts +11 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/admin-account-boot.d.ts +1 -1
- package/dist/builtins/local-auth/auth-config-reader.d.ts +9 -7
- package/dist/builtins/local-auth/jwt-signing-key-keeper.d.ts +30 -0
- package/dist/builtins/local-auth/local-auth.addon.d.ts +2 -6
- package/dist/builtins/local-auth/local-auth.addon.js +127 -221
- package/dist/builtins/local-auth/local-auth.addon.mjs +126 -220
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/cluster-secret-keeper.d.ts +36 -0
- package/dist/builtins/system-config/system-config.addon.d.ts +13 -0
- package/dist/builtins/system-config/system-config.addon.js +244 -53
- package/dist/builtins/system-config/system-config.addon.mjs +244 -54
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{child-cap-dispatch-C9lmrWFT.js → child-cap-dispatch-CZeRUgYF.js} +1 -1
- package/dist/{child-cap-dispatch-DpHovtQd.mjs → child-cap-dispatch-CpjohToR.mjs} +1 -1
- package/dist/cluster-secret-BDue-uJj.mjs +83 -0
- package/dist/cluster-secret-Dg0OOOSr.js +148 -0
- package/dist/{composition-sources-CxhGdtdh.js → composition-sources-CHvLMrFI.js} +1 -1
- package/dist/{composition-sources-BLBd338N.mjs → composition-sources-DT_uJwI3.mjs} +1 -1
- package/dist/{dist-Bvl5JgNt.mjs → dist-B9oFw2jh.mjs} +58 -2
- package/dist/{dist-KxsOMQik.js → dist-Cc6KOdY-.js} +69 -1
- package/dist/{event-loop-stall-monitor-D8rqSWfW.mjs → event-loop-stall-monitor-anUH2IE1.mjs} +14 -14
- package/dist/{event-loop-stall-monitor-CbSmCWkp.js → event-loop-stall-monitor-mk6WGxir.js} +14 -14
- package/dist/index.d.ts +4 -2
- package/dist/index.js +192 -62
- package/dist/index.mjs +171 -55
- package/dist/jwt-signing-key-C2rE3wH6.js +174 -0
- package/dist/jwt-signing-key-Qhde8r82.mjs +127 -0
- package/dist/kernel/config-manager.d.ts +1 -1
- package/dist/kernel/config-schema.d.ts +4 -11
- package/dist/kernel/index.d.ts +2 -1
- package/dist/kernel/moleculer/broker-factory.d.ts +0 -2
- package/dist/kernel/moleculer/cluster-secret.d.ts +31 -0
- package/dist/kernel/moleculer/hub-service.d.ts +7 -4
- package/dist/kernel/moleculer/node-registry.d.ts +1 -1
- package/dist/kernel/system-settings-policy.d.ts +7 -9
- package/dist/{retired-settings-keys-BAcfvFtm.mjs → retired-settings-keys-DlZ3VV6x.mjs} +1 -1
- package/dist/{retired-settings-keys-gTsZfpmP.js → retired-settings-keys-YOOKLA3v.js} +1 -1
- package/package.json +1 -1
package/dist/addon-runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_child_cap_dispatch = require("./child-cap-dispatch-
|
|
2
|
+
const require_child_cap_dispatch = require("./child-cap-dispatch-CZeRUgYF.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as installManifestNativeDeps, H as createUdsLoggerWithControl, It as resolveAddonClass, St as validateProviderRegistrations, U as LocalChildClient, _n as startRunnerHeapWatch, _t as getWorkerNativeCapProvider, bt as setWorkerNativeCapsChangeListener, f as installManifestSystemDeps, g as createUdsAddonContext, i as killOwnRunnerGroupAfterParentLoss, in as RUNNER_RSS_BUDGET_ENV, kn as emitHeapDiagnosticReport, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, vt as getWorkerNativeCapSnapshot } from "./child-cap-dispatch-
|
|
1
|
+
import { Ft as installManifestNativeDeps, H as createUdsLoggerWithControl, It as resolveAddonClass, St as validateProviderRegistrations, U as LocalChildClient, _n as startRunnerHeapWatch, _t as getWorkerNativeCapProvider, bt as setWorkerNativeCapsChangeListener, f as installManifestSystemDeps, g as createUdsAddonContext, i as killOwnRunnerGroupAfterParentLoss, in as RUNNER_RSS_BUDGET_ENV, kn as emitHeapDiagnosticReport, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, vt as getWorkerNativeCapSnapshot } from "./child-cap-dispatch-CpjohToR.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
4
4
|
import * as path$1 from "node:path";
|
package/dist/addon-utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-
|
|
3
|
+
const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-mk6WGxir.js");
|
|
4
4
|
const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
|
|
5
5
|
const require_snapshot_courtesy = require("./snapshot-courtesy-D_C5-nC0.js");
|
|
6
6
|
exports.COURTESY_DEFAULT_WIDTH = require_snapshot_courtesy.COURTESY_DEFAULT_WIDTH;
|
package/dist/addon-utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as resolveFormatRevision, S as isModelDownloaded, a as createFileDataPlaneHandler, b as getModelFilePath, c as parseRangeHeader, d as ModelDownloadService, f as ModelDownloadHttpError, g as downloadFile, h as deleteModelFromDisk, i as startEventLoopStallMonitor, m as collectModelFiles, n as STALL_TICK_MS, o as contentTypeFor, p as adoptModelRevisions, r as attributeStall, t as STALL_REPORT_MS, v as ensureModel, x as isModelDownloadHttpError } from "./event-loop-stall-monitor-
|
|
1
|
+
import { C as resolveFormatRevision, S as isModelDownloaded, a as createFileDataPlaneHandler, b as getModelFilePath, c as parseRangeHeader, d as ModelDownloadService, f as ModelDownloadHttpError, g as downloadFile, h as deleteModelFromDisk, i as startEventLoopStallMonitor, m as collectModelFiles, n as STALL_TICK_MS, o as contentTypeFor, p as adoptModelRevisions, r as attributeStall, t as STALL_REPORT_MS, v as ensureModel, x as isModelDownloadHttpError } from "./event-loop-stall-monitor-anUH2IE1.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
3
3
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg, t as COURTESY_DEFAULT_WIDTH } from "./snapshot-courtesy-CyFs1M3I.mjs";
|
|
4
4
|
export { COURTESY_DEFAULT_WIDTH, CustomActionRegistry, ModelDownloadHttpError, ModelDownloadService, STALL_REPORT_MS, STALL_TICK_MS, adoptModelRevisions, attributeStall, collectModelFiles, contentTypeFor, courtesyCacheKey, createFileDataPlaneHandler, deleteModelFromDisk, downloadFile, ensureModel, getModelFilePath, isModelDownloadHttpError, isModelDownloaded, parseRangeHeader, renderCourtesyJpeg, renderCourtesyOverlayJpeg, resolveFormatRevision, startEventLoopStallMonitor };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IScopedLogger, TokenPayload, SsoBridgeClaimsSchema } from '@camstack/types';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { JwtSigningKeySource } from './jwt-signing-key.js';
|
|
3
4
|
export type { TokenPayload };
|
|
4
5
|
export type AuthConfigReader = {
|
|
5
6
|
/**
|
|
@@ -13,7 +14,7 @@ export type AuthConfigReader = {
|
|
|
13
14
|
};
|
|
14
15
|
export declare class AuthManager {
|
|
15
16
|
private readonly config;
|
|
16
|
-
private readonly
|
|
17
|
+
private readonly signingKey;
|
|
17
18
|
private readonly logger;
|
|
18
19
|
/**
|
|
19
20
|
* Offending `auth.tokenExpiry` values already reported by this instance.
|
|
@@ -25,7 +26,14 @@ export declare class AuthManager {
|
|
|
25
26
|
* rest resolve silently to the same default until the value changes.
|
|
26
27
|
*/
|
|
27
28
|
private readonly reportedInvalidExpiries;
|
|
28
|
-
|
|
29
|
+
/**
|
|
30
|
+
* @param signingKey where the session signing key comes from — the process
|
|
31
|
+
* slot `local-auth` fills from the keychain (D797). Never config, never
|
|
32
|
+
* env; read on every mint and verify, and it THROWS while unavailable.
|
|
33
|
+
*/
|
|
34
|
+
constructor(config: AuthConfigReader, logger?: IScopedLogger, signingKey?: JwtSigningKeySource);
|
|
35
|
+
/** The current signing key; throws `JwtSigningKeyUnavailableError` while there is none. */
|
|
36
|
+
private get jwtSecret();
|
|
29
37
|
signToken(payload: Omit<TokenPayload, 'iat' | 'exp'>): string;
|
|
30
38
|
/**
|
|
31
39
|
* The operator's `auth.tokenExpiry`, or `undefined` → DEFAULT_TOKEN_EXPIRY.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SecretsAccess } from '@camstack/types';
|
|
2
|
+
/** The keychain owner of every system-held secret. */
|
|
3
|
+
export declare const SYSTEM_SECRET_OWNER = "system";
|
|
4
|
+
/** `secret://system/global/jwtSigningKey`. */
|
|
5
|
+
export declare const JWT_SIGNING_KEY_REF: string;
|
|
6
|
+
export type JwtSigningKeyState = {
|
|
7
|
+
readonly state: 'ready';
|
|
8
|
+
readonly key: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly state: 'unavailable';
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
};
|
|
13
|
+
/** Sessions cannot be minted or verified: the signing key is not loaded. */
|
|
14
|
+
export declare class JwtSigningKeyUnavailableError extends Error {
|
|
15
|
+
readonly reason: string;
|
|
16
|
+
constructor(reason: string);
|
|
17
|
+
}
|
|
18
|
+
/** Where an `AuthManager` gets its key. `current()` throws while there is none. */
|
|
19
|
+
export interface JwtSigningKeySource {
|
|
20
|
+
current(): string;
|
|
21
|
+
}
|
|
22
|
+
/** Register the loaded (or unloadable) key. Called by the hub's `local-auth`. */
|
|
23
|
+
export declare function setProcessJwtSigningKey(state: JwtSigningKeyState): void;
|
|
24
|
+
/** Forget the key (tests, shutdown). */
|
|
25
|
+
export declare function clearProcessJwtSigningKey(): void;
|
|
26
|
+
export declare function getProcessJwtSigningKeyState(): JwtSigningKeyState;
|
|
27
|
+
/** The process slot — the default source of every `AuthManager`. */
|
|
28
|
+
export declare const processJwtSigningKey: JwtSigningKeySource;
|
|
29
|
+
/** A fixed key — tests, and nothing else. */
|
|
30
|
+
export declare function staticJwtSigningKey(key: string): JwtSigningKeySource;
|
|
31
|
+
/** 32 random bytes, hex. */
|
|
32
|
+
export declare function generateJwtSigningKey(): string;
|
|
33
|
+
export interface LoadJwtSigningKeyDeps {
|
|
34
|
+
/** A keychain handle acting for owner `system`. */
|
|
35
|
+
readonly secrets: SecretsAccess;
|
|
36
|
+
readonly generate?: () => string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Read the key from the keychain; generate and store one ONLY when the
|
|
40
|
+
* keychain answers that none exists. Never throws.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadJwtSigningKey(deps: LoadJwtSigningKeyDeps): Promise<JwtSigningKeyState>;
|
|
@@ -10,14 +10,20 @@ interface CreateUserInput {
|
|
|
10
10
|
scopes?: TokenScope[];
|
|
11
11
|
}
|
|
12
12
|
type UpdatableUserFields = Partial<Pick<UserRecord, 'isAdmin' | 'allowedProviders' | 'allowedDevices' | 'scopes'>>;
|
|
13
|
+
/**
|
|
14
|
+
* The account a fresh hub seeds on its first boot (D797). Not configurable —
|
|
15
|
+
* no env variable, no config.yaml key: the first sign-in with this password
|
|
16
|
+
* forces a change (admin-ui `mustChangePassword`), and an existing user is
|
|
17
|
+
* never overwritten (D728).
|
|
18
|
+
*/
|
|
19
|
+
export declare const FIRST_BOOT_ADMIN_USERNAME = "admin";
|
|
20
|
+
export declare const FIRST_BOOT_ADMIN_PASSWORD = "changeme";
|
|
13
21
|
export interface EnsureAdminOptions {
|
|
14
22
|
/** The operator's explicit, one-shot recovery request. Never a default. */
|
|
15
23
|
readonly resetPassword?: boolean;
|
|
16
24
|
}
|
|
17
25
|
/** What `ensureAdminExists` did — every branch is named so the caller can log it. */
|
|
18
26
|
export type AdminSeedOutcome = {
|
|
19
|
-
readonly kind: 'not-configured';
|
|
20
|
-
} | {
|
|
21
27
|
readonly kind: 'seeded';
|
|
22
28
|
readonly username: string;
|
|
23
29
|
} | {
|
|
@@ -33,15 +39,10 @@ export type AdminSeedOutcome = {
|
|
|
33
39
|
export interface UserStorageAccess {
|
|
34
40
|
getStore(): SettingsStoreClient;
|
|
35
41
|
}
|
|
36
|
-
export interface UserConfigReader {
|
|
37
|
-
/** See `AuthConfigReader.get` — a reader answers only the paths it resolved. */
|
|
38
|
-
get<T>(path: string): T | undefined;
|
|
39
|
-
}
|
|
40
42
|
export declare class UserManager {
|
|
41
43
|
private readonly storageAccess;
|
|
42
44
|
private readonly auth;
|
|
43
|
-
|
|
44
|
-
constructor(storageAccess: UserStorageAccess, auth: AuthManager, config: UserConfigReader);
|
|
45
|
+
constructor(storageAccess: UserStorageAccess, auth: AuthManager);
|
|
45
46
|
private get store();
|
|
46
47
|
create(input: CreateUserInput): Promise<UserRecord>;
|
|
47
48
|
findByUsername(username: string): Promise<UserRecord | null>;
|
|
@@ -52,20 +53,19 @@ export declare class UserManager {
|
|
|
52
53
|
delete(id: string): Promise<void>;
|
|
53
54
|
resetPassword(id: string, newPassword: string): Promise<void>;
|
|
54
55
|
/**
|
|
55
|
-
* Seed
|
|
56
|
-
*
|
|
56
|
+
* Seed {@link FIRST_BOOT_ADMIN_USERNAME} / {@link FIRST_BOOT_ADMIN_PASSWORD}
|
|
57
|
+
* — on FIRST boot only, i.e. when no admin account exists.
|
|
57
58
|
*
|
|
58
|
-
* The
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* (`changeme` on a Mac hub and on any container without `CAMSTACK_ADMIN_PASS`)
|
|
64
|
-
* at the next restart.
|
|
59
|
+
* The seed is never an authority. Once any admin exists, this never writes a
|
|
60
|
+
* password: the operator's own change in the admin UI is the truth from then
|
|
61
|
+
* on (D728). This method once compared the stored hash with a configured
|
|
62
|
+
* password on every boot and rewrote it when they differed, so a password
|
|
63
|
+
* changed in the UI went back at the next restart.
|
|
65
64
|
*
|
|
66
65
|
* `resetPassword: true` is the one explicit exception — the operator's
|
|
67
|
-
* one-shot recovery request (
|
|
68
|
-
* admin's password
|
|
66
|
+
* one-shot recovery request (`RESET_ADMIN_PASSWORD`, see
|
|
67
|
+
* `admin-account-boot.ts`): the `admin` user's password goes back to
|
|
68
|
+
* `changeme`, and the next sign-in forces a change again.
|
|
69
69
|
*/
|
|
70
70
|
ensureAdminExists(options?: EnsureAdminOptions): Promise<AdminSeedOutcome>;
|
|
71
71
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { W as addonPagesCapability, cr as errMsg, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as addonWidgetsCapability, cr as errMsg, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
//#region src/builtins/alerts/device-label.ts
|
|
8
8
|
/**
|
|
9
9
|
* Operator-facing device label for alert messages.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cr as createEvent, cr as errMsg, lr as BaseAddon, n as AlertSchema, q as alertsCapability, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
//#region src/builtins/alerts/device-label.ts
|
|
3
3
|
/**
|
|
4
4
|
* Operator-facing device label for alert messages.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ar as isEvent, S as FIRST_LEVEL_MACRO_CLASSES, X as bareAddonId, cr as errMsg, gn as ptzAutotrackCapability, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let buffer = require("buffer");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gr as
|
|
1
|
+
import { Gr as toNodeId, In as storageOccupancyCapability, Mr as nodePin, Y as backupCapability, g as DATABASE_SNAPSHOT_SUFFIX, lr as BaseAddon, nn as mayWriteToLocation, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/calendars/calendar-color.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { et as calendarsCapability, lr as BaseAddon, p as CalendarPreferencesSchema } from "../../dist-
|
|
1
|
+
import { et as calendarsCapability, lr as BaseAddon, p as CalendarPreferencesSchema } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/calendars/calendar-color.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let _camstack_types_node = require("@camstack/types/node");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cr as createEvent, Jn as buildFfmpegArgs, M as MOTION_CLOSE_AFTER_MS, Nn as snapshotCapability, Or as hydrateSchema, Rn as streamCatalogCapability, ar as DeviceFeature, b as DeclaredDevices, cr as errMsg, i as BaseDevice, lr as BaseAddon, mt as declarationOwnerNodeId, on as motionCapability, qr as EventCategory, rn as memoizePinnedFfmpeg, sr as DeviceType, tt as cameraGridLayoutCapability, y as DERIVED_CAMERA_SILENCED_CAP_NAMES } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_composition_sources = require("../../composition-sources-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
|
+
const require_composition_sources = require("../../composition-sources-CHvLMrFI.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/shared/device-state-changed.ts
|
|
10
10
|
/** Structural narrowing helper for untrusted bus payloads. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $n as compositionItemFieldPath,
|
|
2
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-
|
|
1
|
+
import { $n as compositionItemFieldPath, Cr as createEvent, Et as evaluateCompositionField, Q as buildCapabilityLookup, Qn as compositionFeatureEnabled, Xn as composedDeviceRef, Yn as cloneStatefulExpressionMemory, Zn as composedDeviceStableId, b as DeclaredDevices, cr as errMsg, er as compositionSliceKey, i as BaseDevice, ir as toExpressionValue, it as compositionFieldKey, kt as expressionContainsBuiltinCall, l as COMPOSED_ITEM_FIXED_FIELDS, lr as BaseAddon, nr as createStatefulExpressionMemory, pn as planComposition, qn as COMPOSER_ADDON_ID, qr as EventCategory, rr as disarmRoseMemory, rt as composerCapability, sr as DeviceType, t as ALL_CAPABILITY_DEFINITIONS, tr as compositionSourceKey } from "../../dist-B9oFw2jh.mjs";
|
|
2
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-DT_uJwI3.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/shared/device-state-changed.ts
|
|
5
5
|
/** Structural narrowing helper for untrusted bus payloads. */
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-
|
|
1
|
+
import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
4
|
-
const require_composition_sources = require("../../composition-sources-
|
|
3
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
4
|
+
const require_composition_sources = require("../../composition-sources-CHvLMrFI.js");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let _camstack_types_node = require("@camstack/types/node");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
1
|
+
import { Or as hydrateSchema, Q as buildCapabilityLookup, Sn as resolveCoreBlockFiles, Vn as validateComposition, Xn as composedDeviceRef, at as compositionSourceRefs, b as DeclaredDevices, cr as errMsg, ct as coreBlockIdFromAddonId, d as CORE_BLOCKS_ADDON_ID, f as CORE_BLOCK_ADDON_PREFIX, lr as BaseAddon, lt as coreBlockSourceKind, m as CoreBlockSchema, ot as coreBlockAddonId, pn as planComposition, sn as normalizeCoreBlockWrite, st as coreBlockComposition, t as ALL_CAPABILITY_DEFINITIONS, tr as compositionSourceKey, u as COMPOSER_RUNNER_ID, ut as coreBlocksCapability, vn as replacedFieldKeys, vt as describeComposableCaps, xn as resolveCoreBlockEntry } from "../../dist-B9oFw2jh.mjs";
|
|
2
|
+
import { t as describeCompositionSources } from "../../composition-sources-DT_uJwI3.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { customizationBlockName } from "@camstack/types/node";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retired_settings_keys = require("../../retired-settings-keys-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-YOOKLA3v.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as buildStreamParamsConfigSchema, A as MINUTES_PER_DAY, C as FieldClaimModeSchema, Dn as runtimeStatePolicyFor,
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { $ as buildStreamParamsConfigSchema, A as MINUTES_PER_DAY, C as FieldClaimModeSchema, Dn as runtimeStatePolicyFor, Hr as secretTreeFromPaths, Kr as transformSecretWrite, Kt as legacyAutoLinkIds, L as STREAM_PROFILE_META, Mn as siteZoneKey, Nt as formatMinutes, O as LocationIconIdSchema, Ot as expandContainer, Sr as collectZodSecretPaths, St as deviceStatusCapability, Tt as enumerateSchemaFields, Wr as sleep$1, Xt as locationIconKey, ar as DeviceFeature, bt as deviceManagerCapability, c as CAP_NAMES_WITH_STATUS, cn as normalizeUnit, cr as errMsg, dn as parseStreamParamsFormPatch, dt as createDeviceExtensionProvider, gr as WELL_KNOWN_TAB_MAP, gt as defineExtensionSlotProvider, kr as isDeviceConfigCap, lr as BaseAddon, o as CAMERA_SWITCH_ORDER, or as DeviceRole, qr as EventCategory, sr as DeviceType, t as ALL_CAPABILITY_DEFINITIONS, v as DAY_NAMES, w as FieldClaimSchema, wt as enumerateItemArrayFields, x as DeviceStatusSchema, xt as deviceStateCapability, yt as deviceExtensionCapability, zr as resolveSecretMarkers } from "../../dist-B9oFw2jh.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-DlZ3VV6x.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-
|
|
1
|
+
import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-B9oFw2jh.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -3,7 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Cc6KOdY-.js");
|
|
7
|
+
const require_jwt_signing_key = require("../../jwt-signing-key-C2rE3wH6.js");
|
|
8
|
+
const require_cluster_secret = require("../../cluster-secret-Dg0OOOSr.js");
|
|
7
9
|
const require_platform_key_source = require("../../platform-key-source-Di7HrlGR.js");
|
|
8
10
|
let node_crypto = require("node:crypto");
|
|
9
11
|
let node_path = require("node:path");
|
|
@@ -635,6 +637,14 @@ var KeychainRepository = class {
|
|
|
635
637
|
return rows.length;
|
|
636
638
|
}
|
|
637
639
|
};
|
|
640
|
+
//#endregion
|
|
641
|
+
//#region src/builtins/keychain/system-held-secrets.ts
|
|
642
|
+
/** The refs `keychain-admin.setSystemSecret` may write, by name. */
|
|
643
|
+
var SYSTEM_HELD_SECRET_REFS = { "jwt-signing-key": require_jwt_signing_key.JWT_SIGNING_KEY_REF };
|
|
644
|
+
/** System refs no blob points at — in use for as long as they exist. */
|
|
645
|
+
var PROCESS_HELD_SECRET_REFS = new Set([require_jwt_signing_key.JWT_SIGNING_KEY_REF]);
|
|
646
|
+
/** `system-settings` keys that may hold a system-owned secret's marker. */
|
|
647
|
+
var SYSTEM_SECRET_SETTINGS_KEYS = [require_cluster_secret.CLUSTER_SECRET_SETTINGS_KEY];
|
|
638
648
|
var KeychainLockedError = class extends Error {
|
|
639
649
|
reason;
|
|
640
650
|
constructor(reason) {
|
|
@@ -845,7 +855,11 @@ var KeychainService = class {
|
|
|
845
855
|
if (parts === null || !this.owns(caller, parts.owner)) throw new KeychainForbiddenError(ref, caller);
|
|
846
856
|
return parts.owner;
|
|
847
857
|
}
|
|
848
|
-
|
|
858
|
+
/**
|
|
859
|
+
* @param actor who the audit names — the owner addon by default; the
|
|
860
|
+
* operator (`user:<id>`) for {@link setSystemSecret}.
|
|
861
|
+
*/
|
|
862
|
+
async put(caller, ref, value, actor = actorOfAddon(caller)) {
|
|
849
863
|
const owner = this.ownerOf(ref, caller);
|
|
850
864
|
const unlocked = this.requireReady();
|
|
851
865
|
if (value.length === 0) throw new Error("keychain.put: an empty value is not stored — delete the ref");
|
|
@@ -871,10 +885,10 @@ var KeychainService = class {
|
|
|
871
885
|
version,
|
|
872
886
|
createdAt: existing?.createdAt ?? t,
|
|
873
887
|
updatedAt: t,
|
|
874
|
-
updatedBy:
|
|
888
|
+
updatedBy: actor,
|
|
875
889
|
lastReadAt: existing?.lastReadAt ?? null
|
|
876
890
|
});
|
|
877
|
-
await this.audit("put",
|
|
891
|
+
await this.audit("put", actor, ref, `version=${version}`);
|
|
878
892
|
this.deps.events.emit({
|
|
879
893
|
ref,
|
|
880
894
|
owner,
|
|
@@ -1004,6 +1018,14 @@ var KeychainService = class {
|
|
|
1004
1018
|
usage: usage.get(row.ref) ?? "unknown"
|
|
1005
1019
|
}));
|
|
1006
1020
|
}
|
|
1021
|
+
/**
|
|
1022
|
+
* The operator replaces a system-held secret no form edits (D797) — the
|
|
1023
|
+
* session signing key. Stored under owner `system`, audited as the user.
|
|
1024
|
+
*/
|
|
1025
|
+
async setSystemSecret(userId, name, value) {
|
|
1026
|
+
const ref = SYSTEM_HELD_SECRET_REFS[name];
|
|
1027
|
+
return this.put(require_jwt_signing_key.SYSTEM_SECRET_OWNER, ref, value, `user:${userId}`);
|
|
1028
|
+
}
|
|
1007
1029
|
async listAudit(limit) {
|
|
1008
1030
|
return this.deps.repo.listAudit(limit);
|
|
1009
1031
|
}
|
|
@@ -1243,6 +1265,13 @@ async function prefixRows(door, collection, prefix) {
|
|
|
1243
1265
|
}
|
|
1244
1266
|
/** The blobs that may hold the marker of a ref in `scope`; `null` = cannot tell. */
|
|
1245
1267
|
async function blobsFor(door, owner, scope) {
|
|
1268
|
+
if (owner === "system" && scope.kind === "global") return [[...PROCESS_HELD_SECRET_REFS].map((ref) => ({
|
|
1269
|
+
$secret: ref,
|
|
1270
|
+
v: 1
|
|
1271
|
+
})), ...await Promise.all(SYSTEM_SECRET_SETTINGS_KEYS.map((key) => door.get({
|
|
1272
|
+
collection: "system-settings",
|
|
1273
|
+
key
|
|
1274
|
+
})))];
|
|
1246
1275
|
switch (scope.kind) {
|
|
1247
1276
|
case "global":
|
|
1248
1277
|
case "node": {
|
|
@@ -1424,6 +1453,7 @@ var KeychainAddon = class extends require_dist.BaseAddon {
|
|
|
1424
1453
|
listSecrets: () => service.listSecrets(),
|
|
1425
1454
|
listAudit: (input) => service.listAudit(input.limit ?? 100),
|
|
1426
1455
|
reveal: (input) => service.reveal(input.caller.userId, input.ref),
|
|
1456
|
+
setSystemSecret: (input) => service.setSystemSecret(input.caller.userId, input.name, input.value),
|
|
1427
1457
|
deleteOrphans: (input) => service.deleteOrphans(input.caller.userId, input.refs),
|
|
1428
1458
|
rotateMasterKey: (input) => service.rotateMasterKey(input.caller.userId),
|
|
1429
1459
|
purgeRetiredKeys: async (input) => ({ purged: await service.purgeRetiredKeys(input.caller.userId) }),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dr as formatSecretScope, Gt as keychainCapability, Ir as parseSecretRef, Nr as normalizeSecretOwner, Wt as keychainAdminCapability, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
|
|
2
|
+
import { r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "../../jwt-signing-key-Qhde8r82.mjs";
|
|
3
|
+
import { i as CLUSTER_SECRET_SETTINGS_KEY } from "../../cluster-secret-BDue-uJj.mjs";
|
|
2
4
|
import { n as getPlatformKeychainKey } from "../../platform-key-source-BWlq0jjn.mjs";
|
|
3
5
|
import { createCipheriv, createDecipheriv, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
4
6
|
import * as path$1 from "node:path";
|
|
@@ -629,6 +631,14 @@ var KeychainRepository = class {
|
|
|
629
631
|
return rows.length;
|
|
630
632
|
}
|
|
631
633
|
};
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/builtins/keychain/system-held-secrets.ts
|
|
636
|
+
/** The refs `keychain-admin.setSystemSecret` may write, by name. */
|
|
637
|
+
var SYSTEM_HELD_SECRET_REFS = { "jwt-signing-key": JWT_SIGNING_KEY_REF };
|
|
638
|
+
/** System refs no blob points at — in use for as long as they exist. */
|
|
639
|
+
var PROCESS_HELD_SECRET_REFS = new Set([JWT_SIGNING_KEY_REF]);
|
|
640
|
+
/** `system-settings` keys that may hold a system-owned secret's marker. */
|
|
641
|
+
var SYSTEM_SECRET_SETTINGS_KEYS = [CLUSTER_SECRET_SETTINGS_KEY];
|
|
632
642
|
var KeychainLockedError = class extends Error {
|
|
633
643
|
reason;
|
|
634
644
|
constructor(reason) {
|
|
@@ -839,7 +849,11 @@ var KeychainService = class {
|
|
|
839
849
|
if (parts === null || !this.owns(caller, parts.owner)) throw new KeychainForbiddenError(ref, caller);
|
|
840
850
|
return parts.owner;
|
|
841
851
|
}
|
|
842
|
-
|
|
852
|
+
/**
|
|
853
|
+
* @param actor who the audit names — the owner addon by default; the
|
|
854
|
+
* operator (`user:<id>`) for {@link setSystemSecret}.
|
|
855
|
+
*/
|
|
856
|
+
async put(caller, ref, value, actor = actorOfAddon(caller)) {
|
|
843
857
|
const owner = this.ownerOf(ref, caller);
|
|
844
858
|
const unlocked = this.requireReady();
|
|
845
859
|
if (value.length === 0) throw new Error("keychain.put: an empty value is not stored — delete the ref");
|
|
@@ -865,10 +879,10 @@ var KeychainService = class {
|
|
|
865
879
|
version,
|
|
866
880
|
createdAt: existing?.createdAt ?? t,
|
|
867
881
|
updatedAt: t,
|
|
868
|
-
updatedBy:
|
|
882
|
+
updatedBy: actor,
|
|
869
883
|
lastReadAt: existing?.lastReadAt ?? null
|
|
870
884
|
});
|
|
871
|
-
await this.audit("put",
|
|
885
|
+
await this.audit("put", actor, ref, `version=${version}`);
|
|
872
886
|
this.deps.events.emit({
|
|
873
887
|
ref,
|
|
874
888
|
owner,
|
|
@@ -998,6 +1012,14 @@ var KeychainService = class {
|
|
|
998
1012
|
usage: usage.get(row.ref) ?? "unknown"
|
|
999
1013
|
}));
|
|
1000
1014
|
}
|
|
1015
|
+
/**
|
|
1016
|
+
* The operator replaces a system-held secret no form edits (D797) — the
|
|
1017
|
+
* session signing key. Stored under owner `system`, audited as the user.
|
|
1018
|
+
*/
|
|
1019
|
+
async setSystemSecret(userId, name, value) {
|
|
1020
|
+
const ref = SYSTEM_HELD_SECRET_REFS[name];
|
|
1021
|
+
return this.put(SYSTEM_SECRET_OWNER, ref, value, `user:${userId}`);
|
|
1022
|
+
}
|
|
1001
1023
|
async listAudit(limit) {
|
|
1002
1024
|
return this.deps.repo.listAudit(limit);
|
|
1003
1025
|
}
|
|
@@ -1237,6 +1259,13 @@ async function prefixRows(door, collection, prefix) {
|
|
|
1237
1259
|
}
|
|
1238
1260
|
/** The blobs that may hold the marker of a ref in `scope`; `null` = cannot tell. */
|
|
1239
1261
|
async function blobsFor(door, owner, scope) {
|
|
1262
|
+
if (owner === "system" && scope.kind === "global") return [[...PROCESS_HELD_SECRET_REFS].map((ref) => ({
|
|
1263
|
+
$secret: ref,
|
|
1264
|
+
v: 1
|
|
1265
|
+
})), ...await Promise.all(SYSTEM_SECRET_SETTINGS_KEYS.map((key) => door.get({
|
|
1266
|
+
collection: "system-settings",
|
|
1267
|
+
key
|
|
1268
|
+
})))];
|
|
1240
1269
|
switch (scope.kind) {
|
|
1241
1270
|
case "global":
|
|
1242
1271
|
case "node": {
|
|
@@ -1418,6 +1447,7 @@ var KeychainAddon = class extends BaseAddon {
|
|
|
1418
1447
|
listSecrets: () => service.listSecrets(),
|
|
1419
1448
|
listAudit: (input) => service.listAudit(input.limit ?? 100),
|
|
1420
1449
|
reveal: (input) => service.reveal(input.caller.userId, input.ref),
|
|
1450
|
+
setSystemSecret: (input) => service.setSystemSecret(input.caller.userId, input.name, input.value),
|
|
1421
1451
|
deleteOrphans: (input) => service.deleteOrphans(input.caller.userId, input.refs),
|
|
1422
1452
|
rotateMasterKey: (input) => service.rotateMasterKey(input.caller.userId),
|
|
1423
1453
|
purgeRetiredKeys: async (input) => ({ purged: await service.purgeRetiredKeys(input.caller.userId) }),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventCategory, KeychainAuditEntry, KeychainKeySource, KeychainResolveResult, KeychainSecretMeta, KeychainSecretUsage, KeychainState, KeychainStatus, KeychainUnavailableReason } from '@camstack/types';
|
|
1
|
+
import { EventCategory, KeychainAuditEntry, KeychainKeySource, KeychainResolveResult, KeychainSecretMeta, KeychainSecretUsage, KeychainState, KeychainStatus, KeychainUnavailableReason, SystemHeldSecretName } from '@camstack/types';
|
|
2
2
|
import { KeychainRepository, KeychainSecretRow } from './keychain-store.js';
|
|
3
3
|
import { KeySourceCandidate } from './key-sources.js';
|
|
4
4
|
/** `lastReadAt` is written at most this often per ref (hub I/O is the bottleneck). */
|
|
@@ -54,7 +54,11 @@ export declare class KeychainService {
|
|
|
54
54
|
/** May `caller` touch values owned by `owner`? */
|
|
55
55
|
owns(caller: string | null, owner: string): boolean;
|
|
56
56
|
private ownerOf;
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @param actor who the audit names — the owner addon by default; the
|
|
59
|
+
* operator (`user:<id>`) for {@link setSystemSecret}.
|
|
60
|
+
*/
|
|
61
|
+
put(caller: string | null, ref: string, value: string, actor?: string): Promise<{
|
|
58
62
|
ref: string;
|
|
59
63
|
version: number;
|
|
60
64
|
}>;
|
|
@@ -66,6 +70,14 @@ export declare class KeychainService {
|
|
|
66
70
|
listSecrets(): Promise<readonly (KeychainSecretMeta & {
|
|
67
71
|
usage: KeychainSecretUsage;
|
|
68
72
|
})[]>;
|
|
73
|
+
/**
|
|
74
|
+
* The operator replaces a system-held secret no form edits (D797) — the
|
|
75
|
+
* session signing key. Stored under owner `system`, audited as the user.
|
|
76
|
+
*/
|
|
77
|
+
setSystemSecret(userId: string, name: SystemHeldSecretName, value: string): Promise<{
|
|
78
|
+
ref: string;
|
|
79
|
+
version: number;
|
|
80
|
+
}>;
|
|
69
81
|
listAudit(limit: number): Promise<readonly KeychainAuditEntry[]>;
|
|
70
82
|
reveal(userId: string, ref: string): Promise<{
|
|
71
83
|
value: string;
|