cassproject 5.0.20 → 5.0.23

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 (107) hide show
  1. package/package.json +49 -52
  2. package/src/com/eduworks/ec/array/EcArray.js +1 -1
  3. package/src/com/eduworks/ec/array/EcAsyncHelper.js +1 -1
  4. package/src/com/eduworks/ec/array/EcObject.js +1 -1
  5. package/src/com/eduworks/ec/crypto/EcAes.js +1 -1
  6. package/src/com/eduworks/ec/crypto/EcAesCtrAsync.js +20 -22
  7. package/src/com/eduworks/ec/crypto/EcCrypto.js +8 -4
  8. package/src/com/eduworks/ec/crypto/EcPk.js +7 -7
  9. package/src/com/eduworks/ec/crypto/EcPpk.js +7 -7
  10. package/src/com/eduworks/ec/crypto/EcRsaOaepAsync.js +20 -19
  11. package/src/com/eduworks/ec/crypto/EcRsaOaepAsyncWorker.js +7 -6
  12. package/src/com/eduworks/ec/crypto/forgeAsync.js +1 -9
  13. package/src/com/eduworks/ec/crypto/forgeAsyncNode.js +8 -8
  14. package/src/com/eduworks/ec/graph/EcDirectedGraph.js +1 -2
  15. package/src/com/eduworks/ec/graph/EcFrameworkGraph.js +18 -24
  16. package/src/com/eduworks/ec/promises/helpers.js +1 -3
  17. package/src/com/eduworks/ec/remote/EcRemote.js +9 -9
  18. package/src/com/eduworks/ec/task/EcAsyncTask.js +5 -20
  19. package/src/com/eduworks/ec/task/EcAsyncTaskManager.js +3 -4
  20. package/src/com/eduworks/ec/task/EcAsyncTaskWorker.js +9 -11
  21. package/src/com/eduworks/schema/cfd/competency/CfdFramework.js +36 -37
  22. package/src/com/eduworks/schema/ebac/EbacContact.js +3 -9
  23. package/src/com/eduworks/schema/ebac/EbacContactGrant.js +3 -9
  24. package/src/com/eduworks/schema/ebac/EbacCredential.js +3 -9
  25. package/src/com/eduworks/schema/ebac/EbacCredentialCommit.js +3 -9
  26. package/src/com/eduworks/schema/ebac/EbacCredentialRequest.js +3 -9
  27. package/src/com/eduworks/schema/ebac/EbacCredentials.js +3 -9
  28. package/src/com/eduworks/schema/ebac/EbacEncryptedSecret.js +3 -9
  29. package/src/com/eduworks/schema/ebac/EbacEncryptedValue.js +5 -12
  30. package/src/com/eduworks/schema/ebac/EbacSignature.js +1 -6
  31. package/src/index/env.js +6 -3
  32. package/src/index/polyfills.js +13 -27
  33. package/src/org/angles/schema/angles/VideoStory.js +1 -1
  34. package/src/org/cass/competency/EcCompetency.js +1 -2
  35. package/src/org/cass/competency/EcDirectory.js +1 -2
  36. package/src/org/cass/competency/EcFramework.js +9 -12
  37. package/src/org/cass/exporter/CSVExport.js +12 -13
  38. package/src/org/cass/importer/ASNImport.js +3 -6
  39. package/src/org/cass/importer/CSVImport.js +9 -17
  40. package/src/org/cass/importer/CTDLASNCSVConceptImport.js +25 -121
  41. package/src/org/cass/importer/CTDLASNCSVImport.js +88 -133
  42. package/src/org/cass/importer/FrameworkImport.js +16 -30
  43. package/src/org/cass/importer/MedbiqImport.js +3 -4
  44. package/src/org/cass/importer/TabStructuredImport.js +6 -6
  45. package/src/org/cass/profile/EcAssertion.js +40 -51
  46. package/src/org/cassproject/ebac/identity/EcContactGrant.js +2 -2
  47. package/src/org/cassproject/ebac/identity/EcIdentityManager.js +56 -62
  48. package/src/org/cassproject/ebac/identity/EcRekeyRequest.js +3 -2
  49. package/src/org/cassproject/ebac/identity/remote/EcRemoteIdentityManager.js +51 -62
  50. package/src/org/cassproject/ebac/identity/remote/OAuth2FileBasedRemoteIdentityManager.js +56 -70
  51. package/src/org/cassproject/ebac/identity/remote/RemoteIdentityManagerInterface.js +3 -3
  52. package/src/org/cassproject/ebac/repository/EcEncryptedValue.js +51 -44
  53. package/src/org/cassproject/ebac/repository/EcRepository.js +228 -301
  54. package/src/org/cassproject/general/repository/GeneralFile.js +8 -9
  55. package/src/org/cassproject/schema/cass/competency/Competency.js +10 -11
  56. package/src/org/cassproject/schema/cass/competency/Framework.js +10 -11
  57. package/src/org/cassproject/schema/cass/competency/Level.js +10 -11
  58. package/src/org/cassproject/schema/cass/competency/Relation.js +10 -11
  59. package/src/org/cassproject/schema/cass/competency/RollupRule.js +7 -7
  60. package/src/org/cassproject/schema/cass/profile/Assertion.js +20 -27
  61. package/src/org/cassproject/schema/cass/profile/AssertionEnvelope.js +3 -5
  62. package/src/org/cassproject/schema/general/EcRemoteLinkedData.js +41 -44
  63. package/src/org/json/ld/EcLinkedData.js +10 -12
  64. package/src/org/schema/EcOrganization.js +10 -10
  65. package/src/org/schema/EcQuestion.js +8 -8
  66. package/src/org/w3/skos/Concept.js +6 -6
  67. package/src/org/w3/skos/ConceptScheme.js +6 -6
  68. package/src/org/w3/skos/EcConcept.js +1 -2
  69. package/src/org/w3/skos/EcConceptScheme.js +1 -2
  70. package/src/test/0.start.test.js +1 -1
  71. package/src/test/0.testLibraries.test.js +172 -0
  72. package/src/test/1.ASNImport.test.js +122 -0
  73. package/src/test/1.CSVExport.test.js +57 -0
  74. package/src/test/1.CSVImport.test.js +185 -0
  75. package/src/test/1.CTDLASNCSVConceptImport.test.js +348 -0
  76. package/src/test/1.CTDLASNCSVImport.import.test.js +497 -0
  77. package/src/test/1.Ebac.schema.test.js +107 -0
  78. package/src/test/1.EcAssertion.decrypt.test.js +98 -0
  79. package/src/test/1.EcAssertion.pinned.test.js +160 -0
  80. package/src/test/1.EcCrypto.formats.test.js +293 -0
  81. package/src/test/1.EcCrypto.generateUUID.test.js +47 -0
  82. package/src/test/1.EcEncryptedValue.helpers.test.js +236 -0
  83. package/src/test/1.EcHelpers.misc.test.js +259 -0
  84. package/src/test/1.EcIdentityManager.keys.test.js +439 -0
  85. package/src/test/1.EcOrganization.rekey.test.js +68 -0
  86. package/src/test/1.EcRemote.responses.test.js +155 -0
  87. package/src/test/1.EcRemoteIdentityManager.flows.test.js +326 -0
  88. package/src/test/1.EcRemoteLinkedData.pinned.test.js +473 -0
  89. package/src/test/1.EcRepository.l0.test.js +14 -5
  90. package/src/test/1.EcRepository.l1.test.js +16 -7
  91. package/src/test/1.EcRepository.l2.test.js +20 -11
  92. package/src/test/1.EcRepository.unit.test.js +961 -0
  93. package/src/test/1.EcRsaOaep.test.js +2 -12
  94. package/src/test/1.EcRsaOaepAsync.test.js +2 -12
  95. package/src/test/1.EcRsaOaepAsyncWorker.test.js +2 -12
  96. package/src/test/1.EcRsaOaepAsyncWorker.workers.test.js +147 -0
  97. package/src/test/1.FrameworkImport.test.js +170 -0
  98. package/src/test/1.MedbiqImport.test.js +92 -0
  99. package/src/test/1.OAuth2FileBasedRemoteIdentityManager.test.js +399 -0
  100. package/src/test/1.TabStructuredImport.test.js +61 -0
  101. package/src/test/1.polyfills.test.js +89 -0
  102. package/src/test/1.schema.competency.pinned.test.js +384 -0
  103. package/src/test/3.EcFrameworkGraph.test.js +3 -2
  104. package/src/test/4.schema.test.js +33 -28
  105. package/src/test/4.skyId.test.js +4 -2
  106. package/src/test/cypressValue.js +9 -0
  107. package/src/test/2.EcCompetency.test.js +0 -17
