core-3nweb-client-lib 0.27.3 → 0.27.5

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 (102) hide show
  1. package/build/api-defs/files.d.ts +92 -29
  2. package/build/core/asmail/config/index.d.ts +2 -2
  3. package/build/core/asmail/config/index.js +2 -2
  4. package/build/core/asmail/config/invitations-anon.d.ts +10 -24
  5. package/build/core/asmail/config/invitations-anon.js +43 -31
  6. package/build/core/asmail/config/published-intro-key.d.ts +11 -22
  7. package/build/core/asmail/config/published-intro-key.js +47 -38
  8. package/build/core/asmail/delivery/per-recipient-wip.js +2 -2
  9. package/build/core/asmail/inbox/inbox-events.js +10 -5
  10. package/build/core/asmail/inbox/index.d.ts +3 -2
  11. package/build/core/asmail/inbox/index.js +15 -11
  12. package/build/core/asmail/inbox/msg-indexing.d.ts +17 -64
  13. package/build/core/asmail/inbox/msg-indexing.js +440 -311
  14. package/build/core/asmail/inbox/msg-on-disk.js +2 -1
  15. package/build/core/asmail/index.d.ts +1 -1
  16. package/build/core/asmail/index.js +5 -4
  17. package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
  18. package/build/core/asmail/keyring/correspondent-keys.js +4 -2
  19. package/build/core/asmail/keyring/index.d.ts +10 -33
  20. package/build/core/asmail/keyring/index.js +88 -75
  21. package/build/core/asmail/msg/opener.js +4 -3
  22. package/build/core/asmail/msg/packer.d.ts +1 -0
  23. package/build/core/asmail/msg/packer.js +8 -4
  24. package/build/core/index.js +3 -5
  25. package/build/core/sign-in.js +1 -1
  26. package/build/core/storage/local/obj-files.js +2 -1
  27. package/build/core/storage/synced/obj-files.d.ts +2 -0
  28. package/build/core/storage/synced/obj-files.js +18 -1
  29. package/build/core/storage/synced/obj-status.d.ts +1 -0
  30. package/build/core/storage/synced/obj-status.js +10 -0
  31. package/build/core/storage/synced/storage.js +7 -23
  32. package/build/core/storage/synced/upload-header-file.js +4 -2
  33. package/build/core/storage/synced/upsyncer.js +3 -5
  34. package/build/ipc-via-protobuf/asmail-cap.js +14 -15
  35. package/build/ipc-via-protobuf/bytes.js +42 -18
  36. package/build/ipc-via-protobuf/file.d.ts +7 -0
  37. package/build/ipc-via-protobuf/file.js +103 -66
  38. package/build/ipc-via-protobuf/fs.js +127 -105
  39. package/build/ipc-via-protobuf/mailerid.js +2 -2
  40. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  41. package/build/ipc-via-protobuf/protobuf-msg.js +5 -1
  42. package/build/ipc-via-protobuf/startup-cap.js +8 -8
  43. package/build/ipc-via-protobuf/storage-cap.js +4 -4
  44. package/build/lib-client/3nstorage/xsp-fs/common.js +2 -0
  45. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
  46. package/build/lib-client/3nstorage/xsp-fs/file-node.js +26 -45
  47. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +8 -7
  48. package/build/lib-client/3nstorage/xsp-fs/file.js +12 -18
  49. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +6 -1
  50. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +20 -8
  51. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +19 -18
  52. package/build/lib-client/3nstorage/xsp-fs/fs.js +18 -19
  53. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +13 -4
  54. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +63 -8
  55. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -0
  56. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +7 -5
  57. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -4
  58. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +20 -15
  59. package/build/lib-client/cryptor/cryptor-in-worker.js +37 -47
  60. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  61. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  62. package/build/lib-client/cryptor/in-proc-js.js +15 -12
  63. package/build/lib-client/cryptor/in-proc-wasm.js +11 -8
  64. package/build/lib-client/cryptor/serialization-for-wasm.d.ts +36 -0
  65. package/build/lib-client/cryptor/serialization-for-wasm.js +58 -0
  66. package/build/lib-client/cryptor-work-labels.d.ts +26 -0
  67. package/build/lib-client/cryptor-work-labels.js +152 -0
  68. package/build/lib-client/fs-sync-utils.d.ts +7 -1
  69. package/build/lib-client/fs-sync-utils.js +18 -7
  70. package/build/lib-client/local-files/dev-file-src.d.ts +2 -1
  71. package/build/lib-client/local-files/dev-file-src.js +5 -1
  72. package/build/lib-client/local-files/device-fs.js +2 -1
  73. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
  74. package/build/lib-client/objs-on-disk/obj-on-disk.js +21 -2
  75. package/build/lib-client/request-utils.js +14 -14
  76. package/build/lib-common/async-cryptor-wrap.d.ts +9 -9
  77. package/build/lib-common/async-cryptor-wrap.js +13 -13
  78. package/build/lib-common/byte-streaming/pipe.d.ts +1 -1
  79. package/build/lib-common/byte-streaming/pipe.js +3 -3
  80. package/build/lib-common/byte-streaming/wrapping.js +4 -2
  81. package/build/lib-common/json-utils.js +0 -3
  82. package/build/lib-common/objs-on-disk/file-layout.js +1 -1
  83. package/build/lib-common/processes/synced.js +0 -184
  84. package/build/lib-sqlite-on-3nstorage/index.d.ts +32 -0
  85. package/build/lib-sqlite-on-3nstorage/index.js +117 -0
  86. package/build/lib-sqlite-on-3nstorage/sqljs.d.ts +279 -0
  87. package/build/lib-sqlite-on-3nstorage/sqljs.js +223 -0
  88. package/build/protos/asmail.proto.js +10145 -5923
  89. package/build/protos/bytes.proto.js +731 -204
  90. package/build/protos/common.proto.js +192 -44
  91. package/build/protos/cryptor.proto.js +184 -61
  92. package/build/protos/file.proto.js +2388 -502
  93. package/build/protos/fs.proto.js +9894 -6046
  94. package/build/protos/ipc.proto.js +244 -61
  95. package/build/protos/logger.proto.js +219 -53
  96. package/build/protos/mailerid.proto.js +230 -50
  97. package/build/protos/startup.proto.js +341 -77
  98. package/build/protos/storage.proto.js +276 -62
  99. package/package.json +8 -7
  100. package/protos/bytes.proto +13 -4
  101. package/protos/file.proto +27 -8
  102. package/protos/fs.proto +31 -14
