core-3nweb-client-lib 0.34.2 → 0.35.1

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 (150) hide show
  1. package/build/api-defs/asmail.d.ts +70 -5
  2. package/build/api-defs/common-caps.d.ts +3 -0
  3. package/build/api-defs/keys.d.ts +154 -0
  4. package/build/api-defs/mailerid.d.ts +8 -0
  5. package/build/api-defs/web3n.d.ts +1 -0
  6. package/build/core/asmail/asmail-cap-ipc.js +20 -1
  7. package/build/core/asmail/config.d.ts +16 -0
  8. package/build/core/asmail/config.js +54 -0
  9. package/build/core/asmail/delivery/common.d.ts +2 -2
  10. package/build/core/asmail/delivery/common.js +2 -1
  11. package/build/core/asmail/delivery/index.d.ts +2 -1
  12. package/build/core/asmail/delivery/index.js +4 -1
  13. package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
  14. package/build/core/asmail/inbox/attachments/fs.d.ts +1 -1
  15. package/build/core/asmail/inbox/attachments/fs.js +2 -2
  16. package/build/core/asmail/inbox/index.d.ts +6 -6
  17. package/build/core/asmail/inbox/index.js +1 -1
  18. package/build/core/asmail/inbox/msg-indexing/index.d.ts +1 -1
  19. package/build/core/asmail/inbox/msg-indexing/logs-n-entries.d.ts +1 -1
  20. package/build/core/asmail/index.d.ts +4 -4
  21. package/build/core/asmail/index.js +11 -22
  22. package/build/core/asmail/key-verification.d.ts +5 -4
  23. package/build/core/asmail/key-verification.js +2 -1
  24. package/build/core/asmail/msg/common.d.ts +5 -4
  25. package/build/core/asmail/msg/opener.d.ts +4 -4
  26. package/build/core/asmail/msg/opener.js +1 -1
  27. package/build/core/asmail/msg/packer.d.ts +3 -3
  28. package/build/core/asmail/msg/packer.js +2 -2
  29. package/build/core/asmail/sending-params/index.d.ts +7 -6
  30. package/build/core/asmail/sending-params/index.js +21 -12
  31. package/build/core/asmail/sending-params/invitations-anon.d.ts +35 -0
  32. package/build/core/asmail/sending-params/invitations-anon.js +164 -0
  33. package/build/core/asmail/sending-params/own-params.d.ts +10 -19
  34. package/build/core/asmail/sending-params/own-params.js +27 -20
  35. package/build/core/asmail/sending-params/params-from-others.d.ts +7 -11
  36. package/build/core/asmail/sending-params/params-from-others.js +32 -23
  37. package/build/core/id-manager/index.d.ts +1 -1
  38. package/build/core/id-manager/key-storage.d.ts +1 -1
  39. package/build/core/index.d.ts +3 -0
  40. package/build/core/index.js +39 -11
  41. package/build/core/{asmail/keyring → keyring}/common.d.ts +3 -1
  42. package/build/core/{asmail/keyring → keyring}/common.js +2 -2
  43. package/build/core/{asmail/keyring → keyring}/correspondent-keys.d.ts +5 -3
  44. package/build/core/{asmail/keyring → keyring}/correspondent-keys.js +5 -5
  45. package/build/core/keyring/index.d.ts +72 -0
  46. package/build/core/{asmail/keyring → keyring}/index.js +64 -59
  47. package/build/core/{asmail/keyring → keyring}/keyring-storage.js +1 -1
  48. package/build/core/keyring/keyrings-cap-ipc.d.ts +5 -0
  49. package/build/core/keyring/keyrings-cap-ipc.js +50 -0
  50. package/build/core/keyring/published-intro-key.d.ts +43 -0
  51. package/build/core/keyring/published-intro-key.js +197 -0
  52. package/build/core/startup/sign-up.d.ts +1 -1
  53. package/build/core/storage/common/constants.d.ts +4 -0
  54. package/build/core/storage/common/constants.js +24 -0
  55. package/build/core/storage/common/obj-info-file.js +1 -1
  56. package/build/core/storage/index.d.ts +7 -1
  57. package/build/core/storage/index.js +33 -3
  58. package/build/core/storage/local/obj-files.d.ts +1 -1
  59. package/build/core/storage/local/obj-status.d.ts +1 -1
  60. package/build/core/storage/local/obj-status.js +1 -1
  61. package/build/core/storage/local/storage.d.ts +1 -1
  62. package/build/core/storage/local/storage.js +2 -2
  63. package/build/core/storage/synced/downloader.d.ts +2 -2
  64. package/build/core/storage/synced/obj-files.d.ts +3 -3
  65. package/build/core/storage/synced/obj-files.js +1 -1
  66. package/build/core/storage/synced/obj-status.d.ts +1 -1
  67. package/build/core/storage/synced/obj-status.js +1 -1
  68. package/build/core/storage/synced/remote-events.d.ts +2 -2
  69. package/build/core/storage/synced/storage.d.ts +2 -2
  70. package/build/core/storage/synced/storage.js +5 -5
  71. package/build/core/storage/synced/upload-header-file.d.ts +1 -1
  72. package/build/core/storage/synced/upsyncer.d.ts +1 -1
  73. package/build/core/storage/synced/upsyncer.js +1 -1
  74. package/build/core-ipc/common-caps.js +5 -1
  75. package/build/lib-client/3nstorage/{service.d.ts → storage-owner.d.ts} +1 -4
  76. package/build/lib-client/3nstorage/{service.js → storage-owner.js} +21 -25
  77. package/build/lib-client/asmail/recipient.d.ts +0 -3
  78. package/build/lib-client/asmail/recipient.js +19 -17
  79. package/build/lib-client/asmail/service-config.d.ts +9 -5
  80. package/build/lib-client/asmail/service-config.js +42 -17
  81. package/build/lib-client/cryptor/cryptor-in-worker.js +1 -1
  82. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  83. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  84. package/build/lib-client/cryptor/in-proc-js.js +1 -1
  85. package/build/lib-client/cryptor/in-proc-wasm.js +1 -1
  86. package/build/lib-client/fs-utils/fs-sync-utils.js +1 -1
  87. package/build/lib-client/key-derivation.d.ts +2 -1
  88. package/build/lib-client/objs-on-disk/obj-folders.d.ts +1 -1
  89. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +1 -1
  90. package/build/lib-client/request-utils.js +4 -2
  91. package/build/lib-client/service-locator.d.ts +2 -1
  92. package/build/lib-client/user-with-mid-session.d.ts +6 -5
  93. package/build/lib-client/user-with-mid-session.js +4 -4
  94. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/attrs.js +3 -3
  95. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/common.d.ts +2 -2
  96. package/build/lib-client/{3nstorage → xsp-fs}/exceptions.d.ts +1 -1
  97. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/file-node.d.ts +1 -1
  98. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/file-node.js +4 -4
  99. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/file.d.ts +1 -1
  100. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/file.js +5 -5
  101. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/folder-node-serialization.js +3 -3
  102. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/folder-node.d.ts +1 -1
  103. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/folder-node.js +9 -9
  104. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/fs.d.ts +1 -1
  105. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/fs.js +6 -6
  106. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/link-node.d.ts +1 -1
  107. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/link-node.js +2 -2
  108. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/node-in-fs.js +6 -6
  109. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/node-persistence.js +4 -4
  110. package/build/lib-client/{3nstorage → xsp-fs}/util/file-based-json.d.ts +10 -4
  111. package/build/lib-client/{3nstorage → xsp-fs}/util/file-based-json.js +33 -15
  112. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/xsp-payload-v1.js +3 -3
  113. package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/xsp-payload-v2.js +5 -5
  114. package/build/lib-common/jwkeys.d.ts +6 -106
  115. package/build/lib-common/mid-sigs-NaCl-Ed.d.ts +4 -1
  116. package/build/lib-common/service-api/asmail/config.d.ts +9 -30
  117. package/build/lib-common/service-api/asmail/config.js +6 -2
  118. package/build/lib-common/service-api/asmail/delivery.d.ts +5 -12
  119. package/build/lib-common/service-api/asmail/delivery.js +3 -0
  120. package/build/lib-common/service-api/mailer-id/login.d.ts +3 -6
  121. package/build/lib-common/service-api/mailer-id/provisioning.d.ts +6 -7
  122. package/build/lib-common/service-api/mailer-id/provisioning.js +3 -0
  123. package/build/lib-common/user-admin-api/signup.d.ts +2 -1
  124. package/build/raw-3nweb-clients.d.ts +1 -1
  125. package/build/raw-3nweb-clients.js +2 -2
  126. package/package.json +3 -3
  127. package/build/core/asmail/config/common.d.ts +0 -24
  128. package/build/core/asmail/config/common.js +0 -87
  129. package/build/core/asmail/config/index.d.ts +0 -47
  130. package/build/core/asmail/config/index.js +0 -69
  131. package/build/core/asmail/config/invitations-anon.d.ts +0 -13
  132. package/build/core/asmail/config/invitations-anon.js +0 -99
  133. package/build/core/asmail/config/published-intro-key.d.ts +0 -17
  134. package/build/core/asmail/config/published-intro-key.js +0 -104
  135. package/build/core/asmail/keyring/index.d.ts +0 -36
  136. /package/build/core/{asmail/keyring → keyring}/id-to-email-map.d.ts +0 -0
  137. /package/build/core/{asmail/keyring → keyring}/id-to-email-map.js +0 -0
  138. /package/build/core/{asmail/keyring → keyring}/keyring-storage.d.ts +0 -0
  139. /package/build/lib-client/{cryptor-work-labels.d.ts → cryptor/cryptor-work-labels.d.ts} +0 -0
  140. /package/build/lib-client/{cryptor-work-labels.js → cryptor/cryptor-work-labels.js} +0 -0
  141. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/attrs.d.ts +0 -0
  142. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/common.js +0 -0
  143. /package/build/lib-client/{3nstorage → xsp-fs}/exceptions.js +0 -0
  144. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/folder-node-serialization.d.ts +0 -0
  145. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/node-in-fs.d.ts +0 -0
  146. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/node-persistence.d.ts +0 -0
  147. /package/build/lib-client/{3nstorage → xsp-fs}/util/for-arrays.d.ts +0 -0
  148. /package/build/lib-client/{3nstorage → xsp-fs}/util/for-arrays.js +0 -0
  149. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/xsp-payload-v1.d.ts +0 -0
  150. /package/build/lib-client/{3nstorage/xsp-fs → xsp-fs}/xsp-payload-v2.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2018, 2022 3NSoft Inc.
