@camstack/system 1.2.435 → 1.2.437

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.
Files changed (107) hide show
  1. package/dist/{agent-https-B8lKYVtU.mjs → agent-https-BPfHrI4c.mjs} +3 -3
  2. package/dist/auth/login-session-manager.d.ts +2 -0
  3. package/dist/auth/session-revocation-bus.d.ts +32 -0
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  8. package/dist/builtins/alerts/alerts.addon.js +1 -1
  9. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  10. package/dist/builtins/autotrack/index.js +1 -1
  11. package/dist/builtins/autotrack/index.mjs +1 -1
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  14. package/dist/builtins/calendars/calendars.addon.js +1 -1
  15. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  16. package/dist/builtins/camera-grid/index.js +1 -1
  17. package/dist/builtins/camera-grid/index.mjs +1 -1
  18. package/dist/builtins/composer/composer.addon.js +2 -2
  19. package/dist/builtins/composer/composer.addon.mjs +2 -2
  20. package/dist/builtins/console-logging/index.js +1 -1
  21. package/dist/builtins/console-logging/index.mjs +1 -1
  22. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  23. package/dist/builtins/core-blocks/core-blocks.addon.mjs +5 -5
  24. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  25. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  26. package/dist/builtins/hub-forwarder/index.js +1 -1
  27. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  28. package/dist/builtins/keychain/index.js +6 -7
  29. package/dist/builtins/keychain/index.mjs +6 -7
  30. package/dist/builtins/keychain/keychain-service.d.ts +1 -2
  31. package/dist/builtins/keychain/system-held-secrets.d.ts +5 -5
  32. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  33. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  34. package/dist/builtins/local-auth/local-auth.addon.js +43 -2
  35. package/dist/builtins/local-auth/local-auth.addon.mjs +43 -3
  36. package/dist/builtins/local-network/local-network.addon.js +1 -1
  37. package/dist/builtins/local-network/local-network.addon.mjs +4 -4
  38. package/dist/builtins/loki-logging/index.js +1 -1
  39. package/dist/builtins/loki-logging/index.mjs +1 -1
  40. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  41. package/dist/builtins/native-metrics/native-metrics.addon.mjs +10 -10
  42. package/dist/builtins/platform-probe/index.js +1 -1
  43. package/dist/builtins/platform-probe/index.mjs +8 -8
  44. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  45. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  46. package/dist/builtins/snapshot/index.js +1 -1
  47. package/dist/builtins/snapshot/index.mjs +1 -1
  48. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  49. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  50. package/dist/builtins/sqlite-storage/index.js +1 -1
  51. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  52. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
  53. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
  54. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  55. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  56. package/dist/builtins/system-config/system-config.addon.d.ts +11 -23
  57. package/dist/builtins/system-config/system-config.addon.js +219 -1479
  58. package/dist/builtins/system-config/system-config.addon.mjs +222 -1472
  59. package/dist/builtins/winston-logging/index.js +1 -1
  60. package/dist/builtins/winston-logging/index.mjs +1 -1
  61. package/dist/{composition-sources-Cm42mgbv.js → composition-sources-BIT8IUKm.js} +1 -1
  62. package/dist/{composition-sources-_7W2Ly9s.mjs → composition-sources-tpYR0f1x.mjs} +1 -1
  63. package/dist/constants-Bc6trhoW.mjs +20 -0
  64. package/dist/constants-CwRY32Nx.js +66 -0
  65. package/dist/{device-ca-B6YJZus6.mjs → device-ca-BhdBByGD.mjs} +1 -1
  66. package/dist/{device-ca-WXuKc8AX.js → device-ca-DImD8IzR.js} +1 -1
  67. package/dist/{dist-CnUtkSwN.js → dist-CEAyXW3Q.js} +42 -12
  68. package/dist/{dist-Bz4_y8Xy.mjs → dist-m5JkT8UN.mjs} +33 -3
  69. package/dist/file-host-worker.js +1 -1
  70. package/dist/file-host-worker.mjs +1 -1
  71. package/dist/{hub-mdns-ciao-DJRwtlA8.mjs → hub-mdns-ciao-DMlQTdPU.mjs} +1 -1
  72. package/dist/index.d.ts +2 -0
  73. package/dist/index.js +135 -796
  74. package/dist/index.mjs +150 -769
  75. package/dist/kernel/index.d.ts +7 -21
  76. package/dist/kernel/moleculer/agent-ui-unlock.d.ts +7 -32
  77. package/dist/kernel/moleculer/broker-factory.d.ts +3 -9
  78. package/dist/kernel/moleculer/broker-transport-swap.d.ts +17 -0
  79. package/dist/kernel/moleculer/hub-service.d.ts +6 -16
  80. package/dist/kernel/moleculer/mesh-access-middleware.d.ts +7 -17
  81. package/dist/kernel/moleculer/mesh-identity.d.ts +57 -0
  82. package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +1 -4
  83. package/dist/kernel/moleculer/mesh-mtls/index.d.ts +1 -4
  84. package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +1 -1
  85. package/dist/kernel/moleculer/mesh-mtls/mesh-renewal.d.ts +1 -1
  86. package/dist/kernel/moleculer/node-registry.d.ts +0 -6
  87. package/dist/kernel/moleculer/register-node-client.d.ts +9 -7
  88. package/dist/{restore-archive-BNoFLAg8.js → restore-archive-C75srVbG.js} +1 -1
  89. package/dist/{restore-archive-DJYuznWP.mjs → restore-archive-DNxAStrJ.mjs} +1 -1
  90. package/dist/{retired-settings-keys-9nA85bwT.mjs → retired-settings-keys-C5qP9QIf.mjs} +1 -1
  91. package/dist/{retired-settings-keys-CO3RqsDw.js → retired-settings-keys-DNfV28R_.js} +1 -1
  92. package/dist/{wal-maintenance-D3gwRj1B.js → wal-maintenance-Ch79gy9S.js} +0 -0
  93. package/dist/{wal-maintenance-DLrbapzi.mjs → wal-maintenance-DvnVO5IK.mjs} +0 -0
  94. package/package.json +1 -1
  95. package/dist/builtins/system-config/cluster-secret-keeper.d.ts +0 -63
  96. package/dist/constants-DL87WgeN.js +0 -221
  97. package/dist/constants-DoiTA134.mjs +0 -102
  98. package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +0 -91
  99. package/dist/kernel/moleculer/cluster-secret.d.ts +0 -46
  100. package/dist/kernel/moleculer/mesh-auth-mode.d.ts +0 -58
  101. package/dist/kernel/moleculer/mesh-authenticator.d.ts +0 -77
  102. package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +0 -46
  103. package/dist/kernel/moleculer/mesh-join-client.d.ts +0 -73
  104. package/dist/kernel/moleculer/mesh-join-hold.d.ts +0 -85
  105. package/dist/kernel/moleculer/mesh-join-proof.d.ts +0 -39
  106. package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +0 -34
  107. package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +0 -56
