@camstack/types 1.2.332 → 1.2.334
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/base-addon.d.ts +32 -0
- package/dist/addon/secret-aware-context.d.ts +49 -6
- package/dist/addon/secret-settings-view.d.ts +23 -1
- package/dist/addon/secret-write-back.d.ts +40 -0
- package/dist/addon.js +5 -7
- package/dist/addon.mjs +5 -7
- package/dist/auth/app-callback.d.ts +28 -0
- package/dist/auth/sso-state.d.ts +16 -0
- package/dist/capabilities/addon-routes.cap.d.ts +3 -0
- package/dist/capabilities/addons.cap.d.ts +4 -4
- package/dist/capabilities/backup.cap.d.ts +101 -1
- package/dist/capabilities/broker.cap.d.ts +4 -4
- package/dist/capabilities/custom-model-registry.cap.d.ts +520 -0
- package/dist/capabilities/device-manager.cap.d.ts +4 -4
- package/dist/capabilities/hub-address.d.ts +2 -2
- package/dist/capabilities/index.d.ts +12 -6
- package/dist/capabilities/keychain-admin.cap.d.ts +83 -0
- package/dist/capabilities/login-method.cap.d.ts +5 -6
- package/dist/capabilities/nodes.cap.d.ts +8 -0
- package/dist/capabilities/notification-output.cap.d.ts +4 -4
- package/dist/capabilities/notification-rules.cap.d.ts +6 -6
- package/dist/capabilities/osd-manager.cap.d.ts +5 -5
- package/dist/capabilities/pipeline-analytics.cap.d.ts +39 -8
- package/dist/capabilities/recording.cap.d.ts +3 -3
- package/dist/capabilities/server-management.cap.d.ts +5 -5
- package/dist/capabilities/snapshot.cap.d.ts +2 -2
- package/dist/capabilities/sso-bridge.cap.d.ts +5 -2
- package/dist/capabilities/training-provider.cap.d.ts +373 -0
- package/dist/capabilities/training.cap.d.ts +1896 -0
- package/dist/capabilities/user-management.cap.d.ts +1 -64
- package/dist/capabilities/videoclips.cap.d.ts +3 -3
- package/dist/client.js +33 -5
- package/dist/client.mjs +33 -5
- package/dist/generated/addon-api.d.ts +872 -173
- package/dist/generated/cap-input-defaults.d.ts +1 -1
- package/dist/generated/capability-router-map.d.ts +10 -4
- package/dist/generated/collection-array-methods.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +2 -2
- package/dist/generated/system-proxy.d.ts +5 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1469 -94
- package/dist/index.mjs +1420 -93
- package/dist/interfaces/addon-routes.d.ts +7 -0
- package/dist/interfaces/addon.d.ts +8 -0
- package/dist/interfaces/auth.d.ts +6 -3
- package/dist/interfaces/event-bus.d.ts +5 -0
- package/dist/schemas/auth-records.d.ts +1 -2
- package/dist/{sleep-ClNXPpWR.js → sleep-DiQYrfm9.js} +425 -75
- package/dist/{sleep-DujUvOcb.mjs → sleep-r3RWkGVx.mjs} +425 -75
- package/dist/training/index.d.ts +1 -0
- package/dist/training/trainer-contract.d.ts +468 -0
- package/package.json +1 -1
|
@@ -128,6 +128,14 @@ export declare abstract class BaseAddon<TConfig extends object = Record<string,
|
|
|
128
128
|
private _secretChangeUnsub;
|
|
129
129
|
/** >0 while an OPERATOR's settings write is being applied. */
|
|
130
130
|
private _operatorWriteDepth;
|
|
131
|
+
/**
|
|
132
|
+
* The keychain-aware settings handle (D798). Its `raw` view is the ONLY way
|
|
133
|
+
* to the marker-bearing blobs and stays private to this class: the form
|
|
134
|
+
* hydrate and config resolution need markers, addon code never does.
|
|
135
|
+
*/
|
|
136
|
+
private _secretSettings;
|
|
137
|
+
/** Refs an addon-facing read could not resolve — each is logged once per process. */
|
|
138
|
+
private _loggedUnresolvedReads;
|
|
131
139
|
constructor(defaults: TConfig);
|
|
132
140
|
/**
|
|
133
141
|
* Override to opt out of the automatic `system.ready-state` emission.
|
|
@@ -279,8 +287,25 @@ export declare abstract class BaseAddon<TConfig extends object = Record<string,
|
|
|
279
287
|
* the store for custom option logic (option narrowing, value snapping) to
|
|
280
288
|
* read it per-node — never `ctx.settings.readAddonStore()` directly.
|
|
281
289
|
* `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
|
|
290
|
+
*
|
|
291
|
+
* Keychain values come back RESOLVED (D798): a secret reads as its value,
|
|
292
|
+
* never as a `{ $secret }` marker. One the keychain cannot serve right now
|
|
293
|
+
* stays a marker — "stored, unavailable" (`isSecretMarker()` is true, and it
|
|
294
|
+
* is listed in {@link unresolvedSecrets}) — never `''` and never absent, so
|
|
295
|
+
* it cannot be mistaken for "nothing stored, mint a new one". Writing the
|
|
296
|
+
* resolved blob back is a no-op for every unchanged secret.
|
|
282
297
|
*/
|
|
283
298
|
protected resolveGlobalStore(nodeId?: string, cap?: string): Promise<Record<string, unknown>>;
|
|
299
|
+
private projectForNode;
|
|
300
|
+
/** The PROJECTED store with its markers — the form hydrate only (D798). */
|
|
301
|
+
private readRawProjectedStore;
|
|
302
|
+
/**
|
|
303
|
+
* `{ ...stored, ...overlay }`, except that an overlay member equal to the
|
|
304
|
+
* RESOLVED stored one keeps the stored (marker-bearing) member — so a form
|
|
305
|
+
* hydrated from a resolved overlay still shows a secret as "set", never as
|
|
306
|
+
* its value.
|
|
307
|
+
*/
|
|
308
|
+
private overlayKeepingMarkers;
|
|
284
309
|
/**
|
|
285
310
|
* Whether ONE global key of this addon's store was written, read three-way
|
|
286
311
|
* (D651). For a question a hydrated view cannot answer: `getGlobalSettings`
|
|
@@ -422,6 +447,13 @@ export declare abstract class BaseAddon<TConfig extends object = Record<string,
|
|
|
422
447
|
* ever written back from here.
|
|
423
448
|
*/
|
|
424
449
|
private resolveStoredSecrets;
|
|
450
|
+
/**
|
|
451
|
+
* The marker-bearing settings reads (D798) — private on purpose. Without a
|
|
452
|
+
* keychain the context's own view is already raw.
|
|
453
|
+
*/
|
|
454
|
+
private rawSettings;
|
|
455
|
+
/** An addon-facing read met markers it could not resolve: say so once per ref. */
|
|
456
|
+
private logUnresolvedRead;
|
|
425
457
|
/** Re-resolve the config (a keychain-only change, or a retry) and apply it. */
|
|
426
458
|
private scheduleSecretReresolve;
|
|
427
459
|
/**
|
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* addon
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* The settings view an addon sees once the kernel provides a keychain.
|
|
3
|
+
*
|
|
4
|
+
* READ (D798) — every addon-facing read answers VALUES, never markers:
|
|
5
|
+
* `readAddonStore`, `readAddonStoreResult`, `readAddonStoreKeyResult`,
|
|
6
|
+
* `readDeviceStore`, `readDeviceStoreBatch`. Markers are resolved through the
|
|
7
|
+
* addon's own `ctx.secrets` (owner-checked by the keychain, batched into one
|
|
8
|
+
* round trip per read, served from its cache). A marker that cannot be
|
|
9
|
+
* resolved STAYS a marker — "stored, unavailable right now" — and is reported
|
|
10
|
+
* through `onUnresolved`; it never reads as `''` or as absent, which is what
|
|
11
|
+
* invites a regenerate-and-save over the kept value. Three addons read their
|
|
12
|
+
* raw config and got a marker in place of their secret in one evening after
|
|
13
|
+
* the keychain migration (Wyze, ONVIF, Reolink); this is the root fix.
|
|
14
|
+
*
|
|
15
|
+
* WRITE (D787) — every write goes through the keychain save path, with the
|
|
16
|
+
* write-back of a resolved read made idempotent (`secret-write-back.ts`): an
|
|
17
|
+
* unchanged value becomes its marker again, nothing is put, a patch equal to
|
|
18
|
+
* what is stored is not written at all.
|
|
19
|
+
*
|
|
20
|
+
* RAW — the marker-bearing blob is reachable only through the handle's `raw`
|
|
21
|
+
* view, which `BaseAddon` keeps PRIVATE for the paths that need markers: the
|
|
22
|
+
* admin form hydrate (markers become "set" views), config resolution (which
|
|
23
|
+
* tracks unresolved refs for retry) and the save path itself. No addon code
|
|
24
|
+
* can reach it.
|
|
7
25
|
*
|
|
8
26
|
* A Proxy rather than a copy: an in-process context carries getters (`api`)
|
|
9
27
|
* and a spread would freeze them at wrap time; a Proxy forwards every other
|
|
@@ -12,6 +30,8 @@
|
|
|
12
30
|
import type { AddonContext } from '../interfaces/addon.js';
|
|
13
31
|
import type { SecretsAccess } from '../keychain/secrets-access.js';
|
|
14
32
|
import type { SecretTree } from './secret-paths.js';
|
|
33
|
+
import { type UnresolvedSecret } from './secret-settings-view.js';
|
|
34
|
+
type SettingsView = NonNullable<AddonContext['settings']>;
|
|
15
35
|
export interface SecretAwareSettingsOptions {
|
|
16
36
|
readonly secrets: SecretsAccess;
|
|
17
37
|
/** The addon store's secret tree (schema + `secretStatePaths`). */
|
|
@@ -22,6 +42,29 @@ export interface SecretAwareSettingsOptions {
|
|
|
22
42
|
readonly onOrphaned: (refs: readonly string[]) => void;
|
|
23
43
|
/** Is the write in progress the OPERATOR's (see `SecretWriteInput.operatorWrite`)? */
|
|
24
44
|
readonly isOperatorWrite?: () => boolean;
|
|
45
|
+
/** Told when an addon-facing read met markers it could not resolve. */
|
|
46
|
+
readonly onUnresolved?: (unresolved: readonly UnresolvedSecret[]) => void;
|
|
47
|
+
}
|
|
48
|
+
/** Whether a write reached the store or the keychain. */
|
|
49
|
+
export interface SecretAwareWriteOutcome {
|
|
50
|
+
readonly changed: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface SecretAwareSettingsHandle {
|
|
53
|
+
/** The view addon code gets: resolved reads, secret-aware writes. */
|
|
54
|
+
readonly settings: SettingsView;
|
|
55
|
+
/**
|
|
56
|
+
* The stored blobs WITH markers. For `BaseAddon`'s private use only — the
|
|
57
|
+
* form hydrate, config resolution, the save path. Never hand it to addon code.
|
|
58
|
+
*/
|
|
59
|
+
readonly raw: Pick<SettingsView, 'readAddonStore' | 'readDeviceStore'>;
|
|
60
|
+
/** `settings.writeAddonStore`, also saying whether anything changed. */
|
|
61
|
+
writeAddonStore(patch: Record<string, unknown>): Promise<SecretAwareWriteOutcome>;
|
|
25
62
|
}
|
|
26
|
-
/** The context the addon sees
|
|
63
|
+
/** The context the addon sees, plus the private raw view and write outcome. */
|
|
64
|
+
export declare function createSecretAwareContext(context: AddonContext, opts: SecretAwareSettingsOptions): {
|
|
65
|
+
readonly context: AddonContext;
|
|
66
|
+
readonly handle: SecretAwareSettingsHandle | null;
|
|
67
|
+
};
|
|
68
|
+
/** The context the addon sees: resolved reads, secret-aware writes. */
|
|
27
69
|
export declare function withSecretAwareSettings(context: AddonContext, opts: SecretAwareSettingsOptions): AddonContext;
|
|
70
|
+
export {};
|
|
@@ -73,8 +73,30 @@ export interface ResolvedSecrets<T> {
|
|
|
73
73
|
readonly value: T;
|
|
74
74
|
readonly unresolved: readonly UnresolvedSecret[];
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* What a marker that cannot be resolved becomes:
|
|
78
|
+
* - `omit` (default) — the member is LEFT OUT, so a typed default applies
|
|
79
|
+
* (`config`, `state()`, a driver's device config);
|
|
80
|
+
* - `keep-marker` — the marker STAYS where it is. An addon-facing raw read
|
|
81
|
+
* (D798) answers "stored, but unavailable right now": present, not a string,
|
|
82
|
+
* `isSecretMarker()` true. Never `''`, never absent — both of those read as
|
|
83
|
+
* "nothing stored" and invite a regenerate-and-save over the kept value.
|
|
84
|
+
*/
|
|
85
|
+
export type UnresolvedMarkerMode = 'omit' | 'keep-marker';
|
|
86
|
+
export interface ResolveSecretMarkersOptions {
|
|
87
|
+
readonly unresolved?: UnresolvedMarkerMode;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve only the markers this owner's refs: any other owner's marker is
|
|
90
|
+
* left exactly as it is — not resolved, not reported. A system builtin that
|
|
91
|
+
* keeps OTHER addons' markers in its own store (device-manager holds each
|
|
92
|
+
* driver's) must not ask the keychain for values it may not read.
|
|
93
|
+
*/
|
|
94
|
+
readonly ownedBy?: string;
|
|
95
|
+
}
|
|
96
|
+
/** Is `ref` one of `owner`'s refs? */
|
|
97
|
+
export declare function isSecretRefOwnedBy(ref: string, owner: string): boolean;
|
|
76
98
|
/**
|
|
77
99
|
* Replace every marker in `value` with its keychain value. Returns the SAME
|
|
78
100
|
* reference when there is no marker (no allocation, no keychain call).
|
|
79
101
|
*/
|
|
80
|
-
export declare function resolveSecretMarkers<T>(value: T, secrets: SecretsAccess): Promise<ResolvedSecrets<T>>;
|
|
102
|
+
export declare function resolveSecretMarkers<T>(value: T, secrets: SecretsAccess, options?: ResolveSecretMarkersOptions): Promise<ResolvedSecrets<T>>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SecretsAccess } from '../keychain/secrets-access.js';
|
|
2
|
+
import type { SecretTree } from './secret-paths.js';
|
|
3
|
+
/** An addon tried to replace a stored secret it could not read. Nothing was written. */
|
|
4
|
+
export declare class SecretOverwriteRefusedError extends Error {
|
|
5
|
+
readonly ref: string;
|
|
6
|
+
readonly reason: string;
|
|
7
|
+
constructor(ref: string, reason: string);
|
|
8
|
+
}
|
|
9
|
+
export interface RestoreSecretsInput {
|
|
10
|
+
readonly patch: Record<string, unknown>;
|
|
11
|
+
/** The blob as stored now (markers). */
|
|
12
|
+
readonly stored: Record<string, unknown>;
|
|
13
|
+
readonly secrets: SecretsAccess;
|
|
14
|
+
/** The write is the operator's (a form, an admin API call), not the addon's own code. */
|
|
15
|
+
readonly operatorWrite: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface RestoreSecretsResult {
|
|
18
|
+
readonly patch: Record<string, unknown>;
|
|
19
|
+
/** Refs whose keychain value this pass changed (a `put`). */
|
|
20
|
+
readonly changedRefs: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
/** Restore markers a write-back carries as values. See the file doc. */
|
|
23
|
+
export declare function restoreUnchangedSecrets(input: RestoreSecretsInput): Promise<RestoreSecretsResult>;
|
|
24
|
+
/** Structural equality over JSON-shaped values (key order does not matter). */
|
|
25
|
+
export declare function isJsonEqual(a: unknown, b: unknown): boolean;
|
|
26
|
+
/** The patch without the keys whose value already equals the stored one. */
|
|
27
|
+
export declare function dropUnchangedKeys(patch: Record<string, unknown>, stored: Record<string, unknown>): Record<string, unknown>;
|
|
28
|
+
/** The top-level keys of a blob that hold at least one of `owner`'s markers. */
|
|
29
|
+
export declare function markerKeysOf(blob: Record<string, unknown>, owner: string): Set<string>;
|
|
30
|
+
/**
|
|
31
|
+
* The declared secret tree, widened by every place the STORED blob holds a
|
|
32
|
+
* marker under one of `keys` — so a marker the schema no longer declares (or
|
|
33
|
+
* never declared: Wyze before b4906cec6) still gets the save path's
|
|
34
|
+
* KEEP / SET / CLEAR semantics instead of being overwritten by whatever the
|
|
35
|
+
* addon writes. Markers inside arrays are not added: a row has no id field to
|
|
36
|
+
* match by unless the schema declares one. Only `owner`'s markers count: a
|
|
37
|
+
* builtin that keeps another addon's marker (device-manager) never takes it
|
|
38
|
+
* over.
|
|
39
|
+
*/
|
|
40
|
+
export declare function widenTreeWithStoredMarkers(declared: SecretTree, stored: Record<string, unknown>, keys: readonly string[], owner: string): SecretTree;
|
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-DiQYrfm9.js");
|
|
3
3
|
const require_event_category = require("./event-category-CHduMGvg.js");
|
|
4
4
|
const require_err_msg = require("./err-msg-Dx2Kor0g.js");
|
|
5
5
|
//#region src/generated/cap-input-defaults.ts
|
|
@@ -16,7 +16,7 @@ const require_err_msg = require("./err-msg-Dx2Kor0g.js");
|
|
|
16
16
|
* Plain data, zero Zod: a forked runner must not import the schema barrel
|
|
17
17
|
* (~144MB RSS per runner — D28).
|
|
18
18
|
*
|
|
19
|
-
* Coverage: 24 caps,
|
|
19
|
+
* Coverage: 24 caps, 61 methods with defaults.
|
|
20
20
|
*/
|
|
21
21
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
22
22
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -254,10 +254,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
|
254
254
|
}
|
|
255
255
|
},
|
|
256
256
|
"terminal-session": { "pullOutput": { "waitMs": 0 } },
|
|
257
|
-
"user-management": {
|
|
258
|
-
"createApiKey": { "isAdmin": false },
|
|
259
|
-
"createUser": { "isAdmin": false }
|
|
260
|
-
},
|
|
257
|
+
"user-management": { "createUser": { "isAdmin": false } },
|
|
261
258
|
"vector-store": {
|
|
262
259
|
"declareIndex": { "metric": "cosine" },
|
|
263
260
|
"scan": { "cursor": 0 }
|
|
@@ -337,7 +334,7 @@ function materialise(defaults) {
|
|
|
337
334
|
* barrel (`ALL_CAPABILITY_DEFINITIONS`), which would cost ~144MB RSS per
|
|
338
335
|
* forked runner. See docs/decisions/adr-0028.md.
|
|
339
336
|
*
|
|
340
|
-
* Coverage:
|
|
337
|
+
* Coverage: 26 collection caps, 43 array methods.
|
|
341
338
|
*/
|
|
342
339
|
var COLLECTION_ARRAY_METHODS = Object.freeze({
|
|
343
340
|
"addon-pages-source": ["listPages"],
|
|
@@ -375,6 +372,7 @@ var COLLECTION_ARRAY_METHODS = Object.freeze({
|
|
|
375
372
|
"recording": ["listSources"],
|
|
376
373
|
"storage-occupancy": ["getOccupancy"],
|
|
377
374
|
"storage-provider": ["list"],
|
|
375
|
+
"training-provider": ["describe", "listJobs"],
|
|
378
376
|
"turn-provider": ["getTurnServers"],
|
|
379
377
|
"user-passkeys": ["listPasskeys"],
|
|
380
378
|
"videoclips": ["listClips", "listSources"]
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $t as normalizeSecretOwner, A as adminUiCapability, At as PEER_BYTES_MAX_OUTSTANDING, C as deviceOpsCapability, Ct as clearKnownSecrets, Dt as scrubKnownSecrets, Et as registerKnownSecret, I as expandCapMethods, It as DisposerChain, Jt as arrayItemFieldPath, K as ReadinessRegistry, Lt as BaseAddon, Mt as PEER_BYTES_TICKET_TTL_MS, O as describeCustomActions, Ot as shortSecretRefHash, Pt as DATAPLANE_SECRET_HEADER, Qt as isSecretRef, Rt as normalizeAddonInitResult, St as MIN_SCRUBBED_LENGTH, T as DEVICE_CHILDREN_BATCH_MAX, Tt as knownSecretCount, U as nodePin, W as readNodePin, X as scopeKey, Xt as formatSecretScope, Yt as buildSecretRef, Zt as globalSecretScope, _n as isSecretMarkerLike, a as asJsonObject, b as collectZodSecretPaths, bt as REVALIDATE_AFTER_MS, d as BOOT_RECOVERY_BACKOFF_MS, en as parseSecretRef, f as DEVICE_SCOPED_CAPS, fn as SECRET_CLEAR, gn as isSecretMarker, h as createEventBusSliceSource, hn as isSecretFieldView, in as emitReadiness, jt as PEER_BYTES_STALL_MS, kt as PEER_BYTES_CHUNK_BYTES, m as createDeviceProxy, mn as isSecretClear, p as isDeviceScopedCap, pn as classifySecretWrite, q as ReadinessTimeoutError, qt as SECRET_REF_SCHEME, s as asString, t as sleep, u as parseJsonUnknown, vn as makeSecretMarker, w as viewerUiCapability, wt as forgetKnownSecret, x as isZodSecret, xt as createSecretsAccess, yn as toSecretFieldView, yt as resolveSecretViewsIn } from "./sleep-
|
|
1
|
+
import { $t as normalizeSecretOwner, A as adminUiCapability, At as PEER_BYTES_MAX_OUTSTANDING, C as deviceOpsCapability, Ct as clearKnownSecrets, Dt as scrubKnownSecrets, Et as registerKnownSecret, I as expandCapMethods, It as DisposerChain, Jt as arrayItemFieldPath, K as ReadinessRegistry, Lt as BaseAddon, Mt as PEER_BYTES_TICKET_TTL_MS, O as describeCustomActions, Ot as shortSecretRefHash, Pt as DATAPLANE_SECRET_HEADER, Qt as isSecretRef, Rt as normalizeAddonInitResult, St as MIN_SCRUBBED_LENGTH, T as DEVICE_CHILDREN_BATCH_MAX, Tt as knownSecretCount, U as nodePin, W as readNodePin, X as scopeKey, Xt as formatSecretScope, Yt as buildSecretRef, Zt as globalSecretScope, _n as isSecretMarkerLike, a as asJsonObject, b as collectZodSecretPaths, bt as REVALIDATE_AFTER_MS, d as BOOT_RECOVERY_BACKOFF_MS, en as parseSecretRef, f as DEVICE_SCOPED_CAPS, fn as SECRET_CLEAR, gn as isSecretMarker, h as createEventBusSliceSource, hn as isSecretFieldView, in as emitReadiness, jt as PEER_BYTES_STALL_MS, kt as PEER_BYTES_CHUNK_BYTES, m as createDeviceProxy, mn as isSecretClear, p as isDeviceScopedCap, pn as classifySecretWrite, q as ReadinessTimeoutError, qt as SECRET_REF_SCHEME, s as asString, t as sleep, u as parseJsonUnknown, vn as makeSecretMarker, w as viewerUiCapability, wt as forgetKnownSecret, x as isZodSecret, xt as createSecretsAccess, yn as toSecretFieldView, yt as resolveSecretViewsIn } from "./sleep-r3RWkGVx.mjs";
|
|
2
2
|
import { t as EventCategory } from "./event-category-DaIZi00R.mjs";
|
|
3
3
|
import { a as DeviceType, t as errMsg } from "./err-msg-DX6i_MY4.mjs";
|
|
4
4
|
//#region src/generated/cap-input-defaults.ts
|
|
@@ -15,7 +15,7 @@ import { a as DeviceType, t as errMsg } from "./err-msg-DX6i_MY4.mjs";
|
|
|
15
15
|
* Plain data, zero Zod: a forked runner must not import the schema barrel
|
|
16
16
|
* (~144MB RSS per runner — D28).
|
|
17
17
|
*
|
|
18
|
-
* Coverage: 24 caps,
|
|
18
|
+
* Coverage: 24 caps, 61 methods with defaults.
|
|
19
19
|
*/
|
|
20
20
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
21
21
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -253,10 +253,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
|
253
253
|
}
|
|
254
254
|
},
|
|
255
255
|
"terminal-session": { "pullOutput": { "waitMs": 0 } },
|
|
256
|
-
"user-management": {
|
|
257
|
-
"createApiKey": { "isAdmin": false },
|
|
258
|
-
"createUser": { "isAdmin": false }
|
|
259
|
-
},
|
|
256
|
+
"user-management": { "createUser": { "isAdmin": false } },
|
|
260
257
|
"vector-store": {
|
|
261
258
|
"declareIndex": { "metric": "cosine" },
|
|
262
259
|
"scan": { "cursor": 0 }
|
|
@@ -336,7 +333,7 @@ function materialise(defaults) {
|
|
|
336
333
|
* barrel (`ALL_CAPABILITY_DEFINITIONS`), which would cost ~144MB RSS per
|
|
337
334
|
* forked runner. See docs/decisions/adr-0028.md.
|
|
338
335
|
*
|
|
339
|
-
* Coverage:
|
|
336
|
+
* Coverage: 26 collection caps, 43 array methods.
|
|
340
337
|
*/
|
|
341
338
|
var COLLECTION_ARRAY_METHODS = Object.freeze({
|
|
342
339
|
"addon-pages-source": ["listPages"],
|
|
@@ -374,6 +371,7 @@ var COLLECTION_ARRAY_METHODS = Object.freeze({
|
|
|
374
371
|
"recording": ["listSources"],
|
|
375
372
|
"storage-occupancy": ["getOccupancy"],
|
|
376
373
|
"storage-provider": ["list"],
|
|
374
|
+
"training-provider": ["describe", "listJobs"],
|
|
377
375
|
"turn-provider": ["getTurnServers"],
|
|
378
376
|
"user-passkeys": ["listPasskeys"],
|
|
379
377
|
"videoclips": ["listClips", "listSources"]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The viewer app's custom-scheme callback — the ONE list of URLs a hub flow
|
|
3
|
+
* may hand a browser back to the native app at.
|
|
4
|
+
*
|
|
5
|
+
* Two readers, one answer: the admin-ui login page (`redirect=` for the
|
|
6
|
+
* native sign-in handoff) and the hub itself (`auth.beginExternalLink`'s
|
|
7
|
+
* `returnTo` for a native account link, D801). Both validate against this
|
|
8
|
+
* list, so a scheme added for one flow can never be accepted by one side and
|
|
9
|
+
* refused by the other.
|
|
10
|
+
*
|
|
11
|
+
* `camstack` is the production app; `camstack.dev` the dev client
|
|
12
|
+
* (`APP_VARIANT=development`). Exact match after canonicalisation — no
|
|
13
|
+
* query or fragment riders, no http(s).
|
|
14
|
+
*/
|
|
15
|
+
export declare const APP_AUTH_CALLBACK_URLS: readonly string[];
|
|
16
|
+
/** Longest raw callback value considered at all. */
|
|
17
|
+
export declare const APP_AUTH_CALLBACK_MAX_LENGTH = 512;
|
|
18
|
+
/**
|
|
19
|
+
* The variants the OS / linking layer produces for the same callback:
|
|
20
|
+
* `scheme:///auth-callback` (expo-linking's empty-host standalone form — three
|
|
21
|
+
* slashes) and a trailing `/` both mean `scheme://auth-callback`. Nothing else
|
|
22
|
+
* is normalised: riders keep failing the exact match.
|
|
23
|
+
*/
|
|
24
|
+
export declare function canonicalizeAppCallback(raw: string): string;
|
|
25
|
+
/** The canonical allowlisted callback `raw` names, or `null`. */
|
|
26
|
+
export declare function parseAppAuthCallback(raw: string | null | undefined): string | null;
|
|
27
|
+
/** True for a URL with a scheme (`camstack://…`, `https://…`) — not a hub-relative path. */
|
|
28
|
+
export declare function hasUrlScheme(url: string): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cookie that binds an SSO sign-in to the browser that started it.
|
|
3
|
+
*
|
|
4
|
+
* An IdP `/start` sets it to a random value and keeps only its SHA-256 in the
|
|
5
|
+
* server-side pending state; the login bridge carries that hash. The hub's
|
|
6
|
+
* `/api/auth/sso/finish` swaps a bridge for a session only when the request
|
|
7
|
+
* presents the cookie whose hash the bridge names — so a bridge copied out of
|
|
8
|
+
* a URL (history, a proxy log, a screenshot) is useless in any other browser.
|
|
9
|
+
* The finish clears the cookie, and records the bridge's `jti` so the same
|
|
10
|
+
* bridge never finishes twice.
|
|
11
|
+
*
|
|
12
|
+
* One name, two readers (the OIDC addon that sets it, the hub that checks it).
|
|
13
|
+
*/
|
|
14
|
+
export declare const SSO_STATE_COOKIE = "camstack_sso_state";
|
|
15
|
+
/** Seconds the state cookie lives — the pending IdP state lasts 5 minutes, the bridge 5 more. */
|
|
16
|
+
export declare const SSO_STATE_COOKIE_MAX_AGE_SEC = 600;
|
|
@@ -50,6 +50,9 @@ export declare const addonRoutesCapability: {
|
|
|
50
50
|
authenticated: "authenticated";
|
|
51
51
|
}>>;
|
|
52
52
|
description: z.ZodOptional<z.ZodString>;
|
|
53
|
+
rateLimit: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
auth: "auth";
|
|
55
|
+
}>>;
|
|
53
56
|
}, z.core.$strip>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
54
57
|
/**
|
|
55
58
|
* Cross-process dispatch entry point. Forked addons implement this
|
|
@@ -139,8 +139,8 @@ declare const AddonAutoUpdateSchema: z.ZodEnum<{
|
|
|
139
139
|
* copy when the node registers again (only once the hub no longer has it).
|
|
140
140
|
*/
|
|
141
141
|
declare const UninstallNodeOutcomeSchema: z.ZodEnum<{
|
|
142
|
-
failed: "failed";
|
|
143
142
|
refused: "refused";
|
|
143
|
+
failed: "failed";
|
|
144
144
|
uninstalled: "uninstalled";
|
|
145
145
|
"not-installed": "not-installed";
|
|
146
146
|
"pending-reconnect": "pending-reconnect";
|
|
@@ -148,8 +148,8 @@ declare const UninstallNodeOutcomeSchema: z.ZodEnum<{
|
|
|
148
148
|
declare const UninstallNodeResultSchema: z.ZodObject<{
|
|
149
149
|
nodeId: z.ZodString;
|
|
150
150
|
outcome: z.ZodEnum<{
|
|
151
|
-
failed: "failed";
|
|
152
151
|
refused: "refused";
|
|
152
|
+
failed: "failed";
|
|
153
153
|
uninstalled: "uninstalled";
|
|
154
154
|
"not-installed": "not-installed";
|
|
155
155
|
"pending-reconnect": "pending-reconnect";
|
|
@@ -165,8 +165,8 @@ declare const UninstallPackageResultSchema: z.ZodObject<{
|
|
|
165
165
|
results: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
166
166
|
nodeId: z.ZodString;
|
|
167
167
|
outcome: z.ZodEnum<{
|
|
168
|
-
failed: "failed";
|
|
169
168
|
refused: "refused";
|
|
169
|
+
failed: "failed";
|
|
170
170
|
uninstalled: "uninstalled";
|
|
171
171
|
"not-installed": "not-installed";
|
|
172
172
|
"pending-reconnect": "pending-reconnect";
|
|
@@ -427,8 +427,8 @@ export declare const addonsCapability: {
|
|
|
427
427
|
results: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
428
428
|
nodeId: z.ZodString;
|
|
429
429
|
outcome: z.ZodEnum<{
|
|
430
|
-
failed: "failed";
|
|
431
430
|
refused: "refused";
|
|
431
|
+
failed: "failed";
|
|
432
432
|
uninstalled: "uninstalled";
|
|
433
433
|
"not-installed": "not-installed";
|
|
434
434
|
"pending-reconnect": "pending-reconnect";
|
|
@@ -57,6 +57,34 @@ declare const BackupDestinationInfoSchema: z.ZodObject<{
|
|
|
57
57
|
lastAttemptAt: z.ZodOptional<z.ZodNumber>;
|
|
58
58
|
lastError: z.ZodOptional<z.ZodString>;
|
|
59
59
|
}, z.core.$strip>;
|
|
60
|
+
/**
|
|
61
|
+
* How an archive is encrypted (operator decision 2026-10-09): to a backup
|
|
62
|
+
* PUBLIC key the hub holds, so only the operator's secret key opens it.
|
|
63
|
+
* Absent on a plain `.tar.gz` — every archive made before encryption, or
|
|
64
|
+
* with it off — which restores without a key.
|
|
65
|
+
*/
|
|
66
|
+
declare const BackupArchiveEncryptionSchema: z.ZodObject<{
|
|
67
|
+
scheme: z.ZodString;
|
|
68
|
+
keyId: z.ZodString;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
/**
|
|
71
|
+
* The backup encryption setting. The hub keeps PUBLIC keys only: the active
|
|
72
|
+
* one new archives are encrypted to, and the retired ones older archives
|
|
73
|
+
* still need. The secret key is shown once, at `setupEncryption`.
|
|
74
|
+
*/
|
|
75
|
+
declare const BackupEncryptionStatusSchema: z.ZodObject<{
|
|
76
|
+
enabled: z.ZodBoolean;
|
|
77
|
+
active: z.ZodNullable<z.ZodObject<{
|
|
78
|
+
keyId: z.ZodString;
|
|
79
|
+
publicKey: z.ZodString;
|
|
80
|
+
createdAt: z.ZodNumber;
|
|
81
|
+
}, z.core.$strip>>;
|
|
82
|
+
keys: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
83
|
+
keyId: z.ZodString;
|
|
84
|
+
createdAt: z.ZodNumber;
|
|
85
|
+
retiredAt: z.ZodNullable<z.ZodNumber>;
|
|
86
|
+
}, z.core.$strip>>>;
|
|
87
|
+
}, z.core.$strip>;
|
|
60
88
|
/**
|
|
61
89
|
* Per-archive entry returned by `backup.listArchives({ destinationId })`.
|
|
62
90
|
* Same shape the destination drill-in renders. Sourced from the per-
|
|
@@ -69,6 +97,10 @@ declare const BackupArchiveEntrySchema: z.ZodObject<{
|
|
|
69
97
|
sizeBytes: z.ZodNumber;
|
|
70
98
|
label: z.ZodOptional<z.ZodString>;
|
|
71
99
|
locations: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
100
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
scheme: z.ZodString;
|
|
102
|
+
keyId: z.ZodString;
|
|
103
|
+
}, z.core.$strip>>;
|
|
72
104
|
}, z.core.$strip>;
|
|
73
105
|
declare const BackupEntrySchema: z.ZodObject<{
|
|
74
106
|
id: z.ZodString;
|
|
@@ -77,6 +109,10 @@ declare const BackupEntrySchema: z.ZodObject<{
|
|
|
77
109
|
createdAt: z.ZodNumber;
|
|
78
110
|
sizeBytes: z.ZodNumber;
|
|
79
111
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
112
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
scheme: z.ZodString;
|
|
114
|
+
keyId: z.ZodString;
|
|
115
|
+
}, z.core.$strip>>;
|
|
80
116
|
}, z.core.$strip>;
|
|
81
117
|
declare const ArchiveEntrySchema: z.ZodObject<{
|
|
82
118
|
path: z.ZodString;
|
|
@@ -200,6 +236,10 @@ declare const BackupTriggerResultSchema: z.ZodObject<{
|
|
|
200
236
|
createdAt: z.ZodNumber;
|
|
201
237
|
sizeBytes: z.ZodNumber;
|
|
202
238
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
239
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
240
|
+
scheme: z.ZodString;
|
|
241
|
+
keyId: z.ZodString;
|
|
242
|
+
}, z.core.$strip>>;
|
|
203
243
|
}, z.core.$strip>>>;
|
|
204
244
|
}, z.core.$strip>;
|
|
205
245
|
/**
|
|
@@ -293,6 +333,10 @@ export declare const backupCapability: {
|
|
|
293
333
|
createdAt: z.ZodNumber;
|
|
294
334
|
sizeBytes: z.ZodNumber;
|
|
295
335
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
336
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
337
|
+
scheme: z.ZodString;
|
|
338
|
+
keyId: z.ZodString;
|
|
339
|
+
}, z.core.$strip>>;
|
|
296
340
|
}, z.core.$strip>>>;
|
|
297
341
|
}, z.core.$strip>, "mutation">;
|
|
298
342
|
/**
|
|
@@ -354,6 +398,10 @@ export declare const backupCapability: {
|
|
|
354
398
|
createdAt: z.ZodNumber;
|
|
355
399
|
sizeBytes: z.ZodNumber;
|
|
356
400
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
401
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
402
|
+
scheme: z.ZodString;
|
|
403
|
+
keyId: z.ZodString;
|
|
404
|
+
}, z.core.$strip>>;
|
|
357
405
|
}, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
358
406
|
/**
|
|
359
407
|
* Pre-backup snapshot of the well-known locations on disk — sizes
|
|
@@ -413,7 +461,53 @@ export declare const backupCapability: {
|
|
|
413
461
|
destinationId: z.ZodString;
|
|
414
462
|
backupId: z.ZodString;
|
|
415
463
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
464
|
+
backupSecretKey: z.ZodOptional<z.ZodString>;
|
|
416
465
|
}, z.core.$strip>, z.ZodVoid, "mutation">;
|
|
466
|
+
/** The encryption setting — public keys only. */
|
|
467
|
+
readonly getEncryption: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
|
|
468
|
+
enabled: z.ZodBoolean;
|
|
469
|
+
active: z.ZodNullable<z.ZodObject<{
|
|
470
|
+
keyId: z.ZodString;
|
|
471
|
+
publicKey: z.ZodString;
|
|
472
|
+
createdAt: z.ZodNumber;
|
|
473
|
+
}, z.core.$strip>>;
|
|
474
|
+
keys: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
475
|
+
keyId: z.ZodString;
|
|
476
|
+
createdAt: z.ZodNumber;
|
|
477
|
+
retiredAt: z.ZodNullable<z.ZodNumber>;
|
|
478
|
+
}, z.core.$strip>>>;
|
|
479
|
+
}, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
480
|
+
/**
|
|
481
|
+
* Turn encryption on, or replace the key: generates a new key pair, keeps
|
|
482
|
+
* the PUBLIC key, and returns the SECRET key — once. It is never stored
|
|
483
|
+
* on the hub and cannot be shown again; archives made from now on need
|
|
484
|
+
* it to be restored. A previous key is retired: archives made with it
|
|
485
|
+
* still need IT.
|
|
486
|
+
*/
|
|
487
|
+
readonly setupEncryption: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
488
|
+
keyId: z.ZodString;
|
|
489
|
+
secretKey: z.ZodString;
|
|
490
|
+
publicKey: z.ZodString;
|
|
491
|
+
createdAt: z.ZodNumber;
|
|
492
|
+
replacedKeyId: z.ZodNullable<z.ZodString>;
|
|
493
|
+
}, z.core.$strip>, "mutation">;
|
|
494
|
+
/** New archives are plain again. Existing encrypted archives keep needing their key. */
|
|
495
|
+
readonly disableEncryption: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
496
|
+
disabledKeyId: z.ZodNullable<z.ZodString>;
|
|
497
|
+
}, z.core.$strip>, "mutation">;
|
|
498
|
+
/**
|
|
499
|
+
* Does this secret key parse, and which backup key is it? A mutation so
|
|
500
|
+
* the key never travels in a URL. Nothing is stored.
|
|
501
|
+
*/
|
|
502
|
+
readonly checkBackupKey: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
503
|
+
backupSecretKey: z.ZodString;
|
|
504
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
505
|
+
valid: z.ZodBoolean;
|
|
506
|
+
keyId: z.ZodNullable<z.ZodString>;
|
|
507
|
+
known: z.ZodBoolean;
|
|
508
|
+
active: z.ZodBoolean;
|
|
509
|
+
error: z.ZodOptional<z.ZodString>;
|
|
510
|
+
}, z.core.$strip>, "mutation">;
|
|
417
511
|
readonly delete: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
418
512
|
destinationId: z.ZodString;
|
|
419
513
|
backupId: z.ZodString;
|
|
@@ -432,6 +526,10 @@ export declare const backupCapability: {
|
|
|
432
526
|
sizeBytes: z.ZodNumber;
|
|
433
527
|
label: z.ZodOptional<z.ZodString>;
|
|
434
528
|
locations: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
529
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
530
|
+
scheme: z.ZodString;
|
|
531
|
+
keyId: z.ZodString;
|
|
532
|
+
}, z.core.$strip>>;
|
|
435
533
|
}, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
436
534
|
/**
|
|
437
535
|
* Upsert a per-destination policy row. The `locationId` MUST be
|
|
@@ -510,7 +608,9 @@ export declare const backupCapability: {
|
|
|
510
608
|
};
|
|
511
609
|
};
|
|
512
610
|
export type IBackupProvider = InferProvider<typeof backupCapability>;
|
|
513
|
-
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupArchiveEntrySchema, BackupDestinationInfoSchema, BackupEntrySchema, BackupRunPhaseSchema, BackupRunSchema, BackupRunStateSchema, BackupScheduleSchema, BackupSubDestinationInfoSchema, BackupTriggerResultSchema, LocationStatSchema, };
|
|
611
|
+
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupArchiveEncryptionSchema, BackupArchiveEntrySchema, BackupEncryptionStatusSchema, BackupDestinationInfoSchema, BackupEntrySchema, BackupRunPhaseSchema, BackupRunSchema, BackupRunStateSchema, BackupScheduleSchema, BackupSubDestinationInfoSchema, BackupTriggerResultSchema, LocationStatSchema, };
|
|
612
|
+
export type BackupArchiveEncryption = z.infer<typeof BackupArchiveEncryptionSchema>;
|
|
613
|
+
export type BackupEncryptionStatus = z.infer<typeof BackupEncryptionStatusSchema>;
|
|
514
614
|
export type BackupRunState = z.infer<typeof BackupRunStateSchema>;
|
|
515
615
|
export type BackupRunPhase = z.infer<typeof BackupRunPhaseSchema>;
|
|
516
616
|
export type BackupRun = z.infer<typeof BackupRunSchema>;
|
|
@@ -47,8 +47,8 @@ import { type InferProvider } from './capability-definition.js';
|
|
|
47
47
|
*/
|
|
48
48
|
export declare const BrokerStatusEnum: z.ZodEnum<{
|
|
49
49
|
error: "error";
|
|
50
|
-
connecting: "connecting";
|
|
51
50
|
unreachable: "unreachable";
|
|
51
|
+
connecting: "connecting";
|
|
52
52
|
connected: "connected";
|
|
53
53
|
disconnected: "disconnected";
|
|
54
54
|
"auth-failed": "auth-failed";
|
|
@@ -61,8 +61,8 @@ declare const BrokerInfoSchema: z.ZodObject<{
|
|
|
61
61
|
kind: z.ZodString;
|
|
62
62
|
status: z.ZodEnum<{
|
|
63
63
|
error: "error";
|
|
64
|
-
connecting: "connecting";
|
|
65
64
|
unreachable: "unreachable";
|
|
65
|
+
connecting: "connecting";
|
|
66
66
|
connected: "connected";
|
|
67
67
|
disconnected: "disconnected";
|
|
68
68
|
"auth-failed": "auth-failed";
|
|
@@ -162,8 +162,8 @@ export declare const brokerCapability: {
|
|
|
162
162
|
kind: z.ZodString;
|
|
163
163
|
status: z.ZodEnum<{
|
|
164
164
|
error: "error";
|
|
165
|
-
connecting: "connecting";
|
|
166
165
|
unreachable: "unreachable";
|
|
166
|
+
connecting: "connecting";
|
|
167
167
|
connected: "connected";
|
|
168
168
|
disconnected: "disconnected";
|
|
169
169
|
"auth-failed": "auth-failed";
|
|
@@ -181,8 +181,8 @@ export declare const brokerCapability: {
|
|
|
181
181
|
kind: z.ZodString;
|
|
182
182
|
status: z.ZodEnum<{
|
|
183
183
|
error: "error";
|
|
184
|
-
connecting: "connecting";
|
|
185
184
|
unreachable: "unreachable";
|
|
185
|
+
connecting: "connecting";
|
|
186
186
|
connected: "connected";
|
|
187
187
|
disconnected: "disconnected";
|
|
188
188
|
"auth-failed": "auth-failed";
|