@fgv/ts-web-extras 5.1.0-17 → 5.1.0-18
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.
- package/.rush/temp/{edc66e6a37414a0b69e52d768684c18c9d5825e3.tar.log → 680645452ebdb4d7f294f08d3b45f143d69c3f5d.tar.log} +2 -2
- package/.rush/temp/chunked-rush-logs/ts-web-extras.build.chunks.jsonl +12 -12
- package/.rush/temp/operation/build/all.log +12 -12
- package/.rush/temp/operation/build/log-chunks.jsonl +12 -12
- package/.rush/temp/operation/build/state.json +1 -1
- package/dist/packlets/crypto-utils/browserCryptoProvider.js +58 -17
- package/dist/packlets/crypto-utils/browserCryptoProvider.js.map +1 -1
- package/dist/ts-web-extras.d.ts +27 -6
- package/docs/CryptoUtils/classes/BrowserCryptoProvider.exportPublicKeyJwk.md +24 -0
- package/docs/CryptoUtils/classes/BrowserCryptoProvider.generateKeyPair.md +25 -0
- package/docs/CryptoUtils/classes/BrowserCryptoProvider.importPublicKeyJwk.md +25 -0
- package/docs/CryptoUtils/classes/BrowserCryptoProvider.md +39 -0
- package/docs/classes/BrowserCryptoProvider.exportPublicKeyJwk.md +24 -0
- package/docs/classes/BrowserCryptoProvider.generateKeyPair.md +25 -0
- package/docs/classes/BrowserCryptoProvider.importPublicKeyJwk.md +25 -0
- package/docs/classes/BrowserCryptoProvider.md +39 -0
- package/etc/ts-web-extras.api.md +5 -5
- package/lib/packlets/crypto-utils/browserCryptoProvider.d.ts +27 -5
- package/lib/packlets/crypto-utils/browserCryptoProvider.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/browserCryptoProvider.js +57 -16
- package/lib/packlets/crypto-utils/browserCryptoProvider.js.map +1 -1
- package/package.json +10 -10
- package/rush-logs/ts-web-extras.build.cache.log +1 -1
- package/rush-logs/ts-web-extras.build.log +12 -12
- package/src/packlets/crypto-utils/browserCryptoProvider.ts +76 -22
- package/temp/build/typescript/ts_8nwakTlr.json +1 -1
- package/temp/coverage/crypto-utils/browserCryptoProvider.ts.html +189 -27
- package/temp/coverage/crypto-utils/browserHashProvider.ts.html +1 -1
- package/temp/coverage/crypto-utils/index.html +7 -7
- package/temp/coverage/file-tree/directoryHandleStore.ts.html +1 -1
- package/temp/coverage/file-tree/fileApiTreeAccessors.ts.html +1 -1
- package/temp/coverage/file-tree/fileSystemAccessTreeAccessors.ts.html +1 -1
- package/temp/coverage/file-tree/httpTreeAccessors.ts.html +1 -1
- package/temp/coverage/file-tree/index.html +1 -1
- package/temp/coverage/file-tree/localStorageTreeAccessors.ts.html +1 -1
- package/temp/coverage/helpers/fileTreeHelpers.ts.html +1 -1
- package/temp/coverage/helpers/index.html +1 -1
- package/temp/coverage/index.html +7 -7
- package/temp/coverage/lcov-report/crypto-utils/browserCryptoProvider.ts.html +189 -27
- package/temp/coverage/lcov-report/crypto-utils/browserHashProvider.ts.html +1 -1
- package/temp/coverage/lcov-report/crypto-utils/index.html +7 -7
- package/temp/coverage/lcov-report/file-tree/directoryHandleStore.ts.html +1 -1
- package/temp/coverage/lcov-report/file-tree/fileApiTreeAccessors.ts.html +1 -1
- package/temp/coverage/lcov-report/file-tree/fileSystemAccessTreeAccessors.ts.html +1 -1
- package/temp/coverage/lcov-report/file-tree/httpTreeAccessors.ts.html +1 -1
- package/temp/coverage/lcov-report/file-tree/index.html +1 -1
- package/temp/coverage/lcov-report/file-tree/localStorageTreeAccessors.ts.html +1 -1
- package/temp/coverage/lcov-report/helpers/fileTreeHelpers.ts.html +1 -1
- package/temp/coverage/lcov-report/helpers/index.html +1 -1
- package/temp/coverage/lcov-report/index.html +7 -7
- package/temp/coverage/lcov-report/url-utils/index.html +1 -1
- package/temp/coverage/lcov-report/url-utils/urlParams.ts.html +1 -1
- package/temp/coverage/lcov.info +75 -15
- package/temp/coverage/url-utils/index.html +1 -1
- package/temp/coverage/url-utils/urlParams.ts.html +1 -1
- package/temp/test/jest/haste-map-7492f1b44480e0cdd1f220078fb3afd8-c8dd6c3430605adeb2f1cadf4f75e791-8c9336785555d572065b28c111982ba4 +0 -0
- package/temp/test/jest/perf-cache-7492f1b44480e0cdd1f220078fb3afd8-da39a3ee5e6b4b0d3255bfef95601890 +1 -1
- package/temp/ts-web-extras.api.json +253 -4
- package/temp/ts-web-extras.api.md +5 -5
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>386/386</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>14/14</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
47
|
<span class="strong">100% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>386/386</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -395,7 +395,115 @@
|
|
|
395
395
|
<a name='L330'></a><a href='#L330'>330</a>
|
|
396
396
|
<a name='L331'></a><a href='#L331'>331</a>
|
|
397
397
|
<a name='L332'></a><a href='#L332'>332</a>
|
|
398
|
-
<a name='L333'></a><a href='#L333'>333</a
|
|
398
|
+
<a name='L333'></a><a href='#L333'>333</a>
|
|
399
|
+
<a name='L334'></a><a href='#L334'>334</a>
|
|
400
|
+
<a name='L335'></a><a href='#L335'>335</a>
|
|
401
|
+
<a name='L336'></a><a href='#L336'>336</a>
|
|
402
|
+
<a name='L337'></a><a href='#L337'>337</a>
|
|
403
|
+
<a name='L338'></a><a href='#L338'>338</a>
|
|
404
|
+
<a name='L339'></a><a href='#L339'>339</a>
|
|
405
|
+
<a name='L340'></a><a href='#L340'>340</a>
|
|
406
|
+
<a name='L341'></a><a href='#L341'>341</a>
|
|
407
|
+
<a name='L342'></a><a href='#L342'>342</a>
|
|
408
|
+
<a name='L343'></a><a href='#L343'>343</a>
|
|
409
|
+
<a name='L344'></a><a href='#L344'>344</a>
|
|
410
|
+
<a name='L345'></a><a href='#L345'>345</a>
|
|
411
|
+
<a name='L346'></a><a href='#L346'>346</a>
|
|
412
|
+
<a name='L347'></a><a href='#L347'>347</a>
|
|
413
|
+
<a name='L348'></a><a href='#L348'>348</a>
|
|
414
|
+
<a name='L349'></a><a href='#L349'>349</a>
|
|
415
|
+
<a name='L350'></a><a href='#L350'>350</a>
|
|
416
|
+
<a name='L351'></a><a href='#L351'>351</a>
|
|
417
|
+
<a name='L352'></a><a href='#L352'>352</a>
|
|
418
|
+
<a name='L353'></a><a href='#L353'>353</a>
|
|
419
|
+
<a name='L354'></a><a href='#L354'>354</a>
|
|
420
|
+
<a name='L355'></a><a href='#L355'>355</a>
|
|
421
|
+
<a name='L356'></a><a href='#L356'>356</a>
|
|
422
|
+
<a name='L357'></a><a href='#L357'>357</a>
|
|
423
|
+
<a name='L358'></a><a href='#L358'>358</a>
|
|
424
|
+
<a name='L359'></a><a href='#L359'>359</a>
|
|
425
|
+
<a name='L360'></a><a href='#L360'>360</a>
|
|
426
|
+
<a name='L361'></a><a href='#L361'>361</a>
|
|
427
|
+
<a name='L362'></a><a href='#L362'>362</a>
|
|
428
|
+
<a name='L363'></a><a href='#L363'>363</a>
|
|
429
|
+
<a name='L364'></a><a href='#L364'>364</a>
|
|
430
|
+
<a name='L365'></a><a href='#L365'>365</a>
|
|
431
|
+
<a name='L366'></a><a href='#L366'>366</a>
|
|
432
|
+
<a name='L367'></a><a href='#L367'>367</a>
|
|
433
|
+
<a name='L368'></a><a href='#L368'>368</a>
|
|
434
|
+
<a name='L369'></a><a href='#L369'>369</a>
|
|
435
|
+
<a name='L370'></a><a href='#L370'>370</a>
|
|
436
|
+
<a name='L371'></a><a href='#L371'>371</a>
|
|
437
|
+
<a name='L372'></a><a href='#L372'>372</a>
|
|
438
|
+
<a name='L373'></a><a href='#L373'>373</a>
|
|
439
|
+
<a name='L374'></a><a href='#L374'>374</a>
|
|
440
|
+
<a name='L375'></a><a href='#L375'>375</a>
|
|
441
|
+
<a name='L376'></a><a href='#L376'>376</a>
|
|
442
|
+
<a name='L377'></a><a href='#L377'>377</a>
|
|
443
|
+
<a name='L378'></a><a href='#L378'>378</a>
|
|
444
|
+
<a name='L379'></a><a href='#L379'>379</a>
|
|
445
|
+
<a name='L380'></a><a href='#L380'>380</a>
|
|
446
|
+
<a name='L381'></a><a href='#L381'>381</a>
|
|
447
|
+
<a name='L382'></a><a href='#L382'>382</a>
|
|
448
|
+
<a name='L383'></a><a href='#L383'>383</a>
|
|
449
|
+
<a name='L384'></a><a href='#L384'>384</a>
|
|
450
|
+
<a name='L385'></a><a href='#L385'>385</a>
|
|
451
|
+
<a name='L386'></a><a href='#L386'>386</a>
|
|
452
|
+
<a name='L387'></a><a href='#L387'>387</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
|
|
453
|
+
<span class="cline-any cline-yes">1x</span>
|
|
454
|
+
<span class="cline-any cline-yes">1x</span>
|
|
455
|
+
<span class="cline-any cline-yes">1x</span>
|
|
456
|
+
<span class="cline-any cline-yes">1x</span>
|
|
457
|
+
<span class="cline-any cline-yes">1x</span>
|
|
458
|
+
<span class="cline-any cline-yes">1x</span>
|
|
459
|
+
<span class="cline-any cline-yes">1x</span>
|
|
460
|
+
<span class="cline-any cline-yes">1x</span>
|
|
461
|
+
<span class="cline-any cline-yes">1x</span>
|
|
462
|
+
<span class="cline-any cline-yes">1x</span>
|
|
463
|
+
<span class="cline-any cline-yes">1x</span>
|
|
464
|
+
<span class="cline-any cline-yes">1x</span>
|
|
465
|
+
<span class="cline-any cline-yes">1x</span>
|
|
466
|
+
<span class="cline-any cline-yes">1x</span>
|
|
467
|
+
<span class="cline-any cline-yes">1x</span>
|
|
468
|
+
<span class="cline-any cline-yes">1x</span>
|
|
469
|
+
<span class="cline-any cline-yes">1x</span>
|
|
470
|
+
<span class="cline-any cline-yes">1x</span>
|
|
471
|
+
<span class="cline-any cline-yes">1x</span>
|
|
472
|
+
<span class="cline-any cline-yes">1x</span>
|
|
473
|
+
<span class="cline-any cline-yes">1x</span>
|
|
474
|
+
<span class="cline-any cline-yes">1x</span>
|
|
475
|
+
<span class="cline-any cline-yes">1x</span>
|
|
476
|
+
<span class="cline-any cline-yes">1x</span>
|
|
477
|
+
<span class="cline-any cline-yes">1x</span>
|
|
478
|
+
<span class="cline-any cline-yes">1x</span>
|
|
479
|
+
<span class="cline-any cline-yes">1x</span>
|
|
480
|
+
<span class="cline-any cline-yes">1x</span>
|
|
481
|
+
<span class="cline-any cline-yes">1x</span>
|
|
482
|
+
<span class="cline-any cline-yes">1x</span>
|
|
483
|
+
<span class="cline-any cline-yes">1x</span>
|
|
484
|
+
<span class="cline-any cline-yes">1x</span>
|
|
485
|
+
<span class="cline-any cline-yes">1x</span>
|
|
486
|
+
<span class="cline-any cline-yes">1x</span>
|
|
487
|
+
<span class="cline-any cline-yes">1x</span>
|
|
488
|
+
<span class="cline-any cline-yes">1x</span>
|
|
489
|
+
<span class="cline-any cline-yes">1x</span>
|
|
490
|
+
<span class="cline-any cline-yes">1x</span>
|
|
491
|
+
<span class="cline-any cline-yes">1x</span>
|
|
492
|
+
<span class="cline-any cline-yes">1x</span>
|
|
493
|
+
<span class="cline-any cline-yes">1x</span>
|
|
494
|
+
<span class="cline-any cline-yes">1x</span>
|
|
495
|
+
<span class="cline-any cline-yes">1x</span>
|
|
496
|
+
<span class="cline-any cline-yes">1x</span>
|
|
497
|
+
<span class="cline-any cline-yes">1x</span>
|
|
498
|
+
<span class="cline-any cline-yes">1x</span>
|
|
499
|
+
<span class="cline-any cline-yes">1x</span>
|
|
500
|
+
<span class="cline-any cline-yes">1x</span>
|
|
501
|
+
<span class="cline-any cline-yes">1x</span>
|
|
502
|
+
<span class="cline-any cline-yes">1x</span>
|
|
503
|
+
<span class="cline-any cline-yes">1x</span>
|
|
504
|
+
<span class="cline-any cline-yes">1x</span>
|
|
505
|
+
<span class="cline-any cline-yes">1x</span>
|
|
506
|
+
<span class="cline-any cline-yes">1x</span>
|
|
399
507
|
<span class="cline-any cline-yes">1x</span>
|
|
400
508
|
<span class="cline-any cline-yes">1x</span>
|
|
401
509
|
<span class="cline-any cline-yes">1x</span>
|
|
@@ -748,13 +856,9 @@
|
|
|
748
856
|
// SOFTWARE.
|
|
749
857
|
|
|
750
858
|
/* c8 ignore start - Browser-only implementation cannot be tested in Node.js environment */
|
|
751
|
-
import { captureResult, fail, Failure, Result, succeed, Success } from '@fgv/ts-utils';
|
|
859
|
+
import { captureAsyncResult, captureResult, fail, Failure, Result, succeed, Success } from '@fgv/ts-utils';
|
|
752
860
|
import { CryptoUtils } from '@fgv/ts-extras';
|
|
753
861
|
|
|
754
|
-
type ICryptoProvider = CryptoUtils.ICryptoProvider;
|
|
755
|
-
type IEncryptionResult = CryptoUtils.IEncryptionResult;
|
|
756
|
-
const CryptoConstants = CryptoUtils.Constants;
|
|
757
|
-
|
|
758
862
|
/**
|
|
759
863
|
* Extracts an `ArrayBuffer` from a Uint8Array, handling the potential SharedArrayBuffer case.
|
|
760
864
|
* @param arr - The Uint8Array to extract from
|
|
@@ -776,7 +880,7 @@ function toArrayBuffer(arr: Uint8Array): ArrayBuffer {
|
|
|
776
880
|
*
|
|
777
881
|
* @public
|
|
778
882
|
*/
|
|
779
|
-
export class BrowserCryptoProvider implements ICryptoProvider {
|
|
883
|
+
export class BrowserCryptoProvider implements CryptoUtils.ICryptoProvider {
|
|
780
884
|
private readonly _crypto: Crypto;
|
|
781
885
|
|
|
782
886
|
/**
|
|
@@ -801,14 +905,14 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
801
905
|
* @param key - 32-byte encryption key
|
|
802
906
|
* @returns `Success` with encryption result, or `Failure` with an error.
|
|
803
907
|
*/
|
|
804
|
-
public async encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>> {
|
|
805
|
-
if (key.length !==
|
|
806
|
-
return Failure.with(`Key must be ${
|
|
908
|
+
public async encrypt(plaintext: string, key: Uint8Array): Promise<Result<CryptoUtils.IEncryptionResult>> {
|
|
909
|
+
if (key.length !== CryptoUtils.Constants.AES_256_KEY_SIZE) {
|
|
910
|
+
return Failure.with(`Key must be ${CryptoUtils.Constants.AES_256_KEY_SIZE} bytes, got ${key.length}`);
|
|
807
911
|
}
|
|
808
912
|
|
|
809
913
|
try {
|
|
810
914
|
// Generate random IV
|
|
811
|
-
const iv = this._crypto.getRandomValues(new Uint8Array(
|
|
915
|
+
const iv = this._crypto.getRandomValues(new Uint8Array(CryptoUtils.Constants.GCM_IV_SIZE));
|
|
812
916
|
|
|
813
917
|
// Import the key
|
|
814
918
|
const cryptoKey = await this._crypto.subtle.importKey(
|
|
@@ -828,7 +932,7 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
828
932
|
{
|
|
829
933
|
name: 'AES-GCM',
|
|
830
934
|
iv: iv,
|
|
831
|
-
tagLength:
|
|
935
|
+
tagLength: CryptoUtils.Constants.GCM_AUTH_TAG_SIZE * 8 // bits
|
|
832
936
|
},
|
|
833
937
|
cryptoKey,
|
|
834
938
|
plaintextBytes
|
|
@@ -838,9 +942,9 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
838
942
|
const encryptedArray = new Uint8Array(encryptedWithTag);
|
|
839
943
|
const encryptedData = encryptedArray.slice(
|
|
840
944
|
0,
|
|
841
|
-
encryptedArray.length -
|
|
945
|
+
encryptedArray.length - CryptoUtils.Constants.GCM_AUTH_TAG_SIZE
|
|
842
946
|
);
|
|
843
|
-
const authTag = encryptedArray.slice(encryptedArray.length -
|
|
947
|
+
const authTag = encryptedArray.slice(encryptedArray.length - CryptoUtils.Constants.GCM_AUTH_TAG_SIZE);
|
|
844
948
|
return Success.with({
|
|
845
949
|
iv,
|
|
846
950
|
authTag,
|
|
@@ -866,15 +970,15 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
866
970
|
iv: Uint8Array,
|
|
867
971
|
authTag: Uint8Array
|
|
868
972
|
): Promise<Result<string>> {
|
|
869
|
-
if (key.length !==
|
|
870
|
-
return Failure.with(`Key must be ${
|
|
973
|
+
if (key.length !== CryptoUtils.Constants.AES_256_KEY_SIZE) {
|
|
974
|
+
return Failure.with(`Key must be ${CryptoUtils.Constants.AES_256_KEY_SIZE} bytes, got ${key.length}`);
|
|
871
975
|
}
|
|
872
|
-
if (iv.length !==
|
|
873
|
-
return Failure.with(`IV must be ${
|
|
976
|
+
if (iv.length !== CryptoUtils.Constants.GCM_IV_SIZE) {
|
|
977
|
+
return Failure.with(`IV must be ${CryptoUtils.Constants.GCM_IV_SIZE} bytes, got ${iv.length}`);
|
|
874
978
|
}
|
|
875
|
-
if (authTag.length !==
|
|
979
|
+
if (authTag.length !== CryptoUtils.Constants.GCM_AUTH_TAG_SIZE) {
|
|
876
980
|
return Failure.with(
|
|
877
|
-
`Auth tag must be ${
|
|
981
|
+
`Auth tag must be ${CryptoUtils.Constants.GCM_AUTH_TAG_SIZE} bytes, got ${authTag.length}`
|
|
878
982
|
);
|
|
879
983
|
}
|
|
880
984
|
|
|
@@ -898,7 +1002,7 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
898
1002
|
{
|
|
899
1003
|
name: 'AES-GCM',
|
|
900
1004
|
iv: toArrayBuffer(iv),
|
|
901
|
-
tagLength:
|
|
1005
|
+
tagLength: CryptoUtils.Constants.GCM_AUTH_TAG_SIZE * 8 // bits
|
|
902
1006
|
},
|
|
903
1007
|
cryptoKey,
|
|
904
1008
|
encryptedWithTag
|
|
@@ -919,7 +1023,9 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
919
1023
|
*/
|
|
920
1024
|
public async generateKey(): Promise<Result<Uint8Array>> {
|
|
921
1025
|
try {
|
|
922
|
-
return Success.with(
|
|
1026
|
+
return Success.with(
|
|
1027
|
+
this._crypto.getRandomValues(new Uint8Array(CryptoUtils.Constants.AES_256_KEY_SIZE))
|
|
1028
|
+
);
|
|
923
1029
|
} catch (e) {
|
|
924
1030
|
const message = e instanceof Error ? e.message : String(e);
|
|
925
1031
|
return Failure.with(`Key generation failed: ${message}`);
|
|
@@ -964,7 +1070,7 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
964
1070
|
hash: 'SHA-256'
|
|
965
1071
|
},
|
|
966
1072
|
keyMaterial,
|
|
967
|
-
|
|
1073
|
+
CryptoUtils.Constants.AES_256_KEY_SIZE * 8 // bits
|
|
968
1074
|
);
|
|
969
1075
|
|
|
970
1076
|
return Success.with(new Uint8Array(derivedBits));
|
|
@@ -1047,6 +1153,62 @@ export class BrowserCryptoProvider implements ICryptoProvider {
|
|
|
1047
1153
|
return Failure.with('Invalid base64 string');
|
|
1048
1154
|
}
|
|
1049
1155
|
}
|
|
1156
|
+
|
|
1157
|
+
// ============================================================================
|
|
1158
|
+
// Asymmetric Key Operations
|
|
1159
|
+
// ============================================================================
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* Generates a new asymmetric keypair via Web Crypto.
|
|
1163
|
+
* @param algorithm - The algorithm to use.
|
|
1164
|
+
* @param extractable - Whether the resulting keys may be exported.
|
|
1165
|
+
* @returns `Success` with the generated `CryptoKeyPair`, or `Failure` with an error.
|
|
1166
|
+
*/
|
|
1167
|
+
public async generateKeyPair(
|
|
1168
|
+
algorithm: CryptoUtils.KeyPairAlgorithm,
|
|
1169
|
+
extractable: boolean
|
|
1170
|
+
): Promise<Result<CryptoKeyPair>> {
|
|
1171
|
+
const params = CryptoUtils.keyPairAlgorithmParams[algorithm];
|
|
1172
|
+
const result = await captureAsyncResult(() =>
|
|
1173
|
+
this._crypto.subtle.generateKey(params.generateKey, extractable, params.keyPairUsages)
|
|
1174
|
+
);
|
|
1175
|
+
return result.withErrorFormat((e) => `Failed to generate ${algorithm} keypair: ${e}`);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* Exports a public `CryptoKey` as a JSON Web Key.
|
|
1180
|
+
* @remarks
|
|
1181
|
+
* Rejects non-public keys at runtime. WebCrypto's `exportKey('jwk', ...)`
|
|
1182
|
+
* does not enforce public-vs-private; without this guard a caller that
|
|
1183
|
+
* passed an extractable private key would receive its private fields
|
|
1184
|
+
* (`d`, `p`, `q`, ...) as JWK, defeating the method's name.
|
|
1185
|
+
* @param publicKey - Extractable public key to export.
|
|
1186
|
+
* @returns `Success` with the JWK, or `Failure` if not a public key or if export fails.
|
|
1187
|
+
*/
|
|
1188
|
+
public async exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>> {
|
|
1189
|
+
if (publicKey.type !== 'public') {
|
|
1190
|
+
return Failure.with(`exportPublicKeyJwk requires a public CryptoKey, got '${publicKey.type}'`);
|
|
1191
|
+
}
|
|
1192
|
+
const result = await captureAsyncResult(() => this._crypto.subtle.exportKey('jwk', publicKey));
|
|
1193
|
+
return result.withErrorFormat((e) => `Failed to export public key as JWK: ${e}`);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Imports a public-key JWK as a `CryptoKey` for the requested algorithm.
|
|
1198
|
+
* @param jwk - The JSON Web Key produced by a prior export.
|
|
1199
|
+
* @param algorithm - The algorithm the key was generated for.
|
|
1200
|
+
* @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
|
|
1201
|
+
*/
|
|
1202
|
+
public async importPublicKeyJwk(
|
|
1203
|
+
jwk: JsonWebKey,
|
|
1204
|
+
algorithm: CryptoUtils.KeyPairAlgorithm
|
|
1205
|
+
): Promise<Result<CryptoKey>> {
|
|
1206
|
+
const params = CryptoUtils.keyPairAlgorithmParams[algorithm];
|
|
1207
|
+
const result = await captureAsyncResult(() =>
|
|
1208
|
+
this._crypto.subtle.importKey('jwk', jwk, params.importPublicKey, true, params.publicKeyUsages)
|
|
1209
|
+
);
|
|
1210
|
+
return result.withErrorFormat((e) => `Failed to import ${algorithm} public key from JWK: ${e}`);
|
|
1211
|
+
}
|
|
1050
1212
|
}
|
|
1051
1213
|
|
|
1052
1214
|
/**
|
|
@@ -1066,7 +1228,7 @@ export function createBrowserCryptoProvider(): Result<BrowserCryptoProvider&g
|
|
|
1066
1228
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1067
1229
|
Code coverage generated by
|
|
1068
1230
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1069
|
-
at 2026-04-
|
|
1231
|
+
at 2026-04-27T05:38:37.090Z
|
|
1070
1232
|
</div>
|
|
1071
1233
|
<script src="../prettify.js"></script>
|
|
1072
1234
|
<script>
|
|
@@ -289,7 +289,7 @@ export class BrowserHashProvider {
|
|
|
289
289
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
290
290
|
Code coverage generated by
|
|
291
291
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
292
|
-
at 2026-04-
|
|
292
|
+
at 2026-04-27T05:38:37.090Z
|
|
293
293
|
</div>
|
|
294
294
|
<script src="../prettify.js"></script>
|
|
295
295
|
<script>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>459/459</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>16/16</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
47
|
<span class="strong">100% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>459/459</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -84,13 +84,13 @@
|
|
|
84
84
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
85
|
</td>
|
|
86
86
|
<td data-value="100" class="pct high">100%</td>
|
|
87
|
-
<td data-value="
|
|
87
|
+
<td data-value="386" class="abs high">386/386</td>
|
|
88
88
|
<td data-value="100" class="pct high">100%</td>
|
|
89
89
|
<td data-value="0" class="abs high">0/0</td>
|
|
90
90
|
<td data-value="100" class="pct high">100%</td>
|
|
91
|
-
<td data-value="
|
|
91
|
+
<td data-value="14" class="abs high">14/14</td>
|
|
92
92
|
<td data-value="100" class="pct high">100%</td>
|
|
93
|
-
<td data-value="
|
|
93
|
+
<td data-value="386" class="abs high">386/386</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
<tr>
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
117
117
|
Code coverage generated by
|
|
118
118
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
119
|
-
at 2026-04-
|
|
119
|
+
at 2026-04-27T05:38:37.090Z
|
|
120
120
|
</div>
|
|
121
121
|
<script src="../prettify.js"></script>
|
|
122
122
|
<script>
|
|
@@ -478,7 +478,7 @@ export class DirectoryHandleStore {
|
|
|
478
478
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
479
479
|
Code coverage generated by
|
|
480
480
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
481
|
-
at 2026-04-
|
|
481
|
+
at 2026-04-27T05:38:37.090Z
|
|
482
482
|
</div>
|
|
483
483
|
<script src="../prettify.js"></script>
|
|
484
484
|
<script>
|
|
@@ -1654,7 +1654,7 @@ export class FileApiTreeAccessors<TCT extends string = string> {
|
|
|
1654
1654
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1655
1655
|
Code coverage generated by
|
|
1656
1656
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1657
|
-
at 2026-04-
|
|
1657
|
+
at 2026-04-27T05:38:37.090Z
|
|
1658
1658
|
</div>
|
|
1659
1659
|
<script src="../prettify.js"></script>
|
|
1660
1660
|
<script>
|
|
@@ -1627,7 +1627,7 @@ export class FileSystemAccessTreeAccessors<TCT extends string = string>
|
|
|
1627
1627
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1628
1628
|
Code coverage generated by
|
|
1629
1629
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1630
|
-
at 2026-04-
|
|
1630
|
+
at 2026-04-27T05:38:37.090Z
|
|
1631
1631
|
</div>
|
|
1632
1632
|
<script src="../prettify.js"></script>
|
|
1633
1633
|
<script>
|
|
@@ -1504,7 +1504,7 @@ export class HttpTreeAccessors<TCT extends string = string>
|
|
|
1504
1504
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1505
1505
|
Code coverage generated by
|
|
1506
1506
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1507
|
-
at 2026-04-
|
|
1507
|
+
at 2026-04-27T05:38:37.090Z
|
|
1508
1508
|
</div>
|
|
1509
1509
|
<script src="../prettify.js"></script>
|
|
1510
1510
|
<script>
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
162
162
|
Code coverage generated by
|
|
163
163
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
164
|
-
at 2026-04-
|
|
164
|
+
at 2026-04-27T05:38:37.090Z
|
|
165
165
|
</div>
|
|
166
166
|
<script src="../prettify.js"></script>
|
|
167
167
|
<script>
|
|
@@ -1360,7 +1360,7 @@ export class LocalStorageTreeAccessors<TCT extends string = string>
|
|
|
1360
1360
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1361
1361
|
Code coverage generated by
|
|
1362
1362
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1363
|
-
at 2026-04-
|
|
1363
|
+
at 2026-04-27T05:38:37.090Z
|
|
1364
1364
|
</div>
|
|
1365
1365
|
<script src="../prettify.js"></script>
|
|
1366
1366
|
<script>
|
|
@@ -391,7 +391,7 @@ export function extractFileMetadata(file: File): IFileMetadata {
|
|
|
391
391
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
392
392
|
Code coverage generated by
|
|
393
393
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
394
|
-
at 2026-04-
|
|
394
|
+
at 2026-04-27T05:38:37.090Z
|
|
395
395
|
</div>
|
|
396
396
|
<script src="../prettify.js"></script>
|
|
397
397
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-04-
|
|
104
|
+
at 2026-04-27T05:38:37.090Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>2902/2902</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>98/98</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
47
|
<span class="strong">100% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>2902/2902</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -84,13 +84,13 @@
|
|
|
84
84
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
85
|
</td>
|
|
86
86
|
<td data-value="100" class="pct high">100%</td>
|
|
87
|
-
<td data-value="
|
|
87
|
+
<td data-value="459" class="abs high">459/459</td>
|
|
88
88
|
<td data-value="100" class="pct high">100%</td>
|
|
89
89
|
<td data-value="9" class="abs high">9/9</td>
|
|
90
90
|
<td data-value="100" class="pct high">100%</td>
|
|
91
|
-
<td data-value="
|
|
91
|
+
<td data-value="16" class="abs high">16/16</td>
|
|
92
92
|
<td data-value="100" class="pct high">100%</td>
|
|
93
|
-
<td data-value="
|
|
93
|
+
<td data-value="459" class="abs high">459/459</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
<tr>
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
147
147
|
Code coverage generated by
|
|
148
148
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
149
|
-
at 2026-04-
|
|
149
|
+
at 2026-04-27T05:38:37.090Z
|
|
150
150
|
</div>
|
|
151
151
|
<script src="prettify.js"></script>
|
|
152
152
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-04-
|
|
104
|
+
at 2026-04-27T05:38:37.090Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -805,7 +805,7 @@ export function isFilePath(path: string): boolean {
|
|
|
805
805
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
806
806
|
Code coverage generated by
|
|
807
807
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
808
|
-
at 2026-04-
|
|
808
|
+
at 2026-04-27T05:38:37.090Z
|
|
809
809
|
</div>
|
|
810
810
|
<script src="../prettify.js"></script>
|
|
811
811
|
<script>
|