@camstack/addon-smtp-nodemailer 1.2.151 → 1.2.152
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/CHANGELOG.md +6 -0
- package/dist/smtp.addon.js +362 -469
- package/dist/smtp.addon.mjs +362 -469
- package/package.json +2 -2
package/dist/smtp.addon.mjs
CHANGED
|
@@ -36,7 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
38
38
|
//#endregion
|
|
39
|
-
//#region ../types/dist/event-category-
|
|
39
|
+
//#region ../types/dist/event-category-78tcBemo.mjs
|
|
40
40
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
41
41
|
EventCategory["SystemBoot"] = "system.boot";
|
|
42
42
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -157,6 +157,23 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
157
157
|
*/
|
|
158
158
|
EventCategory["AddonLoadRecovered"] = "addon.load-recovered";
|
|
159
159
|
/**
|
|
160
|
+
* An addon is RUNNING although its installed package is below what the
|
|
161
|
+
* running server requires (`camstack.requires.addons` of the server, or the
|
|
162
|
+
* addon's own `requires.server`). Raised once per streak by the unsupported-
|
|
163
|
+
* addon tracker, on the hub and on agents; AlertCenter turns it into one
|
|
164
|
+
* operator alert per node and package. The addon is never held back for it.
|
|
165
|
+
*
|
|
166
|
+
* Payload: `{ packageName, addonId, nodeId, installedVersion, requiredMinimum, serverVersion, unmet }`.
|
|
167
|
+
*/
|
|
168
|
+
EventCategory["AddonUnsupportedVersion"] = "addon.unsupported-version";
|
|
169
|
+
/**
|
|
170
|
+
* The package of an {@link AddonUnsupportedVersion} alert reached a supported
|
|
171
|
+
* version, or is no longer installed on the node. AlertCenter dismisses the matching alert.
|
|
172
|
+
*
|
|
173
|
+
* Payload: `{ packageName, addonId, nodeId }`.
|
|
174
|
+
*/
|
|
175
|
+
EventCategory["AddonUnsupportedResolved"] = "addon.unsupported-resolved";
|
|
176
|
+
/**
|
|
160
177
|
* Monitor scheduled the next retry for a failed addon. Transient —
|
|
161
178
|
* surfaced to the UI for live-updating the "next retry in Ns"
|
|
162
179
|
* countdown on the Addons page row, NOT persisted as an alert.
|
|
@@ -267,7 +284,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
267
284
|
EventCategory["ProcessRestarted"] = "process.restarted";
|
|
268
285
|
/**
|
|
269
286
|
* The SET of storage locations changed — one was created, edited, enabled,
|
|
270
|
-
* disabled or deleted through
|
|
287
|
+
* disabled or deleted through the location instances or the forced-delete action.
|
|
271
288
|
*
|
|
272
289
|
* Telemetry, not a transaction (D8/D11): every consumer that re-resolves on
|
|
273
290
|
* it must also converge on its own periodic path, because a dropped event
|
|
@@ -6018,7 +6035,7 @@ var ZodIssueCode = {
|
|
|
6018
6035
|
var ZodFirstPartyTypeKind;
|
|
6019
6036
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6020
6037
|
//#endregion
|
|
6021
|
-
//#region ../types/dist/sleep-
|
|
6038
|
+
//#region ../types/dist/sleep-CQP-REJp.mjs
|
|
6022
6039
|
/**
|
|
6023
6040
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6024
6041
|
* window to float samples (D455).
|
|
@@ -6382,6 +6399,59 @@ Object.fromEntries([
|
|
|
6382
6399
|
function isValuelessField(field) {
|
|
6383
6400
|
return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button" || field.type === "account-sign-in" || field.type === "secret-presence";
|
|
6384
6401
|
}
|
|
6402
|
+
/**
|
|
6403
|
+
* Base collector: flatten a hydrated `ConfigUISchemaWithValues` into
|
|
6404
|
+
* `key → { value, default }`, recursing through `group` and `sub-tabs`
|
|
6405
|
+
* layout fields. Keeping `value` and `default` SEPARATE (rather than
|
|
6406
|
+
* pre-resolving) lets callers both read the effective value AND detect
|
|
6407
|
+
* overrides (`value` differs from `default`). Structural over `unknown`;
|
|
6408
|
+
* malformed input yields an empty map, never throws.
|
|
6409
|
+
*/
|
|
6410
|
+
function collectHydratedFieldEntries(schema) {
|
|
6411
|
+
const out = /* @__PURE__ */ new Map();
|
|
6412
|
+
if (typeof schema !== "object" || schema === null) return out;
|
|
6413
|
+
const sections = schema.sections;
|
|
6414
|
+
if (!Array.isArray(sections)) return out;
|
|
6415
|
+
for (const section of sections) if (typeof section === "object" && section !== null) collectFieldEntriesInto(section.fields, out);
|
|
6416
|
+
return out;
|
|
6417
|
+
}
|
|
6418
|
+
/** Recursive field walker for {@link collectHydratedFieldEntries}. */
|
|
6419
|
+
function collectFieldEntriesInto(fields, into) {
|
|
6420
|
+
if (!Array.isArray(fields)) return;
|
|
6421
|
+
for (const field of fields) {
|
|
6422
|
+
if (typeof field !== "object" || field === null) continue;
|
|
6423
|
+
const type = field.type;
|
|
6424
|
+
if (type === "group") {
|
|
6425
|
+
collectFieldEntriesInto(field.fields, into);
|
|
6426
|
+
continue;
|
|
6427
|
+
}
|
|
6428
|
+
if (type === "sub-tabs") {
|
|
6429
|
+
const tabs = field.tabs;
|
|
6430
|
+
if (Array.isArray(tabs)) {
|
|
6431
|
+
for (const tab of tabs) if (typeof tab === "object" && tab !== null) collectFieldEntriesInto(tab.fields, into);
|
|
6432
|
+
}
|
|
6433
|
+
continue;
|
|
6434
|
+
}
|
|
6435
|
+
const key = field.key;
|
|
6436
|
+
if (typeof key !== "string" || key.length === 0) continue;
|
|
6437
|
+
if (!("value" in field)) continue;
|
|
6438
|
+
into.set(key, {
|
|
6439
|
+
value: field.value,
|
|
6440
|
+
default: field.default
|
|
6441
|
+
});
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6444
|
+
/**
|
|
6445
|
+
* Flatten a hydrated settings payload into `key → EFFECTIVE value`
|
|
6446
|
+
* (`value ?? default`). The read-side inverse of `hydrateSchema` for the
|
|
6447
|
+
* common "just give me the resolved values" case. Built on
|
|
6448
|
+
* {@link collectHydratedFieldEntries}.
|
|
6449
|
+
*/
|
|
6450
|
+
function collectHydratedFieldValues(schema) {
|
|
6451
|
+
const out = /* @__PURE__ */ new Map();
|
|
6452
|
+
for (const [key, entry] of collectHydratedFieldEntries(schema)) out.set(key, entry.value ?? entry.default);
|
|
6453
|
+
return out;
|
|
6454
|
+
}
|
|
6385
6455
|
function hydrateSchema(schema, values, options = {}) {
|
|
6386
6456
|
return {
|
|
6387
6457
|
...schema.tabs ? { tabs: [...schema.tabs] } : {},
|
|
@@ -7266,17 +7336,35 @@ var RecordIntegrationInstances = class {
|
|
|
7266
7336
|
...kind !== void 0 ? { kind } : {}
|
|
7267
7337
|
});
|
|
7268
7338
|
if (minted === void 0) throw new Error("createInstance needs an id: this provider does not mint one");
|
|
7339
|
+
const initial = this.hooks.initialBody(name, kind);
|
|
7340
|
+
const patch = this.patchOf(values ?? {});
|
|
7341
|
+
if (Object.keys(patch).length > 0) Object.assign(patch, await this.hooks.validateWrite?.({
|
|
7342
|
+
kind,
|
|
7343
|
+
body: {
|
|
7344
|
+
...initial,
|
|
7345
|
+
...patch
|
|
7346
|
+
}
|
|
7347
|
+
}));
|
|
7269
7348
|
await this.handle.put({
|
|
7270
7349
|
id: minted,
|
|
7271
|
-
data:
|
|
7350
|
+
data: initial
|
|
7272
7351
|
}, { ifRev: 0 });
|
|
7273
|
-
const patch = this.patchOf(values ?? {});
|
|
7274
7352
|
if (Object.keys(patch).length > 0) await this.handle.patch(minted, patch);
|
|
7275
7353
|
await this.hooks.onChanged?.(minted, "created");
|
|
7276
7354
|
return { id: minted };
|
|
7277
7355
|
};
|
|
7278
7356
|
updateInstance = async ({ id, name, values }) => {
|
|
7279
7357
|
const patch = this.patchOf(values);
|
|
7358
|
+
if (this.hooks.validateWrite !== void 0 && Object.keys(patch).length > 0) {
|
|
7359
|
+
const stored = await this.handle.get(id);
|
|
7360
|
+
if (stored !== null) Object.assign(patch, await this.hooks.validateWrite({
|
|
7361
|
+
kind: void 0,
|
|
7362
|
+
body: {
|
|
7363
|
+
...stored.data,
|
|
7364
|
+
...patch
|
|
7365
|
+
}
|
|
7366
|
+
}));
|
|
7367
|
+
}
|
|
7280
7368
|
if (name !== void 0) patch[this.nameField] = name;
|
|
7281
7369
|
await this.handle.patch(id, patch);
|
|
7282
7370
|
await this.hooks.onChanged?.(id, "updated");
|
|
@@ -7587,6 +7675,21 @@ var SCOPED_SETTINGS_SCOPES = [
|
|
|
7587
7675
|
"device-defaults",
|
|
7588
7676
|
"node"
|
|
7589
7677
|
];
|
|
7678
|
+
/** The one refusal of a key a scope did not declare. */
|
|
7679
|
+
function assertDeclaredKeys(keys, declared) {
|
|
7680
|
+
const undeclared = keys.filter((key) => !declared.has(key));
|
|
7681
|
+
if (undeclared.length > 0) throw new Error(`scoped settings: [${undeclared.join(", ")}] not declared for this scope (declared: [${[...declared].join(", ")}])`);
|
|
7682
|
+
}
|
|
7683
|
+
/** Build the handle over an addon's scoped read, write and unset. */
|
|
7684
|
+
function createScopedSettings(deps) {
|
|
7685
|
+
return {
|
|
7686
|
+
async get() {
|
|
7687
|
+
return deps.schema.parse(await deps.read());
|
|
7688
|
+
},
|
|
7689
|
+
patch: (patch) => deps.write(Object.fromEntries(Object.entries(patch))),
|
|
7690
|
+
unset: (keys) => deps.unset(keys)
|
|
7691
|
+
};
|
|
7692
|
+
}
|
|
7590
7693
|
/** A write to a secret path could not be stored in the keychain, so it was refused. */
|
|
7591
7694
|
var KeychainWriteRefusedError = class extends Error {
|
|
7592
7695
|
fieldPath;
|
|
@@ -8162,7 +8265,16 @@ function createHandle(raw, opts) {
|
|
|
8162
8265
|
return blob;
|
|
8163
8266
|
}
|
|
8164
8267
|
},
|
|
8165
|
-
writeAddonStore: writeAddon
|
|
8268
|
+
writeAddonStore: writeAddon,
|
|
8269
|
+
removeClearedKeys: (keys) => serialize("addon", async () => {
|
|
8270
|
+
const stored = await readStoredAddonBlob(raw);
|
|
8271
|
+
index.seen("addon", stored);
|
|
8272
|
+
const removable = keys.filter((key) => collectSecretMarkerRefs(stored[key]).length === 0);
|
|
8273
|
+
if (removable.length === 0) return;
|
|
8274
|
+
const patch = Object.fromEntries(removable.map((key) => [key, void 0]));
|
|
8275
|
+
await raw.writeAddonStore(patch);
|
|
8276
|
+
index.wrote("addon", patch);
|
|
8277
|
+
})
|
|
8166
8278
|
};
|
|
8167
8279
|
}
|
|
8168
8280
|
/** The context the addon sees, plus the private raw view and write outcome. */
|
|
@@ -8707,6 +8819,151 @@ var BaseAddon = class {
|
|
|
8707
8819
|
}
|
|
8708
8820
|
}
|
|
8709
8821
|
/**
|
|
8822
|
+
* Hook: values layered over the stored ones when the FORM of one scope is served
|
|
8823
|
+
* ({@link getScopedSettings}) — a preview that derives dependent options without writing.
|
|
8824
|
+
* Never applied to {@link ScopedSettings.get} or to a write. `null` ⇒ no overlay.
|
|
8825
|
+
*/
|
|
8826
|
+
async scopedSettingsOverlay(_scope, _cap, _nodeId) {
|
|
8827
|
+
return null;
|
|
8828
|
+
}
|
|
8829
|
+
/**
|
|
8830
|
+
* Hook: a write of one scope changed stored values (not called when the store reports no change,
|
|
8831
|
+
* e.g. the write-back of a stored secret). `keys` are the bare field keys of the write, node keys included.
|
|
8832
|
+
*/
|
|
8833
|
+
async onScopedSettingsChanged(_scope, _cap, _keys) {}
|
|
8834
|
+
/** Typed handle over the CLUSTER settings `cap` declares (`clusterSettingsSchema`). */
|
|
8835
|
+
clusterSettings(cap, schema) {
|
|
8836
|
+
return this.scopedHandle("cluster", cap, schema);
|
|
8837
|
+
}
|
|
8838
|
+
/** Typed handle over the fleet defaults of the per-device settings `cap` declares. */
|
|
8839
|
+
deviceDefaults(cap, schema) {
|
|
8840
|
+
return this.scopedHandle("device-defaults", cap, schema);
|
|
8841
|
+
}
|
|
8842
|
+
/**
|
|
8843
|
+
* Typed handle over the settings `cap` owns PER NODE. `nodeId` omitted ⇒ the local node. A node
|
|
8844
|
+
* with no row yields the schema defaults — never a bare-key fallback.
|
|
8845
|
+
*/
|
|
8846
|
+
nodeSettings(cap, schema, nodeId) {
|
|
8847
|
+
return this.scopedHandle("node", cap, schema, nodeId);
|
|
8848
|
+
}
|
|
8849
|
+
/**
|
|
8850
|
+
* {@link state} for a value that is kept per node: stored under `<key>@<nodeId>`, and the
|
|
8851
|
+
* settings store carries `nodeId` in the row data (D986 §1), so a forgotten node's rows go in one
|
|
8852
|
+
* central delete. `nodeId` omitted ⇒ the local node.
|
|
8853
|
+
*/
|
|
8854
|
+
nodeState(key, schema, fallback, nodeId) {
|
|
8855
|
+
this._declaredStateKeys.add(key);
|
|
8856
|
+
return createDurableState({
|
|
8857
|
+
key: nodeScopedKey(key, nodeId ?? this._ctx?.kernel?.localNodeId ?? ""),
|
|
8858
|
+
schema,
|
|
8859
|
+
fallback,
|
|
8860
|
+
read: async () => this.resolveStoredSecrets(await this.readAddonStoreWithRetry()),
|
|
8861
|
+
write: async (patch) => {
|
|
8862
|
+
await this._ctx?.settings?.writeAddonStore(patch);
|
|
8863
|
+
},
|
|
8864
|
+
onParseError: (k, e) => this._ctx?.logger?.warn?.(`durable-state: stored "${k}" failed validation — using fallback`, { meta: {
|
|
8865
|
+
addonId: this._ctx?.id,
|
|
8866
|
+
key: k,
|
|
8867
|
+
error: String(e)
|
|
8868
|
+
} })
|
|
8869
|
+
});
|
|
8870
|
+
}
|
|
8871
|
+
/** The loaded schema `cap` declares for `scope`, or `null`. */
|
|
8872
|
+
async declaredScopedSchema(scope, cap) {
|
|
8873
|
+
await this.loadScopedSchemas(cap);
|
|
8874
|
+
return this.loadedScopedSchemas(cap).find((entry) => entry.scope === scope)?.schema ?? null;
|
|
8875
|
+
}
|
|
8876
|
+
async requireScopedSchema(scope, cap) {
|
|
8877
|
+
const schema = await this.declaredScopedSchema(scope, cap);
|
|
8878
|
+
if (schema === null) throw new Error(`${this.constructor.name}: cap "${cap}" declares no ${scope} settings`);
|
|
8879
|
+
return schema;
|
|
8880
|
+
}
|
|
8881
|
+
scopedKeys(schema) {
|
|
8882
|
+
return new Set(schema.sections.flatMap((section) => collectValueFieldKeys(section.fields)));
|
|
8883
|
+
}
|
|
8884
|
+
/** `store` narrowed to the keys `schema` declares. */
|
|
8885
|
+
narrowToScope(store, schema) {
|
|
8886
|
+
const keys = this.scopedKeys(schema);
|
|
8887
|
+
return Object.fromEntries(Object.entries(store).filter(([key]) => keys.has(key)));
|
|
8888
|
+
}
|
|
8889
|
+
scopedHandle(scope, cap, schema, nodeId) {
|
|
8890
|
+
return createScopedSettings({
|
|
8891
|
+
schema,
|
|
8892
|
+
read: async () => {
|
|
8893
|
+
const declared = await this.requireScopedSchema(scope, cap);
|
|
8894
|
+
const stored = this.narrowToScope(await this.resolveGlobalStore(nodeId, cap), declared);
|
|
8895
|
+
const effective = collectHydratedFieldValues(hydrateSchema(declared, stored));
|
|
8896
|
+
return {
|
|
8897
|
+
...Object.fromEntries([...effective].filter(([, value]) => value !== void 0)),
|
|
8898
|
+
...stored
|
|
8899
|
+
};
|
|
8900
|
+
},
|
|
8901
|
+
write: (patch) => this.writeScoped(scope, cap, patch, nodeId),
|
|
8902
|
+
unset: (keys) => this.unsetScoped(scope, cap, keys, nodeId)
|
|
8903
|
+
});
|
|
8904
|
+
}
|
|
8905
|
+
/** The one write path of the scoped API: declared keys only, then the global patch. */
|
|
8906
|
+
async writeScoped(scope, cap, patch, nodeId) {
|
|
8907
|
+
assertDeclaredKeys(Object.keys(patch), this.scopedKeys(await this.requireScopedSchema(scope, cap)));
|
|
8908
|
+
if (await this.applyGlobalPatch(patch, scope === "node" ? nodeId : void 0, cap)) await this.onScopedSettingsChanged(scope, cap, Object.keys(patch));
|
|
8909
|
+
}
|
|
8910
|
+
/**
|
|
8911
|
+
* Remove declared keys of one scope. A secret goes through {@link clearSecrets} — its keychain
|
|
8912
|
+
* value is released exactly as there — and the emptied row is then removed; every other key is
|
|
8913
|
+
* removed by an `undefined` patch (which a secret transform would read as "keep").
|
|
8914
|
+
*/
|
|
8915
|
+
async unsetScoped(scope, cap, keys, nodeId) {
|
|
8916
|
+
assertDeclaredKeys(keys, this.scopedKeys(await this.requireScopedSchema(scope, cap)));
|
|
8917
|
+
const target = scope === "node" ? nodeId : void 0;
|
|
8918
|
+
const tree = this.addonSecretTree();
|
|
8919
|
+
const secretKeys = keys.filter((key) => tree.has(key));
|
|
8920
|
+
const plainKeys = keys.filter((key) => !tree.has(key));
|
|
8921
|
+
let changed = false;
|
|
8922
|
+
if (plainKeys.length > 0) {
|
|
8923
|
+
const patch = Object.fromEntries(plainKeys.map((key) => [key, void 0]));
|
|
8924
|
+
changed = await this.applyGlobalPatch(patch, target, cap) || changed;
|
|
8925
|
+
}
|
|
8926
|
+
if (secretKeys.length > 0) {
|
|
8927
|
+
await this.clearSecretKeys(secretKeys, target, cap);
|
|
8928
|
+
const node = normalizeNodeId(target ?? this._ctx?.kernel?.localNodeId);
|
|
8929
|
+
const rows = secretKeys.map((key) => scope === "node" ? nodeScopedKey(key, node) : key);
|
|
8930
|
+
if (this._secretSettings !== null) await this._secretSettings.removeClearedKeys(rows);
|
|
8931
|
+
else await this._ctx?.settings?.writeAddonStore(Object.fromEntries(rows.map((row) => [row, void 0])));
|
|
8932
|
+
changed = true;
|
|
8933
|
+
}
|
|
8934
|
+
if (changed) await this.onScopedSettingsChanged(scope, cap, [...keys]);
|
|
8935
|
+
}
|
|
8936
|
+
/**
|
|
8937
|
+
* The hydrated form of one scope of one capability's settings (any
|
|
8938
|
+
* {@link scopedSettingsOverlay} applied), or `null` when the capability declares nothing there.
|
|
8939
|
+
*/
|
|
8940
|
+
async getScopedSettings(scope, cap, nodeId) {
|
|
8941
|
+
const schema = await this.declaredScopedSchema(scope, cap);
|
|
8942
|
+
if (schema === null) return null;
|
|
8943
|
+
const stored = this.narrowToScope(await this.readRawProjectedStore(nodeId, cap), schema);
|
|
8944
|
+
const overlay = await this.scopedSettingsOverlay(scope, cap, nodeId);
|
|
8945
|
+
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(stored, overlay) : stored, { inlineSecretsAsViews: true });
|
|
8946
|
+
}
|
|
8947
|
+
/** The OPERATOR's write of declared keys of one scope (D787 secret semantics). */
|
|
8948
|
+
async updateScopedSettings(scope, cap, patch, nodeId) {
|
|
8949
|
+
this._operatorWriteDepth++;
|
|
8950
|
+
try {
|
|
8951
|
+
await this.writeScoped(scope, cap, patch, nodeId);
|
|
8952
|
+
} finally {
|
|
8953
|
+
this._operatorWriteDepth--;
|
|
8954
|
+
}
|
|
8955
|
+
}
|
|
8956
|
+
/**
|
|
8957
|
+
* The effective values (`stored ?? default`) of one scope, a secret as its `set` view — never
|
|
8958
|
+
* its value. `null` when the capability declares nothing for the scope.
|
|
8959
|
+
*/
|
|
8960
|
+
async readScopedValues(scope, cap, nodeId) {
|
|
8961
|
+
const schema = await this.declaredScopedSchema(scope, cap);
|
|
8962
|
+
if (schema === null) return null;
|
|
8963
|
+
const form = hydrateSchema(schema, this.narrowToScope(await this.readRawProjectedStore(nodeId, cap), schema), { inlineSecretsAsViews: true });
|
|
8964
|
+
return Object.fromEntries([...collectHydratedFieldValues(form)].filter(([, value]) => value !== void 0));
|
|
8965
|
+
}
|
|
8966
|
+
/**
|
|
8710
8967
|
* What the create wizard and the integration edit page render for one instance: the addon's
|
|
8711
8968
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8712
8969
|
*/
|
|
@@ -8858,6 +9115,9 @@ var BaseAddon = class {
|
|
|
8858
9115
|
* a keychain (an older kernel) it writes `''`, as such code always did.
|
|
8859
9116
|
*/
|
|
8860
9117
|
async clearSecrets(keys, nodeId) {
|
|
9118
|
+
await this.clearSecretKeys(keys, nodeId);
|
|
9119
|
+
}
|
|
9120
|
+
async clearSecretKeys(keys, nodeId, cap) {
|
|
8861
9121
|
const tree = this.addonSecretTree();
|
|
8862
9122
|
const keychain = this._ctx?.secrets !== void 0;
|
|
8863
9123
|
const stored = keychain ? await this.readAddonStoreWithRetry() : {};
|
|
@@ -8870,25 +9130,27 @@ var BaseAddon = class {
|
|
|
8870
9130
|
const keychainStored = tree.has(key) || collectSecretMarkerRefs(stored[key]).length > 0;
|
|
8871
9131
|
patch[key] = keychain && keychainStored ? SECRET_CLEAR : "";
|
|
8872
9132
|
}
|
|
8873
|
-
await this.applyGlobalPatch(patch, nodeId);
|
|
9133
|
+
await this.applyGlobalPatch(patch, nodeId, cap);
|
|
8874
9134
|
}
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
9135
|
+
/** Resolves `true` when the write changed stored values. */
|
|
9136
|
+
async applyGlobalPatch(barePatch, nodeId, cap) {
|
|
9137
|
+
await this.loadScopedSchemas(cap);
|
|
9138
|
+
const keys = this.perNodeKeys(cap);
|
|
8878
9139
|
const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
|
|
8879
9140
|
const target = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
|
|
8880
9141
|
const scoped = keys.size > 0 ? scopePatch(barePatch, keys, target) : barePatch;
|
|
8881
9142
|
const handle = this._secretSettings;
|
|
8882
9143
|
if (handle !== null) {
|
|
8883
9144
|
const { changed } = await handle.writeAddonStore(scoped);
|
|
8884
|
-
if (!changed) return;
|
|
9145
|
+
if (!changed) return false;
|
|
8885
9146
|
} else await this._ctx?.settings?.writeAddonStore(scoped);
|
|
8886
|
-
if (target !== localNode) return;
|
|
9147
|
+
if (target !== localNode) return true;
|
|
8887
9148
|
await this.resolveConfig();
|
|
8888
9149
|
await this.onConfigChanged();
|
|
8889
9150
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
8890
9151
|
const legacy = this.globalSettingsSchema();
|
|
8891
9152
|
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
9153
|
+
return true;
|
|
8892
9154
|
}
|
|
8893
9155
|
/**
|
|
8894
9156
|
* The set of field keys the global settings schema declares `perNode: true`
|
|
@@ -10618,7 +10880,6 @@ var CAP_NAMES = Object.freeze([
|
|
|
10618
10880
|
"notifier",
|
|
10619
10881
|
"numeric-sensor",
|
|
10620
10882
|
"oauth-integration",
|
|
10621
|
-
"oidc-connections",
|
|
10622
10883
|
"osd",
|
|
10623
10884
|
"osd-manager",
|
|
10624
10885
|
"pet-feeder",
|
|
@@ -12510,8 +12771,7 @@ Object.freeze({
|
|
|
12510
12771
|
"device-provider": { "reloadDevice": 18e4 },
|
|
12511
12772
|
"llm": {
|
|
12512
12773
|
"generate": 6e5,
|
|
12513
|
-
"generateVision": 6e5
|
|
12514
|
-
"testProfile": 6e5
|
|
12774
|
+
"generateVision": 6e5
|
|
12515
12775
|
},
|
|
12516
12776
|
"llm-runtime": {
|
|
12517
12777
|
"complete": 6e5,
|
|
@@ -14036,17 +14296,18 @@ function composeInstanceKinds(parts, base) {
|
|
|
14036
14296
|
* message to what the kind supports — callers never special-case a service.
|
|
14037
14297
|
*
|
|
14038
14298
|
* DESIGN DECISIONS (locked):
|
|
14039
|
-
* -
|
|
14040
|
-
*
|
|
14041
|
-
*
|
|
14042
|
-
*
|
|
14043
|
-
*
|
|
14044
|
-
*
|
|
14045
|
-
*
|
|
14046
|
-
*
|
|
14047
|
-
*
|
|
14048
|
-
* routable. `send` / `testTarget` /
|
|
14049
|
-
* `
|
|
14299
|
+
* - A target is an INSTANCE of this function cap (epic #440, step 6): the
|
|
14300
|
+
* providers serve their targets as `integration-instances` records, one
|
|
14301
|
+
* record kind per target kind, and the admin lists, adds, edits, switches
|
|
14302
|
+
* and deletes them through that cap. This cap keeps what an instance cannot
|
|
14303
|
+
* say: the kind catalogue (`listTargetKinds`: capabilities, delivery
|
|
14304
|
+
* parameters, brand icon), dispatch (`send`, `testTarget`) and the form
|
|
14305
|
+
* helpers (`discoverTargets`, `probeTargetConfig`).
|
|
14306
|
+
* - `listTargetKinds` / `discoverTargets` return arrays → the generated
|
|
14307
|
+
* cap-mount auto-`concatCollection`-fans them across every registered
|
|
14308
|
+
* provider so one catalog is routable. `send` / `testTarget` /
|
|
14309
|
+
* `probeTargetConfig` route to ONE provider by the `addonId` the generated
|
|
14310
|
+
* collection router extracts from the call input.
|
|
14050
14311
|
* - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
|
|
14051
14312
|
* transformer) + UDS MsgPack both round-trip typed arrays — already used by
|
|
14052
14313
|
* `storage` / `storage-provider` / `recording` caps over the same path. No
|
|
@@ -14291,7 +14552,7 @@ var TargetKindCapsSchema = object({
|
|
|
14291
14552
|
* the union is large and not meant for runtime validation here; the exported
|
|
14292
14553
|
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
14293
14554
|
*/
|
|
14294
|
-
var ConfigSchemaPassthrough$
|
|
14555
|
+
var ConfigSchemaPassthrough$3 = unknown();
|
|
14295
14556
|
var TargetKindSchema = object({
|
|
14296
14557
|
kind: string(),
|
|
14297
14558
|
label: string(),
|
|
@@ -14328,7 +14589,7 @@ var TargetKindSchema = object({
|
|
|
14328
14589
|
* its raster path, which is the safe default for an unknown image.
|
|
14329
14590
|
*/
|
|
14330
14591
|
iconMediaType: string().optional(),
|
|
14331
|
-
configSchema: ConfigSchemaPassthrough$
|
|
14592
|
+
configSchema: ConfigSchemaPassthrough$3,
|
|
14332
14593
|
/**
|
|
14333
14594
|
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
14334
14595
|
* base URL, instance, chat, recipient). A save that changes any of them
|
|
@@ -14350,9 +14611,11 @@ var TargetKindSchema = object({
|
|
|
14350
14611
|
caps: TargetKindCapsSchema
|
|
14351
14612
|
});
|
|
14352
14613
|
/**
|
|
14353
|
-
* A
|
|
14354
|
-
*
|
|
14355
|
-
*
|
|
14614
|
+
* A target as a provider's own code sees it (the notification-center bridge, the
|
|
14615
|
+
* send path): the flat record body split into the name, the switch and the
|
|
14616
|
+
* kind's fields. `config` holds secrets; a reader that serves it to a client
|
|
14617
|
+
* REDACTS secret fields (a presence marker only) — never round-trip a stored
|
|
14618
|
+
* secret to the UI.
|
|
14356
14619
|
*/
|
|
14357
14620
|
var TargetSchema = object({
|
|
14358
14621
|
id: string(),
|
|
@@ -14395,13 +14658,13 @@ var ProbeTargetConfigResultSchema = object({
|
|
|
14395
14658
|
stateInstance: string().optional(),
|
|
14396
14659
|
error: string().optional()
|
|
14397
14660
|
});
|
|
14398
|
-
method(object({}), array(TargetKindSchema)), method(object({
|
|
14661
|
+
method(object({}), array(TargetKindSchema)), method(object({
|
|
14399
14662
|
kind: string(),
|
|
14400
14663
|
config: record(string(), unknown()).optional(),
|
|
14401
14664
|
/**
|
|
14402
14665
|
* When editing / duplicating, the blank password field never round-trips
|
|
14403
14666
|
* the stored token. Pass the source target id so the provider can restore
|
|
14404
|
-
* secrets server-side before dialling
|
|
14667
|
+
* secrets server-side before dialling.
|
|
14405
14668
|
*/
|
|
14406
14669
|
targetId: string().optional()
|
|
14407
14670
|
}), array(DiscoveredTargetSchema), { auth: "admin" }), method(object({
|
|
@@ -14424,27 +14687,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
14424
14687
|
}), TestResultSchema, {
|
|
14425
14688
|
kind: "mutation",
|
|
14426
14689
|
auth: "admin"
|
|
14427
|
-
}), method(object({
|
|
14428
|
-
target: TargetSchema,
|
|
14429
|
-
/**
|
|
14430
|
-
* Duplicate flow: create a NEW target id while copying secrets from an
|
|
14431
|
-
* existing row. The UI never holds the stored token; blank / redacted
|
|
14432
|
-
* password fields are restored from this source (D634 still applies if
|
|
14433
|
-
* destinations diverge without a re-typed secret).
|
|
14434
|
-
*/
|
|
14435
|
-
cloneSecretsFrom: string().optional()
|
|
14436
|
-
}), TargetSchema, {
|
|
14437
|
-
kind: "mutation",
|
|
14438
|
-
auth: "admin"
|
|
14439
|
-
}), method(object({ targetId: string() }), _void(), {
|
|
14440
|
-
kind: "mutation",
|
|
14441
|
-
auth: "admin"
|
|
14442
|
-
}), method(object({
|
|
14443
|
-
targetId: string(),
|
|
14444
|
-
enabled: boolean()
|
|
14445
|
-
}), _void(), {
|
|
14446
|
-
kind: "mutation",
|
|
14447
|
-
auth: "admin"
|
|
14448
14690
|
});
|
|
14449
14691
|
looseObject({
|
|
14450
14692
|
name: string().min(1),
|
|
@@ -22712,7 +22954,6 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
22712
22954
|
"notification-output": system("notification delivery — reached through notifier devices and rules"),
|
|
22713
22955
|
"notification-rules": system("notification rules — authored on their own page"),
|
|
22714
22956
|
"oauth-integration": system(IDENTITY),
|
|
22715
|
-
"oidc-connections": system(IDENTITY),
|
|
22716
22957
|
"osd-manager": system(PIPELINE),
|
|
22717
22958
|
"pipeline-executor": system(PIPELINE),
|
|
22718
22959
|
"pipeline-orchestrator": system(PIPELINE),
|
|
@@ -44854,6 +45095,8 @@ var SettingsSchemaWithValuesSchema = object({
|
|
|
44854
45095
|
});
|
|
44855
45096
|
/** Patch object — keys are field names, values are the new field values. */
|
|
44856
45097
|
var SettingsPatchSchema = record(string(), unknown());
|
|
45098
|
+
/** The scope of a scoped-settings call (D986): where the capability declared the values. */
|
|
45099
|
+
var ScopedSettingsScopeSchema = _enum(SCOPED_SETTINGS_SCOPES);
|
|
44857
45100
|
/** Standard success response for update operations. */
|
|
44858
45101
|
var SettingsUpdateResultSchema = object({ success: literal(true) });
|
|
44859
45102
|
method(object({
|
|
@@ -44869,6 +45112,25 @@ method(object({
|
|
|
44869
45112
|
kind: "mutation",
|
|
44870
45113
|
auth: "admin"
|
|
44871
45114
|
}), method(object({
|
|
45115
|
+
addonId: string(),
|
|
45116
|
+
cap: string(),
|
|
45117
|
+
scope: ScopedSettingsScopeSchema,
|
|
45118
|
+
nodeId: string().optional()
|
|
45119
|
+
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45120
|
+
addonId: string(),
|
|
45121
|
+
cap: string(),
|
|
45122
|
+
scope: ScopedSettingsScopeSchema,
|
|
45123
|
+
nodeId: string().optional(),
|
|
45124
|
+
patch: SettingsPatchSchema
|
|
45125
|
+
}), SettingsUpdateResultSchema, {
|
|
45126
|
+
kind: "mutation",
|
|
45127
|
+
auth: "admin"
|
|
45128
|
+
}), method(object({
|
|
45129
|
+
addonId: string(),
|
|
45130
|
+
cap: string(),
|
|
45131
|
+
scope: ScopedSettingsScopeSchema,
|
|
45132
|
+
nodeId: string().optional()
|
|
45133
|
+
}), record(string(), unknown()).nullable()), method(object({
|
|
44872
45134
|
addonId: string(),
|
|
44873
45135
|
nodeId: string().optional()
|
|
44874
45136
|
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
@@ -54418,7 +54680,7 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
54418
54680
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
54419
54681
|
* clears it.
|
|
54420
54682
|
*/
|
|
54421
|
-
var ConfigSchemaPassthrough$
|
|
54683
|
+
var ConfigSchemaPassthrough$2 = custom();
|
|
54422
54684
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
54423
54685
|
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
54424
54686
|
/**
|
|
@@ -54464,7 +54726,16 @@ var IntegrationInstanceKindSchema = object({
|
|
|
54464
54726
|
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
54465
54727
|
connectPath: string().min(1).optional(),
|
|
54466
54728
|
/** Relative hub path to disconnect that account. */
|
|
54467
|
-
disconnectPath: string().min(1).optional()
|
|
54729
|
+
disconnectPath: string().min(1).optional(),
|
|
54730
|
+
/**
|
|
54731
|
+
* Parts of the edit dialog the flat form cannot draw (a node picker, a model source), named by a
|
|
54732
|
+
* GENERIC widget id the client maps to a component; a client that knows none of them shows none.
|
|
54733
|
+
* `connection` widgets write connection values, `model` widgets own the model choice.
|
|
54734
|
+
*/
|
|
54735
|
+
widgets: array(object({
|
|
54736
|
+
id: string().min(1),
|
|
54737
|
+
placement: _enum(["connection", "model"])
|
|
54738
|
+
})).optional()
|
|
54468
54739
|
});
|
|
54469
54740
|
/**
|
|
54470
54741
|
* How devices of an instance are found. `none`: the operator adds them by hand; `lan`: the addon
|
|
@@ -54569,7 +54840,7 @@ var integrationInstancesCapability = {
|
|
|
54569
54840
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
54570
54841
|
/** The kind of the create form (`id: null`) of a provider with several. */
|
|
54571
54842
|
kind: string().min(1).optional()
|
|
54572
|
-
}), ConfigSchemaPassthrough$
|
|
54843
|
+
}), ConfigSchemaPassthrough$2, { auth: "admin" }),
|
|
54573
54844
|
listInstances: method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }),
|
|
54574
54845
|
getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }),
|
|
54575
54846
|
/**
|
|
@@ -55520,12 +55791,12 @@ var LlmModelInfoSchema = object({
|
|
|
55520
55791
|
});
|
|
55521
55792
|
/**
|
|
55522
55793
|
* The provider-specific part of a profile, validated by the provider that owns
|
|
55523
|
-
* the kind (
|
|
55794
|
+
* the kind (saving an instance refuses what it does not accept). A field its
|
|
55524
55795
|
* `connectionSchema` declares `type: 'password'` is a secret: it is held in the
|
|
55525
55796
|
* keychain, never in the row, and reads back as the redaction marker.
|
|
55526
55797
|
*/
|
|
55527
55798
|
var LlmProviderConfigSchema = record(string(), unknown());
|
|
55528
|
-
|
|
55799
|
+
object({
|
|
55529
55800
|
id: string(),
|
|
55530
55801
|
name: string(),
|
|
55531
55802
|
/** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
|
|
@@ -55619,8 +55890,8 @@ var LlmProviderWidgetSchema = object({
|
|
|
55619
55890
|
/** ConfigUISchema tree passed through untyped on the wire (the
|
|
55620
55891
|
* notification-output `ConfigSchemaPassthrough` precedent at
|
|
55621
55892
|
* notification-output.cap.ts:151); the exported TS type re-tightens it. */
|
|
55622
|
-
var ConfigSchemaPassthrough$
|
|
55623
|
-
|
|
55893
|
+
var ConfigSchemaPassthrough$1 = unknown();
|
|
55894
|
+
object({
|
|
55624
55895
|
kind: LlmProfileKindSchema,
|
|
55625
55896
|
label: string(),
|
|
55626
55897
|
/** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
|
|
@@ -55628,9 +55899,9 @@ var LlmProfileKindDescriptorSchema = object({
|
|
|
55628
55899
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
55629
55900
|
addonId: string(),
|
|
55630
55901
|
/** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
|
|
55631
|
-
connectionSchema: ConfigSchemaPassthrough$
|
|
55902
|
+
connectionSchema: ConfigSchemaPassthrough$1,
|
|
55632
55903
|
/** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
|
|
55633
|
-
advancedSchema: ConfigSchemaPassthrough$
|
|
55904
|
+
advancedSchema: ConfigSchemaPassthrough$1.optional(),
|
|
55634
55905
|
/** The kind's defaults; a model from `listModels` may override any of them. */
|
|
55635
55906
|
features: LlmModelFeaturesSchema,
|
|
55636
55907
|
/** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
|
|
@@ -55759,20 +56030,7 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
|
|
|
55759
56030
|
}), method(object({
|
|
55760
56031
|
addonId: string().optional(),
|
|
55761
56032
|
requestId: string()
|
|
55762
|
-
}), _void(), { kind: "mutation" }), method(
|
|
55763
|
-
kind: "mutation",
|
|
55764
|
-
auth: "admin"
|
|
55765
|
-
}), method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
|
|
55766
|
-
kind: "mutation",
|
|
55767
|
-
auth: "admin"
|
|
55768
|
-
}), method(ProfileRefInputSchema, _void(), {
|
|
55769
|
-
kind: "mutation",
|
|
55770
|
-
auth: "admin"
|
|
55771
|
-
}), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
|
|
55772
|
-
kind: "mutation",
|
|
55773
|
-
auth: "admin",
|
|
55774
|
-
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
55775
|
-
}), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
56033
|
+
}), _void(), { kind: "mutation" }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
55776
56034
|
kind: "mutation",
|
|
55777
56035
|
auth: "admin"
|
|
55778
56036
|
}), method(object({}), array(LlmDefaultSchema)), method(object({
|
|
@@ -56767,20 +57025,7 @@ method(_void(), MeshStatusSchema), method(object({
|
|
|
56767
57025
|
/** Optional hostname override the host should advertise once joined. */
|
|
56768
57026
|
hostname: string().optional() }), object({
|
|
56769
57027
|
/** Authentication URL the operator should open in a browser. */
|
|
56770
|
-
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }))
|
|
56771
|
-
/** Optional auth key — when provided, probes the key validity
|
|
56772
|
-
* against the provider's API. Omit when already joined to
|
|
56773
|
-
* just ping the daemon. */
|
|
56774
|
-
authKey: string().optional() }), object({
|
|
56775
|
-
ok: boolean(),
|
|
56776
|
-
/** Provider-side identifier resolved by the probe (tailnet
|
|
56777
|
-
* name for Tailscale, network id for ZeroTier, etc.). */
|
|
56778
|
-
tenant: string().optional(),
|
|
56779
|
-
/** Daemon binary version, when reachable. */
|
|
56780
|
-
daemonVersion: string().optional(),
|
|
56781
|
-
/** Human-readable error when `ok: false`. */
|
|
56782
|
-
error: string().optional()
|
|
56783
|
-
}), { kind: "mutation" });
|
|
57028
|
+
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }));
|
|
56784
57029
|
object({
|
|
56785
57030
|
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
56786
57031
|
lastFetchedAt: number()
|
|
@@ -66438,61 +66683,6 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
66438
66683
|
});
|
|
66439
66684
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
66440
66685
|
/**
|
|
66441
|
-
* `oidc-connections` — CRUD for IdP rows under `auth-oidc` (D828 sibling).
|
|
66442
|
-
*
|
|
66443
|
-
* One hub-only singleton (`auth-oidc`). The Settings UI is a DataTable +
|
|
66444
|
-
* ItemFormDialog; there is no `editable-array` in `globalSettingsSchema`.
|
|
66445
|
-
* Operator-chosen `id` is the URL slug (`/addon/auth-oidc/<id>/…`) and is
|
|
66446
|
-
* immutable after create.
|
|
66447
|
-
*/
|
|
66448
|
-
var ConfigSchemaPassthrough$1 = unknown();
|
|
66449
|
-
var OidcConnectionSchema = object({
|
|
66450
|
-
id: string().min(1),
|
|
66451
|
-
displayName: string(),
|
|
66452
|
-
icon: string(),
|
|
66453
|
-
issuerUrl: string(),
|
|
66454
|
-
clientId: string(),
|
|
66455
|
-
/** Client id + secret present — never the secret value. */
|
|
66456
|
-
configured: boolean(),
|
|
66457
|
-
/**
|
|
66458
|
-
* Values for the connection form schema. `clientSecret` is a keychain
|
|
66459
|
-
* {@link SecretFieldView} or `null` / `''`, never plaintext (D789).
|
|
66460
|
-
*/
|
|
66461
|
-
formValues: record(string(), unknown()).optional()
|
|
66462
|
-
});
|
|
66463
|
-
/**
|
|
66464
|
-
* Patch one connection. Omitted or empty `clientSecret` keeps the stored
|
|
66465
|
-
* secret (D787). `{ $secretClear: true }` clears it. `id` is never renamed.
|
|
66466
|
-
*/
|
|
66467
|
-
var OidcConnectionUpdateInputSchema = object({
|
|
66468
|
-
id: string().min(1),
|
|
66469
|
-
displayName: string().min(1),
|
|
66470
|
-
icon: string().optional(),
|
|
66471
|
-
issuerUrl: string().optional(),
|
|
66472
|
-
clientId: string().optional(),
|
|
66473
|
-
clientSecret: union([string(), object({ $secretClear: literal(true) })]).optional(),
|
|
66474
|
-
redirectUri: string().optional(),
|
|
66475
|
-
scopes: string().optional(),
|
|
66476
|
-
usernameClaim: _enum([
|
|
66477
|
-
"preferred_username",
|
|
66478
|
-
"email",
|
|
66479
|
-
"sub"
|
|
66480
|
-
]).optional()
|
|
66481
|
-
});
|
|
66482
|
-
method(object({}), ConfigSchemaPassthrough$1, { auth: "admin" }), method(object({}), array(OidcConnectionSchema).readonly(), { auth: "admin" }), method(object({
|
|
66483
|
-
id: string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug"),
|
|
66484
|
-
displayName: string().min(1)
|
|
66485
|
-
}), object({ id: string() }), {
|
|
66486
|
-
kind: "mutation",
|
|
66487
|
-
auth: "admin"
|
|
66488
|
-
}), method(OidcConnectionUpdateInputSchema, object({ ok: literal(true) }), {
|
|
66489
|
-
kind: "mutation",
|
|
66490
|
-
auth: "admin"
|
|
66491
|
-
}), method(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
66492
|
-
kind: "mutation",
|
|
66493
|
-
auth: "admin"
|
|
66494
|
-
});
|
|
66495
|
-
/**
|
|
66496
66686
|
* Generic on-screen-display (video overlay) cap. Each camera exposes
|
|
66497
66687
|
* a firmware-defined list of overlays (channel name, timestamp,
|
|
66498
66688
|
* watermark, logo, …); the cap models them as a homogeneous array of
|
|
@@ -72678,21 +72868,6 @@ method(object({
|
|
|
72678
72868
|
*/
|
|
72679
72869
|
ttlSec: union([number().int().positive(), literal("never")]).optional()
|
|
72680
72870
|
}), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
|
|
72681
|
-
var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
|
|
72682
|
-
providerId: string().min(1),
|
|
72683
|
-
displayName: string().min(1),
|
|
72684
|
-
configSchema: unknown(),
|
|
72685
|
-
nodeLocal: boolean(),
|
|
72686
|
-
shouldSaveDiskSpace: literal(true),
|
|
72687
|
-
minFreePercent: number().min(0).max(100)
|
|
72688
|
-
}), object({
|
|
72689
|
-
providerId: string().min(1),
|
|
72690
|
-
displayName: string().min(1),
|
|
72691
|
-
configSchema: unknown(),
|
|
72692
|
-
nodeLocal: boolean(),
|
|
72693
|
-
shouldSaveDiskSpace: literal(false),
|
|
72694
|
-
minFreePercent: literal(null)
|
|
72695
|
-
})]);
|
|
72696
72871
|
method(object({
|
|
72697
72872
|
location: StorageLocationRefSchema,
|
|
72698
72873
|
relativePath: string()
|
|
@@ -72754,42 +72929,7 @@ method(object({
|
|
|
72754
72929
|
}), _instanceof(Uint8Array), { auth: "admin" }), method(object({ downloadId: string() }), _void(), {
|
|
72755
72930
|
kind: "mutation",
|
|
72756
72931
|
auth: "admin"
|
|
72757
|
-
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(
|
|
72758
|
-
createdAt: true,
|
|
72759
|
-
updatedAt: true
|
|
72760
|
-
}), StorageLocationSchema, {
|
|
72761
|
-
kind: "mutation",
|
|
72762
|
-
auth: "admin"
|
|
72763
|
-
}), method(object({
|
|
72764
|
-
id: string(),
|
|
72765
|
-
force: boolean().optional()
|
|
72766
|
-
}), _void(), {
|
|
72767
|
-
kind: "mutation",
|
|
72768
|
-
auth: "admin"
|
|
72769
|
-
}), method(_void(), array(StorageDrainProgressSchema).readonly()), method(object({ id: string() }), object({
|
|
72770
|
-
ok: boolean(),
|
|
72771
|
-
error: string().optional()
|
|
72772
|
-
}), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
|
|
72773
|
-
providerId: string(),
|
|
72774
|
-
/**
|
|
72775
|
-
* The location this config is an UNSAVED edit of, when there is one.
|
|
72776
|
-
*
|
|
72777
|
-
* `listLocations` replaces every declared secret with the redaction
|
|
72778
|
-
* sentinel, so the edit modal's form state holds the sentinel for any
|
|
72779
|
-
* credential the operator did not retype — and posting that here
|
|
72780
|
-
* without a way to resolve it makes the provider try to authenticate
|
|
72781
|
-
* as `__camstack_redacted__` and report the operator's own working
|
|
72782
|
-
* password as wrong. Given this id, the orchestrator restores each
|
|
72783
|
-
* sentinel from the stored config (same rule as `upsertLocation`)
|
|
72784
|
-
* before dispatching. Omitted by the "Add location" wizard, where
|
|
72785
|
-
* every value was typed just now and nothing is stored yet.
|
|
72786
|
-
*/
|
|
72787
|
-
locationId: string().optional(),
|
|
72788
|
-
config: record(string(), unknown())
|
|
72789
|
-
}), object({
|
|
72790
|
-
ok: boolean(),
|
|
72791
|
-
error: string().optional()
|
|
72792
|
-
}), { auth: "admin" });
|
|
72932
|
+
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(_void(), array(StorageDrainProgressSchema).readonly());
|
|
72793
72933
|
/** One table of the settings database. */
|
|
72794
72934
|
var StorageTableSchema = object({
|
|
72795
72935
|
/** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
|
|
@@ -74020,7 +74160,7 @@ var TerminalInstanceInfoSchema = object({
|
|
|
74020
74160
|
/**
|
|
74021
74161
|
* False while the node the instance is bound to is not in the cluster
|
|
74022
74162
|
* topology (forgotten, renamed, re-paired). The instance is kept; the
|
|
74023
|
-
* operator re-points it
|
|
74163
|
+
* operator re-points it on the Terminal page.
|
|
74024
74164
|
*/
|
|
74025
74165
|
nodeInCluster: boolean(),
|
|
74026
74166
|
profileId: string(),
|
|
@@ -74058,41 +74198,7 @@ var TerminalOutputBatchSchema = object({
|
|
|
74058
74198
|
snapshot: string().optional(),
|
|
74059
74199
|
events: array(TerminalOutputEventSchema).readonly()
|
|
74060
74200
|
});
|
|
74061
|
-
method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(
|
|
74062
|
-
targetNodeId: string().min(1),
|
|
74063
|
-
profileId: string().min(1),
|
|
74064
|
-
name: string().trim().min(1).max(160).optional(),
|
|
74065
|
-
executable: string().max(1024).optional(),
|
|
74066
|
-
args: array(string().max(2048)).max(64).optional(),
|
|
74067
|
-
cwd: string().max(1024).optional(),
|
|
74068
|
-
environment: array(string().max(4096)).max(64).optional(),
|
|
74069
|
-
profileSettings: ProfileSettingsBagSchema.optional()
|
|
74070
|
-
}), TerminalInstanceInfoSchema, {
|
|
74071
|
-
kind: "mutation",
|
|
74072
|
-
auth: "admin"
|
|
74073
|
-
}), method(object({
|
|
74074
|
-
instanceId: string().min(1),
|
|
74075
|
-
/** Re-point the instance to another node; the profile must exist there. */
|
|
74076
|
-
targetNodeId: string().min(1).max(256).optional(),
|
|
74077
|
-
name: string().trim().min(1).max(160).optional(),
|
|
74078
|
-
executable: string().max(1024).optional(),
|
|
74079
|
-
args: array(string().max(2048)).max(64).optional(),
|
|
74080
|
-
cwd: string().max(1024).optional(),
|
|
74081
|
-
environment: array(string().max(4096)).max(64).optional(),
|
|
74082
|
-
profileSettings: ProfileSettingsBagSchema.optional()
|
|
74083
|
-
}), TerminalInstanceInfoSchema, {
|
|
74084
|
-
kind: "mutation",
|
|
74085
|
-
auth: "admin"
|
|
74086
|
-
}), method(object({ instanceId: string().min(1) }), _void(), {
|
|
74087
|
-
kind: "mutation",
|
|
74088
|
-
auth: "admin"
|
|
74089
|
-
}), method(object({
|
|
74090
|
-
instanceId: string().min(1),
|
|
74091
|
-
enabled: boolean()
|
|
74092
|
-
}), TerminalInstanceInfoSchema, {
|
|
74093
|
-
kind: "mutation",
|
|
74094
|
-
auth: "admin"
|
|
74095
|
-
}), method(_void(), array(TerminalLegacyCameraSchema).readonly(), { auth: "admin" }), method(object({
|
|
74201
|
+
method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalLegacyCameraSchema).readonly(), { auth: "admin" }), method(object({
|
|
74096
74202
|
stableId: string().min(1),
|
|
74097
74203
|
name: string().trim().min(1).max(160).optional()
|
|
74098
74204
|
}), TerminalInstanceInfoSchema, {
|
|
@@ -76910,6 +77016,20 @@ Object.freeze({
|
|
|
76910
77016
|
access: "view",
|
|
76911
77017
|
role: "admin"
|
|
76912
77018
|
},
|
|
77019
|
+
"addonSettings.getScopedSettings": {
|
|
77020
|
+
capName: "addon-settings",
|
|
77021
|
+
capScope: "system",
|
|
77022
|
+
addonId: null,
|
|
77023
|
+
access: "view",
|
|
77024
|
+
role: "admin"
|
|
77025
|
+
},
|
|
77026
|
+
"addonSettings.readScopedValues": {
|
|
77027
|
+
capName: "addon-settings",
|
|
77028
|
+
capScope: "system",
|
|
77029
|
+
addonId: null,
|
|
77030
|
+
access: "view",
|
|
77031
|
+
role: "admin"
|
|
77032
|
+
},
|
|
76913
77033
|
"addonSettings.unsetStoredSettingsKeys": {
|
|
76914
77034
|
capName: "addon-settings",
|
|
76915
77035
|
capScope: "system",
|
|
@@ -76931,6 +77051,13 @@ Object.freeze({
|
|
|
76931
77051
|
access: "create",
|
|
76932
77052
|
role: "admin"
|
|
76933
77053
|
},
|
|
77054
|
+
"addonSettings.updateScopedSettings": {
|
|
77055
|
+
capName: "addon-settings",
|
|
77056
|
+
capScope: "system",
|
|
77057
|
+
addonId: null,
|
|
77058
|
+
access: "create",
|
|
77059
|
+
role: "admin"
|
|
77060
|
+
},
|
|
76934
77061
|
"addonWidgets.listWidgets": {
|
|
76935
77062
|
capName: "addon-widgets",
|
|
76936
77063
|
capScope: "system",
|
|
@@ -80382,13 +80509,6 @@ Object.freeze({
|
|
|
80382
80509
|
access: "delete",
|
|
80383
80510
|
role: "admin"
|
|
80384
80511
|
},
|
|
80385
|
-
"llm.deleteProfile": {
|
|
80386
|
-
capName: "llm",
|
|
80387
|
-
capScope: "system",
|
|
80388
|
-
addonId: null,
|
|
80389
|
-
access: "delete",
|
|
80390
|
-
role: "admin"
|
|
80391
|
-
},
|
|
80392
80512
|
"llm.generate": {
|
|
80393
80513
|
capName: "llm",
|
|
80394
80514
|
capScope: "system",
|
|
@@ -80452,20 +80572,6 @@ Object.freeze({
|
|
|
80452
80572
|
access: "view",
|
|
80453
80573
|
role: "admin"
|
|
80454
80574
|
},
|
|
80455
|
-
"llm.listProfileKinds": {
|
|
80456
|
-
capName: "llm",
|
|
80457
|
-
capScope: "system",
|
|
80458
|
-
addonId: null,
|
|
80459
|
-
access: "view",
|
|
80460
|
-
role: "admin"
|
|
80461
|
-
},
|
|
80462
|
-
"llm.listProfiles": {
|
|
80463
|
-
capName: "llm",
|
|
80464
|
-
capScope: "system",
|
|
80465
|
-
addonId: null,
|
|
80466
|
-
access: "view",
|
|
80467
|
-
role: "admin"
|
|
80468
|
-
},
|
|
80469
80575
|
"llm.listRuntimeNodes": {
|
|
80470
80576
|
capName: "llm",
|
|
80471
80577
|
capScope: "system",
|
|
@@ -80473,13 +80579,6 @@ Object.freeze({
|
|
|
80473
80579
|
access: "view",
|
|
80474
80580
|
role: "admin"
|
|
80475
80581
|
},
|
|
80476
|
-
"llm.migrateRawSecrets": {
|
|
80477
|
-
capName: "llm",
|
|
80478
|
-
capScope: "system",
|
|
80479
|
-
addonId: null,
|
|
80480
|
-
access: "create",
|
|
80481
|
-
role: "admin"
|
|
80482
|
-
},
|
|
80483
80582
|
"llm.resolveModelRef": {
|
|
80484
80583
|
capName: "llm",
|
|
80485
80584
|
capScope: "system",
|
|
@@ -80508,20 +80607,6 @@ Object.freeze({
|
|
|
80508
80607
|
access: "create",
|
|
80509
80608
|
role: "admin"
|
|
80510
80609
|
},
|
|
80511
|
-
"llm.testProfile": {
|
|
80512
|
-
capName: "llm",
|
|
80513
|
-
capScope: "system",
|
|
80514
|
-
addonId: null,
|
|
80515
|
-
access: "create",
|
|
80516
|
-
role: "admin"
|
|
80517
|
-
},
|
|
80518
|
-
"llm.upsertProfile": {
|
|
80519
|
-
capName: "llm",
|
|
80520
|
-
capScope: "system",
|
|
80521
|
-
addonId: null,
|
|
80522
|
-
access: "create",
|
|
80523
|
-
role: "admin"
|
|
80524
|
-
},
|
|
80525
80610
|
"llmRuntime.appleAvailability": {
|
|
80526
80611
|
capName: "llm-runtime",
|
|
80527
80612
|
capScope: "system",
|
|
@@ -81026,13 +81111,6 @@ Object.freeze({
|
|
|
81026
81111
|
access: "create",
|
|
81027
81112
|
role: "admin"
|
|
81028
81113
|
},
|
|
81029
|
-
"meshNetwork.testConnection": {
|
|
81030
|
-
capName: "mesh-network",
|
|
81031
|
-
capScope: "system",
|
|
81032
|
-
addonId: null,
|
|
81033
|
-
access: "create",
|
|
81034
|
-
role: "admin"
|
|
81035
|
-
},
|
|
81036
81114
|
"meter.getStatus": {
|
|
81037
81115
|
capName: "meter",
|
|
81038
81116
|
capScope: "device",
|
|
@@ -81691,13 +81769,6 @@ Object.freeze({
|
|
|
81691
81769
|
access: "create",
|
|
81692
81770
|
role: "admin"
|
|
81693
81771
|
},
|
|
81694
|
-
"notificationOutput.deleteTarget": {
|
|
81695
|
-
capName: "notification-output",
|
|
81696
|
-
capScope: "system",
|
|
81697
|
-
addonId: null,
|
|
81698
|
-
access: "delete",
|
|
81699
|
-
role: "admin"
|
|
81700
|
-
},
|
|
81701
81772
|
"notificationOutput.discoverTargets": {
|
|
81702
81773
|
capName: "notification-output",
|
|
81703
81774
|
capScope: "system",
|
|
@@ -81705,13 +81776,6 @@ Object.freeze({
|
|
|
81705
81776
|
access: "view",
|
|
81706
81777
|
role: "admin"
|
|
81707
81778
|
},
|
|
81708
|
-
"notificationOutput.getTarget": {
|
|
81709
|
-
capName: "notification-output",
|
|
81710
|
-
capScope: "system",
|
|
81711
|
-
addonId: null,
|
|
81712
|
-
access: "view",
|
|
81713
|
-
role: "admin"
|
|
81714
|
-
},
|
|
81715
81779
|
"notificationOutput.listTargetKinds": {
|
|
81716
81780
|
capName: "notification-output",
|
|
81717
81781
|
capScope: "system",
|
|
@@ -81719,13 +81783,6 @@ Object.freeze({
|
|
|
81719
81783
|
access: "view",
|
|
81720
81784
|
role: "admin"
|
|
81721
81785
|
},
|
|
81722
|
-
"notificationOutput.listTargets": {
|
|
81723
|
-
capName: "notification-output",
|
|
81724
|
-
capScope: "system",
|
|
81725
|
-
addonId: null,
|
|
81726
|
-
access: "view",
|
|
81727
|
-
role: "admin"
|
|
81728
|
-
},
|
|
81729
81786
|
"notificationOutput.probeTargetConfig": {
|
|
81730
81787
|
capName: "notification-output",
|
|
81731
81788
|
capScope: "system",
|
|
@@ -81740,13 +81797,6 @@ Object.freeze({
|
|
|
81740
81797
|
access: "create",
|
|
81741
81798
|
role: "admin"
|
|
81742
81799
|
},
|
|
81743
|
-
"notificationOutput.setTargetEnabled": {
|
|
81744
|
-
capName: "notification-output",
|
|
81745
|
-
capScope: "system",
|
|
81746
|
-
addonId: null,
|
|
81747
|
-
access: "create",
|
|
81748
|
-
role: "admin"
|
|
81749
|
-
},
|
|
81750
81800
|
"notificationOutput.testTarget": {
|
|
81751
81801
|
capName: "notification-output",
|
|
81752
81802
|
capScope: "system",
|
|
@@ -81754,13 +81804,6 @@ Object.freeze({
|
|
|
81754
81804
|
access: "create",
|
|
81755
81805
|
role: "admin"
|
|
81756
81806
|
},
|
|
81757
|
-
"notificationOutput.upsertTarget": {
|
|
81758
|
-
capName: "notification-output",
|
|
81759
|
-
capScope: "system",
|
|
81760
|
-
addonId: null,
|
|
81761
|
-
access: "create",
|
|
81762
|
-
role: "admin"
|
|
81763
|
-
},
|
|
81764
81807
|
"notificationRules.activateAlarmProfile": {
|
|
81765
81808
|
capName: "notification-rules",
|
|
81766
81809
|
capScope: "system",
|
|
@@ -82020,41 +82063,6 @@ Object.freeze({
|
|
|
82020
82063
|
access: "view",
|
|
82021
82064
|
role: "admin"
|
|
82022
82065
|
},
|
|
82023
|
-
"oidcConnections.connectionFormSchema": {
|
|
82024
|
-
capName: "oidc-connections",
|
|
82025
|
-
capScope: "system",
|
|
82026
|
-
addonId: null,
|
|
82027
|
-
access: "view",
|
|
82028
|
-
role: "admin"
|
|
82029
|
-
},
|
|
82030
|
-
"oidcConnections.createConnection": {
|
|
82031
|
-
capName: "oidc-connections",
|
|
82032
|
-
capScope: "system",
|
|
82033
|
-
addonId: null,
|
|
82034
|
-
access: "create",
|
|
82035
|
-
role: "admin"
|
|
82036
|
-
},
|
|
82037
|
-
"oidcConnections.deleteConnection": {
|
|
82038
|
-
capName: "oidc-connections",
|
|
82039
|
-
capScope: "system",
|
|
82040
|
-
addonId: null,
|
|
82041
|
-
access: "delete",
|
|
82042
|
-
role: "admin"
|
|
82043
|
-
},
|
|
82044
|
-
"oidcConnections.listConnections": {
|
|
82045
|
-
capName: "oidc-connections",
|
|
82046
|
-
capScope: "system",
|
|
82047
|
-
addonId: null,
|
|
82048
|
-
access: "view",
|
|
82049
|
-
role: "admin"
|
|
82050
|
-
},
|
|
82051
|
-
"oidcConnections.updateConnection": {
|
|
82052
|
-
capName: "oidc-connections",
|
|
82053
|
-
capScope: "system",
|
|
82054
|
-
addonId: null,
|
|
82055
|
-
access: "create",
|
|
82056
|
-
role: "admin"
|
|
82057
|
-
},
|
|
82058
82066
|
"osd.getStatus": {
|
|
82059
82067
|
capName: "osd",
|
|
82060
82068
|
capScope: "device",
|
|
@@ -85086,13 +85094,6 @@ Object.freeze({
|
|
|
85086
85094
|
access: "delete",
|
|
85087
85095
|
role: "admin"
|
|
85088
85096
|
},
|
|
85089
|
-
"storage.deleteLocation": {
|
|
85090
|
-
capName: "storage",
|
|
85091
|
-
capScope: "system",
|
|
85092
|
-
addonId: null,
|
|
85093
|
-
access: "delete",
|
|
85094
|
-
role: "admin"
|
|
85095
|
-
},
|
|
85096
85097
|
"storage.endDownload": {
|
|
85097
85098
|
capName: "storage",
|
|
85098
85099
|
capScope: "system",
|
|
@@ -85149,13 +85150,6 @@ Object.freeze({
|
|
|
85149
85150
|
access: "view",
|
|
85150
85151
|
role: "admin"
|
|
85151
85152
|
},
|
|
85152
|
-
"storage.listProviders": {
|
|
85153
|
-
capName: "storage",
|
|
85154
|
-
capScope: "system",
|
|
85155
|
-
addonId: null,
|
|
85156
|
-
access: "view",
|
|
85157
|
-
role: "admin"
|
|
85158
|
-
},
|
|
85159
85153
|
"storage.read": {
|
|
85160
85154
|
capName: "storage",
|
|
85161
85155
|
capScope: "system",
|
|
@@ -85177,27 +85171,6 @@ Object.freeze({
|
|
|
85177
85171
|
access: "view",
|
|
85178
85172
|
role: "admin"
|
|
85179
85173
|
},
|
|
85180
|
-
"storage.testConfig": {
|
|
85181
|
-
capName: "storage",
|
|
85182
|
-
capScope: "system",
|
|
85183
|
-
addonId: null,
|
|
85184
|
-
access: "view",
|
|
85185
|
-
role: "admin"
|
|
85186
|
-
},
|
|
85187
|
-
"storage.testLocation": {
|
|
85188
|
-
capName: "storage",
|
|
85189
|
-
capScope: "system",
|
|
85190
|
-
addonId: null,
|
|
85191
|
-
access: "view",
|
|
85192
|
-
role: "admin"
|
|
85193
|
-
},
|
|
85194
|
-
"storage.upsertLocation": {
|
|
85195
|
-
capName: "storage",
|
|
85196
|
-
capScope: "system",
|
|
85197
|
-
addonId: null,
|
|
85198
|
-
access: "create",
|
|
85199
|
-
role: "admin"
|
|
85200
|
-
},
|
|
85201
85174
|
"storage.write": {
|
|
85202
85175
|
capName: "storage",
|
|
85203
85176
|
capScope: "system",
|
|
@@ -85975,27 +85948,6 @@ Object.freeze({
|
|
|
85975
85948
|
access: "create",
|
|
85976
85949
|
role: "admin"
|
|
85977
85950
|
},
|
|
85978
|
-
"terminalSession.createInstance": {
|
|
85979
|
-
capName: "terminal-session",
|
|
85980
|
-
capScope: "system",
|
|
85981
|
-
addonId: null,
|
|
85982
|
-
access: "create",
|
|
85983
|
-
role: "admin"
|
|
85984
|
-
},
|
|
85985
|
-
"terminalSession.deleteInstance": {
|
|
85986
|
-
capName: "terminal-session",
|
|
85987
|
-
capScope: "system",
|
|
85988
|
-
addonId: null,
|
|
85989
|
-
access: "delete",
|
|
85990
|
-
role: "admin"
|
|
85991
|
-
},
|
|
85992
|
-
"terminalSession.listInstances": {
|
|
85993
|
-
capName: "terminal-session",
|
|
85994
|
-
capScope: "system",
|
|
85995
|
-
addonId: null,
|
|
85996
|
-
access: "view",
|
|
85997
|
-
role: "admin"
|
|
85998
|
-
},
|
|
85999
85951
|
"terminalSession.listLegacyCameras": {
|
|
86000
85952
|
capName: "terminal-session",
|
|
86001
85953
|
capScope: "system",
|
|
@@ -86038,20 +85990,6 @@ Object.freeze({
|
|
|
86038
85990
|
access: "create",
|
|
86039
85991
|
role: "admin"
|
|
86040
85992
|
},
|
|
86041
|
-
"terminalSession.setInstanceEnabled": {
|
|
86042
|
-
capName: "terminal-session",
|
|
86043
|
-
capScope: "system",
|
|
86044
|
-
addonId: null,
|
|
86045
|
-
access: "create",
|
|
86046
|
-
role: "admin"
|
|
86047
|
-
},
|
|
86048
|
-
"terminalSession.updateInstance": {
|
|
86049
|
-
capName: "terminal-session",
|
|
86050
|
-
capScope: "system",
|
|
86051
|
-
addonId: null,
|
|
86052
|
-
access: "create",
|
|
86053
|
-
role: "admin"
|
|
86054
|
-
},
|
|
86055
85993
|
"terminalSession.writeInput": {
|
|
86056
85994
|
capName: "terminal-session",
|
|
86057
85995
|
capScope: "system",
|
|
@@ -145983,17 +145921,6 @@ function scrub(message, secret) {
|
|
|
145983
145921
|
function mintRelayId() {
|
|
145984
145922
|
return `relay-${randomUUID().slice(0, 8)}`;
|
|
145985
145923
|
}
|
|
145986
|
-
/** The keys the settings page edits: the relay's connection fields. */
|
|
145987
|
-
var RELAY_FORM_KEYS = new Set([
|
|
145988
|
-
"host",
|
|
145989
|
-
"port",
|
|
145990
|
-
"secure",
|
|
145991
|
-
"username",
|
|
145992
|
-
"password",
|
|
145993
|
-
"fromAddress",
|
|
145994
|
-
"fromName"
|
|
145995
|
-
]);
|
|
145996
|
-
var DEFAULT_RELAY_NAME = "Email (SMTP)";
|
|
145997
145924
|
var RELAY_LIST_MAX = 200;
|
|
145998
145925
|
function hasText(value) {
|
|
145999
145926
|
return typeof value === "string" && value.length > 0;
|
|
@@ -146246,44 +146173,10 @@ var SmtpNodemailerAddon = class extends BaseAddon {
|
|
|
146246
146173
|
const rows = (await records.kind(smtpRelaysKind).query({ limit: RELAY_LIST_MAX })).records;
|
|
146247
146174
|
return (rows.find((row) => row.data.host.length > 0) ?? rows[0])?.id;
|
|
146248
146175
|
}
|
|
146249
|
-
/** The relay form.
|
|
146176
|
+
/** The relay form. */
|
|
146250
146177
|
async integrationFormSchema(_instance) {
|
|
146251
146178
|
return this.relayForm();
|
|
146252
146179
|
}
|
|
146253
|
-
async getGlobalSettings() {
|
|
146254
|
-
const schema = this.relayForm();
|
|
146255
|
-
if (this.instances === null) return hydrateSchema(schema, {}, { inlineSecretsAsViews: true });
|
|
146256
|
-
const id = await this.firstRelayId();
|
|
146257
|
-
return hydrateSchema(schema, (id === void 0 ? null : await this.instances.readResolved(id))?.body ?? {}, { inlineSecretsAsViews: true });
|
|
146258
|
-
}
|
|
146259
|
-
async updateGlobalSettingsAsOperator(patch) {
|
|
146260
|
-
await this.writeDefaultRelay(patch);
|
|
146261
|
-
}
|
|
146262
|
-
async updateGlobalSettings(patch) {
|
|
146263
|
-
await this.writeDefaultRelay(patch);
|
|
146264
|
-
}
|
|
146265
|
-
/** Write the form's values onto the default relay, creating it on the first save. */
|
|
146266
|
-
async writeDefaultRelay(patch) {
|
|
146267
|
-
if (this.instances === null) throw new Error("smtp-nodemailer is not initialised");
|
|
146268
|
-
const values = Object.fromEntries(Object.entries(patch).filter(([key]) => RELAY_FORM_KEYS.has(key)));
|
|
146269
|
-
const existing = await this.firstRelayId();
|
|
146270
|
-
if (existing !== void 0) {
|
|
146271
|
-
await this.instances.updateInstance({
|
|
146272
|
-
id: existing,
|
|
146273
|
-
values
|
|
146274
|
-
});
|
|
146275
|
-
return;
|
|
146276
|
-
}
|
|
146277
|
-
const id = mintRelayId();
|
|
146278
|
-
await this.instances.createInstance({
|
|
146279
|
-
id,
|
|
146280
|
-
name: DEFAULT_RELAY_NAME
|
|
146281
|
-
});
|
|
146282
|
-
await this.instances.updateInstance({
|
|
146283
|
-
id,
|
|
146284
|
-
values
|
|
146285
|
-
});
|
|
146286
|
-
}
|
|
146287
146180
|
/** Probe a relay (EHLO + AUTH) with the form's values, falling back to the stored ones. */
|
|
146288
146181
|
async probe(id, values) {
|
|
146289
146182
|
const stored = id !== null && this.instances !== null ? await this.instances.getResolved(id) : null;
|