3
+ Copyright (C) 2015 - 2018, 2022, 2025 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,29 +16,26 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.KEY_USE = void 0;
20
- exports.makeAndKeyRing = makeAndKeyRing;
19
+ exports.Keyrings = exports.KEY_USE = void 0;
21
20
  const correspondent_keys_1 = require("./correspondent-keys");
22
21
  const id_to_email_map_1 = require("./id-to-email-map");
23
22
  const common_1 = require("./common");
24
- const async_cryptor_wrap_1 = require("../../../lib-common/async-cryptor-wrap");
23
+ const async_cryptor_wrap_1 = require("../../lib-common/async-cryptor-wrap");
25
24
  const xsp_files_1 = require("xsp-files");
26
- const random = require("../../../lib-common/random-node");
27
- const buffer_utils_1 = require("../../../lib-common/buffer-utils");
28
- const canonical_address_1 = require("../../../lib-common/canonical-address");
29
- const common_2 = require("../delivery/common");
25
+ const random = require("../../lib-common/random-node");
26
+ const buffer_utils_1 = require("../../lib-common/buffer-utils");
27
+ const canonical_address_1 = require("../../lib-common/canonical-address");
28
+ const common_2 = require("../asmail/delivery/common");
30
29
  const keyring_storage_1 = require("./keyring-storage");
