core-3nweb-client-lib 0.38.0 → 0.39.0

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.
@@ -301,22 +301,6 @@ declare namespace web3n.asmail {
301
301
  msgIsBroken?: true;
302
302
  }
303
303
 
304
- interface ServLocException extends RuntimeException {
305
- type: 'service-locating';
306
- address: string;
307
-
308
- /**
309
- * domainNotFound flag indicates that domain in the address doesn't exist.
310
- */
311
- domainNotFound?: true;
312
-
313
- /**
314
- * noServiceRecord flag indicates that 3NWeb services are not set at
315
- * domain in the address.
316
- */
317
- noServiceRecord?: true;
318
- }
319
-
320
304
  interface ASMailSendException extends RuntimeException {
321
305
  type: 'asmail-delivery';
322
306
  address?: string;
@@ -167,12 +167,14 @@ declare namespace web3n.keys {
167
167
  interface IntroductorySendingPairInfo {
168
168
  type: 'intro';
169
169
  recipientKId: string;
170
+ alg: string;
170
171
  }
171
172
 
172
173
  interface RatchetedSendingPairInfo {
173
174
  type: 'ratcheted';
174
175
  pids: string[];
175
176
  timestamp: number;
177
+ alg: string;
176
178
  senderKId: string;
177
179
  recipientKId: string;
178
180
  sentMsgs?: {
@@ -183,6 +185,7 @@ declare namespace web3n.keys {
183
185
 
184
186
  interface ReceptionPairInfo {
185
187
  pids: string[];
188
+ alg: string;
186
189
  recipientKId: string;
187
190
  isSenderIntroKey?: boolean,
188
191
  senderKId: string;
@@ -25,7 +25,7 @@
25
25
 
26
26
 
27
27
  declare namespace web3n {
28
-
28
+
29
29
  interface RuntimeException {
30
30
  runtimeException: true;
31
31
  type?: string;
@@ -33,21 +33,47 @@ declare namespace web3n {
33
33
  message?: string;
34
34
  }
35
35
 
36
+ interface ConnectException extends RuntimeException {
37
+ type: 'connect';
38
+ connectType: string;
39
+ }
40
+
36
41
  interface HTTPErrorDetails extends web3n.RuntimeException {
37
42
  url: string;
38
43
  method: string;
39
- message?: string;
40
44
  }
41
-
42
- interface ConnectException extends HTTPErrorDetails {
43
- type: 'http-connect';
45
+
46
+ interface HTTPConnectException extends ConnectException {
47
+ connectType: 'http';
48
+ url?: string;
49
+ method?: string;
50
+ }
51
+
52
+ interface DNSConnectException extends ConnectException {
53
+ connectType: 'dns';
44
54
  }
45
-
55
+
46
56
  interface HTTPException extends HTTPErrorDetails {
47
57
  type: 'http-request';
48
58
  status: number;
49
59
  }
50
-
60
+
61
+ interface ServLocException extends RuntimeException {
62
+ type: 'service-locating';
63
+ address: string;
64
+
65
+ /**
66
+ * domainNotFound flag indicates that domain in the address doesn't exist.
67
+ */
68
+ domainNotFound?: true;
69
+
70
+ /**
71
+ * noServiceRecord flag indicates that 3NWeb services are not set at
72
+ * domain in the address.
73
+ */
74
+ noServiceRecord?: true;
75
+ }
76
+
51
77
  interface EncryptionException {
52
78
  failedCipherVerification?: true;
53
79
  failedSignatureVerification?: true;
@@ -214,7 +214,7 @@ class InboxOnServer {
214
214
  msgIds = await this.msgReceiver.listMsgs(fromTS);
215
215
  }
216
216
  catch (exc) {
217
- if (exc.type !== 'http-connect') {
217
+ if (exc.type !== 'connect') {
218
218
  throw exc;
219
219
  }
220
220
  return this.index.listMsgs(fromTS);
@@ -95,7 +95,7 @@ class AnonymousInvites {
95
95
  // synced version is read.
96
96
  const infoOnServer = await this.anonInvitesOnServer.getFromServer()
97
97
  .catch((exc) => {
98
- if (exc.type === 'http-connect') {
98
+ if (exc.type === 'connect') {
99
99
  return;
100
100
  }
101
101
  else {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2018, 2020 - 2022 3NSoft Inc.
3
+ Copyright (C) 2015 - 2018, 2020 - 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
@@ -72,15 +72,7 @@ class IdManager {
72
72
  }
73
73
  static async initFromCachedStore(address, fs, resolver, makeNet, logError, logWarning) {
74
74
  const store = key_storage_1.IdKeysStorage.makeWithStorage(fs, logError, logWarning);
75
- const idManager = new IdManager(store, makeNet, resolver, address);
76
- try {
77
- await idManager.provisionUsingSavedKey();
78
- return idManager;
79
- }
80
- catch (err) {
81
- await logError(err, `Can't initialize id manager from local store`);
82
- return;
83
- }
75
+ return new IdManager(store, makeNet, resolver, address);
84
76
  }
85
77
  async startProvisionWithoutSavedKey(address) {
86
78
  const midUrl = await this.midServiceFor(address);
@@ -86,6 +86,7 @@ class Core {
86
86
  };
87
87
  };
88
88
  this.initForExistingUserWithCache = async (address, storageKey) => {
89
+ // XXX this shouldn't fail without network. All data is on the disk!
89
90
  const completeStorageInit = await this.storages.startInitFromCache(address, storageKey, this.makeNet, this.makeResolver('3nstorage'), this.logger.logError);
90
91
  if (!completeStorageInit) {
91
92
  return;
@@ -222,6 +223,7 @@ class Core {
222
223
  // XXX This should be removed, at some point, as there will be no more
223
224
  // users with very old data folders.
224
225
  await this.performDataMigrationsAtInit();
226
+ // XXX some of these starting can be done any way
225
227
  const keyringsSyncedFS = await this.storages.makeSyncedFSForApp(constants_1.KEYRINGS_APP_NAME);
226
228
  await this.keyrings.init(keyringsSyncedFS, this.idManager.getSigner, asmailServerConfig.makeParamSetterAndGetter('init-pub-key'));
227
229
  const inboxSyncedFS = await this.storages.makeSyncedFSForApp(constants_1.ASMAIL_APP_NAME);
@@ -21,23 +21,6 @@ export interface ReceptionPair {
21
21
  };
22
22
  timestamp: number;
23
23
  }
24
- /**
25
- * Sending pairs are a rotating public key cryptography key material for sending
26
- * messages.
27
- *
28
- * Let's note naming convention. Since this is a sending pair, this side of
29
- * communication is called a sender, while the other side is a recipient.
30
- */
31
- export interface BaseSendingPair {
32
- /**
33
- * This is recipients' public key, to which encryption is done.
34
- * If this is an introductory pair, this key is recipient's published intro
35
- * public key.
36
- * Else, if this is an ratcheted pair, this key comes from crypto material
37
- * that recipients suggests from time to time for further use.
38
- */
39
- recipientPKey: JsonKeyShort;
40
- }
41
24
  /**
42
25
  * Introductory pair appears when the first message is sent to a new
43
26
  * correspondent. By nature it is an introductory message that uses recipient's
@@ -48,14 +31,22 @@ export interface BaseSendingPair {
48
31
  * a flag that allows to distinguish it from ratcheted pair with a clean
49
32
  * if-statement.
50
33
  */
51
- export interface IntroductorySendingPair extends BaseSendingPair {
34
+ export interface IntroductorySendingPair {
52
35
  type: 'intro';
36
+ /**
37
+ * This is recipients' public key, to which encryption is done.
38
+ * If this is an introductory pair, this key is recipient's published intro
39
+ * public key.
40
+ * Else, if this is an ratcheted pair, this key comes from crypto material
41
+ * that recipients suggests from time to time for further use.
42
+ */
43
+ recipientPKey: JsonKey;
53
44
  }
54
45
  /**
55
46
  * Ratcheted sending pair is a sending pair with pair ids (pids), attached to
56
47
  * it. These ids are used to identify correct key material.
57
48
  */
58
- export interface RatchetedSendingPair extends BaseSendingPair {
49
+ export interface RatchetedSendingPair {
59
50
  type: 'ratcheted';
60
51
  pids: string[];
61
52
  timestamp: number;
@@ -67,6 +58,14 @@ export interface RatchetedSendingPair extends BaseSendingPair {
67
58
  * and is moved to the sending pair when it is used by the other side.
68
59
  */
69
60
  senderKey: JWKeyPair;
61
+ /**
62
+ * This is recipients' public key, to which encryption is done.
63
+ * If this is an introductory pair, this key is recipient's published intro
64
+ * public key.
65
+ * Else, if this is an ratcheted pair, this key comes from crypto material
66
+ * that recipients suggests from time to time for further use.
67
+ */
68
+ recipientPKey: JsonKeyShort;
70
69
  /**
71
70
  * This is a precomputed message master key that comes from a given pair.
72
71
  * This exist only as a speedup measure, to save time of public key crypto
@@ -370,6 +370,7 @@ function turnSendingPairToInfo(sp) {
370
370
  type: 'ratcheted',
371
371
  recipientKId: sp.recipientPKey.kid,
372
372
  senderKId: sp.senderKey.pkey.kid,
373
+ alg: sp.senderKey.pkey.alg,
373
374
  pids,
374
375
  timestamp,
375
376
  sentMsgs
@@ -378,7 +379,8 @@ function turnSendingPairToInfo(sp) {
378
379
  else if (sp.type === 'intro') {
379
380
  return {
380
381
  type: 'intro',
381
- recipientKId: sp.recipientPKey.kid
382
+ recipientKId: sp.recipientPKey.kid,
383
+ alg: sp.recipientPKey.alg
382
384
  };
383
385
  }
384
386
  else {
@@ -389,6 +391,7 @@ function turnReceptionPairToInfo(rp) {
389
391
  const { pids, timestamp, receivedMsgs, isSenderIntroKey } = rp;
390
392
  return {
391
393
  pids, timestamp, receivedMsgs, isSenderIntroKey,
394
+ alg: rp.recipientKey.pkey.alg,
392
395
  recipientKId: rp.recipientKey.pkey.kid,
393
396
  senderKId: rp.senderPKey.kid
394
397
  };
@@ -95,7 +95,7 @@ class ServerEvents {
95
95
  if (!exc.runtimeException) {
96
96
  return false;
97
97
  }
98
- if (exc.type === 'http-connect') {
98
+ if (exc.type === 'connect') {
99
99
  return true;
100
100
  }
101
101
  else if (exc.type === 'http-request') {
@@ -24,6 +24,7 @@ exports.getMailerIdInfoFor = getMailerIdInfoFor;
24
24
  const jwkeys_1 = require("../lib-common/jwkeys");
25
25
  const url_1 = require("url");
26
26
  const request_utils_1 = require("./request-utils");
27
+ const runtime_1 = require("../lib-common/exceptions/runtime");
27
28
  async function readJSONLocatedAt(client, url) {
28
29
  if ((0, url_1.parse)(url).protocol !== 'https:') {
29
30
  throw new Error("Url protocol must be https.");
@@ -143,23 +144,17 @@ function checkAndPrepareURL(value) {
143
144
  return 'https://' + value;
144
145
  }
145
146
  function domainNotFoundExc(address, cause) {
146
- const exc = {
147
- runtimeException: true,
148
- type: 'service-locating',
149
- address,
150
- domainNotFound: true,
151
- cause
152
- };
153
- return exc;
147
+ return (0, runtime_1.makeRuntimeException)('service-locating', { address, cause }, { domainNotFound: true });
154
148
  }
155
149
  function noServiceRecordExc(address) {
156
- const exc = {
157
- runtimeException: true,
158
- type: 'service-locating',
159
- address,
160
- noServiceRecord: true
161
- };
162
- return exc;
150
+ return (0, runtime_1.makeRuntimeException)('service-locating', { address }, { noServiceRecord: true });
151
+ }
152
+ function noConnectionExc(cause) {
153
+ return (0, runtime_1.makeRuntimeException)('connect', {
154
+ connectType: 'dns',
155
+ message: `The most likely cause of this error is device not connected. Next likely cause is DNS not setup, or not connecting properly. Like the saying goes: "It's not DNS. There is no way it's DNS. It was DNS."`,
156
+ cause
157
+ }, {});
163
158
  }
164
159
  /**
165
160
  * This implementation extracts exactly one string value for a given service.
@@ -227,7 +222,8 @@ function getRecordAtStartOf(txt) {
227
222
  }
228
223
  const DNS_ERR_CODE = {
229
224
  NODATA: 'ENODATA',
230
- NOTFOUND: 'ENOTFOUND'
225
+ NOTFOUND: 'ENOTFOUND',
226
+ ESERVFAIL: 'ESERVFAIL'
231
227
  };
232
228
  Object.freeze(DNS_ERR_CODE);
233
229
  function makeServiceLocator(resolver) {
@@ -247,6 +243,9 @@ function makeServiceLocator(resolver) {
247
243
  if (code === DNS_ERR_CODE.NODATA) {
248
244
  throw noServiceRecordExc(address);
249
245
  }
246
+ else if (code === DNS_ERR_CODE.ESERVFAIL) {
247
+ throw noConnectionExc({ code, hostname, message });
248
+ }
250
249
  else if (hostname) {
251
250
  throw domainNotFoundExc(address, { code, hostname, message });
252
251
  }
@@ -1,4 +1,4 @@
1
- export type ConnectException = web3n.ConnectException;
1
+ export type ConnectException = web3n.HTTPConnectException;
2
2
  export type HTTPException = web3n.HTTPException;
3
- export declare function makeConnectionException(url: string | undefined, method: string | undefined, msg?: string, cause?: any): ConnectException;
4
- export declare function makeHTTPException(url: string, method: string, status: number, msg?: string, cause?: any): HTTPException;
3
+ export declare function makeConnectionException(url: string | undefined, method: string | undefined, message?: string, cause?: any): ConnectException;
4
+ export declare function makeHTTPException(url: string, method: string, status: number, message?: string, cause?: any): HTTPException;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 3NSoft Inc.
3
+ Copyright (C) 2015, 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
@@ -17,31 +17,11 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.makeConnectionException = makeConnectionException;
19
19
  exports.makeHTTPException = makeHTTPException;
20
- function makeConnectionException(url, method, msg, cause) {
21
- const exc = {
22
- runtimeException: true,
23
- type: 'http-connect',
24
- url: url,
25
- method: method,
26
- cause
27
- };
28
- if (msg) {
29
- exc.message = msg;
30
- }
31
- return exc;
20
+ const runtime_1 = require("./runtime");
21
+ function makeConnectionException(url, method, message, cause) {
22
+ return (0, runtime_1.makeRuntimeException)('connect', { connectType: 'http', url, method, cause, message }, {});
32
23
  }
33
- function makeHTTPException(url, method, status, msg, cause) {
34
- const exc = {
35
- runtimeException: true,
36
- type: 'http-request',
37
- url: url,
38
- method: method,
39
- status: status,
40
- cause
41
- };
42
- if (msg) {
43
- exc.message = msg;
44
- }
45
- return exc;
24
+ function makeHTTPException(url, method, status, message, cause) {
25
+ return (0, runtime_1.makeRuntimeException)('http-request', { url, method, status, cause, message }, {});
46
26
  }
47
27
  Object.freeze(exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-3nweb-client-lib",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "description": "3NWeb client core library, embeddable into different environments",
5
5
  "main": "build/lib-index.js",
6
6
  "types": "build/lib-index.d.ts",