@@ -68,9 +68,9 @@ module.exports = class TabStructuredImport {
68
68
  }
69
69
  }
70
70
  let c = null;
71
- for (let i = 0; i < competencies.length; i++) {
72
- if (competencies[i].getName().trim() == lines[index].trim()) {
73
- c = competencies[i];
71
+ for (let competency of competencies) {
72
+ if (competency.getName().trim() == lines[index].trim()) {
73
+ c = competency;
74
74
  break;
75
75
  }
76
76
  }
@@ -86,9 +86,9 @@ module.exports = class TabStructuredImport {
86
86
  }
87
87
  if (parentI != -1) {
88
88
  let parent = null;
89
- for (let i = 0; i < competencies.length; i++) {
90
- if (competencies[i].getName().trim() == lines[parentI].trim()) {
91
- parent = competencies[i];
89
+ for (let competency of competencies) {
90
+ if (competency.getName().trim() == lines[parentI].trim()) {
91
+ parent = competency;
92
92
  break;
93
93
  }
94
94
  }
@@ -19,20 +19,15 @@ module.exports = class EcAssertion extends Assertion {
19
19
  async decrypt(eim) {
20
20
  eim = eim || EcIdentityManager.default;
21
21
  let a = new Assertion().copyFrom(this);
22
- let subject = this.getSubject(eim);
23
- let agent = this.getAgent(eim);
24
- let assertionDate = this.getAssertionDate(eim);
25
- let expirationDate = this.getExpirationDate(eim);
26
- let evidences = this.getEvidences(eim);
27
- let negative = this.getNegative(eim);
28
- let decayFunction = this.getDecayFunction(eim);
29
- subject = await subject;
30
- agent = await agent;
31
- assertionDate = await assertionDate;
32
- expirationDate = await expirationDate;
33
- evidences = await evidences;
34
- negative = await negative;
35
- decayFunction = await decayFunction;
22
+ const [subject, agent, assertionDate, expirationDate, evidences, negative, decayFunction] = await Promise.all([
23
+ this.getSubject(eim),
24
+ this.getAgent(eim),
25
+ this.getAssertionDate(eim),
26
+ this.getExpirationDate(eim),
27
+ this.getEvidences(eim),
28
+ this.getNegative(eim),
29
+ this.getDecayFunction(eim)
30
+ ]);
36
31
  if (subject)
37
32
  a.setSubject(subject);
38
33
  if (agent)
@@ -95,13 +90,13 @@ module.exports = class EcAssertion extends Assertion {
95
90
  *
96
91
  * @param pk
97
92
  */
98
- async setSubject(pk) {
93
+ async setSubject(pk) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
99
94
  let owners = [];
100
95
  let readers = null;
101
96
  if (this.reader == null)
102
97
  readers = [];
103
98
  else
104
- readers = JSON.parse(JSON.stringify(this.reader));
99
+ readers = JSON.parse(JSON.stringify(this.reader)); // NOSONAR - structuredClone throws on Proxy-wrapped arrays (e.g. Vue reactive state); the JSON round trip does not.
105
100
  if (this.subject != null) {
106
101
  if (this.subject.owner != null)
107
102
  owners = owners.concat(this.subject.owner);
@@ -119,13 +114,12 @@ module.exports = class EcAssertion extends Assertion {
119
114
  }
120
115
  // @deprecated
121
116
  setSubjectAsync(pk, success, failure) {
122
- let me = this;
123
117
  let owners = [];
124
118
  let readers = null;
125
119
  if (this.reader == null)
126
120
  readers = [];
127
121
  else
128
- readers = JSON.parse(JSON.stringify(this.reader));
122
+ readers = JSON.parse(JSON.stringify(this.reader)); // NOSONAR - structuredClone throws on Proxy-wrapped arrays (e.g. Vue reactive state); the JSON round trip does not.
129
123
  if (this.subject != null) {
130
124
  if (this.subject.owner != null)
131
125
  owners = owners.concat(this.subject.owner);
@@ -139,8 +133,8 @@ module.exports = class EcAssertion extends Assertion {
139
133
  this.id,
140
134
  owners,
141
135
  readers,
142
- function (subject) {
143
- me.subject = subject;
136
+ (subject) => {
137
+ this.subject = subject;
144
138
  success();
145
139
  },
146
140
  failure
@@ -188,7 +182,7 @@ module.exports = class EcAssertion extends Assertion {
188
182
  if (decryptedString == null) return null;
189
183
  return EcPk.fromPem(decryptedString);
190
184
  }
191
- async setAgent(pk) {
185
+ async setAgent(pk) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
192
186
  this.agent = await EcEncryptedValue.encryptValue(
193
187
  pk.toPem(),
194
188
  this.id,
@@ -198,14 +192,13 @@ module.exports = class EcAssertion extends Assertion {
198
192
  }
199
193
  // @deprecated
200
194
  setAgentAsync(pk, success, failure) {
201
- let me = this;
202
195
  return EcEncryptedValue.encryptValueAsync(
203
196
  pk.toPem(),
204
197
  this.id,
205
198
  this.subject.owner,
206
199
  this.subject.reader,
207
- function (agent) {
208
- me.agent = agent;
200
+ (agent) => {
201
+ this.agent = agent;
209
202
  success();
210
203
  },
211
204
  failure
@@ -295,9 +288,9 @@ module.exports = class EcAssertion extends Assertion {
295
288
  .catch((error) => null);
296
289
  }
297
290
  if (decryptedString == null) return null;
298
- return parseInt(decryptedString);
291
+ return Number.parseInt(decryptedString);
299
292
  }
300
- async setAssertionDate(assertionDateMs) {
293
+ async setAssertionDate(assertionDateMs) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
301
294
  this.assertionDate = await EcEncryptedValue.encryptValue(
302
295
  assertionDateMs.toString(),
303
296
  this.id,
@@ -307,14 +300,13 @@ module.exports = class EcAssertion extends Assertion {
307
300
  }
308
301
  // @deprecated
309
302
  setAssertionDateAsync(assertionDateMs, success, failure) {
310
- let me = this;
311
303
  return EcEncryptedValue.encryptValueAsync(
312
304
  assertionDateMs.toString(),
313
305
  this.id,
314
306
  this.subject.owner,
315
307
  this.subject.reader,
316
- function (assertionDate) {
317
- me.assertionDate = assertionDate;
308
+ (assertionDate) => {
309
+ this.assertionDate = assertionDate;
318
310
  success();
319
311
  },
320
312
  failure
@@ -331,7 +323,7 @@ module.exports = class EcAssertion extends Assertion {
331
323
  let decrypted = function (decryptedString) {
332
324
  if (decryptedString == null)
333
325
  failure("Could not decrypt assertion date.");
334
- else success(parseInt(decryptedString));
326
+ else success(Number.parseInt(decryptedString));
335
327
  };
336
328
  let codebook = Assertion.getCodebook(this);
337
329
  if (codebook != null)
@@ -358,9 +350,9 @@ module.exports = class EcAssertion extends Assertion {
358
350
  .catch((error) => null);
359
351
  }
360
352
  if (decryptedString == null) return null;
361
- return parseInt(decryptedString);
353
+ return Number.parseInt(decryptedString);
362
354
  }
363
- async setExpirationDate(expirationDateMs) {
355
+ async setExpirationDate(expirationDateMs) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
364
356
  this.expirationDate = await EcEncryptedValue.encryptValue(
365
357
  expirationDateMs.toString(),
366
358
  this.id,
@@ -370,14 +362,13 @@ module.exports = class EcAssertion extends Assertion {
370
362
  }
371
363
  // @deprecated
372
364
  setExpirationDateAsync(expirationDateMs, success, failure) {
373
- let me = this;
374
365
  return EcEncryptedValue.encryptValueAsync(
375
366
  expirationDateMs.toString(),
376
367
  this.id,
377
368
  this.subject.owner,
378
369
  this.subject.reader,
379
- function (expirationDate) {
380
- me.expirationDate = expirationDate;
370
+ (expirationDate) => {
371
+ this.expirationDate = expirationDate;
381
372
  success();
382
373
  },
383
374
  failure
@@ -394,7 +385,7 @@ module.exports = class EcAssertion extends Assertion {
394
385
  let decrypted = function (decryptedString) {
395
386
  if (decryptedString == null)
396
387
  failure("Could not decrypt expiration date.");
397
- else success(parseInt(decryptedString));
388
+ else success(Number.parseInt(decryptedString));
398
389
  };
399
390
  let codebook = Assertion.getCodebook(this);
400
391
  if (codebook != null)
@@ -498,7 +489,7 @@ module.exports = class EcAssertion extends Assertion {
498
489
  if (decryptedString == null) return null;
499
490
  return decryptedString;
500
491
  }
501
- async setDecayFunction(decayFunctionText) {
492
+ async setDecayFunction(decayFunctionText) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
502
493
  this.decayFunction = await EcEncryptedValue.encryptValue(
503
494
  decayFunctionText.toString(),
504
495
  this.id,
@@ -508,14 +499,13 @@ module.exports = class EcAssertion extends Assertion {
508
499
  }
509
500
  // @deprecated
510
501
  setDecayFunctionAsync(decayFunctionText, success, failure) {
511
- let me = this;
512
502
  return EcEncryptedValue.encryptValueAsync(
513
503
  decayFunctionText,
514
504
  this.id,
515
505
  this.subject.owner,
516
506
  this.subject.reader,
517
- function (decayFunction) {
518
- me.decayFunction = decayFunction;
507
+ (decayFunction) => {
508
+ this.decayFunction = decayFunction;
519
509
  success();
520
510
  },
521
511
  failure
@@ -561,7 +551,7 @@ module.exports = class EcAssertion extends Assertion {
561
551
  if (decryptedString != null) decryptedString.toLowerCase();
562
552
  return "true" == decryptedString;
563
553
  }
564
- async setNegative(negativeB) {
554
+ async setNegative(negativeB) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
565
555
  this.negative = await EcEncryptedValue.encryptValue(
566
556
  negativeB.toString(),
567
557
  this.id,
@@ -571,14 +561,13 @@ module.exports = class EcAssertion extends Assertion {
571
561
  }
572
562
  // @deprecated
573
563
  setNegativeAsync(negativeB, success, failure) {
574
- let me = this;
575
564
  return EcEncryptedValue.encryptValueAsync(
576
565
  negativeB.toString(),
577
566
  this.id,
578
567
  this.subject.owner,
579
568
  this.subject.reader,
580
- function (negative) {
581
- me.negative = negative;
569
+ (negative) => {
570
+ this.negative = negative;
582
571
  success();
583
572
  },
584
573
  failure
@@ -619,12 +608,12 @@ module.exports = class EcAssertion extends Assertion {
619
608
  setConfidence(confidenceZeroToOne) {
620
609
  this.confidence = confidenceZeroToOne;
621
610
  }
622
- async setEvidence(evidences) {
611
+ async setEvidence(evidences) { // NOSONAR - Encrypts asynchronously; making Assertion's setters async would turn their errors into rejections
623
612
  let encryptedValues = [];
624
- for (let i = 0; i < evidences.length; i++)
613
+ for (let evidence of evidences)
625
614
  encryptedValues.push(
626
615
  await EcEncryptedValue.encryptValue(
627
- evidences[i],
616
+ evidence,
628
617
  this.id,
629
618
  this.subject.owner,
630
619
  this.subject.reader
@@ -690,8 +679,8 @@ module.exports = class EcAssertion extends Assertion {
690
679
  await this.decayFunction.addReader(newReader, eim);
691
680
  }
692
681
  if (this.evidence != null)
693
- for (let i = 0; i < this.evidence.length; i++) {
694
- await this.evidence[i].addReader(newReader, eim);
682
+ for (let evidence of this.evidence) {
683
+ await evidence.addReader(newReader, eim);
695
684
  }
696
685
  if (this.expirationDate != null) {
697
686
  await this.expirationDate.addReader(newReader, eim);
@@ -715,8 +704,8 @@ module.exports = class EcAssertion extends Assertion {
715
704
  await this.decayFunction.removeReader(newReader, eim);
716
705
  }
717
706
  if (this.evidence != null)
718
- for (let i = 0; i < this.evidence.length; i++) {
719
- await this.evidence[i].removeReader(newReader, eim);
707
+ for (let evidence of this.evidence) {
708
+ await evidence.removeReader(newReader, eim);
720
709
  }
721
710
  if (this.expirationDate != null) {
722
711
  await this.expirationDate.removeReader(newReader, eim);
@@ -19,10 +19,10 @@ module.exports = class EcContactGrant extends EbacContactGrant {
19
19
  if (!this.verify()) return false;
20
20
  if (this.invalid()) return false;
21
21
  let found = false;
22
- for (let i = 0; i < eim.ids.length; i++) {
22
+ for (const id of eim.ids) {
23
23
  if (
24
24
  EcRsaOaep.verify(
25
- eim.ids[i].ppk.toPk(),
25
+ id.ppk.toPk(),
26
26
  this.responseToken,
27
27
  this.responseSignature
28
28
  )
@@ -4,7 +4,7 @@ const EcPpkFacade = require("../../../../com/eduworks/ec/crypto/EcPpkFacade");
4
4
  const EcRsaOaepAsyncWorker = require("../../../../com/eduworks/ec/crypto/EcRsaOaepAsyncWorker");
5
5
  const {cassReturnAsPromise, cassPromisify} = require("../../../../com/eduworks/ec/promises/helpers");
6
6
  const EbacSignature = require("../../../../com/eduworks/schema/ebac/EbacSignature");
7
- let realCrypto = require('crypto');
7
+ let realCrypto = require('crypto'); // NOSONAR - Bare specifier on purpose: browser bundlers polyfill "crypto", but webpack rejects "node:" URIs.
8
8
 
9
9
  /**
10
10
  * Manages identities and contacts, provides hooks to respond to identity and
@@ -20,8 +20,6 @@ let realCrypto = require('crypto');
20
20
  */
21
21
  module.exports = class EcIdentityManager {
22
22
  static default = new this();
23
- constructor() {
24
- }
25
23
  eimId = EcCrypto.generateUUID();
26
24
  /**
27
25
  * The current user's owned identities (keys+displayName)
@@ -97,17 +95,16 @@ module.exports = class EcIdentityManager {
97
95
  return;
98
96
  }
99
97
  let c = JSON.parse(localStore);
100
- for (let i = 0; i < c.length; i++) {
98
+ for (const o of c) {
101
99
  let contact = new EcContact();
102
- let o = c[i];
103
100
  let props = o;
104
101
  contact.displayName = props["displayName"];
105
102
  contact.pk = EcPk.fromPem(props["pk"]);
106
103
  contact.source = props["source"];
107
104
  let cont = false;
108
- for (let j = 0; j < this.contacts.length; j++) {
105
+ for (const existing of this.contacts) {
109
106
  if (
110
- this.contacts[j].pk.toPem() ==
107
+ existing.pk.toPem() ==
111
108
  contact.pk.toPem()
112
109
  ) {
113
110
  cont = true;
@@ -128,10 +125,9 @@ module.exports = class EcIdentityManager {
128
125
  */
129
126
  saveContacts() {
130
127
  let c = [];
131
- for (let i = 0; i < this.contacts.length; i++) {
128
+ for (const contact of this.contacts) {
132
129
  let o = {};
133
130
  let props = o;
134
- let contact = this.contacts[i];
135
131
  props["displayName"] = contact.displayName;
136
132
  props["pk"] = contact.pk.toPem();
137
133
  props["source"] = contact.source;
@@ -153,17 +149,16 @@ module.exports = class EcIdentityManager {
153
149
  return;
154
150
  }
155
151
  let c = JSON.parse(localStore);
156
- for (let i = 0; i < c.length; i++) {
152
+ for (const o of c) {
157
153
  let identity = new EcIdentity();
158
- let o = c[i];
159
154
  let props = o;
160
155
  identity.displayName = props["displayName"];
161
156
  identity.ppk = EcPpk.fromPem(props["ppk"]);
162
157
  identity.source = props["source"];
163
158
  let cont = false;
164
- for (let j = 0; j < this.ids.length; j++) {
159
+ for (const existing of this.ids) {
165
160
  if (
166
- this.ids[j].ppk.toPem() == identity.ppk.toPem()
161
+ existing.ppk.toPem() == identity.ppk.toPem()
167
162
  ) {
168
163
  cont = true;
169
164
  }
@@ -183,10 +178,9 @@ module.exports = class EcIdentityManager {
183
178
  */
184
179
  saveIdentities() {
185
180
  let c = [];
186
- for (let i = 0; i < this.ids.length; i++) {
181
+ for (const identity of this.ids) {
187
182
  let o = {};
188
183
  let props = o;
189
- let identity = this.ids[i];
190
184
  props["displayName"] = identity.displayName;
191
185
  props["ppk"] = identity.ppk.toPem();
192
186
  props["source"] = identity.source;
@@ -229,8 +223,8 @@ module.exports = class EcIdentityManager {
229
223
  * @static
230
224
  */
231
225
  addIdentity(identity) {
232
- for (let i = 0; i < this.ids.length; i++) {
233
- if (this.ids[i].equals(identity)) {
226
+ for (const id of this.ids) {
227
+ if (id.equals(identity)) {
234
228
  return;
235
229
  }
236
230
  }
@@ -247,8 +241,8 @@ module.exports = class EcIdentityManager {
247
241
  * @static
248
242
  */
249
243
  addIdentityQuietly(identity) {
250
- for (let i = 0; i < this.ids.length; i++) {
251
- if (this.ids[i].equals(identity)) {
244
+ for (const id of this.ids) {
245
+ if (id.equals(identity)) {
252
246
  return;
253
247
  }
254
248
  }
@@ -264,29 +258,29 @@ module.exports = class EcIdentityManager {
264
258
  * @static
265
259
  */
266
260
  addContact(contact) {
267
- for (let i = 0; i < this.ids.length; i++) {
261
+ for (const id of this.ids) {
268
262
  if (
269
- this.ids[i].ppk
263
+ id.ppk
270
264
  .toPk()
271
265
  .toPem()
272
266
  .equals(contact.pk.toPem())
273
267
  ) {
274
- this.ids[i].displayName = contact.displayName;
275
- this.identityChanged(this.ids[i]);
268
+ id.displayName = contact.displayName;
269
+ this.identityChanged(id);
276
270
  }
277
271
  }
278
- for (let i = 0; i < this.contacts.length; i++) {
272
+ for (const existing of this.contacts) {
279
273
  if (
280
- this.contacts[i].pk
274
+ existing.pk
281
275
  .toPem()
282
276
  .equals(contact.pk.toPem())
283
277
  ) {
284
- this.contacts[i].displayName = contact.displayName;
285
- this.contactChanged(this.contacts[i]);
278
+ existing.displayName = contact.displayName;
279
+ this.contactChanged(existing);
286
280
  }
287
281
  }
288
- for (let i = 0; i < this.contacts.length; i++) {
289
- if (this.contacts[i].equals(contact)) {
282
+ for (const existing of this.contacts) {
283
+ if (existing.equals(contact)) {
290
284
  return;
291
285
  }
292
286
  }
@@ -303,27 +297,27 @@ module.exports = class EcIdentityManager {
303
297
  * @static
304
298
  */
305
299
  addContactQuietly(contact) {
306
- for (let i = 0; i < this.ids.length; i++) {
300
+ for (const id of this.ids) {
307
301
  if (
308
- this.ids[i].ppk
302
+ id.ppk
309
303
  .toPk()
310
304
  .toPem()
311
305
  .equals(contact.pk.toPem())
312
306
  ) {
313
- this.ids[i].displayName = contact.displayName;
307
+ id.displayName = contact.displayName;
314
308
  }
315
309
  }
316
- for (let i = 0; i < this.contacts.length; i++) {
310
+ for (const existing of this.contacts) {
317
311
  if (
318
- this.contacts[i].pk
312
+ existing.pk
319
313
  .toPem()
320
314
  .equals(contact.pk.toPem())
321
315
  ) {
322
- this.contacts[i].displayName = contact.displayName;
316
+ existing.displayName = contact.displayName;
323
317
  }
324
318
  }
325
- for (let i = 0; i < this.contacts.length; i++) {
326
- if (this.contacts[i].equals(contact)) {
319
+ for (const existing of this.contacts) {
320
+ if (existing.equals(contact)) {
327
321
  return;
328
322
  }
329
323
  }
@@ -356,7 +350,7 @@ module.exports = class EcIdentityManager {
356
350
  if (this.signatureSheetCaching) {
357
351
  cache = this.signatureSheetCache[server];
358
352
  if (cache != null) {
359
- if (cache[0] > new Date().getTime() + duration) {
353
+ if (cache[0] > Date.now() + duration) {
360
354
  return cassReturnAsPromise(cache[1], success, failure);
361
355
  }
362
356
  }
@@ -371,12 +365,12 @@ module.exports = class EcIdentityManager {
371
365
  );
372
366
  let p = Promise.all(promises);
373
367
  p = p.then((signatureCandidates) => {
374
- let signatures = signatureCandidates.filter(x=>x);
368
+ let signatures = signatureCandidates.filter(Boolean);
375
369
  let cache = null;
376
370
  let stringified = JSON.stringify(signatures);
377
371
  if (this.signatureSheetCaching) {
378
372
  cache = [];
379
- cache[0] = new Date().getTime() + finalDuration;
373
+ cache[0] = Date.now() + finalDuration;
380
374
  cache[1] = stringified;
381
375
  this.signatureSheetCache[server] = cache;
382
376
  }
@@ -401,7 +395,7 @@ module.exports = class EcIdentityManager {
401
395
  if (this.signatureSheetCaching) {
402
396
  cache = this.signatureSheetCache[server];
403
397
  if (cache != null) {
404
- if (cache[0] > new Date().getTime() + duration) {
398
+ if (cache[0] > Date.now() + duration) {
405
399
  return cassReturnAsPromise(cache[1], success, failure);
406
400
  }
407
401
  }
@@ -413,12 +407,12 @@ module.exports = class EcIdentityManager {
413
407
  );
414
408
  let p = Promise.all(promises);
415
409
  p = p.then((signatureCandidates) => {
416
- let signatures = signatureCandidates.filter(x=>x);
410
+ let signatures = signatureCandidates.filter(Boolean);
417
411
  let stringified = JSON.stringify(signatures);
418
412
  if (this.signatureSheetCaching) {
419
413
  let cache = null;
420
414
  cache = [];
421
- cache[0] = new Date().getTime() + finalDuration;
415
+ cache[0] = Date.now() + finalDuration;
422
416
  cache[1] = stringified;
423
417
  this.signatureSheetCache[server] = cache;
424
418
  }
@@ -440,7 +434,7 @@ module.exports = class EcIdentityManager {
440
434
  * @static
441
435
  */
442
436
  createSignature(duration, server, ppk, algorithm) {
443
- if (typeof process !== 'undefined' && process && process.env && process.env.FIPS == null && realCrypto.getFips && realCrypto.getFips() == 1)
437
+ if (typeof process !== 'undefined' && process?.env && process.env.FIPS == null && realCrypto.getFips?.() == 1)
444
438
  {
445
439
  algorithm = "SHA-256";
446
440
  }
@@ -448,7 +442,7 @@ module.exports = class EcIdentityManager {
448
442
  return null;
449
443
  }
450
444
  let s = new EbacSignature();
451
- s.expiry = new Date().getTime() + duration;
445
+ s.expiry = Date.now() + duration;
452
446
  s.server = server;
453
447
  delete s.owner;
454
448
  delete s.signature;
@@ -475,9 +469,9 @@ module.exports = class EcIdentityManager {
475
469
  */
476
470
  getPpk(fromPem) {
477
471
  let pem = fromPem.toPem();
478
- for (let i = 0; i < this.ids.length; i++) {
479
- if (pem == this.ids[i].ppk.toPk().toPem()) {
480
- return this.ids[i].ppk;
472
+ for (const id of this.ids) {
473
+ if (pem == id.ppk.toPk().toPem()) {
474
+ return id.ppk;
481
475
  }
482
476
  }
483
477
  return null;
@@ -492,9 +486,9 @@ module.exports = class EcIdentityManager {
492
486
  * @static
493
487
  */
494
488
  getContact(pk) {
495
- for (let i = 0; i < this.contacts.length; i++) {
496
- if (pk.equals(this.contacts[i].pk)) {
497
- return this.contacts[i];
489
+ for (const contact of this.contacts) {
490
+ if (pk.equals(contact.pk)) {
491
+ return contact;
498
492
  }
499
493
  }
500
494
  return null;
@@ -509,9 +503,9 @@ module.exports = class EcIdentityManager {
509
503
  * @static
510
504
  */
511
505
  getIdentity(pk) {
512
- for (let i = 0; i < this.ids.length; i++) {
513
- if (pk.equals(this.ids[i].ppk.toPk())) {
514
- return this.ids[i];
506
+ for (const id of this.ids) {
507
+ if (pk.equals(id.ppk.toPk())) {
508
+ return id;
515
509
  }
516
510
  }
517
511
  return null;
@@ -527,9 +521,9 @@ module.exports = class EcIdentityManager {
527
521
  async sign(d) {
528
522
  let promises = [];
529
523
  if (d.owner != null) {
530
- for (let i = 0; i < d.owner.length; i++) {
524
+ for (const owner of d.owner) {
531
525
  let attempt = this.getPpk(
532
- EcPk.fromPem(d.owner[i])
526
+ EcPk.fromPem(owner)
533
527
  );
534
528
  if (attempt != null) {
535
529
  promises.push(d.signWith(attempt));
@@ -537,8 +531,8 @@ module.exports = class EcIdentityManager {
537
531
  }
538
532
  }
539
533
  return Promise.all(promises).then((signatures) => {
540
- d.signatureSha256 = signatures.filter(x=>x);
541
- if (d.signatureSha256 != null && d.signatureSha256.length == 0) {
534
+ d.signatureSha256 = signatures.filter(Boolean);
535
+ if (d.signatureSha256?.length == 0) {
542
536
  delete d["signatureSha256"];
543
537
  delete d["signature"];
544
538
  }
@@ -552,12 +546,12 @@ module.exports = class EcIdentityManager {
552
546
  searchString += " OR ";
553
547
  }
554
548
  searchString +=
555
- '\\*reader:"' +
549
+ String.raw`\*reader:"` +
556
550
  this.ids[i].ppk.toPk().toPem() +
557
551
  '"';
558
552
  searchString += " OR ";
559
553
  searchString +=
560
- '\\*owner:"' +
554
+ String.raw`\*owner:"` +
561
555
  this.ids[i].ppk.toPk().toPem() +
562
556
  '"';
563
557
  }
@@ -566,8 +560,8 @@ module.exports = class EcIdentityManager {
566
560
  getMyPks() {
567
561
  let pks = [];
568
562
  if (this.ids == null) return pks;
569
- for (let i = 0; i < this.ids.length; i++)
570
- pks.push(this.ids[i].ppk.toPk());
563
+ for (const id of this.ids)
564
+ pks.push(id.ppk.toPk());
571
565
  return pks;
572
566
  }
573
567
  };
@@ -91,15 +91,16 @@ module.exports = class EcRekeyRequest extends EcRemoteLinkedData {
91
91
  */
92
92
  async verify() {
93
93
  if (!await super.verify()) return false;
94
+ //Compare to true: the browser worker resolves to an {error} object, not false, when a signature is malformed.
94
95
  return (await EcRsaOaepAsyncWorker.verifySha256(
95
96
  EcPk.fromPem(this.rekeyPk),
96
97
  this.toSignableRekeyJson(),
97
98
  this.rekeySignature
98
- ) || (await EcRsaOaepAsyncWorker.verify(
99
+ )) === true || (await EcRsaOaepAsyncWorker.verify(
99
100
  EcPk.fromPem(this.rekeyPk),
100
101
  this.toSignableRekeyJson(),
101
102
  this.rekeySignature
102
- )));
103
+ )) === true;
103
104
  }
104
105
  async addRekeyRequestToForwardingTable() {
105
106
  if (!(await this.verify())) return;