@@ -3,7 +3,7 @@ import { X509Certificate, createHash, createPrivateKey, randomBytes, webcrypto }
3
3
  import { writeOwnerOnlyFileSync } from "@camstack/types/node";
4
4
  import { isIP } from "node:net";
5
5
  import { join } from "node:path";
6
- import * as os from "node:os";
6
+ import * as os$1 from "node:os";
7
7
  import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
8
8
  //#region src/tls/agent-https-names.ts
9
9
  /**
@@ -189,8 +189,8 @@ function evaluateExistingCert(input) {
189
189
  /** The real machine. The only place in `tls/` that touches `os`. */
190
190
  function systemHostFacts() {
191
191
  return {
192
- hostname: os.hostname(),
193
- networkInterfaces: os.networkInterfaces()
192
+ hostname: os$1.hostname(),
193
+ networkInterfaces: os$1.networkInterfaces()
194
194
  };
195
195
  }
196
196
  /**
@@ -121,6 +121,8 @@ export declare class LoginSessionManager {
121
121
  listActive(): readonly LoginSessionSummary[];
122
122
  /** Delete rows expired more than 7 days ago or revoked more than 30. Returns how many. */
123
123
  reap(): Promise<number>;
124
+ /** Tell the hub which sessions just ended — right after the mirror, before the store write. */
125
+ private announce;
124
126
  private newRefreshToken;
125
127
  private remember;
126
128
  private forget;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * "These login sessions just ended" — the one announcement every revoke path
