core-3nweb-client-lib 0.49.5 → 0.49.7

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 (81) hide show
  1. package/build/api-defs/files.d.ts +11 -5
  2. package/build/core/asmail/delivery/common.d.ts +8 -28
  3. package/build/core/asmail/delivery/common.js +1 -47
  4. package/build/core/asmail/delivery/index.js +3 -8
  5. package/build/core/asmail/delivery/msg.js +1 -7
  6. package/build/core/asmail/delivery/per-recipient-wip.js +3 -29
  7. package/build/core/asmail/inbox/index.d.ts +1 -2
  8. package/build/core/asmail/inbox/index.js +14 -15
  9. package/build/core/asmail/inbox/msg-indexing/dataset/v0/sql-db-v-none.d.ts +11 -0
  10. package/build/core/asmail/inbox/msg-indexing/dataset/v0/sql-db-v-none.js +25 -0
  11. package/build/core/asmail/inbox/msg-indexing/dataset/v1/logs.d.ts +33 -0
  12. package/build/core/asmail/inbox/msg-indexing/dataset/v1/logs.js +72 -0
  13. package/build/core/asmail/inbox/msg-indexing/dataset/v1/sql-db.d.ts +28 -0
  14. package/build/core/asmail/inbox/msg-indexing/dataset/v1/sql-db.js +477 -0
  15. package/build/core/asmail/inbox/msg-indexing/index.d.ts +12 -26
  16. package/build/core/asmail/inbox/msg-indexing/index.js +47 -68
  17. package/build/core/asmail/inbox/msg-on-disk.js +1 -2
  18. package/build/core/asmail/index.js +8 -7
  19. package/build/core/asmail/msg/common.d.ts +0 -1
  20. package/build/core/asmail/msg/common.js +1 -1
  21. package/build/core/asmail/msg/packer.js +1 -3
  22. package/build/core/index.js +7 -4
  23. package/build/core/keyring/common.d.ts +1 -0
  24. package/build/core/keyring/common.js +2 -1
  25. package/build/core/keyring/index.d.ts +7 -44
  26. package/build/core/keyring/index.js +89 -222
  27. package/build/core/keyring/introductory-keys/published-intro-key.d.ts +17 -0
  28. package/build/core/keyring/introductory-keys/published-intro-key.js +190 -0
  29. package/build/core/keyring/peer-keys/dataset/v1/json-files.d.ts +105 -0
  30. package/build/core/keyring/peer-keys/dataset/v1/json-files.js +89 -0
  31. package/build/core/keyring/peer-keys/dataset/v2/logs.d.ts +43 -0
  32. package/build/core/keyring/peer-keys/dataset/v2/logs.js +116 -0
  33. package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.d.ts +73 -0
  34. package/build/core/keyring/peer-keys/dataset/v2/peer-keys-db.js +543 -0
  35. package/build/core/keyring/peer-keys/index.d.ts +24 -0
  36. package/build/core/keyring/peer-keys/index.js +208 -0
  37. package/build/core/storage/synced/obj-files.js +10 -3
  38. package/build/core/storage/synced/obj-status.d.ts +1 -1
  39. package/build/core/storage/synced/obj-status.js +8 -2
  40. package/build/core/storage/synced/storage.d.ts +4 -4
  41. package/build/core/storage/system-folders/apps-data.d.ts +0 -1
  42. package/build/core/storage/system-folders/apps-data.js +2 -6
  43. package/build/lib-client/fs-utils/fs-sync-utils.d.ts +1 -1
  44. package/build/lib-client/fs-utils/fs-sync-utils.js +70 -13
  45. package/build/lib-client/xsp-fs/fs.js +3 -1
  46. package/build/lib-client/xsp-fs/node-in-fs.d.ts +1 -0
  47. package/build/lib-client/xsp-fs/node-in-fs.js +7 -2
  48. package/build/lib-client/xsp-fs/node-persistence.js +1 -3
  49. package/build/lib-client/xsp-fs/xsp-payload-v2.js +1 -2
  50. package/build/lib-common/dataset-sync/per-device-json-array-logs.d.ts +58 -0
  51. package/build/lib-common/dataset-sync/per-device-json-array-logs.js +432 -0
  52. package/build/lib-common/number-line.d.ts +10 -0
  53. package/build/lib-common/number-line.js +66 -0
  54. package/build/lib-common/objs-on-disk/obj-version-file.d.ts +1 -1
  55. package/build/lib-common/objs-on-disk/obj-version-file.js +3 -3
  56. package/build/lib-common/rng-def.d.ts +1 -0
  57. package/build/lib-common/rng-def.js +8 -0
  58. package/build/lib-sqlite-on-3nstorage/for-sqlite.d.ts +38 -0
  59. package/build/lib-sqlite-on-3nstorage/for-sqlite.js +162 -0
  60. package/build/lib-sqlite-on-3nstorage/index.d.ts +18 -5
  61. package/build/lib-sqlite-on-3nstorage/index.js +49 -26
  62. package/build/tests/caps-api/file-sink-checks/splice.js +72 -1
  63. package/build/tests/caps-api/fs-checks/sync-on-one-dev/upload.js +27 -1
  64. package/build/tests/caps-api/fs-checks/sync-with-two-devs/update-propagation.js +12 -3
  65. package/build/tests/computer.3nweb.core/inbox/msg-indexing.js +16 -12
  66. package/build/tests/computer.3nweb.core/keyrings.js +113 -28
  67. package/build/tests/jasmine.js +2 -2
  68. package/build/tests/units/number-line.js +9 -9
  69. package/package.json +2 -1
  70. package/build/core/asmail/inbox/msg-indexing/logs-n-entries.d.ts +0 -52
  71. package/build/core/asmail/inbox/msg-indexing/logs-n-entries.js +0 -333
  72. package/build/core/asmail/inbox/msg-indexing/sql-indexing.d.ts +0 -4
  73. package/build/core/asmail/inbox/msg-indexing/sql-indexing.js +0 -319
  74. package/build/core/keyring/correspondent-keys.d.ts +0 -149
  75. package/build/core/keyring/correspondent-keys.js +0 -403
  76. package/build/core/keyring/id-to-email-map.d.ts +0 -38
  77. package/build/core/keyring/id-to-email-map.js +0 -105
  78. package/build/core/keyring/keyring-storage.d.ts +0 -9
  79. package/build/core/keyring/keyring-storage.js +0 -54
  80. package/build/core/keyring/published-intro-key.d.ts +0 -45
  81. package/build/core/keyring/published-intro-key.js +0 -200