31
- const assert_1 = require("../../../lib-common/assert");
32
- const cryptor_work_labels_1 = require("../../../lib-client/cryptor-work-labels");
30
+ const cryptor_work_labels_1 = require("../../lib-client/cryptor/cryptor-work-labels");
31
+ const published_intro_key_1 = require("./published-intro-key");
33
32
  var common_3 = require("./common");
34
33
  Object.defineProperty(exports, "KEY_USE", { enumerable: true, get: function () { return common_3.KEY_USE; } });
35
- function makeAndKeyRing(cryptor, fs, publishedKeys) {
36
- return KRing.makeAndStart(cryptor, fs, publishedKeys);
37
- }
38
- class KRing {
39
- constructor(cryptor, publishedKeys) {
34
+ const FILE_FOR_INTRO_KEY_ON_SERVER = 'introductory-keys/published-on-server.json';
35
+ // XXX Keyring is just a storage and crypto functionality around keys
36
+ class Keyrings {
37
+ constructor(cryptor) {
40
38
  this.cryptor = cryptor;
41
- this.publishedKeys = publishedKeys;
42
39
  /**
43
40
  * This is a map from correspondents' canonical addresses to key objects.
44
41
  */
@@ -46,39 +43,11 @@ class KRing {
46
43
  this.pairIdToEmailMap = new id_to_email_map_1.IdToEmailMap();
47
44
  this.workLabel = cryptor_work_labels_1.cryptoWorkLabels.makeRandom('asmail');
48
45
  this.storage = undefined;
46
+ this.publishedKeys = undefined;
49
47
  this.asKeyPairsStorage = {
50
48
  pairIdToEmailMap: this.pairIdToEmailMap,
51
49
  saveChanges: this.saveChanges.bind(this)
52
50
  };
53
- this.needIntroKeyFor = address => {
54
- address = (0, canonical_address_1.toCanonicalAddress)(address);
55
- return !this.corrKeys.has(address);
56
- };
57
- this.generateKeysToSend = async (address, introPKeyFromServer) => {
58
- address = (0, canonical_address_1.toCanonicalAddress)(address);
59
- let ck = this.corrKeys.get(address);
60
- if (!ck) {
61
- if (!introPKeyFromServer) {
62
- throw new Error(`There are no known keys for given address ${address} and a key from a mail server is not given either.`);
63
- }
64
- ck = this.addCorrespondent(address);
65
- }
66
- const { msgMasterKey, currentPair, msgCount } = await ck.getSendingPair(introPKeyFromServer);
67
- // prepare message encryptor
68
- const nextNonce = await random.bytes(xsp_files_1.NONCE_LENGTH);
69
- const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, this.workLabel, msgMasterKey, nextNonce);
70
- msgMasterKey.fill(0);
71
- return { encryptor, currentPair, msgCount };
72
- };
73
- this.nextCrypto = async (address) => {
74
- address = (0, canonical_address_1.toCanonicalAddress)(address);
75
- let ck = this.corrKeys.get(address);
76
- if (!ck) {
77
- throw new Error(`No correspondent keys found for ${address}`);
78
- }
79
- const suggestPair = await ck.suggestPair();
80
- return suggestPair;
81
- };
82
51
  Object.seal(this);
83
52
  }
84
53
  addCorrespondent(address, serialForm) {
@@ -94,8 +63,8 @@ class KRing {
94
63
  }
95
64
  return ck;
96
65
  }
97
- async init(fs) {
98
- (0, assert_1.assert)(!this.storage);
66
+ async init(fs, getSigner, pkeyOnServer) {
67
+ this.publishedKeys = await published_intro_key_1.PublishedIntroKey.makeAndInit(await fs.writableFile(FILE_FOR_INTRO_KEY_ON_SERVER), getSigner, pkeyOnServer);
99
68
  this.storage = (0, keyring_storage_1.makeKeyringStorage)(fs);
100
69
  await this.storage.start();
101
70
  const serialForm = await this.storage.load();
@@ -112,15 +81,13 @@ class KRing {
112
81
  this.saveChanges();
113
82
  }
114
83
  }
115
- static async makeAndStart(cryptor, fs, publishedKeys) {
116
- const kr = new KRing(cryptor, publishedKeys);
117
- await kr.init(fs);
84
+ forASMail() {
118
85
  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)
86
+ close: this.close.bind(this),
87
+ decrypt: this.decrypt.bind(this),
88
+ generateKeysToSend: this.generateKeysToSend.bind(this),
89
+ needIntroKeyFor: this.needIntroKeyFor.bind(this),
90
+ nextCrypto: this.nextCrypto.bind(this),
124
91
  };
125
92
  }
126
93
  saveChanges() {
@@ -134,6 +101,36 @@ class KRing {
134
101
  // trigger saving utility
135
102
  this.storage.save(JSON.stringify(dataToSave));
136
103
  }
104
+ needIntroKeyFor(address) {
105
+ address = (0, canonical_address_1.toCanonicalAddress)(address);
106
+ return !this.corrKeys.has(address);
107
+ }
108
+ ;
109
+ async generateKeysToSend(address, introPKeyFromServer) {
110
+ address = (0, canonical_address_1.toCanonicalAddress)(address);
111
+ let ck = this.corrKeys.get(address);
112
+ if (!ck) {
113
+ if (!introPKeyFromServer) {
114
+ throw new Error(`There are no known keys for given address ${address} and a key from a mail server is not given either.`);
115
+ }
116
+ ck = this.addCorrespondent(address);
117
+ }
118
+ const { msgMasterKey, currentPair, msgCount } = await ck.getSendingPair(introPKeyFromServer);
119
+ // prepare message encryptor
120
+ const nextNonce = await random.bytes(xsp_files_1.NONCE_LENGTH);
121
+ const encryptor = (0, async_cryptor_wrap_1.makeEncryptor)(this.cryptor, this.workLabel, msgMasterKey, nextNonce);
122
+ msgMasterKey.fill(0);
123
+ return { encryptor, currentPair, msgCount };
124
+ }
125
+ async nextCrypto(address) {
126
+ address = (0, canonical_address_1.toCanonicalAddress)(address);
127
+ let ck = this.corrKeys.get(address);
128
+ if (!ck) {
129
+ throw new Error(`No correspondent keys found for ${address}`);
130
+ }
131
+ const suggestPair = await ck.suggestPair();
132
+ return suggestPair;
133
+ }
137
134
  async decryptMsgKeyWithIntroPair(recipientKid, senderPKey, getMainObjHeader) {
138
135
  const recipKey = this.publishedKeys.find(recipientKid);
139
136
  if (!recipKey) {
@@ -315,12 +312,20 @@ class KRing {
315
312
  return { decrInfo, openedMsg };
316
313
  }
317
314
  ;
318
- close() {
319
- return this.storage.close();
315
+ async close() {
316
+ await this.publishedKeys.close();
317
+ await this.storage.close();
318
+ }
319
+ makeKeyringsCAP() {
320
+ const w = {
321
+ introKeyOnASMailServer: this.publishedKeys.makeIntroKeyCAP(),
322
+ };
323
+ return Object.freeze(w);
320
324
  }
321
325
  }
322
- Object.freeze(KRing.prototype);
323
- Object.freeze(KRing);
326
+ exports.Keyrings = Keyrings;
327
+ Object.freeze(Keyrings.prototype);
328
+ Object.freeze(Keyrings);
324
329
  function msgKeyPackLenForPair(p) {
325
330
  return (0, common_1.msgKeyPackSizeFor)(p.recipientKey.skey.alg);
326
331
  }
@@ -17,7 +17,7 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.makeKeyringStorage = makeKeyringStorage;
20
- const synced_1 = require("../../../lib-common/processes/synced");
20
+ const synced_1 = require("../../lib-common/processes/synced");
21
21
  const KEYRING_FNAME = 'keyring.json';
22
22
  function makeKeyringStorage(fs) {
23
23
  const proc = new synced_1.SingleProc();
@@ -0,0 +1,5 @@
1
+ import { Caller, ExposedObj } from "../../ipc-via-protobuf/connector";
2
+ type Keyrings = web3n.keys.Keyrings;
3
+ export declare function exposeKeyringsCAP(cap: Keyrings): ExposedObj<Keyrings>;
4
+ export declare function makeKeyringsCaller(caller: Caller, objPath: string[]): Keyrings;
5
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2025 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.exposeKeyringsCAP = exposeKeyringsCAP;
20
+ exports.makeKeyringsCaller = makeKeyringsCaller;
21
+ const caller_side_wrap_1 = require("../../core-ipc/json-ipc-wrapping/caller-side-wrap");
22
+ const service_side_wrap_1 = require("../../core-ipc/json-ipc-wrapping/service-side-wrap");
23
+ function exposeKeyringsCAP(cap) {
24
+ return {
25
+ introKeyOnASMailServer: exposeIntroKey(cap.introKeyOnASMailServer),
26
+ };
27
+ }
28
+ function exposeIntroKey(cap) {
29
+ return {
30
+ getCurrent: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'getCurrent'),
31
+ makeAndPublishNew: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'makeAndPublishNew'),
32
+ remove: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'remove'),
33
+ };
34
+ }
35
+ function callIntroKeyOnASMailServer(caller, objPath, method) {
36
+ return (0, caller_side_wrap_1.makeReqRepObjCaller)(caller, objPath, method);
37
+ }
38
+ function makeIntroKeyCaller(caller, objPath) {
39
+ return {
40
+ getCurrent: callIntroKeyOnASMailServer(caller, objPath, 'getCurrent'),
41
+ makeAndPublishNew: callIntroKeyOnASMailServer(caller, objPath, 'makeAndPublishNew'),
42
+ remove: callIntroKeyOnASMailServer(caller, objPath, 'remove'),
43
+ };
44
+ }
45
+ function makeKeyringsCaller(caller, objPath) {
46
+ return {
47
+ introKeyOnASMailServer: makeIntroKeyCaller(caller, objPath.concat('introKeyOnASMailServer')),
48
+ };
49
+ }
50
+ Object.freeze(exports);
@@ -0,0 +1,43 @@
1
+ import { ParamOnServer } from '../../lib-client/asmail/service-config';
2
+ import { GetSigner } from '../id-manager';
3
+ import { JWKeyPair, MsgKeyRole } from './common';
4
+ type WritableFile = web3n.files.WritableFile;
5
+ type IntroKeyCAP = web3n.keys.Keyrings['introKeyOnASMailServer'];
6
+ export declare class PublishedIntroKey {
7
+ private readonly getSigner;
8
+ private pkeyOnServer;
9
+ private published;
10
+ private readonly fileProc;
11
+ private periodicExpiryCheck;
12
+ private constructor();
13
+ static makeAndInit(file: WritableFile, getSigner: GetSigner, pkeyOnServer: ParamOnServer<'init-pub-key'>): Promise<PublishedIntroKey>;
14
+ private startExpiryCheckProcess;
15
+ close(): Promise<void>;
16
+ private onFileEvent;
17
+ private setFromJSON;
18
+ private toFileJSON;
19
+ private absorbRemoteChanges;
20
+ private makeNewIntroKey;
21
+ private update;
22
+ private retireCurrent;
23
+ /**
24
+ * This looks for a published key with a given key id. If it is found, an
25
+ * object is returned with following fields:
26
+ * - pair is JWK key pair;
27
+ * - role of a found key pair;
28
+ * - replacedAt field is present for a previously published key pair,
29
+ * telling, in milliseconds, when this key was superseded a newer one.
30
+ * Undefined is returned, when a key is not found.
31
+ * @param kid
32
+ * @return if key is found, object with following fields is returned:
33
+ */
34
+ find(kid: string): {
35
+ role: MsgKeyRole;
36
+ pair: JWKeyPair;
37
+ replacedAt?: number;
38
+ } | undefined;
39
+ makeIntroKeyCAP(): IntroKeyCAP;
40
+ private getCurrent;
41
+ private removeCurrent;
42
+ }
43
+ export {};
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2015 - 2018, 2025 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.PublishedIntroKey = void 0;
20
+ const file_based_json_1 = require("../../lib-client/xsp-fs/util/file-based-json");
21
+ const jwkeys_1 = require("../../lib-common/jwkeys");
22
+ const common_1 = require("./common");
23
+ const INTRO_KEY_VALIDITY = 31 * 24 * 60 * 60;
24
+ const UPDATE_BEFORE_EXPIRY = 7 * 24 * 60 * 60;
25
+ class PublishedIntroKey {
26
+ constructor(getSigner, pkeyOnServer) {
27
+ this.getSigner = getSigner;
28
+ this.pkeyOnServer = pkeyOnServer;
29
+ this.published = {
30
+ previous: []
31
+ };
32
+ this.periodicExpiryCheck = undefined;
33
+ this.fileProc = new file_based_json_1.JsonFileProc(this.onFileEvent.bind(this));
34
+ Object.seal(this);
35
+ }
36
+ static async makeAndInit(file, getSigner, pkeyOnServer) {
37
+ const pk = new PublishedIntroKey(getSigner, pkeyOnServer);
38
+ if (file.isNew) {
39
+ await pk.fileProc.start(file, () => pk.toFileJSON());
40
+ await pk.update();
41
+ }
42
+ else {
43
+ await pk.fileProc.start(file, undefined);
44
+ pk.setFromJSON((await pk.fileProc.get()).json);
45
+ await pk.absorbRemoteChanges();
46
+ pk.startExpiryCheckProcess(true);
47
+ }
48
+ return pk;
49
+ }
50
+ startExpiryCheckProcess(calledInInit = false) {
51
+ if (!calledInInit && !this.periodicExpiryCheck) {
52
+ return;
53
+ }
54
+ if (this.published.current) {
55
+ const { pkeyCert } = this.published.current.certs;
56
+ const expiryInSeconds = (0, jwkeys_1.getKeyCert)(pkeyCert).expiresAt;
57
+ const now = Math.floor(Date.now() / 1000);
58
+ if (expiryInSeconds < (now + UPDATE_BEFORE_EXPIRY)) {
59
+ this.update();
60
+ }
61
+ }
62
+ if (calledInInit) {
63
+ this.periodicExpiryCheck = setTimeout(() => this.startExpiryCheckProcess(), UPDATE_BEFORE_EXPIRY * 1000 / 20).unref();
64
+ }
65
+ }
66
+ async close() {
67
+ if (this.periodicExpiryCheck) {
68
+ clearTimeout(this.periodicExpiryCheck);
69
+ this.periodicExpiryCheck = undefined;
70
+ }
71
+ await this.fileProc.close();
72
+ }
73
+ async onFileEvent(ev) {
74
+ if (ev.src === 'local') {
75
+ return;
76
+ }
77
+ switch (ev.type) {
78
+ case 'file-change':
79
+ await this.fileProc.order.startOrChain(() => this.absorbRemoteChanges());
80
+ break;
81
+ case 'removed':
82
+ throw new Error(`Unexpected removal of file with parameter "anon-sender/invites"`);
83
+ default:
84
+ return;
85
+ }
86
+ }
87
+ setFromJSON(json) {
88
+ if (!Array.isArray(json.previous)) { // migration part
89
+ json.previous = (json.previous ? [json.previous] : []);
90
+ }
91
+ this.published = json;
92
+ }
93
+ toFileJSON() {
94
+ return this.published;
95
+ }
96
+ // private toServerParam(): PKeyCertChain|undefined {
97
+ // return this.published.current?.certs;
98
+ // }
99
+ async absorbRemoteChanges() {
100
+ // XXX
101
+ // - check for changes: what is needed here from fileProc, and what is
102
+ // generic in absorbing remote changes to refactor it into JsonFileProc
103
+ // - absorb and sync, if needed: what can be in JsonFileProc
104
+ // Code from pre-v.sync:
105
+ // const { json } = await this.fileProc.get();
106
+ // this.setFromJSON(json);
107
+ }
108
+ async makeNewIntroKey() {
109
+ const signer = await this.getSigner();
110
+ const pair = await (0, common_1.generateKeyPair)();
111
+ const certs = {
112
+ pkeyCert: signer.certifyPublicKey(pair.pkey, INTRO_KEY_VALIDITY),
113
+ userCert: signer.userCert,
114
+ provCert: signer.providerCert
115
+ };
116
+ pair.createdAt = Date.now();
117
+ return { pair, certs };
118
+ }
119
+ update() {
120
+ return this.fileProc.order.startOrChain(async () => {
121
+ const { certs, pair: keyPair } = await this.makeNewIntroKey();
122
+ await this.pkeyOnServer.setOnServer(certs);
123
+ this.retireCurrent(keyPair.createdAt);
124
+ this.published.current = { keyPair, certs };
125
+ await this.fileProc.save(this.toFileJSON(), false);
126
+ return certs;
127
+ });
128
+ }
129
+ ;
130
+ retireCurrent(retiredAt) {
131
+ if (!this.published.current) {
132
+ return;
133
+ }
134
+ const current = this.published.current;
135
+ current.keyPair.retiredAt = retiredAt;
136
+ this.published.previous.push(current.keyPair);
137
+ this.published.current = undefined;
138
+ }
139
+ /**
140
+ * This looks for a published key with a given key id. If it is found, an
141
+ * object is returned with following fields:
142
+ * - pair is JWK key pair;
143
+ * - role of a found key pair;
144
+ * - replacedAt field is present for a previously published key pair,
145
+ * telling, in milliseconds, when this key was superseded a newer one.
146
+ * Undefined is returned, when a key is not found.
147
+ * @param kid
148
+ * @return if key is found, object with following fields is returned:
149
+ */
150
+ find(kid) {
151
+ // check current key
152
+ if (this.published.current
153
+ && (this.published.current.keyPair.skey.kid === kid)) {
154
+ return {
155
+ role: 'published_intro',
156
+ pair: this.published.current.keyPair
157
+ };
158
+ }
159
+ // check previous key
160
+ const pair = this.published.previous.find(({ skey }) => (skey.kid === kid));
161
+ if (pair) {
162
+ return {
163
+ role: 'prev_published_intro',
164
+ pair,
165
+ replacedAt: pair.retiredAt
166
+ };
167
+ }
168
+ // if nothing found, explicitly return undefined
169
+ return;
170
+ }
171
+ makeIntroKeyCAP() {
172
+ const w = {
173
+ getCurrent: this.getCurrent.bind(this),
174
+ makeAndPublishNew: this.update.bind(this),
175
+ remove: this.removeCurrent.bind(this)
176
+ };
177
+ return Object.freeze(w);
178
+ }
179
+ async getCurrent() {
180
+ var _a;
181
+ const certs = (_a = this.published.current) === null || _a === void 0 ? void 0 : _a.certs;
182
+ return (certs ? certs : null);
183
+ }
184
+ async removeCurrent() {
185
+ if (!this.published.current) {
186
+ return;
187
+ }
188
+ return this.fileProc.order.startOrChain(async () => {
189
+ await this.pkeyOnServer.setOnServer(null);
190
+ this.retireCurrent(Math.floor(Date.now() / 1000));
191
+ });
192
+ }
193
+ }
194
+ exports.PublishedIntroKey = PublishedIntroKey;
195
+ Object.freeze(PublishedIntroKey.prototype);
196
+ Object.freeze(PublishedIntroKey);
197
+ Object.freeze(exports);
@@ -1,9 +1,9 @@
1
1
  import { NetClient } from '../../lib-client/request-utils';
2
- import { JsonKey } from '../../lib-common/jwkeys';
3
2
  import * as keyDeriv from '../../lib-client/key-derivation';
4
3
  import type { GetUsersOnDisk } from '../app-files';
5
4
  import { Cryptor } from '../../lib-client/cryptor/cryptor';
6
5
  import { LogError } from '../../lib-client/logging/log-to-file';
6
+ type JsonKey = web3n.keys.JsonKey;
7
7
  export interface ScryptGenParams {
8
8
  logN: number;
9
9
  r: number;
@@ -0,0 +1,4 @@
1
+ export declare const CORE_APPS_PREFIX = "computer.3nweb.core";
2
+ export declare const ASMAIL_APP_NAME = "computer.3nweb.core.asmail";
3
+ export declare const KEYRINGS_APP_NAME = "computer.3nweb.core.keyrings";
4
+ export declare const MAILERID_APP_NAME = "computer.3nweb.core.mailerid";
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2025 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.MAILERID_APP_NAME = exports.KEYRINGS_APP_NAME = exports.ASMAIL_APP_NAME = exports.CORE_APPS_PREFIX = void 0;
20
+ exports.CORE_APPS_PREFIX = 'computer.3nweb.core';
21
+ exports.ASMAIL_APP_NAME = `${exports.CORE_APPS_PREFIX}.asmail`;
22
+ exports.KEYRINGS_APP_NAME = `${exports.CORE_APPS_PREFIX}.keyrings`;
23
+ exports.MAILERID_APP_NAME = `${exports.CORE_APPS_PREFIX}.mailerid`;
24
+ Object.freeze(exports);
@@ -30,7 +30,7 @@ exports.addArchived = addArchived;
30
30
  exports.isEmptyVersions = isEmptyVersions;
31
31
  const fs = require("../../../lib-common/async-fs-node");
32
32
  const path_1 = require("path");
33
- const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
33
+ const exceptions_1 = require("../../../lib-client/xsp-fs/exceptions");
34
34
  async function readJSONInfoFileIn(objFolder, fileName) {
35
35
  try {
36
36
  const infoJSONStr = await fs.readFile((0, path_1.join)(objFolder, fileName), { encoding: 'utf8' }).catch((exc) => {
@@ -1,6 +1,6 @@
1
1
  import { GetSigner } from '../id-manager';
2
2
  import { GenerateKey } from '../startup/sign-in';
3
- import { StorageGetter } from '../../lib-client/3nstorage/xsp-fs/common';
3
+ import { StorageGetter } from '../../lib-client/xsp-fs/common';
4
4
  import { ServiceLocator } from '../../lib-client/service-locator';
5
5
  import { ScryptGenParams } from '../../lib-client/key-derivation';
6
6
  import { AsyncSBoxCryptor } from 'xsp-files';
@@ -40,6 +40,12 @@ export declare class Storages implements FactoryOfFSs {
40
40
  getSysFSs(type: StorageType): Promise<FSItem>;
41
41
  close(): Promise<void>;
42
42
  wrap(): FactoryOfFSs;
43
+ /**
44
+ * This is a migration used for developing/evolving core's apps.
45
+ * @param src is a path starting with core app folder name
46
+ * @param dst is a path starting with core app folder name
47
+ */
48
+ migrateCoreAppDataOnFirstRun(type: StorageType, src: string, dst: string): Promise<void>;
43
49
  }
44
50
  export interface FactoryOfFSs {
45
51
  makeSyncedFSForApp(appFolder: string): Promise<WritableFS>;
@@ -18,7 +18,7 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.PerAppStorage = exports.Storages = void 0;
20
20
  exports.reverseDomain = reverseDomain;
21
- const fs_1 = require("../../lib-client/3nstorage/xsp-fs/fs");
21
+ const fs_1 = require("../../lib-client/xsp-fs/fs");
22
22
  const storage_1 = require("./synced/storage");
23
23
  const storage_2 = require("./local/storage");
24
24
  const file_1 = require("../../lib-common/exceptions/file");
@@ -29,6 +29,8 @@ const fs = require("../../lib-common/async-fs-node");
29
29
  const error_1 = require("../../lib-common/exceptions/error");
30
30
  const system_folders_1 = require("./system-folders");
31
31
  const apps_data_1 = require("./system-folders/apps-data");
32
+ const constants_1 = require("./common/constants");
33
+ const assert_1 = require("../../lib-common/assert");
32
34
  function makeBadAppNameExc(appName) {
33
35
  return {
34
36
  runtimeException: true,
@@ -65,7 +67,6 @@ function makeNotAllowedToOpenSysFSExc(storageType) {
65
67
  storageType
66
68
  };
67
69
  }
68
- const CORE_APPS_PREFIX = 'computer.3nweb.core';
69
70
  const KD_PARAMS_FILE_NAME = 'kd-params';
70
71
  const LOCAL_STORAGE_DIR = 'local';
71
72
  const SYNCED_STORAGE_DIR = 'synced';
@@ -179,6 +180,22 @@ class StorageAndFS {
179
180
  this.rootFS = undefined;
180
181
  this.storage = undefined;
181
182
  }
183
+ /**
184
+ * Moves src to dst if dst doesn't exist.
185
+ * @param src is a path starting with core app folder name
186
+ * @param dst is a path starting with core app folder name
187
+ */
188
+ async migrateCoreAppDataOnFirstRun(src, dst) {
189
+ (0, assert_1.assert)(src.startsWith(constants_1.CORE_APPS_PREFIX) && !src.includes('..') &&
190
+ dst.startsWith(constants_1.CORE_APPS_PREFIX) && !dst.includes('..'), `Invalid core app data migration paths`);
191
+ if (!(await this.rootFS.checkFolderPresence(src))
192
+ || !(await this.rootFS.checkFilePresence(src))
193
+ || (await this.rootFS.checkFolderPresence(dst))
194
+ || (await this.rootFS.checkFilePresence(dst))) {
195
+ return;
196
+ }
197
+ await this.rootFS.move(`${system_folders_1.sysFolders.appData}/${src}`, `${system_folders_1.sysFolders.appData}/${dst}`);
198
+ }
182
199
  }
183
200
  Object.freeze(StorageAndFS.prototype);
184
201
  Object.freeze(StorageAndFS);
@@ -356,6 +373,19 @@ class Storages {
356
373
  makeSyncedFSForApp: this.makeSyncedFSForApp.bind(this)
357
374
  };
358
375
  }
376
+ /**
377
+ * This is a migration used for developing/evolving core's apps.
378
+ * @param src is a path starting with core app folder name
379
+ * @param dst is a path starting with core app folder name
380
+ */
381
+ async migrateCoreAppDataOnFirstRun(type, src, dst) {
382
+ if (type === 'synced') {
383
+ await this.synced.migrateCoreAppDataOnFirstRun(src, dst);
384
+ }
385
+ else if (type === 'local') {
386
+ await this.local.migrateCoreAppDataOnFirstRun(src, dst);
387
+ }
388
+ }
359
389
  }
360
390
  exports.Storages = Storages;
361
391
  Object.freeze(Storages.prototype);
@@ -416,7 +446,7 @@ class PerAppStorage {
416
446
  if (typeof appFolder !== 'string') {
417
447
  throw makeBadAppNameExc(appFolder);
418
448
  }
419
- if (appFolder.startsWith(CORE_APPS_PREFIX)) {
449
+ if (appFolder.startsWith(constants_1.CORE_APPS_PREFIX)) {
420
450
  throw makeNotAllowedToOpenAppFSExc(appFolder);
421
451
  }
422
452
  if (!this.policy.canOpenAppFS(appFolder, type)) {
@@ -1,4 +1,4 @@
1
- import { LocalObjStatus, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
1
+ import { LocalObjStatus, ObjId } from '../../../lib-client/xsp-fs/common';
2
2
  import { ObjSource, Subscribe } from 'xsp-files';
3
3
  import { GC } from './obj-files-gc';
4
4
  import { ObjStatus } from './obj-status';
@@ -1,4 +1,4 @@
1
- import { LocalObjStatus, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
1
+ import { LocalObjStatus, ObjId } from '../../../lib-client/xsp-fs/common';
2
2
  import { VersionsInfo } from '../common/obj-info-file';
3
3
  import { LogError } from '../../../lib-client/logging/log-to-file';
4
4
  export interface ObjStatusInfo {
@@ -18,7 +18,7 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.ObjStatus = void 0;
20
20
  const path_1 = require("path");
21
- const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
21
+ const exceptions_1 = require("../../../lib-client/xsp-fs/exceptions");
22
22
  const obj_info_file_1 = require("../common/obj-info-file");
23
23
  const json_saving_1 = require("../common/json-saving");
24
24
  const obj_info_file_2 = require("../common/obj-info-file");