@agentvault/agentvault 0.13.9 → 0.13.11

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/channel.d.ts CHANGED
@@ -35,6 +35,8 @@ export declare class SecureChannel extends EventEmitter {
35
35
  private _telemetryReporter;
36
36
  /** Topic ID from the most recent inbound message — used as fallback for replies. */
37
37
  private _lastIncomingTopicId;
38
+ /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
39
+ private _lastResyncRequest;
38
40
  private static readonly PING_INTERVAL_MS;
39
41
  private static readonly SILENCE_TIMEOUT_MS;
40
42
  private static readonly POLL_FALLBACK_INTERVAL_MS;
@@ -227,6 +229,12 @@ export declare class SecureChannel extends EventEmitter {
227
229
  * a new ratchet session.
228
230
  */
229
231
  private _handleDeviceLinked;
232
+ /**
233
+ * Handle a resync_request from the owner (owner-initiated ratchet re-establishment).
234
+ * Re-derives shared secret via X3DH as responder, initializes fresh receiver ratchet,
235
+ * and sends resync_ack back with agent's public keys.
236
+ */
237
+ private _handleResyncRequest;
230
238
  /**
231
239
  * Handle an incoming room message. Finds the pairwise conversation
232
240
  * for the sender, decrypts, and emits a room_message event.
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -44897,6 +44897,7 @@ var init_ratchet = __esm({
44897
44897
  serialize() {
44898
44898
  const s2 = this.state;
44899
44899
  return JSON.stringify({
44900
+ version: 1,
44900
44901
  rootKey: libsodium_wrappers_default.to_hex(s2.rootKey),
44901
44902
  sendingChain: s2.sendingChain ? {
44902
44903
  chainKey: libsodium_wrappers_default.to_hex(s2.sendingChain.chainKey),
@@ -44924,33 +44925,59 @@ var init_ratchet = __esm({
44924
44925
  });
44925
44926
  }
44926
44927
  static deserialize(json) {
44927
- const d2 = JSON.parse(json);
44928
- return new _DoubleRatchet({
44929
- rootKey: libsodium_wrappers_default.from_hex(d2.rootKey),
44930
- sendingChain: d2.sendingChain ? {
44931
- chainKey: libsodium_wrappers_default.from_hex(d2.sendingChain.chainKey),
44932
- messageNumber: d2.sendingChain.messageNumber
44933
- } : null,
44934
- receivingChain: d2.receivingChain ? {
44935
- chainKey: libsodium_wrappers_default.from_hex(d2.receivingChain.chainKey),
44936
- messageNumber: d2.receivingChain.messageNumber
44937
- } : null,
44938
- dhSendingKeypair: {
44939
- publicKey: libsodium_wrappers_default.from_hex(d2.dhSendingKeypair.publicKey),
44940
- privateKey: libsodium_wrappers_default.from_hex(d2.dhSendingKeypair.privateKey)
44941
- },
44942
- dhReceivingPublicKey: d2.dhReceivingPublicKey ? libsodium_wrappers_default.from_hex(d2.dhReceivingPublicKey) : null,
44943
- identityKeypair: {
44944
- publicKey: libsodium_wrappers_default.from_hex(d2.identityKeypair.publicKey),
44945
- privateKey: libsodium_wrappers_default.from_hex(d2.identityKeypair.privateKey)
44946
- },
44947
- previousSendingChainLength: d2.previousSendingChainLength,
44948
- skippedKeys: d2.skippedKeys.map((sk) => ({
44949
- dhPub: sk.dhPub,
44950
- n: sk.n,
44951
- messageKey: libsodium_wrappers_default.from_hex(sk.messageKey)
44952
- }))
44953
- });
44928
+ let d2;
44929
+ try {
44930
+ d2 = JSON.parse(json);
44931
+ } catch {
44932
+ throw new Error("Ratchet state: corrupt JSON");
44933
+ }
44934
+ if (d2.version !== void 0 && d2.version !== 1) {
44935
+ throw new Error(`Ratchet state version ${d2.version} not supported`);
44936
+ }
44937
+ if (typeof d2.rootKey !== "string") {
44938
+ throw new Error("Ratchet state: missing required field rootKey");
44939
+ }
44940
+ const dhSend = d2.dhSendingKeypair;
44941
+ if (!dhSend || typeof dhSend.publicKey !== "string" || typeof dhSend.privateKey !== "string") {
44942
+ throw new Error("Ratchet state: missing required field dhSendingKeypair");
44943
+ }
44944
+ const idKp = d2.identityKeypair;
44945
+ if (!idKp || typeof idKp.publicKey !== "string" || typeof idKp.privateKey !== "string") {
44946
+ throw new Error("Ratchet state: missing required field identityKeypair");
44947
+ }
44948
+ try {
44949
+ return new _DoubleRatchet({
44950
+ rootKey: libsodium_wrappers_default.from_hex(d2.rootKey),
44951
+ sendingChain: d2.sendingChain ? {
44952
+ chainKey: libsodium_wrappers_default.from_hex(d2.sendingChain.chainKey),
44953
+ messageNumber: d2.sendingChain.messageNumber
44954
+ } : null,
44955
+ receivingChain: d2.receivingChain ? {
44956
+ chainKey: libsodium_wrappers_default.from_hex(d2.receivingChain.chainKey),
44957
+ messageNumber: d2.receivingChain.messageNumber
44958
+ } : null,
44959
+ dhSendingKeypair: {
44960
+ publicKey: libsodium_wrappers_default.from_hex(dhSend.publicKey),
44961
+ privateKey: libsodium_wrappers_default.from_hex(dhSend.privateKey)
44962
+ },
44963
+ dhReceivingPublicKey: d2.dhReceivingPublicKey ? libsodium_wrappers_default.from_hex(d2.dhReceivingPublicKey) : null,
44964
+ identityKeypair: {
44965
+ publicKey: libsodium_wrappers_default.from_hex(idKp.publicKey),
44966
+ privateKey: libsodium_wrappers_default.from_hex(idKp.privateKey)
44967
+ },
44968
+ previousSendingChainLength: d2.previousSendingChainLength,
44969
+ skippedKeys: d2.skippedKeys.map((sk) => ({
44970
+ dhPub: sk.dhPub,
44971
+ n: sk.n,
44972
+ messageKey: libsodium_wrappers_default.from_hex(sk.messageKey)
44973
+ }))
44974
+ });
44975
+ } catch (err) {
44976
+ if (err instanceof Error && err.message.startsWith("Ratchet state")) {
44977
+ throw err;
44978
+ }
44979
+ throw new Error(`Ratchet state: corrupt hex data \u2014 ${err instanceof Error ? err.message : String(err)}`);
44980
+ }
44954
44981
  }
44955
44982
  };
44956
44983
  }
@@ -45756,6 +45783,8 @@ var init_channel = __esm({
45756
45783
  _telemetryReporter = null;
45757
45784
  /** Topic ID from the most recent inbound message — used as fallback for replies. */
45758
45785
  _lastIncomingTopicId;
45786
+ /** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
45787
+ _lastResyncRequest = /* @__PURE__ */ new Map();
45759
45788
  // Liveness detection: server sends app-level {"event":"ping"} every 30s.
45760
45789
  // We check every 30s; if no data received in 90s (3 missed pings), connection is dead.
45761
45790
  static PING_INTERVAL_MS = 3e4;
@@ -47014,6 +47043,13 @@ var init_channel = __esm({
47014
47043
  await this._handleDeviceLinked(data.data);
47015
47044
  return;
47016
47045
  }
47046
+ if (data.event === "resync_request") {
47047
+ await this._handleResyncRequest(data.data);
47048
+ return;
47049
+ }
47050
+ if (data.event === "resync_ack") {
47051
+ return;
47052
+ }
47017
47053
  if (data.event === "message") {
47018
47054
  try {
47019
47055
  await this._handleIncomingMessage(data.data);
@@ -47400,8 +47436,28 @@ var init_channel = __esm({
47400
47436
  const session = this._sessions.get(convId);
47401
47437
  if (!session) {
47402
47438
  console.warn(
47403
- `[SecureChannel] No session for conversation ${convId}, skipping`
47439
+ `[SecureChannel] No session for conversation ${convId}, requesting resync`
47404
47440
  );
47441
+ const RESYNC_COOLDOWN_MS = 5 * 60 * 1e3;
47442
+ const lastResync = this._lastResyncRequest.get(convId) ?? 0;
47443
+ if (Date.now() - lastResync > RESYNC_COOLDOWN_MS && this._ws && this._persisted) {
47444
+ this._lastResyncRequest.set(convId, Date.now());
47445
+ this._ws.send(
47446
+ JSON.stringify({
47447
+ event: "resync_request",
47448
+ data: {
47449
+ conversation_id: convId,
47450
+ reason: "no_session",
47451
+ identity_public_key: this._persisted.identityKeypair.publicKey,
47452
+ ephemeral_public_key: this._persisted.ephemeralKeypair.publicKey
47453
+ }
47454
+ })
47455
+ );
47456
+ this.emit("resync_requested", {
47457
+ conversationId: convId,
47458
+ reason: "no_session"
47459
+ });
47460
+ }
47405
47461
  return;
47406
47462
  }
47407
47463
  const encrypted = transportToEncryptedMessage({
@@ -47419,6 +47475,26 @@ var init_channel = __esm({
47419
47475
  } catch (restoreErr) {
47420
47476
  console.error("[SecureChannel] Ratchet restore failed:", restoreErr);
47421
47477
  }
47478
+ const RESYNC_COOLDOWN_MS = 5 * 60 * 1e3;
47479
+ const lastResync = this._lastResyncRequest.get(convId) ?? 0;
47480
+ if (Date.now() - lastResync > RESYNC_COOLDOWN_MS && this._ws && this._persisted) {
47481
+ this._lastResyncRequest.set(convId, Date.now());
47482
+ const idPubHex = this._persisted.identityKeypair.publicKey;
47483
+ const ephPubHex = this._persisted.ephemeralKeypair.publicKey;
47484
+ this._ws.send(
47485
+ JSON.stringify({
47486
+ event: "resync_request",
47487
+ data: {
47488
+ conversation_id: convId,
47489
+ reason: "decrypt_failure",
47490
+ identity_public_key: idPubHex,
47491
+ ephemeral_public_key: ephPubHex
47492
+ }
47493
+ })
47494
+ );
47495
+ console.log(`[SecureChannel] Sent resync_request for conv ${convId.slice(0, 8)}...`);
47496
+ this.emit("resync_requested", { conversationId: convId, reason: "decrypt_failure" });
47497
+ }
47422
47498
  return;
47423
47499
  }
47424
47500
  this._sendAck(msgData.message_id);
@@ -47743,6 +47819,70 @@ ${messageText}`;
47743
47819
  this.emit("error", err);
47744
47820
  }
47745
47821
  }
47822
+ /**
47823
+ * Handle a resync_request from the owner (owner-initiated ratchet re-establishment).
47824
+ * Re-derives shared secret via X3DH as responder, initializes fresh receiver ratchet,
47825
+ * and sends resync_ack back with agent's public keys.
47826
+ */
47827
+ async _handleResyncRequest(data) {
47828
+ const convId = data.conversation_id;
47829
+ console.log(
47830
+ `[SecureChannel] Received resync_request for conv ${convId.slice(0, 8)}... (reason: ${data.reason ?? "unknown"})`
47831
+ );
47832
+ try {
47833
+ if (!this._persisted) {
47834
+ console.error("[SecureChannel] Cannot handle resync \u2014 no persisted state");
47835
+ return;
47836
+ }
47837
+ const identity = this._persisted.identityKeypair;
47838
+ const ephemeral = this._persisted.ephemeralKeypair;
47839
+ const sharedSecret = performX3DH({
47840
+ myIdentityPrivate: hexToBytes(identity.privateKey),
47841
+ myEphemeralPrivate: hexToBytes(ephemeral.privateKey),
47842
+ theirIdentityPublic: hexToBytes(data.identity_public_key),
47843
+ theirEphemeralPublic: hexToBytes(data.ephemeral_public_key),
47844
+ isInitiator: false
47845
+ });
47846
+ const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
47847
+ publicKey: hexToBytes(identity.publicKey),
47848
+ privateKey: hexToBytes(identity.privateKey),
47849
+ keyType: "ed25519"
47850
+ });
47851
+ const existingSession = this._sessions.get(convId);
47852
+ const ownerDeviceId = data.sender_device_id ?? existingSession?.ownerDeviceId ?? "";
47853
+ this._sessions.set(convId, {
47854
+ ownerDeviceId,
47855
+ ratchet,
47856
+ activated: false
47857
+ // Wait for owner's encrypted session_init
47858
+ });
47859
+ this._persisted.sessions[convId] = {
47860
+ ownerDeviceId,
47861
+ ratchetState: ratchet.serialize(),
47862
+ activated: false
47863
+ };
47864
+ await this._persistState();
47865
+ if (this._ws) {
47866
+ this._ws.send(
47867
+ JSON.stringify({
47868
+ event: "resync_ack",
47869
+ data: {
47870
+ conversation_id: convId,
47871
+ identity_public_key: identity.publicKey,
47872
+ ephemeral_public_key: ephemeral.publicKey
47873
+ }
47874
+ })
47875
+ );
47876
+ }
47877
+ console.log(
47878
+ `[SecureChannel] Resync complete for conv ${convId.slice(0, 8)}... \u2014 waiting for owner session_init`
47879
+ );
47880
+ this.emit("resync_completed", { conversationId: convId });
47881
+ } catch (err) {
47882
+ console.error(`[SecureChannel] Resync failed for conv ${convId.slice(0, 8)}...:`, err);
47883
+ this.emit("error", err);
47884
+ }
47885
+ }
47746
47886
  /**
47747
47887
  * Handle an incoming room message. Finds the pairwise conversation
47748
47888
  * for the sender, decrypts, and emits a room_message event.
@@ -47952,8 +48092,28 @@ ${messageText}`;
47952
48092
  const session = this._sessions.get(msg.conversation_id);
47953
48093
  if (!session) {
47954
48094
  console.warn(
47955
- `[SecureChannel] No session for conversation ${msg.conversation_id} during sync, skipping`
48095
+ `[SecureChannel] No session for conversation ${msg.conversation_id} during sync, requesting resync`
47956
48096
  );
48097
+ const RESYNC_COOLDOWN_MS = 5 * 60 * 1e3;
48098
+ const lastResync = this._lastResyncRequest.get(msg.conversation_id) ?? 0;
48099
+ if (Date.now() - lastResync > RESYNC_COOLDOWN_MS && this._ws && this._persisted) {
48100
+ this._lastResyncRequest.set(msg.conversation_id, Date.now());
48101
+ this._ws.send(
48102
+ JSON.stringify({
48103
+ event: "resync_request",
48104
+ data: {
48105
+ conversation_id: msg.conversation_id,
48106
+ reason: "no_session",
48107
+ identity_public_key: this._persisted.identityKeypair.publicKey,
48108
+ ephemeral_public_key: this._persisted.ephemeralKeypair.publicKey
48109
+ }
48110
+ })
48111
+ );
48112
+ this.emit("resync_requested", {
48113
+ conversationId: msg.conversation_id,
48114
+ reason: "no_session"
48115
+ });
48116
+ }
47957
48117
  continue;
47958
48118
  }
47959
48119
  try {