@@ -314,7 +314,7 @@ declare namespace web3n.files {
314
314
  * sink with this error. When err is given, no errors will be thrown back
315
315
  * to this call.
316
316
  */
317
- done(err?: any, xattrChanges?: XAttrsChanges): Promise<void>;
317
+ done(err?: any): Promise<void>;
318
318
 
319
319
  }
320
320
 
@@ -1178,27 +1178,33 @@ declare namespace web3n.files {
1178
1178
  type RemoteEvent = RemoteVersionArchivalEvent | RemoteArchVerRemovalEvent |
1179
1179
  RemoteRemovalEvent | RemoteChangeEvent;
1180
1180
 
1181
+ /**
1182
+ * SyncStatus has fields that connect to item's parent, uploading, i.e. not just state of the item.
1183
+ * Hence, we pick only related fields.
1184
+ */
1185
+ type ItemSyncStatus = Pick<SyncStatus, 'state' | 'remote' | 'synced' | 'local'>;
1186
+
1181
1187
  interface RemoteVersionArchivalEvent extends FSEvent {
1182
1188
  type: 'remote-version-archival';
1183
1189
  archivedVersion: number;
1184
- syncStatus: SyncStatus;
1190
+ syncStatus: ItemSyncStatus;
1185
1191
  }
1186
1192
 
1187
1193
  interface RemoteArchVerRemovalEvent extends FSEvent {
1188
1194
  type: 'remote-arch-ver-removal';
1189
1195
  removedArchVer: number;
1190
- syncStatus: SyncStatus;
1196
+ syncStatus: ItemSyncStatus;
1191
1197
  }
1192
1198
 
1193
1199
  interface RemoteRemovalEvent extends FSEvent {
1194
1200
  type: 'remote-removal';
1195
- syncStatus: SyncStatus;
1201
+ syncStatus: ItemSyncStatus;
1196
1202
  }
1197
1203
 
1198
1204
  interface RemoteChangeEvent extends FSEvent {
1199
1205
  type: 'remote-change';
1200
1206
  newRemoteVersion: number;
1201
- syncStatus: SyncStatus;
1207
+ syncStatus: ItemSyncStatus;
1202
1208
  }
1203
1209
 
1204
1210
  type UploadEvent = UploadStartEvent | UploadProgressEvent | UploadDisconnectedEvent | UploadDoneEvent;
@@ -40,22 +40,17 @@ export interface ResourcesForSending {
40
40
  * @param address
41
41
  */
42
42
  needIntroKeyFor(address: string): boolean;
43
- /**
44
- * This function generates keys that are needed to send a message, i.e.
45
- * current crypto encryptor and identifiers to place in message's meta.
46
- * Returned object has following fields:
47
- * (a) encryptor - with encryptor, which should be used to pack message's
48
- * main part's key,
49
- * (b) currentPair - contains sendable form for current key pair.
50
- * (c) msgCount - message count for a current pair.
51
- * @param address
52
- * @param introPKeyFromServer is an optional recipient's key from a mail
53
- * server.
54
- */
55
- generateKeysToSend: (address: string, introPKeyFromServer?: JsonKey) => Promise<{
43
+ getEstablishedKeysToSendMsg: (address: string) => Promise<{
44
+ encryptor: Encryptor;
45
+ currentPair: ASMailKeyPair;
46
+ msgCount: number;
47
+ nextMsgCrypto?: SuggestedNextKeyPair;
48
+ }>;
49
+ generateIntroKeysToSendMsg: (address: string, introPKey: JsonKey) => Promise<{
56
50
  encryptor: Encryptor;
57
51
  currentPair: ASMailKeyPair;
58
52
  msgCount: number;
53
+ nextMsgCrypto?: SuggestedNextKeyPair;
59
54
  }>;
60
55
  /**
61
56
  * This function returns sending parameters that should be used now to
@@ -64,11 +59,6 @@ export interface ResourcesForSending {
64
59
  * @param address
65
60
  */
66
61
  paramsForSendingTo: (address: string) => SendingParams | undefined;
67
- /**
68
- * This function returns next key pair
69
- * @param address
70
- */
71
- nextCrypto: (address: string) => Promise<SuggestedNextKeyPair | undefined>;
72
62
  /**
73
63
  * This returns a new sending parameters that given address should use to
74
64
  * send messages back. Undefined is returned, if current parameters don't
@@ -89,14 +79,4 @@ export interface SavedMsgToSend {
89
79
  recipients: string[];
90
80
  retryOpts: DeliveryOptions['retryRecipient'];
91
81
  }
92
- /**
93
- * This is a utility function that adds a number into given number line
94
- * segments. Each segment is represented by an array, in which 0-th element is
95
- * the smallest number in the segment, while 1-st element is the largest.
96
- * Segments don't overlap and are ordered as they would on a number line:
97
- * segment with smaller numbers go first.
98
- * @param segments
99
- * @param n
100
- */
101
- export declare function addToNumberLineSegments(segments: number[][], n: number): void;
102
82
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2017, 2020 3NSoft Inc.
3
+ Copyright (C) 2016 - 2017, 2020, 2026 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -18,7 +18,6 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.SEG_SIZE_IN_K_QUATS = exports.Attachments = void 0;
20
20
  exports.estimatePackedSizeOf = estimatePackedSizeOf;
21
- exports.addToNumberLineSegments = addToNumberLineSegments;
22
21
  const attachments_container_1 = require("../msg/attachments-container");
23
22
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
24
23
  const ATTACHMENTS_NAME = 'attachments';
@@ -139,49 +138,4 @@ function estimatePackedSizeOf(size) {
139
138
  }
140
139
  return 148 + numOfCompleteSegs * exports.SEG_SIZE_IN_K_QUATS * 256 + lastSegSize;
141
140
  }
142
- /**
143
- * This is a utility function that adds a number into given number line
144
- * segments. Each segment is represented by an array, in which 0-th element is
145
- * the smallest number in the segment, while 1-st element is the largest.
146
- * Segments don't overlap and are ordered as they would on a number line:
147
- * segment with smaller numbers go first.
148
- * @param segments
149
- * @param n
150
- */
151
- function addToNumberLineSegments(segments, n) {
152
- for (let i = (segments.length - 1); i >= 0; i -= 1) {
153
- const [low, high] = segments[i];
154
- if (high < n) {
155
- if ((high + 1) >= n) {
156
- // segment should be grown on a high side.
157
- // But now bigger segment won't merge with higher segment, cause if
158
- // it does, it would've merge from lower side of a higher segment.
159
- segments[i][1] = n;
160
- }
161
- else {
162
- // new segment should be added higher than this one
163
- segments.splice(i + 1, 0, [n, n]);
164
- }
165
- return;
166
- }
167
- if ((low <= n) && (n <= high)) {
168
- // do nothing as number falls into current segment
169
- return;
170
- }
171
- if (low <= (n + 1)) {
172
- // segment should be grown on a lower side
173
- segments[i][0] = n;
174
- if ((i - 1) >= 0) {
175
- // bigger segment may overlap with a lower one
176
- const lowerSeg = segments[i - 1];
177
- if ((lowerSeg[1] + 1) >= n) {
178
- lowerSeg[1] = high;
179
- segments.splice(i, 1);
180
- }
181
- }
182
- return;
183
- }
184
- }
185
- segments.unshift([n, n]);
186
- }
187
141
  Object.freeze(exports);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2017, 2020 - 2023 3NSoft Inc.
3
+ Copyright (C) 2016 - 2017, 2020 - 2023, 2026 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -28,8 +28,8 @@ const utils_for_observables_1 = require("../../../lib-common/utils-for-observabl
28
28
  const SMALL_MSG_SIZE = 1024 * 1024;
29
29
  const MSGS_FOLDER = 'msgs';
30
30
  function idToMsgFolder(id) {
31
- if (id.indexOf('/') > -1) {
32
- throw new Error(`Message id ${id} contains illegal character '/'.`);
31
+ if (id.includes('/') || id.includes('.')) {
32
+ throw new Error(`Message id ${id} contains illegal character(s).`);
33
33
  }
34
34
  return `${MSGS_FOLDER}/${id}`;
35
35
  }
@@ -154,11 +154,6 @@ class Delivery {
154
154
  }
155
155
  const attachments = common_1.Attachments.fromMsg(msgToSend);
156
156
  const localMeta = opts === null || opts === void 0 ? void 0 : opts.localMeta;
157
- // DEBUG log
158
- console.log(`\n adding message ${msgToSend.attachments ? `with attachments: ${JSON.stringify({
159
- files: msgToSend.attachments.files ? Object.keys(msgToSend.attachments.files).length : 0,
160
- folders: msgToSend.attachments.folders ? Object.keys(msgToSend.attachments.folders).length : 0
161
- })}` : `without attachments in outgoing msg object.`}`);
162
157
  // save msg, in case delivery should be restarted
163
158
  const msgFS = await this.makeFSForNewMsg(id);
164
159
  const msg = await msg_1.Msg.forNew(id, msgFS, msgToSend, sender, recipients, this.r, attachments, localMeta, opts === null || opts === void 0 ? void 0 : opts.retryRecipient);
@@ -127,11 +127,7 @@ class Msg {
127
127
  await this.msgFS.writeJSONFile(MAIN_OBJ_FILE_NAME, main, { create: true, exclusive: true });
128
128
  await this.msgFS.writeJSONFile(PROGRESS_INFO_FILE_NAME, this.progress, { create: true, exclusive: true });
129
129
  if (this.attachments) {
130
- console.log(`Linking attachments ...`);
131
- await this.attachments.linkIn(this.msgFS)
132
- .then(
133
- // DEBUG log
134
- () => console.log(` .... msg attachments linked while delivery`), err => console.error(`linking attachments error:`, err));
130
+ await this.attachments.linkIn(this.msgFS);
135
131
  }
136
132
  }
137
133
  notifyOfChangesInProgress(saveProgress, saveWIPs) {
@@ -192,8 +188,6 @@ class Msg {
192
188
  msg.setSection('Cc', this.msgToSend.carbonCopy);
193
189
  msg.setSection('To', this.msgToSend.recipients);
194
190
  if (this.attachments) {
195
- // DEBUG log
196
- console.log(`setting attachment on messages packer`);
197
191
  await msg.setAttachments(this.attachments);
198
192
  }
199
193
  return msg;
@@ -80,7 +80,6 @@ class WIP {
80
80
  * or if this wip is done, undefined is returned.
81
81
  */
82
82
  startNext() {
83
- var _a, _b;
84
83
  let proc = this.proc.latestTaskAtThisMoment();
85
84
  if (proc) {
86
85
  return;
@@ -102,13 +101,9 @@ class WIP {
102
101
  proc = this.proc.addStarted(this.sendObjs());
103
102
  }
104
103
  else if (stage === "cancel") {
105
- // DEBUG log
106
- console.log(` canceled sending msgId: ${(_a = this.state.session) === null || _a === void 0 ? void 0 : _a.msgId}`);
107
104
  return;
108
105
  }
109
106
  else if (stage === undefined) {
110
- // DEBUG log
111
- console.log(` done sending msgId: ${(_b = this.state.session) === null || _b === void 0 ? void 0 : _b.msgId}`);
112
107
  return;
113
108
  }
114
109
  else {
@@ -164,11 +159,11 @@ class WIP {
164
159
  async getRecipientKeyAndEncrypt() {
165
160
  const recipient = this.sender.recipient;
166
161
  const introPKeyFromServer = await this.getIntroKeyIfRecipientIsUnknown(recipient);
167
- // DEBUG log
168
- console.log(`\n wip.getRecipientKeyAndEncrypt()`);
169
162
  this.packer = await this.msg.msgPacker();
170
163
  // get crypto parts for encrypting this message
171
- const { currentPair, encryptor, msgCount } = await this.msg.r.correspondents.generateKeysToSend(recipient, introPKeyFromServer);
164
+ const { currentPair, encryptor, msgCount, nextMsgCrypto } = await (introPKeyFromServer ?
165
+ this.msg.r.correspondents.generateIntroKeysToSendMsg(recipient, introPKeyFromServer) :
166
+ this.msg.r.correspondents.getEstablishedKeysToSendMsg(recipient));
172
167
  // add crypto parameters to the message
173
168
  if (currentPair.pid) {
174
169
  this.packer.setEstablishedKeyPairInfo(currentPair.pid, msgCount);
@@ -183,7 +178,6 @@ class WIP {
183
178
  this.packer.setNewKeyInfo(currentPair.recipientKid, currentPair.senderPKey.k, pkCerts, msgCount);
184
179
  }
185
180
  // add next crypto parameters to the message
186
- const nextMsgCrypto = await this.msg.r.correspondents.nextCrypto(recipient);
187
181
  if (nextMsgCrypto) {
188
182
  this.packer.setNextCrypto(nextMsgCrypto);
189
183
  }
@@ -262,8 +256,6 @@ class WIP {
262
256
  throw new Error(`Message pack is not set.`);
263
257
  }
264
258
  this.state.session = await this.sender.sendMetadata(this.state.pack.meta);
265
- // DEBUG log
266
- console.log(`\n wip.sendMeta() returned with\n msgId: ${this.state.session.msgId}\n meta.objIds sent to server:`, this.state.pack.meta.objIds);
267
259
  this.msg.progress.recipients[this.state.recipient].idOnDelivery = this.state.session.msgId;
268
260
  if (this.state.stage !== "cancel") {
269
261
  this.state.stage = "5-send-objs";
@@ -317,9 +309,6 @@ class WIP {
317
309
  return { objId, upload, src };
318
310
  }
319
311
  async completeDelivery() {
320
- var _a;
321
- // DEBUG log
322
- console.log(` wip.completeDelivery() msg ${!!((_a = this.state.session) === null || _a === void 0 ? void 0 : _a.msgId)}`);
323
312
  await this.sender.completeDelivery();
324
313
  this.updateInfo(0, true);
325
314
  this.state.stage = undefined;
@@ -339,17 +328,12 @@ class WIP {
339
328
  * completes sending, when no more sending is left.
340
329
  */
341
330
  async sendObjs() {
342
- var _a, _b, _c;
343
- // DEBUG log
344
- console.log(` wip.sendObjs(), msgId: ${(_a = this.state.session) === null || _a === void 0 ? void 0 : _a.msgId}, p 0, \n !!this.sender is ${!!this.sender}\n this.currentObj is ${(_b = this.currentObj) === null || _b === void 0 ? void 0 : _b.objId}`);
345
331
  if (!this.sender) {
346
332
  this.sender = await sender_1.MailSender.resume(this.msg.r.makeNet(), this.state.recipient, this.state.session);
347
333
  }
348
334
  // ensure there is an object to send, or complete delivery
349
335
  if (!this.currentObj) {
350
336
  this.currentObj = await this.getObjToSend();
351
- // DEBUG log
352
- console.log(` ... this.getObjToSend() sets currentObj to be ${(_c = this.currentObj) === null || _c === void 0 ? void 0 : _c.objId}`);
353
337
  if (!this.currentObj) {
354
338
  return this.completeDelivery();
355
339
  }
@@ -377,8 +361,6 @@ class WIP {
377
361
  * @param obj is a message object to send
378
362
  */
379
363
  async firstObjSendingRequest(obj) {
380
- // DEBUG log
381
- console.log(` wip.firstObjSendingRequest() ${obj.objId}`);
382
364
  // read from source
383
365
  const header = await obj.src.readHeader();
384
366
  const { size, isEndless } = await obj.src.segSrc.getSize();
@@ -410,8 +392,6 @@ class WIP {
410
392
  obj.upload.header = buffer_utils_1.base64.pack(header);
411
393
  }
412
394
  this.updateInfo(header.length + segsChunk.length);
413
- // DEBUG log
414
- console.log(` ... ${obj.objId} 1st/single obj request send, isObjDone is ${isObjDone}`);
415
395
  return isObjDone;
416
396
  }
417
397
  /**
@@ -421,16 +401,12 @@ class WIP {
421
401
  * @param obj is a message object to send
422
402
  */
423
403
  async followingObjSendingRequest(obj) {
424
- // DEBUG log
425
- console.log(` wip.followingObjSendingRequest() ${obj.objId}`);
426
404
  // read from source
427
405
  const segsSize = obj.upload.expectedSegsSize;
428
406
  const chunk = await obj.src.segSrc.readNext(this.sender.maxChunkSize);
429
407
  // return early, when there are no bytes
430
408
  if (!chunk) {
431
409
  await this.sender.sendObj(obj.objId, EMPTY_BYTE_ARR, undefined, { ofs: obj.upload.segsOffset, last: true });
432
- // DEBUG log
433
- console.log(` ... ${obj.objId} 2nd/following obj request has no more chunk to send, and completed sending obj`);
434
410
  return true;
435
411
  }
436
412
  // check for an overrun
@@ -450,8 +426,6 @@ class WIP {
450
426
  await this.sender.sendObj(obj.objId, chunk, undefined, opts);
451
427
  obj.upload.segsOffset += chunk.length;
452
428
  this.updateInfo(chunk.length);
453
- // DEBUG log
454
- console.log(` ... ${obj.objId} 2nd/following obj request sent ${chunk.length} bytes, isObjDone is ${isObjDone}`);
455
429
  return isObjDone;
456
430
  }
457
431
  }
@@ -86,7 +86,7 @@ export declare class InboxOnServer {
86
86
  private readonly procs;
87
87
  private readonly recentlyOpenedMsgs;
88
88
  private constructor();
89
- static makeAndStart(cachePath: string, syncedFS: WritableFS, r: ResourcesForReceiving): Promise<InboxOnServer>;
89
+ static makeAndStart(cachePath: string, syncedFS: WritableFS, localFS: WritableFS, r: ResourcesForReceiving): Promise<InboxOnServer>;
90
90
  close(): Promise<void>;
91
91
  makeCAP(): InboxService;
92
92
  private removeMsg;
@@ -95,7 +95,6 @@ export declare class InboxOnServer {
95
95
  private startCachingAndAddKeyToIndex;
96
96
  private markOwnParams;
97
97
  private absorbSendingParams;
98
- private checkServerAuthIfPresent;
99
98
  private listMsgs;
100
99
  private listNewMsgs;
101
100
  private getMsg;
@@ -55,15 +55,15 @@ class InboxOnServer {
55
55
  this.inboxEvents = new inbox_events_1.InboxEvents(this.msgReceiver, this.getMsg.bind(this), this.listNewMsgs.bind(this), this.removeMsg.bind(this), this.logError);
56
56
  Object.seal(this);
57
57
  }
58
- static async makeAndStart(cachePath, syncedFS, r) {
58
+ static async makeAndStart(cachePath, syncedFS, localFS, r) {
59
59
  try {
60
60
  (0, file_1.ensureCorrectFS)(syncedFS, 'synced', true);
61
61
  const msgReceiver = new recipient_1.MailRecipient(r.address, r.getSigner, () => r.asmailResolver(r.address), r.makeNet());
62
62
  const downloader = new msg_downloader_1.MsgDownloader(msgReceiver);
63
63
  const cache = await cached_msgs_1.CachedMessages.makeFor(cachePath, downloader, r.logError);
64
- const indexSyncedFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, MSG_INDEX_FOLDER);
65
- const index = await msg_indexing_1.MsgIndex.make(indexSyncedFS);
66
- await (0, fs_sync_utils_1.uploadFolderChangesIfAny)(syncedFS);
64
+ const indexSyncedFS = await (0, fs_sync_utils_1.getOrMakeSyncedDirOnInit)(syncedFS, MSG_INDEX_FOLDER);
65
+ const indexLocalFS = await localFS.writableSubRoot(MSG_INDEX_FOLDER);
66
+ const index = await (0, msg_indexing_1.makeMsgIndex)(indexSyncedFS, indexLocalFS, r.logError);
67
67
  const inbox = new InboxOnServer(r.correspondents, msgReceiver, r.getStorages, r.cryptor, r.random, downloader, cache, index, r.logError);
68
68
  return inbox;
69
69
  }
@@ -141,7 +141,7 @@ class InboxOnServer {
141
141
  if (decrOut) {
142
142
  const { decrInfo, openedMsg } = decrOut;
143
143
  openedMsg.setMsgKeyRole(decrInfo.keyStatus);
144
- this.checkServerAuthIfPresent(meta, decrInfo);
144
+ checkServerAuthIfPresent(meta, decrInfo);
145
145
  // add records cache and to index
146
146
  this.recentlyOpenedMsgs.set(msgId, openedMsg);
147
147
  const msgInfo = {
@@ -189,14 +189,6 @@ class InboxOnServer {
189
189
  const address = openedMsg.sender;
190
190
  await this.r.saveParamsForSendingTo(address, sendingParams);
191
191
  }
192
- checkServerAuthIfPresent(meta, decrInfo) {
193
- // if sender authenticated to server, check that it matches address,
194
- // recovered from message decryption
195
- if (meta.authSender
196
- && !(0, canonical_address_1.areAddressesEqual)(meta.authSender, decrInfo.correspondent)) {
197
- throw new Error(`Sender authenticated to server as ${meta.authSender}, while decrypting key is associated with ${decrInfo.correspondent}`);
198
- }
199
- }
200
192
  async listMsgs(fromTS) {
201
193
  const checkServer = true; // XXX in future this will be an option from req
202
194
  if (!checkServer) {
@@ -272,8 +264,8 @@ class InboxOnServer {
272
264
  if (msg) {
273
265
  return this.msgToUIForm(msg, msgOnDisk.deliveryTS, msgOnDisk);
274
266
  }
275
- if ((msgOnDisk.keyStatus === 'not-found') ||
276
- (msgOnDisk.keyStatus === 'fail')) {
267
+ if ((msgOnDisk.keyStatus === 'not-found')
268
+ || (msgOnDisk.keyStatus === 'fail')) {
277
269
  // XXX
278
270
  // message cannot be opened, and should be removed
279
271
  // await Promise.all([
@@ -342,4 +334,11 @@ class InboxOnServer {
342
334
  exports.InboxOnServer = InboxOnServer;
343
335
  Object.freeze(InboxOnServer.prototype);
344
336
  Object.freeze(InboxOnServer);
337
+ function checkServerAuthIfPresent(meta, { correspondent }) {
338
+ // if sender authenticated to server, check that it matches address,
339
+ // recovered from message decryption
340
+ if (meta.authSender && !(0, canonical_address_1.areAddressesEqual)(meta.authSender, correspondent)) {
341
+ throw new Error(`Sender authenticated to server as ${meta.authSender}, while decrypting key is associated with ${correspondent}`);
342
+ }
343
+ }
345
344
  Object.freeze(exports);
@@ -0,0 +1,11 @@
1
+ import { Database } from '../../../../../../lib-sqlite-on-3nstorage/sqljs';
2
+ export interface MsgIndexDbVNoneEntry {
3
+ msg_id: string;
4
+ msg_type: string;
5
+ delivery_ts: number;
6
+ key: Uint8Array;
7
+ key_status: string;
8
+ main_obj_header_ofs: number;
9
+ remove_after: number;
10
+ }
11
+ export declare function getAllRecordsFromVersionNone(db: Database): MsgIndexDbVNoneEntry[];
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2026 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.getAllRecordsFromVersionNone = getAllRecordsFromVersionNone;
20
+ const lib_sqlite_on_3nstorage_1 = require("../../../../../../lib-sqlite-on-3nstorage");
21
+ function getAllRecordsFromVersionNone(db) {
22
+ const result = db.exec(`--sql
23
+ SELECT * FROM inbox_index`)[0];
24
+ return (result ? (0, lib_sqlite_on_3nstorage_1.objectFromQueryExecResult)(result) : []);
25
+ }
@@ -0,0 +1,33 @@
1
+ import { SingleProc } from '../../../../../../lib-common/processes/synced';
2
+ import { MsgKeyInfo, MsgKeyRole } from '../../../../../keyring';
3
+ import { LogError } from '../../../../../../lib-client/logging/log-to-file';
4
+ type WritableFS = web3n.files.WritableFS;
5
+ type MsgInfo = web3n.asmail.MsgInfo;
6
+ interface MsgOpenedLog {
7
+ eventType: 'msg-opened';
8
+ eventTS: number;
9
+ msgId: string;
10
+ msgType: string;
11
+ deliveryTS: number;
12
+ keyB64: string;
13
+ keyStatus: MsgKeyRole;
14
+ mainObjHeaderOfs: number;
15
+ }
16
+ interface MsgRemovedLog {
17
+ eventType: 'msg-removed';
18
+ eventTS: number;
19
+ msgId: string;
20
+ deliveryTS: number;
21
+ }
22
+ export type MsgOp = MsgOpenedLog | MsgRemovedLog;
23
+ export declare function msgOpenedEventToRecordParams(op: MsgOpenedLog): {
24
+ msgInfo: MsgInfo;
25
+ decrInfo: MsgKeyInfo;
26
+ };
27
+ export declare function makeRecentMsgIndexChangesLogs(logsFS: WritableFS, localLogsFS: WritableFS, logError: LogError): Promise<{
28
+ recordMsgAddition: (msgInfo: MsgInfo, decrInfo: MsgKeyInfo) => Promise<void>;
29
+ recordMsgRemoval: (msgId: string, deliveryTS: number) => Promise<void>;
30
+ watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, sink: (ops: import("../../../../../../lib-common/dataset-sync/per-device-json-array-logs").LogEntry<MsgOp>[]) => Promise<void>) => () => void;
31
+ cutLogOnDatasetSyncAndUpload: (syncPointV: number, params?: any) => Promise<void> | undefined;
32
+ }>;
33
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2016 - 2020, 2023, 2026 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.msgOpenedEventToRecordParams = msgOpenedEventToRecordParams;
20
+ exports.makeRecentMsgIndexChangesLogs = makeRecentMsgIndexChangesLogs;
21
+ const buffer_utils_1 = require("../../../../../../lib-common/buffer-utils");
22
+ const per_device_json_array_logs_1 = require("../../../../../../lib-common/dataset-sync/per-device-json-array-logs");
23
+ function msgOpenedEventToRecordParams(op) {
24
+ const { msgType, msgId, deliveryTS, keyB64, keyStatus, mainObjHeaderOfs } = op;
25
+ return {
26
+ msgInfo: {
27
+ msgId, msgType, deliveryTS
28
+ },
29
+ decrInfo: {
30
+ correspondent: '',
31
+ keyStatus,
32
+ msgKeyPackLen: mainObjHeaderOfs,
33
+ key: buffer_utils_1.base64.open(keyB64)
34
+ }
35
+ };
36
+ }
37
+ function areOpsEqual(a, b) {
38
+ return ((a.eventType === b.eventType) && (a.msgId === b.msgId) && (a.deliveryTS === b.deliveryTS));
39
+ }
40
+ async function makeRecentMsgIndexChangesLogs(logsFS, localLogsFS, logError) {
41
+ const { appendLogsAndUpload, cutLogOnDatasetSyncAndUpload, watchAndApplyOpsFromOtherDevices } = await (0, per_device_json_array_logs_1.makeRecentChangesLogs)(logsFS, localLogsFS, areOpsEqual, logError);
42
+ function recordMsgAddition(msgInfo, decrInfo) {
43
+ if (!decrInfo.key) {
44
+ throw new Error(`Given message decryption info doesn't have a key for message ${msgInfo.msgId}`);
45
+ }
46
+ return appendLogsAndUpload({
47
+ eventType: 'msg-opened',
48
+ eventTS: Date.now(),
49
+ msgType: msgInfo.msgType,
50
+ msgId: msgInfo.msgId,
51
+ deliveryTS: msgInfo.deliveryTS,
52
+ keyB64: buffer_utils_1.base64.pack(decrInfo.key),
53
+ keyStatus: decrInfo.keyStatus,
54
+ mainObjHeaderOfs: decrInfo.msgKeyPackLen,
55
+ });
56
+ }
57
+ function recordMsgRemoval(msgId, deliveryTS) {
58
+ return appendLogsAndUpload({
59
+ eventType: 'msg-removed',
60
+ eventTS: Date.now(),
61
+ msgId,
62
+ deliveryTS
63
+ });
64
+ }
65
+ return {
66
+ recordMsgAddition,
67
+ recordMsgRemoval,
68
+ watchAndApplyOpsFromOtherDevices,
69
+ cutLogOnDatasetSyncAndUpload
70
+ };
71
+ }
72
+ Object.freeze(exports);
@@ -0,0 +1,28 @@
1
+ import { MsgKeyInfo, MsgKeyRole } from '../../../../../keyring';
2
+ import { MsgOp } from './logs';
3
+ import { SingleProc } from '../../../../../../lib-common/processes/synced';
4
+ import { LogEntry } from '../../../../../../lib-common/dataset-sync/per-device-json-array-logs';
5
+ type WritableFS = web3n.files.WritableFS;
6
+ type WritableFile = web3n.files.WritableFile;
7
+ type MsgInfo = web3n.asmail.MsgInfo;
8
+ export interface MsgKey {
9
+ msgKey: Uint8Array;
10
+ msgKeyRole: MsgKeyRole;
11
+ mainObjHeaderOfs: number;
12
+ }
13
+ export declare function makeSqliteDBs(dbsFS: WritableFS): Promise<{
14
+ absorbOpsFromOtherDevices: (changeProc: SingleProc, ops: LogEntry<MsgOp>[]) => Promise<void>;
15
+ addToLatest: (msgInfo: MsgInfo, decrInfo: MsgKeyInfo) => Promise<boolean>;
16
+ getDBFile: (fileTS: number) => Promise<WritableFile>;
17
+ getKeyFor: (msgId: string, deliveryTS: number) => Promise<MsgKey | undefined>;
18
+ isForLatestDb: (deliveryTS: number) => boolean;
19
+ latestDbHasNewRemoteVersion: () => Promise<boolean>;
20
+ listMsgs: (fromTS: number | undefined) => Promise<MsgInfo[]>;
21
+ msgExists: ({ msgId, deliveryTS }: MsgInfo) => Promise<boolean>;
22
+ makeNewShardWithRecordsUpToTS: (shardTS: number) => Promise<number>;
23
+ syncPastShards: () => Promise<void>;
24
+ numberOfRecordsInLatestBefore: (ts: number) => number;
25
+ remove: (msgId: string) => Promise<number | undefined>;
26
+ watchAndApplyOpsFromOtherDevices: (changeProc: SingleProc, resetSyncInterval: () => void) => () => void;
27
+ }>;
28
+ export {};