core-3nweb-client-lib 0.27.0 → 0.27.4

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 +56 -26
  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/inbox/attachments/fs.d.ts +2 -1
  9. package/build/core/asmail/inbox/attachments/fs.js +4 -3
  10. package/build/core/asmail/inbox/index.js +2 -2
  11. package/build/core/asmail/index.d.ts +1 -1
  12. package/build/core/asmail/index.js +2 -2
  13. package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
  14. package/build/core/asmail/keyring/correspondent-keys.js +1 -1
  15. package/build/core/asmail/keyring/index.d.ts +9 -29
  16. package/build/core/asmail/keyring/index.js +82 -69
  17. package/build/core/id-manager/index.d.ts +43 -0
  18. package/build/core/{id-manager.js → id-manager/index.js} +33 -114
  19. package/build/core/id-manager/key-storage.d.ts +21 -0
  20. package/build/core/id-manager/key-storage.js +96 -0
  21. package/build/core/index.js +22 -25
  22. package/build/core/sign-in.d.ts +1 -2
  23. package/build/core/sign-in.js +5 -14
  24. package/build/core/sign-up.d.ts +2 -0
  25. package/build/core/sign-up.js +2 -1
  26. package/build/core/storage/index.d.ts +4 -2
  27. package/build/core/storage/index.js +36 -57
  28. package/build/core/storage/local/storage.d.ts +1 -1
  29. package/build/core/storage/synced/obj-files-gc.d.ts +1 -4
  30. package/build/core/storage/synced/obj-files-gc.js +1 -18
  31. package/build/core/storage/synced/obj-files.d.ts +11 -1
  32. package/build/core/storage/synced/obj-files.js +59 -34
  33. package/build/core/storage/synced/obj-status.d.ts +19 -7
  34. package/build/core/storage/synced/obj-status.js +158 -83
  35. package/build/core/storage/synced/storage.d.ts +7 -2
  36. package/build/core/storage/synced/storage.js +38 -15
  37. package/build/core/storage/synced/upsyncer.d.ts +4 -4
  38. package/build/core/storage/synced/upsyncer.js +14 -9
  39. package/build/ipc-via-protobuf/file.d.ts +7 -0
  40. package/build/ipc-via-protobuf/file.js +60 -27
  41. package/build/ipc-via-protobuf/fs.js +55 -38
  42. package/build/lib-client/3nstorage/exceptions.d.ts +13 -1
  43. package/build/lib-client/3nstorage/exceptions.js +9 -3
  44. package/build/lib-client/3nstorage/service.d.ts +6 -2
  45. package/build/lib-client/3nstorage/service.js +33 -17
  46. package/build/lib-client/3nstorage/util/file-based-json.js +2 -1
  47. package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
  48. package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
  49. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +5 -4
  50. package/build/lib-client/3nstorage/xsp-fs/common.js +1 -0
  51. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
  52. package/build/lib-client/3nstorage/xsp-fs/file-node.js +43 -45
  53. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +7 -6
  54. package/build/lib-client/3nstorage/xsp-fs/file.js +14 -20
  55. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +16 -5
  56. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +238 -68
  57. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +18 -17
  58. package/build/lib-client/3nstorage/xsp-fs/fs.js +32 -37
  59. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +15 -11
  60. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +72 -22
  61. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +1 -1
  62. package/build/lib-client/local-files/device-fs.js +11 -11
  63. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
  64. package/build/lib-client/objs-on-disk/obj-on-disk.js +16 -1
  65. package/build/lib-client/user-with-mid-session.d.ts +2 -1
  66. package/build/lib-client/user-with-mid-session.js +7 -1
  67. package/build/lib-common/async-fs-node.js +8 -8
  68. package/build/lib-common/exceptions/file.d.ts +4 -2
  69. package/build/lib-common/exceptions/file.js +24 -58
  70. package/build/lib-common/ipc/generic-ipc.js +5 -4
  71. package/build/lib-common/objs-on-disk/file-layout.js +1 -1
  72. package/build/lib-common/objs-on-disk/utils.js +1 -1
  73. package/build/lib-common/service-api/3nstorage/owner.d.ts +8 -9
  74. package/build/lib-common/service-api/3nstorage/owner.js +2 -1
  75. package/build/protos/asmail.proto.js +5943 -4348
  76. package/build/protos/file.proto.js +874 -0
  77. package/build/protos/fs.proto.js +7014 -5419
  78. package/package.json +3 -2
  79. package/protos/file.proto +23 -7
  80. package/protos/fs.proto +27 -13
  81. package/build/core/id-manager.d.ts +0 -46
