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