3
+ * of the login-session table makes, so the hub can end what those sessions
4
+ * still HOLD (open WebSockets, live media). A revoked `sid` is refused on the
5
+ * next call; without this the socket stays open and the client keeps polling
6
+ * as an anonymous principal.
7
+ *
8
+ * Process-global (`Symbol.for`), like the hub-internal user-management surface:
9
+ * the table lives in `local-auth` and the listener in the hub, and neither may
10
+ * import the other. Listeners are synchronous; one that throws never reaches
11
+ * the revoke (reported to `onListenerError`).
12
+ */
13
+ import type { LoginSessionRevocation } from "./login-session-manager.js";
14
+ export interface SessionsRevokedEvent {
15
+ /** The sessions that ended just now (never one that was already ended). */
16
+ readonly sessionIds: readonly string[];
17
+ /** The user they belong to, when the revoke named one. */
18
+ readonly userId: string | null;
19
+ /**
20
+ * The revoke was "everything of this user" (logout everywhere, password
21
+ * change or reset, deletion): a connection of `userId` that carries NO
22
+ * session id (a pre-session token) ends too, except `exceptSessionId`.
23
+ */
24
+ readonly allOfUser: boolean;
25
+ readonly exceptSessionId: string | null;
26
+ readonly reason: LoginSessionRevocation;
27
+ }
28
+ export type SessionsRevokedListener = (event: SessionsRevokedEvent) => void;
29
+ /** Subscribe; returns the unsubscribe. */
30
+ export declare function onSessionsRevoked(listener: SessionsRevokedListener): () => void;
31
+ /** Announce an ended batch. A listener that throws never reaches the revoke. */
32
+ export declare function announceSessionsRevoked(event: SessionsRevokedEvent, onListenerError?: (error: unknown) => void): void;
@@ -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-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Q as addonPagesCapability, br as errMsg, pi as EventCategory, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { $ as addonPagesCapability, Cr as BaseAddon, Sr as errMsg, pi as EventCategory } from "../../dist-m5JkT8UN.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { br as errMsg, et as addonWidgetsCapability, pi as EventCategory, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, Sr as errMsg, pi as EventCategory, tt as addonWidgetsCapability } from "../../dist-m5JkT8UN.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  //#region src/builtins/alerts/device-label.ts
8
8
  /**
9
9
  * Operator-facing device label for alert messages.
@@ -1,4 +1,4 @@
1
- import { Lr as createEvent, br as errMsg, i as AlertSchema, pi as EventCategory, tt as alertsCapability, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, Sr as errMsg, i as AlertSchema, nt as alertsCapability, pi as EventCategory, zr as createEvent } from "../../dist-m5JkT8UN.mjs";
2
2
  //#region src/builtins/alerts/device-label.ts
3
3
  /**
4
4
  * Operator-facing device label for alert messages.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  //#region src/builtins/autotrack/autotrack-config.ts
8
8
  var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
9
9
  deadZoneFraction: .5,
@@ -1,4 +1,4 @@
1
- import { Dn as ptzAutotrackCapability, Kr as isEvent, br as errMsg, it as bareAddonId, k as FIRST_LEVEL_MACRO_CLASSES, pi as EventCategory, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, Jr as isEvent, On as ptzAutotrackCapability, Sr as errMsg, at as bareAddonId, k as FIRST_LEVEL_MACRO_CLASSES, pi as EventCategory } from "../../dist-m5JkT8UN.mjs";
2
2
  //#region src/builtins/autotrack/autotrack-config.ts
3
3
  var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
4
4
  deadZoneFraction: .5,
@@ -3,8 +3,8 @@ 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-CnUtkSwN.js");
7
- const require_restore_archive = require("../../restore-archive-BNoFLAg8.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
+ const require_restore_archive = require("../../restore-archive-C75srVbG.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_fs_promises = require("node:fs/promises");
10
10
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -1,5 +1,5 @@
1
- import { Qr as nodePin, pi as EventCategory, pn as mayWriteToLocation, qn as storageOccupancyCapability, rt as backupCapability, ui as toNodeId, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
2
- import { a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-DJYuznWP.mjs";
1
+ import { $r as nodePin, Cr as BaseAddon, Yn as storageOccupancyCapability, it as backupCapability, mn as mayWriteToLocation, pi as EventCategory, ui as toNodeId } from "../../dist-m5JkT8UN.mjs";
2
+ import { a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-DNxAStrJ.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import * as fsp from "node:fs/promises";
5
5
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let zod = require("zod");
9
9
  //#region src/builtins/calendars/calendar-color.ts
@@ -1,4 +1,4 @@
1
- import { h as CalendarPreferencesSchema, ut as calendarsCapability, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, dt as calendarsCapability, h as CalendarPreferencesSchema } from "../../dist-m5JkT8UN.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/builtins/calendars/calendar-color.ts
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  let zod = require("zod");
8
8
  let _camstack_types_node = require("@camstack/types/node");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { D as DeclaredDevices, Lr as createEvent, S as DERIVED_CAMERA_SILENCED_CAP_NAMES, Tt as declarationOwnerNodeId, Wn as snapshotCapability, Wr as hydrateSchema, Yn as streamCatalogCapability, _n as motionCapability, _r as DeviceFeature, br as errMsg, dt as cameraGridLayoutCapability, mn as memoizePinnedFfmpeg, o as BaseDevice, or as buildFfmpegArgs, pi as EventCategory, xr as BaseAddon, yr as DeviceType, z as MOTION_CLOSE_AFTER_MS } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, D as DeclaredDevices, Et as declarationOwnerNodeId, Kn as snapshotCapability, Kr as hydrateSchema, S as DERIVED_CAMERA_SILENCED_CAP_NAMES, Sr as errMsg, Zn as streamCatalogCapability, cr as buildFfmpegArgs, ft as cameraGridLayoutCapability, hn as memoizePinnedFfmpeg, o as BaseDevice, pi as EventCategory, vn as motionCapability, xr as DeviceType, yr as DeviceFeature, z as MOTION_CLOSE_AFTER_MS, zr as createEvent } from "../../dist-m5JkT8UN.mjs";
2
2
  import { z } from "zod";
3
3
  import { FfmpegProcess } from "@camstack/types/node";
4
4
  import { join } from "node:path";
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
7
- const require_composition_sources = require("../../composition-sources-Cm42mgbv.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
+ const require_composition_sources = require("../../composition-sources-BIT8IUKm.js");
8
8
  let zod = require("zod");
9
9
  //#region src/builtins/shared/device-state-changed.ts
10
10
  /** Structural narrowing helper for untrusted bus payloads. */