@@ -25,35 +25,15 @@ export interface MsgKeyInfo {
25
25
  declare type WritableFS = web3n.files.WritableFS;
26
26
  declare type SendingResources = ResourcesForSending['correspondents'];
27
27
  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;
28
+ export interface KeyRing {
42
29
  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'];
30
+ generateKeysToSend: SendingResources['generateKeysToSend'];
31
+ nextCrypto: SendingResources['nextCrypto'];
32
+ decrypt: ReceptionResources['msgDecryptor'];
58
33
  close(): Promise<void>;
59
34
  }
35
+ export declare function makeAndKeyRing(cryptor: AsyncSBoxCryptor, fs: WritableFS, publishedKeys: ConfigOfASMailServer['publishedKeys']): Promise<KeyRing>;
36
+ export interface KeyPairsStorage {
37
+ pairIdToEmailMap: IdToEmailMap;
38
+ saveChanges: () => void;
39
+ }
@@ -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,14 @@ 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");
30
31
  var common_3 = require("./common");
31
32
  Object.defineProperty(exports, "KEY_USE", { enumerable: true, get: function () { return common_3.KEY_USE; } });
32
- class KeyRing {
33
+ function makeAndKeyRing(cryptor, fs, publishedKeys) {
34
+ return KRing.makeAndStart(cryptor, fs, publishedKeys);
35
+ }
36
+ exports.makeAndKeyRing = makeAndKeyRing;
37
+ class KRing {
33
38
  constructor(cryptor, publishedKeys) {
34
39
  this.cryptor = cryptor;
35
40
  this.publishedKeys = publishedKeys;
@@ -39,7 +44,11 @@ class KeyRing {
39
44
  this.corrKeys = new Map();
40
45
  this.pairIdToEmailMap = new id_to_email_map_1.IdToEmailMap();
41
46
  this.storage = undefined;
42
- this.needIntroKeyFor = (address) => {
47
+ this.asKeyPairsStorage = {
48
+ pairIdToEmailMap: this.pairIdToEmailMap,
49
+ saveChanges: this.saveChanges.bind(this)
50
+ };
51
+ this.needIntroKeyFor = address => {
43
52
  address = (0, canonical_address_1.toCanonicalAddress)(address);
44
53
  return !this.corrKeys.has(address);
45
54
  };
@@ -68,65 +77,14 @@ class KeyRing {
68
77
  const suggestPair = await ck.suggestPair();
69
78
  return suggestPair;
70
79
  };
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
80
  Object.seal(this);
122
81
  }
123
82
  addCorrespondent(address, serialForm) {
124
83
  const ck = (serialForm ?
125
- new correspondent_keys_1.CorrespondentKeys(this, undefined, serialForm) :
126
- new correspondent_keys_1.CorrespondentKeys(this, address));
84
+ new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, undefined, serialForm) :
85
+ new correspondent_keys_1.CorrespondentKeys(this.asKeyPairsStorage, address));
127
86
  if (this.corrKeys.has(ck.correspondent)) {
128
- throw new Error("Correspondent with address " + ck.correspondent +
129
- " is already present.");
87
+ throw new Error(`Correspondent with address ${ck.correspondent} is already present.`);
130
88
  }
131
89
  this.corrKeys.set(ck.correspondent, ck);
132
90
  if (serialForm) {
@@ -135,9 +93,7 @@ class KeyRing {
135
93
  return ck;
136
94
  }
137
95
  async init(fs) {
138
- if (this.storage) {
139
- throw new Error("Keyring has already been initialized.");
140
- }
96
+ (0, assert_1.assert)(!this.storage);
141
97
  this.storage = (0, keyring_storage_1.makeKeyringStorage)(fs);
142
98
  await this.storage.start();
143
99
  const serialForm = await this.storage.load();
@@ -155,9 +111,15 @@ class KeyRing {
155
111
  }
156
112
  }
157
113
  static async makeAndStart(cryptor, fs, publishedKeys) {
158
- const kr = new KeyRing(cryptor, publishedKeys);
114
+ const kr = new KRing(cryptor, publishedKeys);
159
115
  await kr.init(fs);
160
- return kr;
116
+ return {
117
+ close: kr.close.bind(kr),
118
+ decrypt: kr.decrypt.bind(kr),
119
+ generateKeysToSend: kr.generateKeysToSend.bind(kr),
120
+ needIntroKeyFor: kr.needIntroKeyFor.bind(kr),
121
+ nextCrypto: kr.nextCrypto.bind(kr)
122
+ };
161
123
  }
162
124
  saveChanges() {
163
125
  // pack bytes that need to be encrypted and saved
@@ -253,9 +215,10 @@ class KeyRing {
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
  }
@@ -0,0 +1,43 @@
1
+ import { user as mid } from '../../lib-common/mid-sigs-NaCl-Ed';
2
+ import { JsonKey } from '../../lib-common/jwkeys';
3
+ import { GenerateKey } from '../sign-in';
4
+ import { LogError, LogWarning } from '../../lib-client/logging/log-to-file';
5
+ import { NetClient } from '../../lib-client/request-utils';
6
+ import { ServiceLocator } from '../../lib-client/service-locator';
7
+ declare type WritableFS = web3n.files.WritableFS;
8
+ /**
9
+ * This function completes provisioning process, returning a promise, resolvable
10
+ * to either true, when all is done, or to false, when challenge reply is not
11
+ * accepted by the server.
12
+ */
13
+ export interface CompleteProvisioning {
14
+ keyParams: any;
15
+ complete(defaultSKey: Uint8Array): Promise<boolean>;
16
+ }
17
+ /**
18
+ * This returns a promise, resolvable to mailerId signer.
19
+ */
20
+ export declare type GetSigner = () => Promise<mid.MailerIdSigner>;
21
+ export declare type SetupManagerStorage = (fs: WritableFS, keysToSave?: JsonKey[]) => Promise<void>;
22
+ export declare class IdManager {
23
+ private readonly store;
24
+ private readonly makeNet;
25
+ private readonly midServiceFor;
26
+ private address;
27
+ private signer;
28
+ private provisioningProc;
29
+ private constructor();
30
+ static initWithoutStore(address: string, resolver: ServiceLocator, makeNet: () => NetClient, logError: LogError, logWarning: LogWarning): Promise<((midLoginKey: GenerateKey | Uint8Array) => Promise<{
31
+ idManager: IdManager;
32
+ setupManagerStorage: SetupManagerStorage;
33
+ } | undefined>) | undefined>;
34
+ static initFromCachedStore(address: string, fs: WritableFS, resolver: ServiceLocator, makeNet: () => NetClient, logError: LogError, logWarning: LogWarning): Promise<IdManager | undefined>;
35
+ private startProvisionWithoutSavedKey;
36
+ private provisionUsingSavedKey;
37
+ getId(): string;
38
+ getSigner: GetSigner;
39
+ isProvisionedAndValid(): boolean;
40
+ makeMailerIdCAP(): Service;
41
+ }
42
+ declare type Service = web3n.mailerid.Service;
43
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2018, 2020 - 2021 3NSoft Inc.
3
+ Copyright (C) 2015 - 2018, 2020 - 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
@@ -18,24 +18,21 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.IdManager = void 0;
20
20
  const ecma_nacl_1 = require("ecma-nacl");
21
- const provisioner_1 = require("../lib-client/mailer-id/provisioner");
22
- const jwkeys_1 = require("../lib-common/jwkeys");
23
- const synced_1 = require("../lib-common/processes/synced");
24
- const login_1 = require("../lib-client/mailer-id/login");
21
+ const provisioner_1 = require("../../lib-client/mailer-id/provisioner");
22
+ const jwkeys_1 = require("../../lib-common/jwkeys");
23
+ const synced_1 = require("../../lib-common/processes/synced");
24
+ const login_1 = require("../../lib-client/mailer-id/login");
25
+ const key_storage_1 = require("./key-storage");
25
26
  const CERTIFICATE_DURATION_SECONDS = 16 * 60 * 60;
26
27
  const ASSERTION_VALIDITY = 15 * 60;
27
28
  const MIN_SECS_LEFT_ASSUMED_OK = 10 * 60;
28
- const LOGIN_KEY_FILE_NAME = 'login-keys';
29
29
  class IdManager {
30
- constructor(makeNet, midServiceFor, logError, logWarning, address, localFS) {
30
+ constructor(store, makeNet, midServiceFor, address) {
31
+ this.store = store;
31
32
  this.makeNet = makeNet;
32
33
  this.midServiceFor = midServiceFor;
33
- this.logError = logError;
34
- this.logWarning = logWarning;
35
34
  this.address = address;
36
35
  this.signer = undefined;
37
- this.localFS = undefined;
38
- this.syncedFS = undefined;
39
36
  this.provisioningProc = new synced_1.SingleProc();
40
37
  this.getSigner = async () => {
41
38
  if (!this.address) {
@@ -46,117 +43,46 @@ class IdManager {
46
43
  }
47
44
  return this.signer;
48
45
  };
49
- if (localFS) {
50
- this.localFS = localFS;
51
- }
52
46
  Object.seal(this);
53
47
  }
54
- static async initInOneStepWithoutStore(address, midLoginKey, resolver, makeNet, logError, logWarning) {
55
- const stepTwo = await IdManager.initWithoutStore(address, resolver, makeNet, logError, logWarning);
56
- if (!stepTwo) {
57
- throw new Error(`MailerId server doesn't recognize identity ${address}`);
58
- }
59
- return stepTwo(midLoginKey);
60
- }
61
48
  static async initWithoutStore(address, resolver, makeNet, logError, logWarning) {
62
- const idManager = new IdManager(makeNet, resolver, logError, logWarning, address);
63
- const completion = await idManager.provisionWithGivenKey(address);
64
- if (!completion) {
49
+ const { store, setupManagerStorage } = key_storage_1.IdKeysStorage.makeWithoutStorage(logError, logWarning);
50
+ const idManager = new IdManager(store, makeNet, resolver, address);
51
+ const provisioning = await idManager.startProvisionWithoutSavedKey(address);
52
+ if (!provisioning) {
65
53
  return;
66
54
  }
67
55
  return async (midLoginKey) => {
68
56
  const key = ((typeof midLoginKey === 'function') ?
69
- await midLoginKey(completion.keyParams) :
57
+ await midLoginKey(provisioning.keyParams) :
70
58
  midLoginKey);
71
- const isDone = await completion.complete(key);
59
+ const isDone = await provisioning.complete(key);
72
60
  key.fill(0);
73
- return (isDone ? idManager : undefined);
61
+ if (!isDone) {
62
+ return;
63
+ }
64
+ return {
65
+ idManager,
66
+ setupManagerStorage: (fs, keys) => setupManagerStorage(fs, (keys ? {
67
+ address: idManager.address,
68
+ keys
69
+ } : undefined))
70
+ };
74
71
  };
75
72
  }
76
- static async initFromLocalStore(address, localFS, resolver, makeNet, logError, logWarning) {
77
- const idMan = new IdManager(makeNet, resolver, logError, logWarning, address);
78
- if (localFS.type !== 'local') {
79
- throw new Error(`Expected local storage is typed as ${localFS.type}`);
80
- }
81
- idMan.localFS = localFS;
73
+ static async initFromCachedStore(address, fs, resolver, makeNet, logError, logWarning) {
74
+ const store = key_storage_1.IdKeysStorage.makeWithStorage(fs, logError, logWarning);
75
+ const idManager = new IdManager(store, makeNet, resolver, address);
82
76
  try {
83
- await idMan.provisionUsingSavedKey();
77
+ await idManager.provisionUsingSavedKey();
78
+ return idManager;
84
79
  }
85
80
  catch (err) {
86
81
  await logError(err, `Can't initialize id manager from local store`);
87
82
  return;
88
83
  }
89
- return idMan;
90
- }
91
- async ensureLocalCacheOfKeys() {
92
- if (!this.localFS || !this.syncedFS) {
93
- throw new Error(`Id manager's storages are not set.`);
94
- }
95
- const keysCached = await this.localFS.checkFilePresence(LOGIN_KEY_FILE_NAME);
96
- if (keysCached) {
97
- return;
98
- }
99
- try {
100
- const bytes = await this.syncedFS.readBytes(LOGIN_KEY_FILE_NAME);
101
- await this.localFS.writeBytes(LOGIN_KEY_FILE_NAME, bytes);
102
- bytes.fill(0);
103
- }
104
- catch (err) {
105
- await this.logError(err, `Fail to ensure local cache of MailerId login keys.`);
106
- }
107
- }
108
- async getSavedKey() {
109
- if (!this.localFS) {
110
- throw new Error(`Id manager's local storage is not set.`);
111
- }
112
- const json = await this.localFS.readJSONFile(LOGIN_KEY_FILE_NAME).catch(notFoundOrReThrow);
113
- if (json) {
114
- return json.keys[0];
115
- }
116
- if (this.syncedFS) {
117
- const json = await this.syncedFS.readJSONFile(LOGIN_KEY_FILE_NAME).catch(notFoundOrReThrow);
118
- if (json) {
119
- await this.ensureLocalCacheOfKeys();
120
- return json.keys[0];
121
- }
122
- else {
123
- await this.logWarning(`IdManager: there is no login MailerId login keys`);
124
- }
125
- }
126
- return;
127
- }
128
- async setStorages(localFS, syncedFS, keysToSave) {
129
- if (localFS) {
130
- if (localFS.type !== 'local') {
131
- throw new Error(`Expected local storage is typed as ${localFS.type}`);
132
- }
133
- this.localFS = localFS;
134
- }
135
- else {
136
- if (!this.localFS) {
137
- throw new Error(`Local storage is not given`);
138
- }
139
- }
140
- if (syncedFS.type !== 'synced') {
141
- throw new Error(`Expected synced storage is typed as ${syncedFS.type}`);
142
- }
143
- this.syncedFS = syncedFS;
144
- if (keysToSave) {
145
- const json = {
146
- address: this.address,
147
- keys: keysToSave
148
- };
149
- await this.localFS.writeJSONFile(LOGIN_KEY_FILE_NAME, json);
150
- await this.syncedFS.writeJSONFile(LOGIN_KEY_FILE_NAME, json);
151
- // XXX must add work with not-online condition
152
- await this.syncedFS.v.sync.upload(LOGIN_KEY_FILE_NAME);
153
- await this.syncedFS.v.sync.upload('');
154
- }
155
- else {
156
- await this.ensureLocalCacheOfKeys();
157
- }
158
84
  }
159
- async provisionWithGivenKey(address) {
85
+ async startProvisionWithoutSavedKey(address) {
160
86
  const midUrl = await this.midServiceFor(address);
161
87
  const provisioner = new provisioner_1.MailerIdProvisioner(address, midUrl, this.makeNet());
162
88
  try {
@@ -202,7 +128,7 @@ class IdManager {
202
128
  proc = this.provisioningProc.start(async () => {
203
129
  const midUrl = await this.midServiceFor(this.address);
204
130
  const provisioner = new provisioner_1.MailerIdProvisioner(this.address, midUrl, this.makeNet());
205
- const key = await this.getSavedKey();
131
+ const key = await this.store.getSavedKey();
206
132
  if (!key) {
207
133
  throw new Error(`No saved MailerId login key can be found`);
208
134
  }
@@ -245,15 +171,8 @@ class IdManager {
245
171
  }
246
172
  }
247
173
  exports.IdManager = IdManager;
248
- /**
249
- * This is a catch callback, which returns undefined on file(folder) not found
250
- * exception, and re-throws all other exceptions/errors.
251
- */
252
- function notFoundOrReThrow(exc) {
253
- if (!exc.notFound) {
254
- throw exc;
255
- }
256
- }
174
+ Object.freeze(IdManager.prototype);
175
+ Object.freeze(IdManager);
257
176
  async function doMidLogin(loginUrl, userId, net, signer) {
258
177
  const { sessionId, redirect } = await (0, login_1.startMidSession)(userId, net, loginUrl);
259
178
  if (!sessionId) {
@@ -0,0 +1,21 @@
1
+ import { LogError, LogWarning } from "../../lib-client/logging/log-to-file";
2
+ import { JsonKey } from "../../lib-common/jwkeys";
3
+ declare type WritableFS = web3n.files.WritableFS;
4
+ export interface LoginKeysJSON {
5
+ address: string;
6
+ keys: JsonKey[];
7
+ }
8
+ export declare class IdKeysStorage {
9
+ private readonly logError;
10
+ private readonly logWarning;
11
+ private fs;
12
+ private constructor();
13
+ static makeWithStorage(fs: WritableFS, logError: LogError, logWarning: LogWarning): IdKeysStorage;
14
+ static makeWithoutStorage(logError: LogError, logWarning: LogWarning): {
15
+ store: IdKeysStorage;
16
+ setupManagerStorage: (fs: WritableFS, keysToSave?: LoginKeysJSON) => Promise<void>;
17
+ };
18
+ getSavedKey(): Promise<JsonKey | undefined>;
19
+ private setStorageFS;
20
+ }
21
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2022 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.IdKeysStorage = void 0;
20
+ const assert_1 = require("../../lib-common/assert");
21
+ const error_1 = require("../../lib-common/exceptions/error");
22
+ const LOGIN_KEY_FILE_NAME = 'login-keys';
23
+ class IdKeysStorage {
24
+ constructor(logError, logWarning, fs) {
25
+ this.logError = logError;
26
+ this.logWarning = logWarning;
27
+ this.fs = undefined;
28
+ if (fs) {
29
+ (0, assert_1.assert)(fs.type === 'synced');
30
+ this.fs = fs;
31
+ }
32
+ Object.seal(this);
33
+ }
34
+ static makeWithStorage(fs, logError, logWarning) {
35
+ return new IdKeysStorage(logError, logWarning, fs);
36
+ }
37
+ static makeWithoutStorage(logError, logWarning) {
38
+ const store = new IdKeysStorage(logError, logWarning);
39
+ return {
40
+ store,
41
+ setupManagerStorage: (fs, keys) => store.setStorageFS(fs, keys)
42
+ };
43
+ }
44
+ async getSavedKey() {
45
+ var _a, _b;
46
+ if (!((_b = (_a = this.fs) === null || _a === void 0 ? void 0 : _a.v) === null || _b === void 0 ? void 0 : _b.sync)) {
47
+ throw new Error(`Id manager's storages are not set.`);
48
+ }
49
+ try {
50
+ const json = await this.fs.readJSONFile(LOGIN_KEY_FILE_NAME);
51
+ return json.keys[0];
52
+ }
53
+ catch (exc) {
54
+ if (!exc.notFound) {
55
+ throw exc;
56
+ }
57
+ await this.fs.v.sync.updateStatusInfo('');
58
+ await this.fs.v.sync.adoptRemote('');
59
+ if (await this.fs.checkFilePresence(LOGIN_KEY_FILE_NAME)) {
60
+ return this.getSavedKey();
61
+ }
62
+ else {
63
+ await this.logWarning(`IdManager: no saved login MailerId keys`);
64
+ return;
65
+ }
66
+ }
67
+ }
68
+ async setStorageFS(fs, keysToSave) {
69
+ (0, assert_1.assert)(!this.fs);
70
+ (0, assert_1.assert)(fs.type === 'synced');
71
+ this.fs = fs;
72
+ if (keysToSave) {
73
+ await this.fs.writeJSONFile(LOGIN_KEY_FILE_NAME, keysToSave);
74
+ // XXX must add work with not-online condition
75
+ await this.fs.v.sync.upload(LOGIN_KEY_FILE_NAME);
76
+ await this.fs.v.sync.upload('');
77
+ }
78
+ else {
79
+ try {
80
+ await this.fs.readJSONFile(LOGIN_KEY_FILE_NAME);
81
+ }
82
+ catch (exc) {
83
+ throw (0, error_1.errWithCause)(exc, `Fail expection read of login MailerId keys from the storage`);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ exports.IdKeysStorage = IdKeysStorage;
89
+ Object.freeze(IdKeysStorage.prototype);
90
+ Object.freeze(IdKeysStorage);
91
+ function notFoundOrReThrow(exc) {
92
+ if (!exc.notFound) {
93
+ throw exc;
94
+ }
95
+ }
96
+ Object.freeze(exports);