@@ -13,7 +13,8 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
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/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.MsgOnDisk = void 0;
19
20
  const fs = require("../../../lib-common/async-fs-node");
@@ -10,6 +10,7 @@ declare type Service = web3n.asmail.Service;
10
10
  export declare type MailCAPMaker = () => Service;
11
11
  export declare class ASMail {
12
12
  private readonly cryptor;
13
+ private readonly makeNet;
13
14
  private readonly inboxPathForUser;
14
15
  private readonly logger;
15
16
  private keyring;
@@ -18,7 +19,6 @@ export declare class ASMail {
18
19
  private delivery;
19
20
  private config;
20
21
  private sendingParams;
21
- private readonly makeNet;
22
22
  constructor(cryptor: AsyncSBoxCryptor, makeNet: MakeNet, inboxPathForUser: InboxPathForUser, logger: Logger);
23
23
  init(address: string, getSigner: GetSigner, syncedFS: WritableFS, localFS: WritableFS, getStorages: StorageGetter, makeResolver: ServiceLocatorMaker): Promise<void>;
24
24
  private setupConfig;
@@ -32,6 +32,7 @@ const SEND_PARAMS_DATA_FOLDER = 'sending-params';
32
32
  class ASMail {
33
33
  constructor(cryptor, makeNet, inboxPathForUser, logger) {
34
34
  this.cryptor = cryptor;
35
+ this.makeNet = makeNet;
35
36
  this.inboxPathForUser = inboxPathForUser;
36
37
  this.logger = logger;
37
38
  this.keyring = undefined;
@@ -40,7 +41,6 @@ class ASMail {
40
41
  this.delivery = undefined;
41
42
  this.config = undefined;
42
43
  this.sendingParams = undefined;
43
- this.makeNet = () => makeNet();
44
44
  Object.seal(this);
45
45
  }
46
46
  async init(address, getSigner, syncedFS, localFS, getStorages, makeResolver) {
@@ -70,7 +70,7 @@ class ASMail {
70
70
  }
71
71
  async setupKeyring(syncedFS) {
72
72
  const fs = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, KEYRING_DATA_FOLDER);
73
- this.keyring = await keyring_1.KeyRing.makeAndStart(this.cryptor, fs, this.config.publishedKeys);
73
+ this.keyring = await (0, keyring_1.makeAndKeyRing)(this.cryptor, fs, this.config.publishedKeys);
74
74
  }
75
75
  async setupSendingParams(syncedFS) {
76
76
  const fs = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, SEND_PARAMS_DATA_FOLDER);
@@ -99,8 +99,8 @@ class ASMail {
99
99
  }
100
100
  async setupInbox(syncedFS, getSigner, getStorages, makeResolver) {
101
101
  const cachePath = this.inboxPathForUser(this.address);
102
- const inboxFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, INBOX_DATA_FOLDER);
103
- this.inbox = await inbox_1.InboxOnServer.makeAndStart(cachePath, inboxFS, {
102
+ const inboxSyncedFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, INBOX_DATA_FOLDER);
103
+ this.inbox = await inbox_1.InboxOnServer.makeAndStart(cachePath, inboxSyncedFS, {
104
104
  address: this.address,
105
105
  cryptor: this.cryptor,
106
106
  getSigner,
@@ -126,6 +126,7 @@ class ASMail {
126
126
  }
127
127
  ;
128
128
  async close() {
129
+ await this.inbox.close();
129
130
  await this.keyring.close();
130
131
  }
131
132
  }
@@ -4,7 +4,7 @@
4
4
  import { JWKeyPair, MsgKeyRole, ASMailKeyPair } from './common';
5
5
  import { JsonKey, JsonKeyShort } from '../../../lib-common/jwkeys';
6
6
  import { SuggestedNextKeyPair } from '../msg/opener';
7
- import { KeyRing } from './index';
7
+ import { KeyPairsStorage } from './index';
8
8
  import { Decryptor } from '../../../lib-common/async-cryptor-wrap';
9
9
  import { AsyncSBoxCryptor } from 'xsp-files';
10
10
  export interface ReceptionPair {
@@ -89,7 +89,7 @@ export declare class CorrespondentKeys {
89
89
  * @param serialData from which this object should be reconstructed.
90
90
  * Either serialData, or an address should be defined, not both.
91
91
  */
92
- constructor(keyring: KeyRing, address: string | undefined, serialData?: string);
92
+ constructor(keyring: KeyPairsStorage, address: string | undefined, serialData?: string);
93
93
  /**
94
94
  * This attaches all keys into ring's maps.
95
95
  * Theis method should be called only once, and only on a deserialized
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2018 3NSoft Inc.
3
+ Copyright (C) 2015 - 2018, 2022 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
@@ -26,6 +26,7 @@ const ecma_nacl_1 = require("ecma-nacl");
26
26
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
27
27
  const error_1 = require("../../../lib-common/exceptions/error");
28
28
  const async_cryptor_wrap_1 = require("../../../lib-common/async-cryptor-wrap");
29
+ const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
29
30
  function generatePids() {
30
31
  const pids = [];
31
32
  for (let i = 0; i < 5; i += 1) {
@@ -35,7 +36,8 @@ function generatePids() {
35
36
  }
36
37
  function msgMasterDecryptor(cryptor, skey, pkey) {
37
38
  const msgMasterKey = calcMsgMasterKey(skey, pkey);
38
- const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(cryptor, msgMasterKey);
39
+ const workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeRandom('asmail');
40
+ const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(cryptor, workLabel, msgMasterKey);
39
41
  msgMasterKey.fill(0);
40
42
  return masterDecr;
41
43
  }
@@ -7,10 +7,7 @@ import { ResourcesForReceiving } from '../inbox';
7
7
  export { KEY_USE, MsgKeyRole } from './common';
8
8
  export interface MsgKeyInfo {
9
9
  correspondent: string;
10
- /**
11
- * This is a base64 form of key's byte array.
12
- */
13
- key?: string;
10
+ key?: Uint8Array;
14
11
  /**
15
12
  * This is a current status of the key in this keyring.
16
13
  */
@@ -25,35 +22,15 @@ export interface MsgKeyInfo {
25
22
  declare type WritableFS = web3n.files.WritableFS;
26
23
  declare type SendingResources = ResourcesForSending['correspondents'];
27
24
  declare type ReceptionResources = ResourcesForReceiving['correspondents'];
28
- export declare class KeyRing {
29
- private readonly cryptor;
30
- private readonly publishedKeys;
31
- /**
32
- * This is a map from correspondents' canonical addresses to key objects.
33
- */
34
- private readonly corrKeys;
35
- readonly pairIdToEmailMap: IdToEmailMap;
36
- private storage;
37
- constructor(cryptor: AsyncSBoxCryptor, publishedKeys: ConfigOfASMailServer['publishedKeys']);
38
- private addCorrespondent;
39
- private init;
40
- static makeAndStart(cryptor: AsyncSBoxCryptor, fs: WritableFS, publishedKeys: ConfigOfASMailServer['publishedKeys']): Promise<KeyRing>;
41
- saveChanges(): void;
25
+ export interface KeyRing {
42
26
  needIntroKeyFor: SendingResources['needIntroKeyFor'];
43
- readonly generateKeysToSend: SendingResources['generateKeysToSend'];
44
- readonly nextCrypto: SendingResources['nextCrypto'];
45
- private decryptMsgKeyWithIntroPair;
46
- private findEstablishedReceptionPairs;
47
- private decryptMsgKeyWithEstablishedPair;
48
- /**
49
- * This method updates message counts and a timestamp in a given reception
50
- * pair.
51
- * @param rp is a sending pair, in which changes should be done. Note this
52
- * must be a shared structure at this point, not a copy of a pair.
53
- * @param msgCount is a message count that should be added to the pair.
54
- */
55
- private updateReceivedMsgCountIn;
56
- private absorbSuggestedNextKeyPair;
57
- readonly decrypt: ReceptionResources['msgDecryptor'];
27
+ generateKeysToSend: SendingResources['generateKeysToSend'];
28
+ nextCrypto: SendingResources['nextCrypto'];
29
+ decrypt: ReceptionResources['msgDecryptor'];
58
30
  close(): Promise<void>;
59
31
  }
32
+ export declare function makeAndKeyRing(cryptor: AsyncSBoxCryptor, fs: WritableFS, publishedKeys: ConfigOfASMailServer['publishedKeys']): Promise<KeyRing>;
33
+ export interface KeyPairsStorage {
34
+ pairIdToEmailMap: IdToEmailMap;
35
+ saveChanges: () => void;
36
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2018 3NSoft Inc.
3
+ Copyright (C) 2015 - 2018, 2022 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
@@ -16,7 +16,7 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.KeyRing = exports.KEY_USE = void 0;
19
+ exports.makeAndKeyRing = exports.KEY_USE = void 0;
20
20
  const correspondent_keys_1 = require("./correspondent-keys");
21
21
  const id_to_email_map_1 = require("./id-to-email-map");
22
22
  const common_1 = require("./common");
@@ -27,9 +27,15 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
27
27
  const canonical_address_1 = require("../../../lib-common/canonical-address");
28
28
  const common_2 = require("../delivery/common");
29
29
  const keyring_storage_1 = require("./keyring-storage");
30
+ const assert_1 = require("../../../lib-common/assert");
31
+ const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
30
32
  var common_3 = require("./common");
31
33
  Object.defineProperty(exports, "KEY_USE", { enumerable: true, get: function () { return common_3.KEY_USE; } });
32
- class KeyRing {
34
+ function makeAndKeyRing(cryptor, fs, publishedKeys) {
35
+ return KRing.makeAndStart(cryptor, fs, publishedKeys);
36
+ }
37
+ exports.makeAndKeyRing = makeAndKeyRing;
38
+ class KRing {
33
39
  constructor(cryptor, publishedKeys) {
34
40
  this.cryptor = cryptor;
35
41
  this.publishedKeys = publishedKeys;
@@ -38,8 +44,13 @@ class KeyRing {
38
44
  */
39
45
  this.corrKeys = new Map();
40
46
  this.pairIdToEmailMap = new id_to_email_map_1.IdToEmailMap();
47
+ this.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeRandom('asmail');
41
48
  this.storage = undefined;
42
- this.needIntroKeyFor = (address) => {
49
+ this.asKeyPairsStorage = {
50
+ pairIdToEmailMap: this.pairIdToEmailMap,
51
+ saveChanges: this.saveChanges.bind(this)
52
+ };
53
+ this.needIntroKeyFor = address => {
43
54
  address = (0, canonical_address_1.toCanonicalAddress)(address);
44
55
  return !this.corrKeys.has(address);
45
56
  };
@@ -55,7 +66,7 @@ class KeyRing {
55
66
  const { msgMasterKey, currentPair, msgCount } = await ck.getSendingPair(introPKeyFromServer);
56
67
  // prepare message encryptor
57
68
  const nextNonce = await random.bytes(xsp_files_1.NONCE_LENGTH);
58
- const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, msgMasterKey, nextNonce);
69
+ const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, this.workLabel, msgMasterKey, nextNonce);
59
70
  msgMasterKey.fill(0);
60
71
  return { encryptor, currentPair, msgCount };
61
72
  };
@@ -68,65 +79,14 @@ class KeyRing {
68
79
  const suggestPair = await ck.suggestPair();
69
80
  return suggestPair;
70
81
  };
71
- this.decrypt = async (msgMeta, getMainObjHeader, getOpenedMsg, checkMidKeyCerts) => {
72
- let decrInfo;
73
- let incrMsgCount;
74
- let openedMsg;
75
- if (msgMeta.pid) {
76
- const r = await this.decryptMsgKeyWithEstablishedPair(msgMeta.pid, getMainObjHeader);
77
- if (!r) {
78
- return;
79
- }
80
- decrInfo = r.keyInfo;
81
- incrMsgCount = r.incrMsgCount;
82
- openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
83
- }
84
- else {
85
- decrInfo = await this.decryptMsgKeyWithIntroPair(msgMeta.recipientKid, msgMeta.senderPKey, getMainObjHeader);
86
- if (!decrInfo) {
87
- return;
88
- }
89
- openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
90
- const certs = openedMsg.introCryptoCerts;
91
- const { address, pkey } = await checkMidKeyCerts(certs);
92
- if (pkey.k !== msgMeta.senderPKey) {
93
- throw new Error(`Key certificates in the message are not for a key that encrypted this message.`);
94
- }
95
- decrInfo.correspondent = (0, canonical_address_1.toCanonicalAddress)(address);
96
- }
97
- // check that sender is the same as the trusted correspondent
98
- const sender = openedMsg.sender;
99
- if (!sender || !(0, canonical_address_1.areAddressesEqual)(sender, decrInfo.correspondent)) {
100
- throw new Error(`Mismatch between message sender field '${sender}', and address '${decrInfo.correspondent}', associated with decrypting key.`);
101
- }
102
- // update received msg counts and a time stamp
103
- if (incrMsgCount) {
104
- incrMsgCount(openedMsg.msgCount);
105
- }
106
- // absorb next crypto
107
- const pair = openedMsg.nextCrypto;
108
- if (pair) {
109
- if (msgMeta.recipientKid) {
110
- if (!pair.isSenderIntroKey) {
111
- throw new Error(`Introductory message is not referencing used intro key in the next crypto`);
112
- }
113
- if (msgMeta.recipientKid !== pair.senderKid) {
114
- throw new Error(`Introductory message is referencing wrong key in the next crypto`);
115
- }
116
- }
117
- this.absorbSuggestedNextKeyPair(decrInfo.correspondent, pair);
118
- }
119
- return { decrInfo, openedMsg };
120
- };
121
82
  Object.seal(this);
122
83
  }
123
84
  addCorrespondent(address, serialForm) {
124
85
  const ck = (serialForm ?
125
- new correspondent_keys_1.CorrespondentKeys(this, undefined, serialForm) :
126
- new correspondent_keys_1.CorrespondentKeys(this, address));
86
+ new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, undefined, serialForm) :
87
+ new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, address));
127
88
  if (this.corrKeys.has(ck.correspondent)) {
128
- throw new Error("Correspondent with address " + ck.correspondent +
129
- " is already present.");
89
+ throw new Error(`Correspondent with address ${ck.correspondent} is already present.`);
130
90
  }
131
91
  this.corrKeys.set(ck.correspondent, ck);
132
92
  if (serialForm) {
@@ -135,9 +95,7 @@ class KeyRing {
135
95
  return ck;
136
96
  }
137
97
  async init(fs) {
138
- if (this.storage) {
139
- throw new Error("Keyring has already been initialized.");
140
- }
98
+ (0, assert_1.assert)(!this.storage);
141
99
  this.storage = (0, keyring_storage_1.makeKeyringStorage)(fs);
142
100
  await this.storage.start();
143
101
  const serialForm = await this.storage.load();
@@ -155,9 +113,15 @@ class KeyRing {
155
113
  }
156
114
  }
157
115
  static async makeAndStart(cryptor, fs, publishedKeys) {
158
- const kr = new KeyRing(cryptor, publishedKeys);
116
+ const kr = new KRing(cryptor, publishedKeys);
159
117
  await kr.init(fs);
160
- return kr;
118
+ return {
119
+ close: kr.close.bind(kr),
120
+ decrypt: kr.decrypt.bind(kr),
121
+ generateKeysToSend: kr.generateKeysToSend.bind(kr),
122
+ needIntroKeyFor: kr.needIntroKeyFor.bind(kr),
123
+ nextCrypto: kr.nextCrypto.bind(kr)
124
+ };
161
125
  }
162
126
  saveChanges() {
163
127
  // pack bytes that need to be encrypted and saved
@@ -186,10 +150,9 @@ class KeyRing {
186
150
  const info = {
187
151
  correspondent: undefined,
188
152
  keyStatus: recipKey.role,
189
- key: buffer_utils_1.base64.pack(mainObjFileKey),
153
+ key: mainObjFileKey,
190
154
  msgKeyPackLen
191
155
  };
192
- mainObjFileKey.fill(0);
193
156
  return info;
194
157
  }
195
158
  catch (err) {
@@ -233,7 +196,7 @@ class KeyRing {
233
196
  const h = await getMainObjHeader();
234
197
  for (const { correspondent, pair, role } of pairs) {
235
198
  const masterKey = buffer_utils_1.base64.open(pair.msgMasterKey);
236
- const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(this.cryptor, masterKey);
199
+ const masterDecr = (0, async_cryptor_wrap_1.makeDecryptor)(this.cryptor, this.workLabel, masterKey);
237
200
  masterKey.fill(0);
238
201
  try {
239
202
  const msgKeyPackLen = msgKeyPackLenForPair(pair);
@@ -244,18 +207,18 @@ class KeyRing {
244
207
  const keyInfo = {
245
208
  correspondent: correspondent,
246
209
  keyStatus: role,
247
- key: buffer_utils_1.base64.pack(mainObjFileKey),
210
+ key: mainObjFileKey,
248
211
  msgKeyPackLen
249
212
  };
250
- mainObjFileKey.fill(0);
251
213
  // set pair as in use
252
214
  if (keyInfo.keyStatus === 'suggested') {
253
215
  const corrKeys = this.corrKeys.get(keyInfo.correspondent);
254
216
  corrKeys.markPairAsInUse(pair);
255
217
  }
256
- // prepare msg count incrementor that will be "called back"
257
- const incrMsgCount = (msgCount) => this.updateReceivedMsgCountIn(pair, msgCount);
258
- return { keyInfo, incrMsgCount };
218
+ return {
219
+ keyInfo,
220
+ incrMsgCount: msgCount => this.updateReceivedMsgCountIn(pair, msgCount)
221
+ };
259
222
  }
260
223
  catch (err) {
261
224
  if (!err.failedCipherVerification) {
@@ -301,13 +264,63 @@ class KeyRing {
301
264
  }
302
265
  this.saveChanges();
303
266
  }
267
+ async decrypt(msgMeta, getMainObjHeader, getOpenedMsg, checkMidKeyCerts) {
268
+ let decrInfo;
269
+ let incrMsgCount;
270
+ let openedMsg;
271
+ if (msgMeta.pid) {
272
+ const r = await this.decryptMsgKeyWithEstablishedPair(msgMeta.pid, getMainObjHeader);
273
+ if (!r) {
274
+ return;
275
+ }
276
+ decrInfo = r.keyInfo;
277
+ incrMsgCount = r.incrMsgCount;
278
+ openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
279
+ }
280
+ else {
281
+ decrInfo = await this.decryptMsgKeyWithIntroPair(msgMeta.recipientKid, msgMeta.senderPKey, getMainObjHeader);
282
+ if (!decrInfo) {
283
+ return;
284
+ }
285
+ openedMsg = await getOpenedMsg(decrInfo.key, decrInfo.msgKeyPackLen);
286
+ const certs = openedMsg.introCryptoCerts;
287
+ const { address, pkey } = await checkMidKeyCerts(certs);
288
+ if (pkey.k !== msgMeta.senderPKey) {
289
+ throw new Error(`Key certificates in the message are not for a key that encrypted this message.`);
290
+ }
291
+ decrInfo.correspondent = (0, canonical_address_1.toCanonicalAddress)(address);
292
+ }
293
+ // check that sender is the same as the trusted correspondent
294
+ const sender = openedMsg.sender;
295
+ if (!sender || !(0, canonical_address_1.areAddressesEqual)(sender, decrInfo.correspondent)) {
296
+ throw new Error(`Mismatch between message sender field '${sender}', and address '${decrInfo.correspondent}', associated with decrypting key.`);
297
+ }
298
+ // update received msg counts and a time stamp
299
+ if (incrMsgCount) {
300
+ incrMsgCount(openedMsg.msgCount);
301
+ }
302
+ // absorb next crypto
303
+ const pair = openedMsg.nextCrypto;
304
+ if (pair) {
305
+ if (msgMeta.recipientKid) {
306
+ if (!pair.isSenderIntroKey) {
307
+ throw new Error(`Introductory message is not referencing used intro key in the next crypto`);
308
+ }
309
+ if (msgMeta.recipientKid !== pair.senderKid) {
310
+ throw new Error(`Introductory message is referencing wrong key in the next crypto`);
311
+ }
312
+ }
313
+ this.absorbSuggestedNextKeyPair(decrInfo.correspondent, pair);
314
+ }
315
+ return { decrInfo, openedMsg };
316
+ }
317
+ ;
304
318
  close() {
305
319
  return this.storage.close();
306
320
  }
307
321
  }
308
- exports.KeyRing = KeyRing;
309
- Object.freeze(KeyRing.prototype);
310
- Object.freeze(KeyRing);
322
+ Object.freeze(KRing.prototype);
323
+ Object.freeze(KRing);
311
324
  function msgKeyPackLenForPair(p) {
312
325
  return (0, common_1.msgKeyPackSizeFor)(p.recipientKey.skey.alg);
313
326
  }
@@ -20,6 +20,7 @@ exports.openMsg = exports.OpenedMsg = void 0;
20
20
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
21
21
  const error_1 = require("../../../lib-common/exceptions/error");
22
22
  const xsp_files_1 = require("xsp-files");
23
+ const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
23
24
  class OpenedMsg {
24
25
  constructor(msgId, main) {
25
26
  this.msgId = msgId;
@@ -77,9 +78,9 @@ Object.freeze(OpenedMsg);
77
78
  async function openMsg(msgId, mainObjId, mainObj, headerOfs, fKey, cryptor) {
78
79
  try {
79
80
  const header = await mainObj.readHeader();
80
- const segReader = await (0, xsp_files_1.makeSegmentsReader)(fKey, (0, xsp_files_1.idToHeaderNonce)(mainObjId), 0, header.subarray(headerOfs), cryptor);
81
- const byteSrc = await (0, xsp_files_1.makeDecryptedByteSource)(mainObj.segSrc, segReader);
82
- const bytes = await byteSrc.read(undefined);
81
+ const segReader = await (0, xsp_files_1.makeSegmentsReader)(fKey, (0, xsp_files_1.idToHeaderNonce)(mainObjId), 0, header.subarray(headerOfs), cryptor, cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', msgId));
82
+ const byteSrc = (0, xsp_files_1.makeDecryptedByteSource)(mainObj.segSrc, segReader);
83
+ const bytes = await byteSrc.readNext(undefined);
83
84
  if (!bytes) {
84
85
  throw new Error(`End of bytes is reached too soon`);
85
86
  }
@@ -52,6 +52,7 @@ export declare class MsgPacker {
52
52
  private hasAttachments;
53
53
  private attachmentsFS;
54
54
  private attachmentsCont;
55
+ private workLabel;
55
56
  private constructor();
56
57
  static empty(segSizeIn256bs: number): MsgPacker;
57
58
  static fromPack(p: PackJSON, segSizeIn256bs: number, att: undefined | {
@@ -24,6 +24,7 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
24
24
  const folder_node_serialization_1 = require("../../../lib-client/3nstorage/xsp-fs/folder-node-serialization");
25
25
  const json_utils_1 = require("../../../lib-common/json-utils");
26
26
  const attachments_container_1 = require("./attachments-container");
27
+ const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
27
28
  function turnKeysToB64(obj) {
28
29
  obj.key = buffer_utils_1.base64.pack(obj.key);
29
30
  if (!obj.folder) {
@@ -88,6 +89,7 @@ class MsgPacker {
88
89
  'From': undefined
89
90
  };
90
91
  this.mainObjId = this.addJsonObj(this.main);
92
+ this.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', this.mainObjId);
91
93
  Object.seal(this);
92
94
  }
93
95
  static empty(segSizeIn256bs) {
@@ -97,6 +99,7 @@ class MsgPacker {
97
99
  const packer = new MsgPacker(segSizeIn256bs);
98
100
  packer.readyPack = p;
99
101
  packer.mainObjId = p.meta.objIds[0];
102
+ packer.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeFor('asmail', packer.mainObjId);
100
103
  Object.values((0, json_utils_1.copy)(p.objs))
101
104
  .forEach(obj => {
102
105
  packer.allObjs.set(obj.id, obj);
@@ -347,7 +350,7 @@ class MsgPacker {
347
350
  }
348
351
  const msgKeyPack = await msgKeyEnc.pack(obj.key);
349
352
  const bytes = buffer_utils_1.utf8.pack(JSON.stringify(obj.json));
350
- const segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor);
353
+ const segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor, this.workLabel);
351
354
  // make source that inserts message key pack into header
352
355
  return makeMainObjSrc(msgKeyPack, bytes, segWriter);
353
356
  }
@@ -410,10 +413,10 @@ class MsgPacker {
410
413
  // make object segments writer
411
414
  let segWriter;
412
415
  if (header) {
413
- segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'restart', header }, random.bytes, cryptor);
416
+ segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'restart', header }, random.bytes, cryptor, this.workLabel);
414
417
  }
415
418
  else {
416
- segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor);
419
+ segWriter = await (0, xsp_files_1.makeSegmentsWriter)(obj.key, (0, xsp_files_1.idToHeaderNonce)(obj.id), 0, { type: 'new', segSize: this.segSizeIn256bs, payloadFormat: 1 }, random.bytes, cryptor, this.workLabel);
417
420
  }
418
421
  // make object source
419
422
  let src;
@@ -492,7 +495,8 @@ function fileSrcToByteSrc(fileSrc) {
492
495
  size: await fileSrc.getSize()
493
496
  };
494
497
  },
495
- read: fileSrc.read,
498
+ readNext: fileSrc.readNext,
499
+ readAt: fileSrc.readAt,
496
500
  seek: fileSrc.seek
497
501
  };
498
502
  }
@@ -120,9 +120,8 @@ class Core {
120
120
  const initFromSignUp$ = signUp.newUser$
121
121
  .pipe((0, operators_1.mergeMap)(this.initForNewUser, 1));
122
122
  const initFromSignIn$ = signIn.existingUser$;
123
- const coreInit = (0, rxjs_1.merge)(initFromSignIn$, initFromSignUp$)
124
- .pipe((0, operators_1.take)(1), (0, operators_1.mergeMap)(idManager => this.initCore(idManager), 1))
125
- .toPromise();
123
+ const coreInit = (0, rxjs_1.lastValueFrom)((0, rxjs_1.merge)(initFromSignIn$, initFromSignUp$)
124
+ .pipe((0, operators_1.take)(1), (0, operators_1.mergeMap)(idManager => this.initCore(idManager), 1)));
126
125
  return { coreInit, capsForStartup };
127
126
  }
128
127
  ;
@@ -225,8 +224,7 @@ function makeStoragePolicy(appDomain, requestedCAPs) {
225
224
  }
226
225
  else if (Array.isArray(capReq.appFS)) {
227
226
  const okDomains = capReq.appFS
228
- .filter(fsInfo => (fsInfo.domain === appDomain) ||
229
- fsInfo.domain.endsWith('.' + appDomain))
227
+ .filter(fsInfo => (fsInfo.domain === appDomain) || fsInfo.domain.endsWith('.' + appDomain))
230
228
  .map(fsInfo => (0, json_utils_1.copy)(fsInfo));
231
229
  policy = {
232
230
  canOpenAppFS: severalDomainsAppFSChecker(okDomains)
@@ -45,7 +45,7 @@ class SignIn {
45
45
  const midKeyProgressCB = makeKeyGenProgressCB(0, 50, progressCB);
46
46
  const midKeyGen = async (params) => (await (0, key_derivation_1.deriveMidKeyPair)(this.cryptor, pass, params, midKeyProgressCB)).skey;
47
47
  const storeKeyProgressCB = makeKeyGenProgressCB(51, 100, progressCB);
48
- const storeKeyGen = (params) => (0, key_derivation_1.deriveStorageSKey)(this.cryptor, pass, params, storeKeyProgressCB);
48
+ const storeKeyGen = params => (0, key_derivation_1.deriveStorageSKey)(this.cryptor, pass, params, storeKeyProgressCB);
49
49
  const idManager = await this.completeInitWithoutCache(midKeyGen, storeKeyGen);
50
50
  if (!idManager) {
51
51
  return false;
@@ -24,6 +24,7 @@ const path_1 = require("path");
24
24
  const obj_files_gc_1 = require("./obj-files-gc");
25
25
  const obj_status_1 = require("./obj-status");
26
26
  const timed_cache_1 = require("../../../lib-common/timed-cache");
27
+ const rxjs_1 = require("rxjs");
27
28
  class ObjFiles {
28
29
  constructor(folders, logError) {
29
30
  this.folders = folders;
@@ -140,7 +141,7 @@ class LocalObj {
140
141
  const fPath = this.path(version);
141
142
  const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, undefined, this.objSegsGetterFromDisk);
142
143
  try {
143
- await write$.toPromise();
144
+ await (0, rxjs_1.lastValueFrom)(write$);
144
145
  }
145
146
  catch (err) {
146
147
  if (this.verObjs.get(version) === obj) {
@@ -89,4 +89,6 @@ export declare class SyncedObj {
89
89
  syncStatus(): SyncedObjStatus;
90
90
  statusObj(): ObjStatus;
91
91
  recordRemovalUploadAndGC(): Promise<void>;
92
+ isRemoteVersionOnDisk(version: number): Promise<'complete' | 'partial' | 'none'>;
93
+ downloadRemoteVersion(version: number): Promise<void>;
92
94
  }
@@ -32,6 +32,7 @@ const obj_status_1 = require("./obj-status");
32
32
  const timed_cache_1 = require("../../../lib-common/timed-cache");
33
33
  const upload_header_file_1 = require("./upload-header-file");
34
34
  const utils_1 = require("../common/utils");
35
+ const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
35
36
  exports.UNSYNCED_FILE_NAME_EXT = 'unsynced';
36
37
  exports.REMOTE_FILE_NAME_EXT = 'v';
37
38
  /**
@@ -338,7 +339,8 @@ class SyncedObj {
338
339
  this.remoteVers.set(uploadVersion, syncedVerObj);
339
340
  }
340
341
  else {
341
- await fs.rename(this.localVerPath(localVersion), remotePath);
342
+ const localPath = this.localVerPath(localVersion);
343
+ await fs.rename(localPath, remotePath);
342
344
  }
343
345
  await this.status.recordUploadCompletion(localVersion, uploadVersion);
344
346
  this.scheduleSelfGC();
@@ -395,6 +397,21 @@ class SyncedObj {
395
397
  await this.status.recordRemoteRemovalCompletion();
396
398
  this.scheduleSelfGC();
397
399
  }
400
+ async isRemoteVersionOnDisk(version) {
401
+ if (!this.status.isAmongRemote(version)) {
402
+ throw (0, exceptions_1.makeObjVersionNotFoundExc)(this.objId, version);
403
+ }
404
+ const verPath = this.remoteVerPath(version);
405
+ if (!(await isOnDisk(verPath))) {
406
+ return 'none';
407
+ }
408
+ const objVer = await this.instanceOfRemoteObjVer(version);
409
+ return (objVer.doesFileNeedDownload() ? 'complete' : 'partial');
410
+ }
411
+ async downloadRemoteVersion(version) {
412
+ const objVer = await this.instanceOfRemoteObjVer(version);
413
+ await objVer.downloadMissingSections();
414
+ }
398
415
  }
399
416
  exports.SyncedObj = SyncedObj;
400
417
  Object.freeze(SyncedObj.prototype);
@@ -125,6 +125,7 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
125
125
  neverUploaded(): boolean;
126
126
  versionBeforeUnsyncedRemoval(): number | undefined;
127
127
  adoptRemoteVersion(version?: number, dropLocalVer?: boolean): Promise<void>;
128
+ isAmongRemote(version: number): boolean;
128
129
  }
129
130
  export declare function readAndCheckStatus(objFolder: string, objId: ObjId): Promise<ObjStatusInfo>;
130
131
  export {};
@@ -551,6 +551,16 @@ class ObjStatus {
551
551
  this.updateStateIndicator();
552
552
  await this.triggerSaveProc();
553
553
  }
554
+ isAmongRemote(version) {
555
+ var _a;
556
+ if (this.status.remote.current === version) {
557
+ return true;
558
+ }
559
+ if ((_a = this.status.remote.archived) === null || _a === void 0 ? void 0 : _a.includes(version)) {
560
+ return true;
561
+ }
562
+ return false;
563
+ }
554
564
  }
555
565
  exports.ObjStatus = ObjStatus;
556
566
  Object.freeze(ObjStatus.prototype);