@@ -1,5 +1,5 @@
1
- import { D as DeclaredDevices, Lr as createEvent, Rt as evaluateCompositionField, Vt as expressionContainsBuiltinCall, ar as COMPOSER_ADDON_ID, br as errMsg, cr as composedDeviceRef, d as COMPOSED_ITEM_FIXED_FIELDS, dr as compositionItemFieldPath, fr as compositionSliceKey, gr as toExpressionValue, hr as disarmRoseMemory, ht as compositionFieldKey, lr as composedDeviceStableId, mr as createStatefulExpressionMemory, mt as composerCapability, o as BaseDevice, ot as buildCapabilityLookup, pi as EventCategory, pr as compositionSourceKey, r as ALL_CAPABILITY_DEFINITIONS, sr as cloneStatefulExpressionMemory, ur as compositionFeatureEnabled, wn as planComposition, xr as BaseAddon, yr as DeviceType } from "../../dist-Bz4_y8Xy.mjs";
2
- import { n as normalizedNativeOwner } from "../../composition-sources-_7W2Ly9s.mjs";
1
+ import { Cr as BaseAddon, D as DeclaredDevices, Ht as expressionContainsBuiltinCall, Sr as errMsg, Tn as planComposition, _r as disarmRoseMemory, d as COMPOSED_ITEM_FIXED_FIELDS, dr as composedDeviceStableId, fr as compositionFeatureEnabled, gr as createStatefulExpressionMemory, gt as compositionFieldKey, hr as compositionSourceKey, ht as composerCapability, lr as cloneStatefulExpressionMemory, mr as compositionSliceKey, o as BaseDevice, pi as EventCategory, pr as compositionItemFieldPath, r as ALL_CAPABILITY_DEFINITIONS, sr as COMPOSER_ADDON_ID, st as buildCapabilityLookup, ur as composedDeviceRef, vr as toExpressionValue, xr as DeviceType, zr as createEvent, zt as evaluateCompositionField } from "../../dist-m5JkT8UN.mjs";
2
+ import { n as normalizedNativeOwner } from "../../composition-sources-tpYR0f1x.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/builtins/shared/device-state-changed.ts
5
5
  /** Structural narrowing helper for untrusted bus payloads. */
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/console-logging/console-destination.ts
9
9
  var LEVEL_RANK = {
@@ -1,4 +1,4 @@
1
- import { ln as logDestinationCapability, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, un as logDestinationCapability } from "../../dist-m5JkT8UN.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/console-logging/console-destination.ts
4
4
  var LEVEL_RANK = {
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-CnUtkSwN.js");
4
- const require_composition_sources = require("../../composition-sources-Cm42mgbv.js");
3
+ const require_dist = require("../../dist-CEAyXW3Q.js");
4
+ const require_composition_sources = require("../../composition-sources-BIT8IUKm.js");
5
5
  let node_crypto = require("node:crypto");
6
6
  let _camstack_types_node = require("@camstack/types/node");
7
7
  let node_fs_promises = require("node:fs/promises");
@@ -1,11 +1,11 @@
1
- import { $n as validateComposition, D as DeclaredDevices, Mn as resolveCoreBlockEntry, Nn as resolveCoreBlockFiles, Wr as hydrateSchema, _t as coreBlockAddonId, br as errMsg, bt as coreBlockSourceKind, cr as composedDeviceRef, f as COMPOSER_RUNNER_ID, g as CoreBlockSchema, gt as compositionSourceRefs, kn as replacedFieldKeys, kt as describeComposableCaps, m as CORE_BLOCK_ADDON_PREFIX, ot as buildCapabilityLookup, p as CORE_BLOCKS_ADDON_ID, pr as compositionSourceKey, r as ALL_CAPABILITY_DEFINITIONS, vn as normalizeCoreBlockWrite, vt as coreBlockComposition, wn as planComposition, xr as BaseAddon, xt as coreBlocksCapability, yt as coreBlockIdFromAddonId } from "../../dist-Bz4_y8Xy.mjs";
2
- import { t as describeCompositionSources } from "../../composition-sources-_7W2Ly9s.mjs";
1
+ import { An as replacedFieldKeys, At as describeComposableCaps, Cr as BaseAddon, D as DeclaredDevices, Kr as hydrateSchema, Nn as resolveCoreBlockEntry, Pn as resolveCoreBlockFiles, Sr as errMsg, St as coreBlocksCapability, Tn as planComposition, _t as compositionSourceRefs, bt as coreBlockIdFromAddonId, f as COMPOSER_RUNNER_ID, g as CoreBlockSchema, hr as compositionSourceKey, m as CORE_BLOCK_ADDON_PREFIX, p as CORE_BLOCKS_ADDON_ID, r as ALL_CAPABILITY_DEFINITIONS, st as buildCapabilityLookup, tr as validateComposition, ur as composedDeviceRef, vt as coreBlockAddonId, xt as coreBlockSourceKind, yn as normalizeCoreBlockWrite, yt as coreBlockComposition } from "../../dist-m5JkT8UN.mjs";
2
+ import { t as describeCompositionSources } from "../../composition-sources-tpYR0f1x.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { customizationBlockName } from "@camstack/types/node";
6
6
  import * as fs from "node:fs/promises";
7
7
  import * as path$1 from "node:path";
8
- import * as os from "node:os";
8
+ import * as os$1 from "node:os";
9
9
  import { pathToFileURL } from "node:url";
10
10
  //#region src/builtins/core-blocks/block-package.ts
11
11
  /**
@@ -864,7 +864,7 @@ async function compileFiles(transpiler, files, entryPath) {
864
864
  ok: false,
865
865
  error: "the multi-file bundler is unavailable on this node"
866
866
  };
867
- const work = await fs.mkdtemp(path$1.join(os.tmpdir(), "core-block-compile-"));
867
+ const work = await fs.mkdtemp(path$1.join(os$1.tmpdir(), "core-block-compile-"));
868
868
  try {
869
869
  for (const [rel, content] of Object.entries(files)) {
870
870
  const abs = path$1.resolve(work, rel);
@@ -1810,7 +1810,7 @@ function looksLikeSchema(value) {
1810
1810
  * Never throws.
1811
1811
  */
1812
1812
  async function extractSettingsSchema(js) {
1813
- const dir = await fs.mkdtemp(path$1.join(os.tmpdir(), "core-block-schema-"));
1813
+ const dir = await fs.mkdtemp(path$1.join(os$1.tmpdir(), "core-block-schema-"));
1814
1814
  const file = path$1.join(dir, "block.mjs");
1815
1815
  try {
1816
1816
  await fs.writeFile(file, js, "utf-8");
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
7
- const require_retired_settings_keys = require("../../retired-settings-keys-CO3RqsDw.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
+ const require_retired_settings_keys = require("../../retired-settings-keys-DNfV28R_.js");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
10
10
  let _camstack_types_node = require("@camstack/types/node");
@@ -1,5 +1,5 @@
1
- import { A as FieldClaimModeSchema, Ar as WELL_KNOWN_TAB_MAP, Bt as expandContainer, Dt as defineExtensionSlotProvider, Gr as isDeviceConfigCap, Ir as collectZodSecretPaths, It as enumerateItemArrayFields, Jr as isSecretClear, Kt as formatMinutes, Lt as enumerateSchemaFields, Mt as deviceManagerCapability, Nt as deviceStateCapability, O as DeviceStatusSchema, Pt as deviceStatusCapability, R as MINUTES_PER_DAY, Rn as runtimeStatePolicyFor, Sn as parseStreamParamsFormPatch, St as createDeviceExtensionProvider, Un as siteZoneKey, W as STREAM_PROFILE_META, Xr as isSecretMarkerLike, Yr as isSecretMarker, _r as DeviceFeature, ai as resolveSecretMarkers, br as errMsg, c as CAMERA_SWITCH_ORDER, cn as locationIconKey, di as toSecretFieldView, fi as transformSecretWrite, ft as canonicalIconKey, in as legacyAutoLinkIds, j as FieldClaimSchema, jt as deviceExtensionCapability, kr as SECRET_CLEAR, li as sleep$1, lt as buildStreamParamsConfigSchema, pi as EventCategory, qr as isKeychainStoredField, r as ALL_CAPABILITY_DEFINITIONS, si as secretTreeFromPaths, u as CAP_NAMES_WITH_STATUS, vr as DeviceRole, x as DAY_NAMES, xr as BaseAddon, yn as normalizeUnit, yr as DeviceType } from "../../dist-Bz4_y8Xy.mjs";
2
- import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-9nA85bwT.mjs";
1
+ import { A as FieldClaimModeSchema, Cn as parseStreamParamsFormPatch, Cr as BaseAddon, Ct as createDeviceExtensionProvider, Ft as deviceStatusCapability, Gn as siteZoneKey, Lt as enumerateItemArrayFields, Mr as WELL_KNOWN_TAB_MAP, Mt as deviceExtensionCapability, Nt as deviceManagerCapability, O as DeviceStatusSchema, Ot as defineExtensionSlotProvider, Pt as deviceStateCapability, Qr as isSecretMarkerLike, R as MINUTES_PER_DAY, Rr as collectZodSecretPaths, Rt as enumerateSchemaFields, Sr as errMsg, Vt as expandContainer, W as STREAM_PROFILE_META, Xr as isSecretClear, Yr as isKeychainStoredField, Zr as isSecretMarker, an as legacyAutoLinkIds, bn as normalizeUnit, br as DeviceRole, c as CAMERA_SWITCH_ORDER, ci as secretTreeFromPaths, di as toSecretFieldView, fi as transformSecretWrite, j as FieldClaimSchema, jr as SECRET_CLEAR, li as sleep$1, ln as locationIconKey, oi as resolveSecretMarkers, pi as EventCategory, pt as canonicalIconKey, qr as isDeviceConfigCap, qt as formatMinutes, r as ALL_CAPABILITY_DEFINITIONS, u as CAP_NAMES_WITH_STATUS, ut as buildStreamParamsConfigSchema, x as DAY_NAMES, xr as DeviceType, yr as DeviceFeature, zn as runtimeStatePolicyFor } from "../../dist-m5JkT8UN.mjs";
2
+ import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-C5qP9QIf.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.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 { ln as logDestinationCapability, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, un as logDestinationCapability } from "../../dist-m5JkT8UN.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
4
4
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-CnUtkSwN.js");
7
- const require_device_ca = require("../../device-ca-WXuKc8AX.js");
8
- const require_constants = require("../../constants-DL87WgeN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
+ const require_device_ca = require("../../device-ca-DImD8IzR.js");
8
+ const require_constants = require("../../constants-CwRY32Nx.js");
9
9
  const require_platform_key_source = require("../../platform-key-source-Di7HrlGR.js");
10
10
  let node_crypto = require("node:crypto");
11
11
  let _camstack_types_node = require("@camstack/types/node");
@@ -336,7 +336,7 @@ async function applyKeychainResetTrigger(input) {
336
336
  }
337
337
  await consume(file, logger);
338
338
  const toReenter = ((await service.resetReport().catch(() => null))?.pendingReentry ?? []).map((m) => `${m.owner}:${m.scope}:${m.fieldPath}`);
339
- logger.error("*** KEYCHAIN RESET by the RESET_KEYCHAIN trigger file *** Every stored secret was archived (unreadable without the lost master key) and a new master key and data key were created. Every secret field now reads \"not set\" — re-enter them (System → Secrets lists them). The session signing key is regenerated: everyone signs in again. The cluster secret was cleared: set it again in System → Cluster if agents used one.", {
339
+ logger.error("*** KEYCHAIN RESET by the RESET_KEYCHAIN trigger file *** Every stored secret was archived (unreadable without the lost master key) and a new master key and data key were created. Every secret field now reads \"not set\" — re-enter them (System → Secrets lists them). The session signing key is regenerated: everyone signs in again.", {
340
340
  lockedReason: state.reason,
341
341
  archived: record.archived,
342
342
  archivedCollection: record.archivedCollection,
@@ -360,7 +360,7 @@ var PROCESS_HELD_SECRET_REFS = new Set([
360
360
  require_device_ca.DEVICE_CA_KEY_REF
361
361
  ]);
362
362
  /** `system-settings` keys that may hold a system-owned secret's marker. */
363
- var SYSTEM_SECRET_SETTINGS_KEYS = [require_constants.CLUSTER_SECRET_SETTINGS_KEY];
363
+ var SYSTEM_SECRET_SETTINGS_KEYS = [];
364
364
  var KeychainLockedError = class extends Error {
365
365
  reason;
366
366
  constructor(reason) {
@@ -899,8 +899,7 @@ var KeychainService = class {
899
899
  * 2. Archive every value AND every wrapped data key — the archive stays
900
900
  * openable if the lost master key turns up.
901
901
  * 3. New data key under the new master key ({@link firstBoot}).
902
- * 4. Clear the system-held markers (the cluster secret's): a marker pointing
903
- * at an archived value would refuse every agent forever (D797). The
902
+ * 4. Clear the system-held markers (none remain since D857). The
904
903
  * session signing key has no marker; it now resolves `missing`, and
905
904
  * `local-auth` generates a new one (everyone signs in again).
906
905
  * 5. One `delete` event per archived ref, so every keeper reloads.
@@ -1,6 +1,6 @@
1
- import { $r as normalizeSecretOwner, P as KEYCHAIN_RESET_TRIGGER_ACTOR, Ur as formatSecretScope, ni as parseSecretRef, nn as keychainAdminCapability, pi as EventCategory, rn as keychainCapability, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
2
- import { d as JWT_SIGNING_KEY_REF, n as DEVICE_CA_KEY_REF, p as SYSTEM_SECRET_OWNER } from "../../device-ca-B6YJZus6.mjs";
3
- import { a as MESH_CA_KEY_REF, p as CLUSTER_SECRET_SETTINGS_KEY } from "../../constants-DoiTA134.mjs";
1
+ import { Cr as BaseAddon, Gr as formatSecretScope, P as KEYCHAIN_RESET_TRIGGER_ACTOR, ei as normalizeSecretOwner, in as keychainCapability, pi as EventCategory, ri as parseSecretRef, rn as keychainAdminCapability } from "../../dist-m5JkT8UN.mjs";
2
+ import { d as JWT_SIGNING_KEY_REF, n as DEVICE_CA_KEY_REF, p as SYSTEM_SECRET_OWNER } from "../../device-ca-BhdBByGD.mjs";
3
+ import { a as MESH_CA_KEY_REF } from "../../constants-Bc6trhoW.mjs";
4
4
  import { n as getPlatformKeychainKey } from "../../platform-key-source-BWlq0jjn.mjs";
5
5
  import { createCipheriv, createDecipheriv, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
6
6
  import { restrictDirToOwnerSync, restrictFileToOwnerSync, writeOwnerOnlyFileSync } from "@camstack/types/node";
@@ -330,7 +330,7 @@ async function applyKeychainResetTrigger(input) {
330
330
  }
331
331
  await consume(file, logger);
332
332
  const toReenter = ((await service.resetReport().catch(() => null))?.pendingReentry ?? []).map((m) => `${m.owner}:${m.scope}:${m.fieldPath}`);
333
- logger.error("*** KEYCHAIN RESET by the RESET_KEYCHAIN trigger file *** Every stored secret was archived (unreadable without the lost master key) and a new master key and data key were created. Every secret field now reads \"not set\" — re-enter them (System → Secrets lists them). The session signing key is regenerated: everyone signs in again. The cluster secret was cleared: set it again in System → Cluster if agents used one.", {
333
+ logger.error("*** KEYCHAIN RESET by the RESET_KEYCHAIN trigger file *** Every stored secret was archived (unreadable without the lost master key) and a new master key and data key were created. Every secret field now reads \"not set\" — re-enter them (System → Secrets lists them). The session signing key is regenerated: everyone signs in again.", {
334
334
  lockedReason: state.reason,
335
335
  archived: record.archived,
336
336
  archivedCollection: record.archivedCollection,
@@ -354,7 +354,7 @@ var PROCESS_HELD_SECRET_REFS = new Set([
354
354
  DEVICE_CA_KEY_REF
355
355
  ]);
356
356
  /** `system-settings` keys that may hold a system-owned secret's marker. */
357
- var SYSTEM_SECRET_SETTINGS_KEYS = [CLUSTER_SECRET_SETTINGS_KEY];
357
+ var SYSTEM_SECRET_SETTINGS_KEYS = [];
358
358
  var KeychainLockedError = class extends Error {
359
359
  reason;
360
360
  constructor(reason) {
@@ -893,8 +893,7 @@ var KeychainService = class {
893
893
  * 2. Archive every value AND every wrapped data key — the archive stays
894
894
  * openable if the lost master key turns up.
895
895
  * 3. New data key under the new master key ({@link firstBoot}).
896
- * 4. Clear the system-held markers (the cluster secret's): a marker pointing
897
- * at an archived value would refuse every agent forever (D797). The
896
+ * 4. Clear the system-held markers (none remain since D857). The
898
897
  * session signing key has no marker; it now resolves `missing`, and
899
898
  * `local-auth` generates a new one (everyone signs in again).
900
899
  * 5. One `delete` event per archived ref, so every keeper reloads.
@@ -122,8 +122,7 @@ export declare class KeychainService {
122
122
  * 2. Archive every value AND every wrapped data key — the archive stays
123
123
  * openable if the lost master key turns up.
124
124
  * 3. New data key under the new master key ({@link firstBoot}).
125
- * 4. Clear the system-held markers (the cluster secret's): a marker pointing
126
- * at an archived value would refuse every agent forever (D797). The
125
+ * 4. Clear the system-held markers (none remain since D857). The
127
126
  * session signing key has no marker; it now resolves `missing`, and
128
127
  * `local-auth` generates a new one (everyone signs in again).
129
128
  * 5. One `delete` event per archived ref, so every keeper reloads.
@@ -7,13 +7,13 @@
7
7
  * offered for deletion as an orphan.
8
8
  * - The mesh CA key is HELD the same way (mesh mTLS issuance); the public
9
9
  * certificate lives in `system-settings` `cluster.meshCa`.
10
- * - The cluster secret is a `password` field of `system-config` (System →
11
- * Cluster): its marker lives in the `system-settings` row
12
- * `cluster.clusterSecret`, like any other form-owned secret.
10
+ * - No form-owned system secret remains: the cluster secret was removed (D857) and the
11
+ * mesh certificate is the node identity. A `system/global/clusterSecret` entry left in
12
+ * the keychain by an older hub is NOT recognised here, so it reads as an orphan the
13
+ * operator deletes by hand; nothing reads or writes it any more.
13
14
  */
14
15
  import type { SystemHeldSecretName } from "@camstack/types";
15
16
  import { SYSTEM_SECRET_OWNER } from "../../auth/jwt-signing-key.js";
16
- import { CLUSTER_SECRET_REF } from "../../kernel/moleculer/cluster-secret.js";
17
17
  import { MESH_CA_KEY_REF } from "../../kernel/moleculer/mesh-mtls/constants.js";
18
18
  export { SYSTEM_SECRET_OWNER };
19
19
  /** The refs `keychain-admin.setSystemSecret` may write, by name. */
@@ -22,4 +22,4 @@ export declare const SYSTEM_HELD_SECRET_REFS: Readonly<Record<SystemHeldSecretNa
22
22
  export declare const PROCESS_HELD_SECRET_REFS: ReadonlySet<string>;
23
23
  /** `system-settings` keys that may hold a system-owned secret's marker. */
24
24
  export declare const SYSTEM_SECRET_SETTINGS_KEYS: readonly string[];
25
- export { CLUSTER_SECRET_REF, MESH_CA_KEY_REF };
25
+ export { MESH_CA_KEY_REF };
@@ -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-CnUtkSwN.js");
3
+ const require_dist = require("../../dist-CEAyXW3Q.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 { H as RecordingStatusSchema, Lr as createEvent, V as RECORDING_SOURCE_CAMSTACK_ADDON, br as errMsg, pi as EventCategory, xr as BaseAddon } from "../../dist-Bz4_y8Xy.mjs";
1
+ import { Cr as BaseAddon, H as RecordingStatusSchema, Sr as errMsg, V as RECORDING_SOURCE_CAMSTACK_ADDON, pi as EventCategory, zr as createEvent } from "../../dist-m5JkT8UN.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,10 +3,10 @@ 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-CnUtkSwN.js");
6
+ const require_dist = require("../../dist-CEAyXW3Q.js");
7
7
  const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
8
8
  const require_ms$1 = require("../../ms-LB3giGoU.js");
9
- const require_device_ca = require("../../device-ca-WXuKc8AX.js");
9
+ const require_device_ca = require("../../device-ca-DImD8IzR.js");
10
10
  let node_crypto = require("node:crypto");
11
11
  node_crypto = require_chunk.__toESM(node_crypto);
12
12
  let crypto$1 = require("crypto");
@@ -6458,6 +6458,33 @@ var ScopedTokenManager = class {
6458
6458
  }
6459
6459
  };
6460
6460
  //#endregion
6461
+ //#region src/auth/session-revocation-bus.ts
6462
+ var BUS_KEY = Symbol.for("camstack.login-sessions.revocation-bus");
6463
+ function listeners() {
6464
+ const existing = Reflect.get(globalThis, BUS_KEY);
6465
+ if (existing instanceof Set) return existing;
6466
+ const created = /* @__PURE__ */ new Set();
6467
+ Reflect.set(globalThis, BUS_KEY, created);
6468
+ return created;
6469
+ }
6470
+ /** Subscribe; returns the unsubscribe. */
6471
+ function onSessionsRevoked(listener) {
6472
+ const set = listeners();
6473
+ set.add(listener);
6474
+ return () => {
6475
+ set.delete(listener);
6476
+ };
6477
+ }
6478
+ /** Announce an ended batch. A listener that throws never reaches the revoke. */
6479
+ function announceSessionsRevoked(event, onListenerError) {
6480
+ if (event.sessionIds.length === 0 && !event.allOfUser) return;
6481
+ for (const listener of [...listeners()]) try {
6482
+ listener(event);
6483
+ } catch (error) {
6484
+ onListenerError?.(error);
6485
+ }
6486
+ }
6487
+ //#endregion
6461
6488
  //#region src/auth/login-session-manager.ts
6462
6489
  /**
6463
6490
  * Login sessions — the server-side record behind every session token.
@@ -6807,6 +6834,7 @@ var LoginSessionManager = class {
6807
6834
  revokedReason: reason
6808
6835
  };
6809
6836
  this.replace(session, updated);
6837
+ this.announce([updated.id], session.userId, false, null, reason);
6810
6838
  await this.persist(updated);
6811
6839
  return true;
6812
6840
  }
@@ -6830,6 +6858,7 @@ var LoginSessionManager = class {
6830
6858
  this.replace(session, updated);
6831
6859
  ended.push(updated);
6832
6860
  }
6861
+ this.announce(ended.map((s) => s.id), userId, true, options.exceptSessionId ?? null, options.reason);
6833
6862
  await this.persistCutoff(userId, at);
6834
6863
  for (const session of ended) await this.persist(session);
6835
6864
  return ended.length;
@@ -6848,6 +6877,7 @@ var LoginSessionManager = class {
6848
6877
  this.replace(session, updated);
6849
6878
  ended.push(updated);
6850
6879
  }
6880
+ this.announce(ended.map((s) => s.id), null, false, null, reason);
6851
6881
  for (const session of ended) await this.persist(session);
6852
6882
  return ended.length;
6853
6883
  }
@@ -6873,6 +6903,16 @@ var LoginSessionManager = class {
6873
6903
  }
6874
6904
  return dead.length;
6875
6905
  }
6906
+ /** Tell the hub which sessions just ended — right after the mirror, before the store write. */
6907
+ announce(sessionIds, userId, allOfUser, exceptSessionId, reason) {
6908
+ announceSessionsRevoked({
6909
+ sessionIds,
6910
+ userId,
6911
+ allOfUser,
6912
+ exceptSessionId,
6913
+ reason
6914
+ }, (error) => this.logger?.error("A session-revocation listener threw — the revoke stands", { meta: { error: error instanceof Error ? error.message : String(error) } }));
6915
+ }
6876
6916
  newRefreshToken() {
6877
6917
  return `${REFRESH_TOKEN_PREFIX}${node_crypto.randomBytes(32).toString("base64url")}`;
6878
6918
  }
@@ -12093,4 +12133,5 @@ exports.UserManager = UserManager;
12093
12133
  exports.attachUserManagementInternal = attachUserManagementInternal;
12094
12134
  exports.getUserManagementInternal = getUserManagementInternal;
12095
12135
  exports.isSettingsReadUnavailable = isSettingsReadUnavailable;
12136
+ exports.onSessionsRevoked = onSessionsRevoked;
12096
12137
  exports.parseTokenExpiry = parseTokenExpiry;