@camstack/system 1.2.316 → 1.2.317
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/auth/auth-manager.d.ts +11 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +347 -181
- package/dist/builtins/composer/composer.addon.mjs +347 -181
- package/dist/builtins/composer/composition-evaluation.d.ts +37 -0
- package/dist/builtins/composer/composition-runtime.d.ts +11 -52
- package/dist/builtins/composer/composition-target.d.ts +50 -0
- package/dist/builtins/composer/existing-target.d.ts +19 -1
- package/dist/builtins/composer/own-field-reads.d.ts +19 -0
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +265 -29
- package/dist/builtins/device-manager/device-manager.addon.mjs +265 -29
- package/dist/builtins/device-manager/device-provider-context.d.ts +6 -0
- package/dist/builtins/device-manager/device-source-activation.d.ts +26 -1
- package/dist/builtins/device-manager/device-state-mirror.d.ts +41 -9
- package/dist/builtins/device-manager/mirror-row-writer.d.ts +59 -1
- package/dist/builtins/doorbell/binding-mirror.d.ts +45 -81
- package/dist/builtins/doorbell/doorbell-extension-slot.d.ts +4 -3
- package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +53 -11
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +207 -82
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +207 -82
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +47 -3
- package/dist/builtins/local-auth/local-auth.addon.mjs +46 -4
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +4 -4
- package/dist/builtins/system-config/system-config.addon.mjs +4 -4
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{child-cap-dispatch-AAltfBUH.mjs → child-cap-dispatch-C2VINHu1.mjs} +70 -18
- package/dist/{child-cap-dispatch-DzcUd_ct.js → child-cap-dispatch-C8uts1P4.js} +70 -18
- package/dist/{composition-sources-fUyF4z39.mjs → composition-sources-DVClu006.mjs} +1 -1
- package/dist/{composition-sources-BwE1POnF.js → composition-sources-Dep7nBwu.js} +1 -1
- package/dist/{dist-BPvku43i.mjs → dist-Dori4pf3.mjs} +85 -6
- package/dist/{dist-RAl10EfG.js → dist-a6p0V-IL.js} +85 -6
- package/dist/index.js +739 -350
- package/dist/index.mjs +737 -352
- package/dist/kernel/bootstrap-config.d.ts +8 -0
- package/dist/kernel/capability-registry.d.ts +30 -0
- package/dist/kernel/config-manager.d.ts +75 -129
- package/dist/kernel/index.d.ts +5 -2
- package/dist/kernel/moleculer/runtime-state-load.d.ts +19 -0
- package/dist/kernel/settings-door-view.d.ts +24 -1
- package/dist/kernel/settings-read-error.d.ts +37 -0
- package/dist/kernel/settings-view-types.d.ts +105 -0
- package/dist/kernel/store-settings-view.d.ts +17 -0
- package/dist/kernel/system-settings-mirror.d.ts +34 -0
- package/dist/kernel/system-settings-policy.d.ts +47 -0
- package/dist/{retired-settings-keys-D3rGTGq5.js → retired-settings-keys-DC1uHWPZ.js} +1 -1
- package/dist/{retired-settings-keys-DqVWSrVw.mjs → retired-settings-keys-DVcKRgzm.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as isSameAddonId, Dn as SOURCE_CAP_ACTIVE_FIELD, En as SOURCE_CAPS, Gn as BaseAddon, On as SOURCE_CAP_CHANGED_AT_FIELD, Rn as evaluateSensorEdge, Un as DeviceType, W as bareAddonId, Wn as errMsg, ct as defineExtensionSlotProvider, hr as EventCategory, it as createDeviceExtensionProvider, mt as doorbellCapability, tr as createEvent, ut as deviceExtensionCapability, zn as isSourceCap } from "../../dist-
|
|
1
|
+
import { At as isSameAddonId, Dn as SOURCE_CAP_ACTIVE_FIELD, En as SOURCE_CAPS, Gn as BaseAddon, On as SOURCE_CAP_CHANGED_AT_FIELD, Rn as evaluateSensorEdge, Un as DeviceType, W as bareAddonId, Wn as errMsg, ct as defineExtensionSlotProvider, hr as EventCategory, it as createDeviceExtensionProvider, mt as doorbellCapability, tr as createEvent, ut as deviceExtensionCapability, zn as isSourceCap } from "../../dist-Dori4pf3.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -196,11 +196,18 @@ var DoorbellTriggerEngine = class {
|
|
|
196
196
|
* 2. The DERIVED view (`deviceManager.getBindings`) is no longer the sole
|
|
197
197
|
* input. Before a negative is believed — and again on the ring path
|
|
198
198
|
* before a press is destroyed — the DURABLE authority is consulted
|
|
199
|
-
* directly ({@link
|
|
200
|
-
*
|
|
201
|
-
* the derived view genuinely cannot offer:
|
|
202
|
-
*
|
|
203
|
-
*
|
|
199
|
+
* directly ({@link durableVerdictOf} over
|
|
200
|
+
* `deviceManager.getWrapperActivation`). That read carries a discriminator
|
|
201
|
+
* the derived view genuinely cannot offer: it is three-way, so a store
|
|
202
|
+
* that could not answer (`failed`) is never mistaken for a store that
|
|
203
|
+
* answered "nothing here" (`missing`).
|
|
204
|
+
*
|
|
205
|
+
* 2026-09-29 (D675). Until then the durable read was
|
|
206
|
+
* `addonSettingsRaw.getGlobal({ addonId: 'device-manager' })`, whose backend
|
|
207
|
+
* (`ConfigManager.getAddonConfig`) has had no store on the hub since D231
|
|
208
|
+
* isolated the engine: it answered `{}` on every call, so every durable read
|
|
209
|
+
* was `unreadable`, an operator's explicit "off" (camera 615,
|
|
210
|
+
* `wrapperAddonId: null`) was never honoured, and a press rang anyway.
|
|
204
211
|
*/
|
|
205
212
|
/**
|
|
206
213
|
* Fold one SUCCESSFUL bindings read into the mirror. A read that failed must
|
|
@@ -211,9 +218,12 @@ function nextBindingState(previous, boundNow) {
|
|
|
211
218
|
if (boundNow) return "bound";
|
|
212
219
|
return previous === "unbind-pending" || previous === "unbound" ? "unbound" : "unbind-pending";
|
|
213
220
|
}
|
|
214
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* May a ring proceed on the mirror STATE alone? Only a corroborated unbind
|
|
223
|
+
* stops one. {@link needsDurableRead} adds the served-elsewhere case on top.
|
|
224
|
+
*/
|
|
215
225
|
function allowsRing(state) {
|
|
216
|
-
return
|
|
226
|
+
return state !== "unbound";
|
|
217
227
|
}
|
|
218
228
|
/** True only when a read has positively confirmed the binding. */
|
|
219
229
|
function hasConfirmedBinding(state) {
|
|
@@ -238,46 +248,62 @@ function entriesBindWrapper(entries, capName, ownAddonId) {
|
|
|
238
248
|
function summariseEntries(entries) {
|
|
239
249
|
return entries.map((entry) => `${entry.capName}:${entry.kind}:${entry.providerAddonId}`);
|
|
240
250
|
}
|
|
241
|
-
function isRecord$2(value) {
|
|
242
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
243
|
-
}
|
|
244
251
|
/**
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* `capName` on `deviceId`".
|
|
252
|
+
* The durable verdict for `ownAddonId`, from device-manager's STORED
|
|
253
|
+
* activation of this cap on this device (`deviceManager.getWrapperActivation`).
|
|
248
254
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
+
* - `value` naming this wrapper → `bound`.
|
|
256
|
+
* - `value` naming another wrapper, or `null` — the operator's explicit "off"
|
|
257
|
+
* marker (D62) — → `unbound`.
|
|
258
|
+
* - `missing` → `unbound`: the store ANSWERED and holds no activation, and the
|
|
259
|
+
* doorbell cap is `defaultActive: false`, so a wrapper nobody activated is
|
|
260
|
+
* not bound.
|
|
261
|
+
* - `failed` → `unreadable`: it carries no information and destroys nothing.
|
|
262
|
+
*/
|
|
263
|
+
function durableVerdictOf(read, ownAddonId) {
|
|
264
|
+
switch (read.kind) {
|
|
265
|
+
case "failed": return "unreadable";
|
|
266
|
+
case "missing": return "unbound";
|
|
267
|
+
case "value": return read.wrapperAddonId !== null && isSameAddonId(read.wrapperAddonId, ownAddonId) ? "bound" : "unbound";
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Who, other than this wrapper, the derived view says serves `capName` —
|
|
272
|
+
* `composer` on a camera whose doorbell was migrated to a composition (D671).
|
|
273
|
+
* Non-empty means a press this wrapper does not ring is still somebody's ring.
|
|
255
274
|
*/
|
|
256
|
-
function
|
|
257
|
-
|
|
258
|
-
const deviceBindings = record["deviceBindings"];
|
|
259
|
-
if (!isRecord$2(deviceBindings)) return "unreadable";
|
|
260
|
-
const perDevice = deviceBindings[String(deviceId)];
|
|
261
|
-
if (!isRecord$2(perDevice)) return "unbound";
|
|
262
|
-
const activation = perDevice[capName];
|
|
263
|
-
if (!isRecord$2(activation)) return "unbound";
|
|
264
|
-
const wrapperAddonId = activation["wrapperAddonId"];
|
|
265
|
-
if (typeof wrapperAddonId !== "string") return "unbound";
|
|
266
|
-
return isSameAddonId(wrapperAddonId, ownAddonId) ? "bound" : "unbound";
|
|
275
|
+
function otherProvidersOf(entries, capName, ownAddonId) {
|
|
276
|
+
return entries.filter((entry) => entry.capName === capName && !isSameAddonId(entry.providerAddonId, ownAddonId)).map((entry) => entry.providerAddonId);
|
|
267
277
|
}
|
|
268
|
-
/**
|
|
269
|
-
|
|
270
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Does this camera need the durable authority before a verdict?
|
|
280
|
+
*
|
|
281
|
+
* An `unbound` mirror does (D72). So does any mirror short of `bound` on a
|
|
282
|
+
* camera whose doorbell another provider serves — the D671 cutover, where
|
|
283
|
+
* erring open means ringing ON TOP of the composer: after every restart the
|
|
284
|
+
* mirror starts `undefined` and spends a reload cycle at `unbind-pending`, and
|
|
285
|
+
* each press in that window was a duplicate ring. Two independent reads
|
|
286
|
+
* agreeing — the derived view naming another provider, the store naming no
|
|
287
|
+
* wrapper — is the D49 "second read agrees"; an unreadable store still rings.
|
|
288
|
+
*/
|
|
289
|
+
function needsDurableRead(mirror) {
|
|
290
|
+
if (!allowsRing(mirror.state)) return true;
|
|
291
|
+
return mirror.servedBy.length > 0 && mirror.state !== "bound";
|
|
271
292
|
}
|
|
272
293
|
/**
|
|
273
|
-
* THE decision — the ring gate (`fireDoorbell` / `
|
|
294
|
+
* THE decision — the ring gate (`fireDoorbell` / `ringsAfterDurableRead`)
|
|
274
295
|
* and the Extensions card's activation both call it, so what the card says
|
|
275
296
|
* and what a press does cannot disagree. `durable` is `null` when it was not
|
|
276
|
-
* read, which {@link needsDurableRead} allows
|
|
297
|
+
* read, which {@link needsDurableRead} allows only where it says so.
|
|
277
298
|
* Pure: it reads nothing and writes nothing.
|
|
278
299
|
*/
|
|
279
|
-
function ringVerdict(
|
|
300
|
+
function ringVerdict(mirror, durable) {
|
|
301
|
+
const state = mirror.state;
|
|
280
302
|
if (state === "bound") return "rings";
|
|
303
|
+
if (mirror.servedBy.length > 0) {
|
|
304
|
+
if (durable === "unbound") return "silent";
|
|
305
|
+
if (durable === "bound") return "rings";
|
|
306
|
+
}
|
|
281
307
|
if (state === "unbind-pending") return "rings-pending";
|
|
282
308
|
if (state === void 0) return "rings-unconfirmed";
|
|
283
309
|
if (durable === "bound") return "rings";
|
|
@@ -848,13 +874,6 @@ function errorText(err) {
|
|
|
848
874
|
}
|
|
849
875
|
//#endregion
|
|
850
876
|
//#region src/builtins/doorbell/virtual-doorbell.addon.ts
|
|
851
|
-
/**
|
|
852
|
-
* The addon whose store IS the durable authority on wrapper activations.
|
|
853
|
-
* `deviceBindings[<deviceId>][<capName>].wrapperAddonId` is the row the
|
|
854
|
-
* operator's bindings toggle writes; `deviceManager.getBindings` is a VIEW
|
|
855
|
-
* derived from it plus the capability registry.
|
|
856
|
-
*/
|
|
857
|
-
var DEVICE_MANAGER_ADDON_ID = "device-manager";
|
|
858
877
|
/** Narrow a raw `doorbell` runtime-state slice to counters (defaults on absence). */
|
|
859
878
|
function parseDoorbellSlice(slice) {
|
|
860
879
|
const lastPressedAtRaw = slice?.["lastPressedAt"];
|
|
@@ -907,6 +926,24 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
907
926
|
* `binding-mirror.ts` for why a single negative read is not believed.
|
|
908
927
|
*/
|
|
909
928
|
bindingMirror = /* @__PURE__ */ new Map();
|
|
929
|
+
/**
|
|
930
|
+
* Per camera, the last NEGATIVE refresh this addon reported — its state,
|
|
931
|
+
* the authority's verdict and who else serves the doorbell. A refresh runs
|
|
932
|
+
* every reload cycle (about once a minute); the same answer repeated is not
|
|
933
|
+
* news, so it is reported once per change and forgotten on a positive read.
|
|
934
|
+
* Camera 615 logged the same WARN 607 times in 14 h after D671.
|
|
935
|
+
*/
|
|
936
|
+
reportedNegative = /* @__PURE__ */ new Map();
|
|
937
|
+
/** Cameras whose last durable-authority read THREW — reported once per outage. */
|
|
938
|
+
durableReadFailing = /* @__PURE__ */ new Set();
|
|
939
|
+
/**
|
|
940
|
+
* Per camera, the OTHER providers of `doorbell` the last successful derived
|
|
941
|
+
* read named (the composer after D671). Written off the ring path with the
|
|
942
|
+
* mirror; read on it, to decide whether erring open would double a ring.
|
|
943
|
+
*/
|
|
944
|
+
servedElsewhere = /* @__PURE__ */ new Map();
|
|
945
|
+
/** Cameras whose store-over-derived disagreement has been reported, until a derived read agrees. */
|
|
946
|
+
reportedStoreOverride = /* @__PURE__ */ new Set();
|
|
910
947
|
constructor() {
|
|
911
948
|
super({
|
|
912
949
|
debounceMs: 2e3,
|
|
@@ -987,7 +1024,7 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
987
1024
|
projection: "slim",
|
|
988
1025
|
deviceIds: [...deviceIds]
|
|
989
1026
|
})).map(toSlotDevice),
|
|
990
|
-
readBindingMirror: (deviceId) => this.
|
|
1027
|
+
readBindingMirror: (deviceId) => this.mirrorRead(deviceId),
|
|
991
1028
|
readDurableBinding: (deviceId) => this.readDurableAuthority(deviceId),
|
|
992
1029
|
sourceCapableDeviceIds: () => this.ctx.api.deviceManager.listDeviceIdsByCaps.query({ capNames: [...SOURCE_CAPS] }),
|
|
993
1030
|
listFleet: async () => (await this.ctx.api.deviceManager.listAll.query({ projection: "slim" })).map(toSlotDevice)
|
|
@@ -1036,9 +1073,9 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1036
1073
|
* (UI toast, notifier rules, exporters) is agnostic to the origin.
|
|
1037
1074
|
*
|
|
1038
1075
|
* The binding gate here is a pure in-memory read on the path that RINGS:
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1076
|
+
* a `bound` mirror, or an open one on a camera nobody else serves, performs
|
|
1077
|
+
* NO I/O and cannot fail. Every other case asks the durable authority once
|
|
1078
|
+
* before deciding — see `needsDurableRead` and `ringsAfterDurableRead`.
|
|
1042
1079
|
*
|
|
1043
1080
|
* `sourceDeviceId`/`capName` are the source that produced this rise —
|
|
1044
1081
|
* carried through purely so the terminal `pressed` line can name it. Every
|
|
@@ -1048,8 +1085,9 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1048
1085
|
* timestamp against provider logs (proven live 2026-08-25, camera 615).
|
|
1049
1086
|
*/
|
|
1050
1087
|
async fireDoorbell(cameraId, timestamp, sourceDeviceId, capName) {
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1088
|
+
const mirror = this.mirrorRead(cameraId);
|
|
1089
|
+
const binding = mirror.state;
|
|
1090
|
+
if (needsDurableRead(mirror) && !await this.ringsAfterDurableRead(cameraId, mirror)) return;
|
|
1053
1091
|
if (!hasConfirmedBinding(binding)) this.ctx.logger.warn("virtual-doorbell: ringing on an unconfirmed binding — the bindings store has not corroborated an unbind, and a one-shot press is never dropped on an unproven read", {
|
|
1054
1092
|
tags: { deviceId: cameraId },
|
|
1055
1093
|
meta: { bindingState: binding ?? "never-read" }
|
|
@@ -1126,8 +1164,10 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1126
1164
|
}
|
|
1127
1165
|
}
|
|
1128
1166
|
/**
|
|
1129
|
-
* One read of the DURABLE authority: the
|
|
1130
|
-
*
|
|
1167
|
+
* One read of the DURABLE authority: the wrapper activation device-manager
|
|
1168
|
+
* STORED for this camera (`deviceManager.getWrapperActivation`, D675) — the
|
|
1169
|
+
* row the operator's bindings toggle writes. `deviceManager.getBindings` is
|
|
1170
|
+
* a VIEW derived from it plus the capability registry.
|
|
1131
1171
|
*
|
|
1132
1172
|
* This is deliberately NOT `getBindings`. The derived view folds the store
|
|
1133
1173
|
* together with the capability registry, `defaultActive` auto-binding and
|
|
@@ -1136,17 +1176,35 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1136
1176
|
* spelling mismatch) made it disagree *systematically* while looking
|
|
1137
1177
|
* exactly like a genuine unbind. The raw row cannot: it is what the
|
|
1138
1178
|
* bindings toggle wrote, and it grades its own trustworthiness (D44).
|
|
1179
|
+
*
|
|
1180
|
+
* A read that throws is reported when the outage STARTS and when it ends —
|
|
1181
|
+
* never per read: this runs on every reload cycle.
|
|
1139
1182
|
*/
|
|
1140
1183
|
async readDurableAuthority(cameraId) {
|
|
1184
|
+
let read;
|
|
1141
1185
|
try {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
tags: { deviceId: cameraId },
|
|
1146
|
-
meta: { error: errMsg(err) }
|
|
1186
|
+
read = await this.ctx.api.deviceManager.getWrapperActivation.query({
|
|
1187
|
+
deviceId: cameraId,
|
|
1188
|
+
capName: doorbellCapability.name
|
|
1147
1189
|
});
|
|
1190
|
+
} catch (err) {
|
|
1191
|
+
read = {
|
|
1192
|
+
kind: "failed",
|
|
1193
|
+
error: errMsg(err)
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
if (read.kind === "failed") {
|
|
1197
|
+
if (!this.durableReadFailing.has(cameraId)) {
|
|
1198
|
+
this.durableReadFailing.add(cameraId);
|
|
1199
|
+
this.ctx.logger.warn("virtual-doorbell: the durable bindings store could not be read — it carries no information and revokes nothing (reported once until it answers again)", {
|
|
1200
|
+
tags: { deviceId: cameraId },
|
|
1201
|
+
meta: { error: read.error }
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1148
1204
|
return "unreadable";
|
|
1149
1205
|
}
|
|
1206
|
+
if (this.durableReadFailing.delete(cameraId)) this.ctx.logger.info("virtual-doorbell: the durable bindings store answers again", { tags: { deviceId: cameraId } });
|
|
1207
|
+
return durableVerdictOf(read, this.ownAddonId);
|
|
1150
1208
|
}
|
|
1151
1209
|
/**
|
|
1152
1210
|
* Reconcile `cameraId`'s mirror against the authority. Runs on the
|
|
@@ -1164,60 +1222,114 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1164
1222
|
async refreshBindingMirror(cameraId) {
|
|
1165
1223
|
const derived = await this.readDerivedBinding(cameraId);
|
|
1166
1224
|
if (derived === null) return;
|
|
1225
|
+
const servedBy = otherProvidersOf(derived.entries, doorbellCapability.name, this.ownAddonId);
|
|
1226
|
+
this.servedElsewhere.set(cameraId, servedBy);
|
|
1167
1227
|
if (derived.bound) {
|
|
1168
1228
|
this.bindingMirror.set(cameraId, nextBindingState(this.bindingMirror.get(cameraId), true));
|
|
1229
|
+
this.reportedNegative.delete(cameraId);
|
|
1230
|
+
this.reportedStoreOverride.delete(cameraId);
|
|
1169
1231
|
return;
|
|
1170
1232
|
}
|
|
1171
1233
|
const authority = await this.readDurableAuthority(cameraId);
|
|
1172
1234
|
const entries = summariseEntries(derived.entries);
|
|
1173
1235
|
if (authority === "bound") {
|
|
1174
|
-
this.
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1236
|
+
this.reportedNegative.delete(cameraId);
|
|
1237
|
+
if (!this.reportedStoreOverride.has(cameraId)) {
|
|
1238
|
+
this.reportedStoreOverride.add(cameraId);
|
|
1239
|
+
this.ctx.logger.warn("virtual-doorbell: the derived binding list omits this wrapper but the durable bindings store still names this wrapper — trusting the store (reported once until they agree)", {
|
|
1240
|
+
tags: { deviceId: cameraId },
|
|
1241
|
+
meta: {
|
|
1242
|
+
ownAddonId: this.ownAddonId,
|
|
1243
|
+
entries
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1181
1247
|
this.bindingMirror.set(cameraId, nextBindingState(this.bindingMirror.get(cameraId), true));
|
|
1182
1248
|
return;
|
|
1183
1249
|
}
|
|
1250
|
+
this.reportedStoreOverride.delete(cameraId);
|
|
1184
1251
|
const previous = this.bindingMirror.get(cameraId);
|
|
1185
1252
|
const next = nextBindingState(previous, false);
|
|
1186
1253
|
this.bindingMirror.set(cameraId, next);
|
|
1187
|
-
this.
|
|
1254
|
+
this.reportNegativeRefresh(cameraId, {
|
|
1255
|
+
from: previous ?? "never-read",
|
|
1256
|
+
to: next,
|
|
1257
|
+
authority,
|
|
1258
|
+
servedBy,
|
|
1259
|
+
entries
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
/** The ring gate's in-memory input for one camera — no I/O. */
|
|
1263
|
+
mirrorRead(cameraId) {
|
|
1264
|
+
return {
|
|
1265
|
+
state: this.bindingMirror.get(cameraId),
|
|
1266
|
+
servedBy: this.servedElsewhere.get(cameraId) ?? []
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Report a negative refresh ONCE per change of what it says (D391: a
|
|
1271
|
+
* repeated identical line is noise that buries the next real one).
|
|
1272
|
+
*
|
|
1273
|
+
* The level follows what the answer MEANS:
|
|
1274
|
+
* - the durable store could not grade it (`unreadable`) — WARN: the
|
|
1275
|
+
* camera's ring now depends on erring open, and nobody can say whether
|
|
1276
|
+
* that is right;
|
|
1277
|
+
* - the store CONFIRMS the wrapper is not bound — an operator's unbind or
|
|
1278
|
+
* the D671 cutover to a composition. That is a state, not an anomaly:
|
|
1279
|
+
* INFO when it is believed (`unbound`), DEBUG for the first,
|
|
1280
|
+
* not-yet-believed read.
|
|
1281
|
+
*/
|
|
1282
|
+
reportNegativeRefresh(cameraId, report) {
|
|
1283
|
+
const key = `${report.to}|${report.authority}|${report.servedBy.join(",")}`;
|
|
1284
|
+
if (this.reportedNegative.get(cameraId) === key) return;
|
|
1285
|
+
this.reportedNegative.set(cameraId, key);
|
|
1286
|
+
const options = {
|
|
1188
1287
|
tags: { deviceId: cameraId },
|
|
1189
1288
|
meta: {
|
|
1190
|
-
from:
|
|
1191
|
-
to:
|
|
1289
|
+
from: report.from,
|
|
1290
|
+
to: report.to,
|
|
1192
1291
|
ownAddonId: this.ownAddonId,
|
|
1193
|
-
durableAuthority: authority,
|
|
1194
|
-
|
|
1292
|
+
durableAuthority: report.authority,
|
|
1293
|
+
doorbellServedBy: report.servedBy,
|
|
1294
|
+
entries: report.entries
|
|
1195
1295
|
}
|
|
1196
|
-
}
|
|
1296
|
+
};
|
|
1297
|
+
if (report.authority === "unreadable") {
|
|
1298
|
+
this.ctx.logger.warn("virtual-doorbell: bindings read did not see this wrapper and the durable store cannot confirm it — a press still rings", options);
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
const message = report.servedBy.length > 0 ? `virtual-doorbell: wrapper deactivated on this camera — its doorbell is served by ${report.servedBy.join(", ")}` : "virtual-doorbell: wrapper deactivated on this camera — the bindings store confirms it";
|
|
1302
|
+
if (report.to === "unbound") this.ctx.logger.info(message, options);
|
|
1303
|
+
else this.ctx.logger.debug(message, options);
|
|
1197
1304
|
}
|
|
1198
1305
|
/**
|
|
1199
|
-
*
|
|
1200
|
-
*
|
|
1306
|
+
* A real press arrived on a camera the in-memory gate cannot clear on its
|
|
1307
|
+
* own: the mirror is `unbound`, or it is short of `bound` while another
|
|
1308
|
+
* provider serves the doorbell. Decide, with ONE read of the durable
|
|
1309
|
+
* authority, whether this wrapper rings.
|
|
1201
1310
|
*
|
|
1202
1311
|
* D49 forbade I/O on the ring path because the read it would have made was
|
|
1203
1312
|
* the same fallible derived read that caused the problem. This read is
|
|
1204
1313
|
* different in both directions: it is the authority rather than a view of
|
|
1205
|
-
* it, and it is paid ONLY
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1314
|
+
* it, and it is paid ONLY where erring open could be wrong — a dropped ring
|
|
1315
|
+
* (an `unbound` mirror) or a DOUBLED one (another provider rings this
|
|
1316
|
+
* camera). A ring is rare and one query is cheap. An unreadable store still
|
|
1317
|
+
* rings: it carries no information.
|
|
1208
1318
|
*
|
|
1209
1319
|
* Returns `true` when the ring must proceed.
|
|
1210
1320
|
*/
|
|
1211
|
-
async
|
|
1321
|
+
async ringsAfterDurableRead(cameraId, mirror) {
|
|
1322
|
+
const binding = mirror.state;
|
|
1212
1323
|
const authority = await this.readDurableAuthority(cameraId);
|
|
1213
|
-
const verdict = ringVerdict(
|
|
1324
|
+
const verdict = ringVerdict(mirror, authority);
|
|
1214
1325
|
switch (verdict) {
|
|
1215
1326
|
case "rings":
|
|
1216
1327
|
this.bindingMirror.set(cameraId, "bound");
|
|
1217
|
-
this.ctx.logger.warn("virtual-doorbell: ring RESCUED — the mirror
|
|
1328
|
+
this.ctx.logger.warn("virtual-doorbell: ring RESCUED — the mirror did not confirm this wrapper but the durable bindings store still names it; the mirror has been repaired", {
|
|
1218
1329
|
tags: { deviceId: cameraId },
|
|
1219
1330
|
meta: {
|
|
1220
|
-
bindingState: binding,
|
|
1331
|
+
bindingState: binding ?? "never-read",
|
|
1332
|
+
doorbellServedBy: mirror.servedBy,
|
|
1221
1333
|
ownAddonId: this.ownAddonId
|
|
1222
1334
|
}
|
|
1223
1335
|
});
|
|
@@ -1233,19 +1345,32 @@ var VirtualDoorbellAddon = class extends BaseAddon {
|
|
|
1233
1345
|
return verdictRings(verdict);
|
|
1234
1346
|
case "silent": {
|
|
1235
1347
|
const derived = await this.readDerivedBinding(cameraId);
|
|
1236
|
-
|
|
1348
|
+
const servedBy = derived === null ? mirror.servedBy : otherProvidersOf(derived.entries, doorbellCapability.name, this.ownAddonId);
|
|
1349
|
+
const options = {
|
|
1237
1350
|
tags: { deviceId: cameraId },
|
|
1238
1351
|
meta: {
|
|
1239
1352
|
bindingState: binding,
|
|
1240
1353
|
ownAddonId: this.ownAddonId,
|
|
1241
1354
|
durableAuthority: authority,
|
|
1355
|
+
doorbellServedBy: servedBy,
|
|
1242
1356
|
entries: derived === null ? "unreadable" : summariseEntries(derived.entries)
|
|
1243
1357
|
}
|
|
1244
|
-
}
|
|
1358
|
+
};
|
|
1359
|
+
if (servedBy.length > 0) this.ctx.logger.info(`virtual-doorbell: press left to ${servedBy.join(", ")} — this wrapper is deactivated on this camera`, options);
|
|
1360
|
+
else this.ctx.logger.warn("virtual-doorbell: ring DROPPED — the wrapper is not bound to this camera, but a trigger source is still configured for it", options);
|
|
1245
1361
|
return verdictRings(verdict);
|
|
1246
1362
|
}
|
|
1247
1363
|
case "rings-pending":
|
|
1248
|
-
case "rings-unconfirmed":
|
|
1364
|
+
case "rings-unconfirmed":
|
|
1365
|
+
this.ctx.logger.warn(`virtual-doorbell: ringing although ${mirror.servedBy.join(", ")} serves this doorbell — the durable bindings store could not confirm this wrapper was deactivated`, {
|
|
1366
|
+
tags: { deviceId: cameraId },
|
|
1367
|
+
meta: {
|
|
1368
|
+
bindingState: binding ?? "never-read",
|
|
1369
|
+
durableAuthority: authority,
|
|
1370
|
+
ownAddonId: this.ownAddonId
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
return verdictRings(verdict);
|
|
1249
1374
|
}
|
|
1250
1375
|
}
|
|
1251
1376
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-a6p0V-IL.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as BaseAddon, Rt as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { Gn as BaseAddon, Rt as logDestinationCapability } from "../../dist-Dori4pf3.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-a6p0V-IL.js");
|
|
4
4
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
5
5
|
var NO_DEVICES = "liveness:no-devices";
|
|
6
6
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as RECORDING_SOURCE_CAMSTACK_ADDON, Gn as BaseAddon, Wn as errMsg, hr as EventCategory, k as RecordingStatusSchema, tr as createEvent } from "../../dist-
|
|
1
|
+
import { E as RECORDING_SOURCE_CAMSTACK_ADDON, Gn as BaseAddon, Wn as errMsg, hr as EventCategory, k as RecordingStatusSchema, tr as createEvent } from "../../dist-Dori4pf3.mjs";
|
|
2
2
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
3
3
|
var NO_DEVICES = "liveness:no-devices";
|
|
4
4
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-a6p0V-IL.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
@@ -6017,8 +6017,24 @@ var require_jsonwebtoken = /* @__PURE__ */ require_chunk.__commonJSMin(((exports
|
|
|
6017
6017
|
};
|
|
6018
6018
|
}));
|
|
6019
6019
|
//#endregion
|
|
6020
|
-
//#region src/
|
|
6020
|
+
//#region src/kernel/settings-read-error.ts
|
|
6021
6021
|
var import_jsonwebtoken = /* @__PURE__ */ require_chunk.__toESM(require_jsonwebtoken());
|
|
6022
|
+
var SettingsReadUnavailableError = class extends Error {
|
|
6023
|
+
reader;
|
|
6024
|
+
reason;
|
|
6025
|
+
name = "SettingsReadUnavailableError";
|
|
6026
|
+
constructor(reader, reason, detail) {
|
|
6027
|
+
super(`[${reader}] settings read refused (${reason}): ${detail}`);
|
|
6028
|
+
this.reader = reader;
|
|
6029
|
+
this.reason = reason;
|
|
6030
|
+
}
|
|
6031
|
+
};
|
|
6032
|
+
/** Narrow an unknown throw to {@link SettingsReadUnavailableError}. */
|
|
6033
|
+
function isSettingsReadUnavailable(err) {
|
|
6034
|
+
return err instanceof SettingsReadUnavailableError;
|
|
6035
|
+
}
|
|
6036
|
+
//#endregion
|
|
6037
|
+
//#region src/auth/token-expiry.ts
|
|
6022
6038
|
/**
|
|
6023
6039
|
* Validation for the operator-configured session-JWT lifetime
|
|
6024
6040
|
* (`auth.tokenExpiry`, System → Settings → Authentication → Token Expiry).
|
|
@@ -6209,7 +6225,7 @@ var AuthManager = class {
|
|
|
6209
6225
|
}
|
|
6210
6226
|
}
|
|
6211
6227
|
signToken(payload) {
|
|
6212
|
-
const configured = this.
|
|
6228
|
+
const configured = this.readConfiguredExpiry();
|
|
6213
6229
|
const parsed = parseTokenExpiry(configured);
|
|
6214
6230
|
if (!parsed.ok) {
|
|
6215
6231
|
const seen = typeof configured === "string" ? configured : JSON.stringify(configured);
|
|
@@ -6220,6 +6236,32 @@ var AuthManager = class {
|
|
|
6220
6236
|
}
|
|
6221
6237
|
return import_jsonwebtoken.sign({ ...payload }, this.jwtSecret, { expiresIn: parsed.seconds });
|
|
6222
6238
|
}
|
|
6239
|
+
/**
|
|
6240
|
+
* The operator's `auth.tokenExpiry`, or `undefined` → DEFAULT_TOKEN_EXPIRY.
|
|
6241
|
+
*
|
|
6242
|
+
* On the hub this reader is `ConfigService`, which answers the key from its
|
|
6243
|
+
* boot-time mirror of the settings store and REFUSES while that mirror is
|
|
6244
|
+
* unknown (pending or failed, D675). A login must not fail over it, so the
|
|
6245
|
+
* refusal signs with the default — and says so once per reason, because a
|
|
6246
|
+
* mint that silently ignored a saved lifetime is the defect this setting
|
|
6247
|
+
* already had once.
|
|
6248
|
+
*/
|
|
6249
|
+
readConfiguredExpiry() {
|
|
6250
|
+
try {
|
|
6251
|
+
return this.config.get("auth.tokenExpiry");
|
|
6252
|
+
} catch (err) {
|
|
6253
|
+
if (!isSettingsReadUnavailable(err)) throw err;
|
|
6254
|
+
const key = `unreadable:${err.reason}`;
|
|
6255
|
+
if (!this.reportedInvalidExpiries.has(key)) {
|
|
6256
|
+
this.reportedInvalidExpiries.add(key);
|
|
6257
|
+
this.logger.warn("auth.tokenExpiry could not be read from the settings store — signing with the default lifetime", { meta: {
|
|
6258
|
+
reason: err.reason,
|
|
6259
|
+
error: err.message
|
|
6260
|
+
} });
|
|
6261
|
+
}
|
|
6262
|
+
return;
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6223
6265
|
verifyToken(token) {
|
|
6224
6266
|
return import_jsonwebtoken.verify(token, this.jwtSecret);
|
|
6225
6267
|
}
|
|
@@ -9947,7 +9989,9 @@ exports.AuthManager = AuthManager;
|
|
|
9947
9989
|
exports.LocalAuthAddon = LocalAuthAddon;
|
|
9948
9990
|
exports.default = LocalAuthAddon;
|
|
9949
9991
|
exports.ScopedTokenManager = ScopedTokenManager;
|
|
9992
|
+
exports.SettingsReadUnavailableError = SettingsReadUnavailableError;
|
|
9950
9993
|
exports.UserManager = UserManager;
|
|
9994
|
+
exports.isSettingsReadUnavailable = isSettingsReadUnavailable;
|
|
9951
9995
|
Object.defineProperty(exports, "require_ms", {
|
|
9952
9996
|
enumerable: true,
|
|
9953
9997
|
get: function() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { Gn as BaseAddon, H as authProviderCapability, L as UserRecordSchema, M as ScopedTokenSchema, r as ApiKeyRecordSchema, vn as userManagementCapability } from "../../dist-
|
|
2
|
+
import { Gn as BaseAddon, H as authProviderCapability, L as UserRecordSchema, M as ScopedTokenSchema, r as ApiKeyRecordSchema, vn as userManagementCapability } from "../../dist-Dori4pf3.mjs";
|
|
3
3
|
import * as crypto$2 from "node:crypto";
|
|
4
4
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
5
5
|
import nodeCrypto from "crypto";
|
|
@@ -6000,7 +6000,7 @@ var require_sign = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
6000
6000
|
};
|
|
6001
6001
|
}));
|
|
6002
6002
|
//#endregion
|
|
6003
|
-
//#region src/
|
|
6003
|
+
//#region src/kernel/settings-read-error.ts
|
|
6004
6004
|
var import_jsonwebtoken = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6005
6005
|
module.exports = {
|
|
6006
6006
|
decode: require_decode(),
|
|
@@ -6011,6 +6011,22 @@ var import_jsonwebtoken = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin
|
|
|
6011
6011
|
TokenExpiredError: require_TokenExpiredError()
|
|
6012
6012
|
};
|
|
6013
6013
|
})))());
|
|
6014
|
+
var SettingsReadUnavailableError = class extends Error {
|
|
6015
|
+
reader;
|
|
6016
|
+
reason;
|
|
6017
|
+
name = "SettingsReadUnavailableError";
|
|
6018
|
+
constructor(reader, reason, detail) {
|
|
6019
|
+
super(`[${reader}] settings read refused (${reason}): ${detail}`);
|
|
6020
|
+
this.reader = reader;
|
|
6021
|
+
this.reason = reason;
|
|
6022
|
+
}
|
|
6023
|
+
};
|
|
6024
|
+
/** Narrow an unknown throw to {@link SettingsReadUnavailableError}. */
|
|
6025
|
+
function isSettingsReadUnavailable(err) {
|
|
6026
|
+
return err instanceof SettingsReadUnavailableError;
|
|
6027
|
+
}
|
|
6028
|
+
//#endregion
|
|
6029
|
+
//#region src/auth/token-expiry.ts
|
|
6014
6030
|
/**
|
|
6015
6031
|
* Validation for the operator-configured session-JWT lifetime
|
|
6016
6032
|
* (`auth.tokenExpiry`, System → Settings → Authentication → Token Expiry).
|
|
@@ -6201,7 +6217,7 @@ var AuthManager = class {
|
|
|
6201
6217
|
}
|
|
6202
6218
|
}
|
|
6203
6219
|
signToken(payload) {
|
|
6204
|
-
const configured = this.
|
|
6220
|
+
const configured = this.readConfiguredExpiry();
|
|
6205
6221
|
const parsed = parseTokenExpiry(configured);
|
|
6206
6222
|
if (!parsed.ok) {
|
|
6207
6223
|
const seen = typeof configured === "string" ? configured : JSON.stringify(configured);
|
|
@@ -6212,6 +6228,32 @@ var AuthManager = class {
|
|
|
6212
6228
|
}
|
|
6213
6229
|
return import_jsonwebtoken.sign({ ...payload }, this.jwtSecret, { expiresIn: parsed.seconds });
|
|
6214
6230
|
}
|
|
6231
|
+
/**
|
|
6232
|
+
* The operator's `auth.tokenExpiry`, or `undefined` → DEFAULT_TOKEN_EXPIRY.
|
|
6233
|
+
*
|
|
6234
|
+
* On the hub this reader is `ConfigService`, which answers the key from its
|
|
6235
|
+
* boot-time mirror of the settings store and REFUSES while that mirror is
|
|
6236
|
+
* unknown (pending or failed, D675). A login must not fail over it, so the
|
|
6237
|
+
* refusal signs with the default — and says so once per reason, because a
|
|
6238
|
+
* mint that silently ignored a saved lifetime is the defect this setting
|
|
6239
|
+
* already had once.
|
|
6240
|
+
*/
|
|
6241
|
+
readConfiguredExpiry() {
|
|
6242
|
+
try {
|
|
6243
|
+
return this.config.get("auth.tokenExpiry");
|
|
6244
|
+
} catch (err) {
|
|
6245
|
+
if (!isSettingsReadUnavailable(err)) throw err;
|
|
6246
|
+
const key = `unreadable:${err.reason}`;
|
|
6247
|
+
if (!this.reportedInvalidExpiries.has(key)) {
|
|
6248
|
+
this.reportedInvalidExpiries.add(key);
|
|
6249
|
+
this.logger.warn("auth.tokenExpiry could not be read from the settings store — signing with the default lifetime", { meta: {
|
|
6250
|
+
reason: err.reason,
|
|
6251
|
+
error: err.message
|
|
6252
|
+
} });
|
|
6253
|
+
}
|
|
6254
|
+
return;
|
|
6255
|
+
}
|
|
6256
|
+
}
|
|
6215
6257
|
verifyToken(token) {
|
|
6216
6258
|
return import_jsonwebtoken.verify(token, this.jwtSecret);
|
|
6217
6259
|
}
|
|
@@ -9934,4 +9976,4 @@ var LocalAuthAddon = class extends BaseAddon {
|
|
|
9934
9976
|
}
|
|
9935
9977
|
};
|
|
9936
9978
|
//#endregion
|
|
9937
|
-
export { LocalAuthAddon, LocalAuthAddon as default,
|
|
9979
|
+
export { LocalAuthAddon, LocalAuthAddon as default, isSettingsReadUnavailable as a, ApiKeyManager as c, SettingsReadUnavailableError as i, ScopedTokenManager as n, require_ms as o, AuthManager as r, require_safe_buffer as s, UserManager as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-a6p0V-IL.js");
|
|
4
4
|
const require_tls = require("../../tls-D_wUeOTD.js");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
let node_path = require("node:path");
|