enclave-link 0.1.0 → 0.2.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.
- package/README.md +32 -12
- package/dist/chunk-7QIF4PCL.js +6783 -0
- package/dist/{chunk-LUHJCCBX.js → chunk-RHLID3KU.js} +598 -461
- package/dist/enclave.js +48 -24
- package/dist/index.js +4 -2
- package/dist/{mcp-WPCCWEA2.js → mcp-7TGVJUG4.js} +899 -7395
- package/dist/types/answer.d.ts +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/passkey.d.ts +8 -6
- package/dist/types/proton.d.ts +21 -12
- package/dist/types/store.d.ts +2 -0
- package/dist/types/vault.d.ts +24 -12
- package/package.json +18 -14
- package/dist/chunk-U67V476Y.js +0 -35
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__commonJS,
|
|
3
3
|
__export,
|
|
4
|
-
__toESM
|
|
5
|
-
|
|
4
|
+
__toESM,
|
|
5
|
+
_enum,
|
|
6
|
+
array,
|
|
7
|
+
number,
|
|
8
|
+
object,
|
|
9
|
+
record,
|
|
10
|
+
string,
|
|
11
|
+
tuple,
|
|
12
|
+
union,
|
|
13
|
+
unknown
|
|
14
|
+
} from "./chunk-7QIF4PCL.js";
|
|
6
15
|
|
|
7
16
|
// node_modules/@msgpack/msgpack/dist.cjs/utils/utf8.cjs
|
|
8
17
|
var require_utf8 = __commonJS({
|
|
@@ -92,26 +101,26 @@ var require_utf8 = __commonJS({
|
|
|
92
101
|
}
|
|
93
102
|
}
|
|
94
103
|
var CHUNK_SIZE = 4096;
|
|
95
|
-
function utf8DecodeJs(
|
|
104
|
+
function utf8DecodeJs(bytes2, inputOffset, byteLength2) {
|
|
96
105
|
let offset = inputOffset;
|
|
97
106
|
const end = offset + byteLength2;
|
|
98
107
|
const units = [];
|
|
99
108
|
let result = "";
|
|
100
109
|
while (offset < end) {
|
|
101
|
-
const byte1 =
|
|
110
|
+
const byte1 = bytes2[offset++];
|
|
102
111
|
if ((byte1 & 128) === 0) {
|
|
103
112
|
units.push(byte1);
|
|
104
113
|
} else if ((byte1 & 224) === 192) {
|
|
105
|
-
const byte2 =
|
|
114
|
+
const byte2 = bytes2[offset++] & 63;
|
|
106
115
|
units.push((byte1 & 31) << 6 | byte2);
|
|
107
116
|
} else if ((byte1 & 240) === 224) {
|
|
108
|
-
const byte2 =
|
|
109
|
-
const byte3 =
|
|
117
|
+
const byte2 = bytes2[offset++] & 63;
|
|
118
|
+
const byte3 = bytes2[offset++] & 63;
|
|
110
119
|
units.push((byte1 & 31) << 12 | byte2 << 6 | byte3);
|
|
111
120
|
} else if ((byte1 & 248) === 240) {
|
|
112
|
-
const byte2 =
|
|
113
|
-
const byte3 =
|
|
114
|
-
const byte4 =
|
|
121
|
+
const byte2 = bytes2[offset++] & 63;
|
|
122
|
+
const byte3 = bytes2[offset++] & 63;
|
|
123
|
+
const byte4 = bytes2[offset++] & 63;
|
|
115
124
|
let unit = (byte1 & 7) << 18 | byte2 << 12 | byte3 << 6 | byte4;
|
|
116
125
|
if (unit > 65535) {
|
|
117
126
|
unit -= 65536;
|
|
@@ -134,15 +143,15 @@ var require_utf8 = __commonJS({
|
|
|
134
143
|
}
|
|
135
144
|
var sharedTextDecoder = new TextDecoder();
|
|
136
145
|
var TEXT_DECODER_THRESHOLD = 200;
|
|
137
|
-
function utf8DecodeTD(
|
|
138
|
-
const stringBytes =
|
|
146
|
+
function utf8DecodeTD(bytes2, inputOffset, byteLength2) {
|
|
147
|
+
const stringBytes = bytes2.subarray(inputOffset, inputOffset + byteLength2);
|
|
139
148
|
return sharedTextDecoder.decode(stringBytes);
|
|
140
149
|
}
|
|
141
|
-
function utf8Decode(
|
|
150
|
+
function utf8Decode(bytes2, inputOffset, byteLength2) {
|
|
142
151
|
if (byteLength2 > TEXT_DECODER_THRESHOLD) {
|
|
143
|
-
return utf8DecodeTD(
|
|
152
|
+
return utf8DecodeTD(bytes2, inputOffset, byteLength2);
|
|
144
153
|
} else {
|
|
145
|
-
return utf8DecodeJs(
|
|
154
|
+
return utf8DecodeJs(bytes2, inputOffset, byteLength2);
|
|
146
155
|
}
|
|
147
156
|
}
|
|
148
157
|
}
|
|
@@ -274,9 +283,9 @@ var require_timestamp = __commonJS({
|
|
|
274
283
|
nsec: nsec - nsecInSec * 1e9
|
|
275
284
|
};
|
|
276
285
|
}
|
|
277
|
-
function encodeTimestampExtension(
|
|
278
|
-
if (
|
|
279
|
-
const timeSpec = encodeDateToTimeSpec(
|
|
286
|
+
function encodeTimestampExtension(object2) {
|
|
287
|
+
if (object2 instanceof Date) {
|
|
288
|
+
const timeSpec = encodeDateToTimeSpec(object2);
|
|
280
289
|
return encodeTimeSpecToTimestamp(timeSpec);
|
|
281
290
|
} else {
|
|
282
291
|
return null;
|
|
@@ -351,11 +360,11 @@ var require_ExtensionCodec = __commonJS({
|
|
|
351
360
|
this.builtInDecoders[index] = decode2;
|
|
352
361
|
}
|
|
353
362
|
}
|
|
354
|
-
tryToEncode(
|
|
363
|
+
tryToEncode(object2, context) {
|
|
355
364
|
for (let i = 0; i < this.builtInEncoders.length; i++) {
|
|
356
365
|
const encodeExt = this.builtInEncoders[i];
|
|
357
366
|
if (encodeExt != null) {
|
|
358
|
-
const data = encodeExt(
|
|
367
|
+
const data = encodeExt(object2, context);
|
|
359
368
|
if (data != null) {
|
|
360
369
|
const type = -1 - i;
|
|
361
370
|
return new ExtData_ts_1.ExtData(type, data);
|
|
@@ -365,15 +374,15 @@ var require_ExtensionCodec = __commonJS({
|
|
|
365
374
|
for (let i = 0; i < this.encoders.length; i++) {
|
|
366
375
|
const encodeExt = this.encoders[i];
|
|
367
376
|
if (encodeExt != null) {
|
|
368
|
-
const data = encodeExt(
|
|
377
|
+
const data = encodeExt(object2, context);
|
|
369
378
|
if (data != null) {
|
|
370
379
|
const type = i;
|
|
371
380
|
return new ExtData_ts_1.ExtData(type, data);
|
|
372
381
|
}
|
|
373
382
|
}
|
|
374
383
|
}
|
|
375
|
-
if (
|
|
376
|
-
return
|
|
384
|
+
if (object2 instanceof ExtData_ts_1.ExtData) {
|
|
385
|
+
return object2;
|
|
377
386
|
}
|
|
378
387
|
return null;
|
|
379
388
|
}
|
|
@@ -474,15 +483,15 @@ var require_Encoder = __commonJS({
|
|
|
474
483
|
*
|
|
475
484
|
* @returns Encodes the object and returns a shared reference the encoder's internal buffer.
|
|
476
485
|
*/
|
|
477
|
-
encodeSharedRef(
|
|
486
|
+
encodeSharedRef(object2) {
|
|
478
487
|
if (this.entered) {
|
|
479
488
|
const instance = this.clone();
|
|
480
|
-
return instance.encodeSharedRef(
|
|
489
|
+
return instance.encodeSharedRef(object2);
|
|
481
490
|
}
|
|
482
491
|
try {
|
|
483
492
|
this.entered = true;
|
|
484
493
|
this.reinitializeState();
|
|
485
|
-
this.doEncode(
|
|
494
|
+
this.doEncode(object2, 1);
|
|
486
495
|
return this.bytes.subarray(0, this.pos);
|
|
487
496
|
} finally {
|
|
488
497
|
this.entered = false;
|
|
@@ -491,40 +500,40 @@ var require_Encoder = __commonJS({
|
|
|
491
500
|
/**
|
|
492
501
|
* @returns Encodes the object and returns a copy of the encoder's internal buffer.
|
|
493
502
|
*/
|
|
494
|
-
encode(
|
|
503
|
+
encode(object2) {
|
|
495
504
|
if (this.entered) {
|
|
496
505
|
const instance = this.clone();
|
|
497
|
-
return instance.encode(
|
|
506
|
+
return instance.encode(object2);
|
|
498
507
|
}
|
|
499
508
|
try {
|
|
500
509
|
this.entered = true;
|
|
501
510
|
this.reinitializeState();
|
|
502
|
-
this.doEncode(
|
|
511
|
+
this.doEncode(object2, 1);
|
|
503
512
|
return this.bytes.slice(0, this.pos);
|
|
504
513
|
} finally {
|
|
505
514
|
this.entered = false;
|
|
506
515
|
}
|
|
507
516
|
}
|
|
508
|
-
doEncode(
|
|
517
|
+
doEncode(object2, depth) {
|
|
509
518
|
if (depth > this.maxDepth) {
|
|
510
519
|
throw new Error(`Too deep objects in depth ${depth}`);
|
|
511
520
|
}
|
|
512
|
-
if (
|
|
521
|
+
if (object2 == null) {
|
|
513
522
|
this.encodeNil();
|
|
514
|
-
} else if (typeof
|
|
515
|
-
this.encodeBoolean(
|
|
516
|
-
} else if (typeof
|
|
523
|
+
} else if (typeof object2 === "boolean") {
|
|
524
|
+
this.encodeBoolean(object2);
|
|
525
|
+
} else if (typeof object2 === "number") {
|
|
517
526
|
if (!this.forceIntegerToFloat) {
|
|
518
|
-
this.encodeNumber(
|
|
527
|
+
this.encodeNumber(object2);
|
|
519
528
|
} else {
|
|
520
|
-
this.encodeNumberAsFloat(
|
|
529
|
+
this.encodeNumberAsFloat(object2);
|
|
521
530
|
}
|
|
522
|
-
} else if (typeof
|
|
523
|
-
this.encodeString(
|
|
524
|
-
} else if (this.useBigInt64 && typeof
|
|
525
|
-
this.encodeBigInt64(
|
|
531
|
+
} else if (typeof object2 === "string") {
|
|
532
|
+
this.encodeString(object2);
|
|
533
|
+
} else if (this.useBigInt64 && typeof object2 === "bigint") {
|
|
534
|
+
this.encodeBigInt64(object2);
|
|
526
535
|
} else {
|
|
527
|
-
this.encodeObject(
|
|
536
|
+
this.encodeObject(object2, depth);
|
|
528
537
|
}
|
|
529
538
|
}
|
|
530
539
|
ensureBufferSizeToWrite(sizeToWrite) {
|
|
@@ -544,72 +553,72 @@ var require_Encoder = __commonJS({
|
|
|
544
553
|
encodeNil() {
|
|
545
554
|
this.writeU8(192);
|
|
546
555
|
}
|
|
547
|
-
encodeBoolean(
|
|
548
|
-
if (
|
|
556
|
+
encodeBoolean(object2) {
|
|
557
|
+
if (object2 === false) {
|
|
549
558
|
this.writeU8(194);
|
|
550
559
|
} else {
|
|
551
560
|
this.writeU8(195);
|
|
552
561
|
}
|
|
553
562
|
}
|
|
554
|
-
encodeNumber(
|
|
555
|
-
if (!this.forceIntegerToFloat && Number.isSafeInteger(
|
|
556
|
-
if (
|
|
557
|
-
if (
|
|
558
|
-
this.writeU8(
|
|
559
|
-
} else if (
|
|
563
|
+
encodeNumber(object2) {
|
|
564
|
+
if (!this.forceIntegerToFloat && Number.isSafeInteger(object2)) {
|
|
565
|
+
if (object2 >= 0) {
|
|
566
|
+
if (object2 < 128) {
|
|
567
|
+
this.writeU8(object2);
|
|
568
|
+
} else if (object2 < 256) {
|
|
560
569
|
this.writeU8(204);
|
|
561
|
-
this.writeU8(
|
|
562
|
-
} else if (
|
|
570
|
+
this.writeU8(object2);
|
|
571
|
+
} else if (object2 < 65536) {
|
|
563
572
|
this.writeU8(205);
|
|
564
|
-
this.writeU16(
|
|
565
|
-
} else if (
|
|
573
|
+
this.writeU16(object2);
|
|
574
|
+
} else if (object2 < 4294967296) {
|
|
566
575
|
this.writeU8(206);
|
|
567
|
-
this.writeU32(
|
|
576
|
+
this.writeU32(object2);
|
|
568
577
|
} else if (!this.useBigInt64) {
|
|
569
578
|
this.writeU8(207);
|
|
570
|
-
this.writeU64(
|
|
579
|
+
this.writeU64(object2);
|
|
571
580
|
} else {
|
|
572
|
-
this.encodeNumberAsFloat(
|
|
581
|
+
this.encodeNumberAsFloat(object2);
|
|
573
582
|
}
|
|
574
583
|
} else {
|
|
575
|
-
if (
|
|
576
|
-
this.writeU8(224 |
|
|
577
|
-
} else if (
|
|
584
|
+
if (object2 >= -32) {
|
|
585
|
+
this.writeU8(224 | object2 + 32);
|
|
586
|
+
} else if (object2 >= -128) {
|
|
578
587
|
this.writeU8(208);
|
|
579
|
-
this.writeI8(
|
|
580
|
-
} else if (
|
|
588
|
+
this.writeI8(object2);
|
|
589
|
+
} else if (object2 >= -32768) {
|
|
581
590
|
this.writeU8(209);
|
|
582
|
-
this.writeI16(
|
|
583
|
-
} else if (
|
|
591
|
+
this.writeI16(object2);
|
|
592
|
+
} else if (object2 >= -2147483648) {
|
|
584
593
|
this.writeU8(210);
|
|
585
|
-
this.writeI32(
|
|
594
|
+
this.writeI32(object2);
|
|
586
595
|
} else if (!this.useBigInt64) {
|
|
587
596
|
this.writeU8(211);
|
|
588
|
-
this.writeI64(
|
|
597
|
+
this.writeI64(object2);
|
|
589
598
|
} else {
|
|
590
|
-
this.encodeNumberAsFloat(
|
|
599
|
+
this.encodeNumberAsFloat(object2);
|
|
591
600
|
}
|
|
592
601
|
}
|
|
593
602
|
} else {
|
|
594
|
-
this.encodeNumberAsFloat(
|
|
603
|
+
this.encodeNumberAsFloat(object2);
|
|
595
604
|
}
|
|
596
605
|
}
|
|
597
|
-
encodeNumberAsFloat(
|
|
606
|
+
encodeNumberAsFloat(object2) {
|
|
598
607
|
if (this.forceFloat32) {
|
|
599
608
|
this.writeU8(202);
|
|
600
|
-
this.writeF32(
|
|
609
|
+
this.writeF32(object2);
|
|
601
610
|
} else {
|
|
602
611
|
this.writeU8(203);
|
|
603
|
-
this.writeF64(
|
|
612
|
+
this.writeF64(object2);
|
|
604
613
|
}
|
|
605
614
|
}
|
|
606
|
-
encodeBigInt64(
|
|
607
|
-
if (
|
|
615
|
+
encodeBigInt64(object2) {
|
|
616
|
+
if (object2 >= BigInt(0)) {
|
|
608
617
|
this.writeU8(207);
|
|
609
|
-
this.writeBigUint64(
|
|
618
|
+
this.writeBigUint64(object2);
|
|
610
619
|
} else {
|
|
611
620
|
this.writeU8(211);
|
|
612
|
-
this.writeBigInt64(
|
|
621
|
+
this.writeBigInt64(object2);
|
|
613
622
|
}
|
|
614
623
|
}
|
|
615
624
|
writeStringHeader(byteLength2) {
|
|
@@ -628,30 +637,30 @@ var require_Encoder = __commonJS({
|
|
|
628
637
|
throw new Error(`Too long string: ${byteLength2} bytes in UTF-8`);
|
|
629
638
|
}
|
|
630
639
|
}
|
|
631
|
-
encodeString(
|
|
640
|
+
encodeString(object2) {
|
|
632
641
|
const maxHeaderSize = 1 + 4;
|
|
633
|
-
const byteLength2 = (0, utf8_ts_1.utf8Count)(
|
|
642
|
+
const byteLength2 = (0, utf8_ts_1.utf8Count)(object2);
|
|
634
643
|
this.ensureBufferSizeToWrite(maxHeaderSize + byteLength2);
|
|
635
644
|
this.writeStringHeader(byteLength2);
|
|
636
|
-
(0, utf8_ts_1.utf8Encode)(
|
|
645
|
+
(0, utf8_ts_1.utf8Encode)(object2, this.bytes, this.pos);
|
|
637
646
|
this.pos += byteLength2;
|
|
638
647
|
}
|
|
639
|
-
encodeObject(
|
|
640
|
-
const ext = this.extensionCodec.tryToEncode(
|
|
648
|
+
encodeObject(object2, depth) {
|
|
649
|
+
const ext = this.extensionCodec.tryToEncode(object2, this.context);
|
|
641
650
|
if (ext != null) {
|
|
642
651
|
this.encodeExtension(ext);
|
|
643
|
-
} else if (Array.isArray(
|
|
644
|
-
this.encodeArray(
|
|
645
|
-
} else if (ArrayBuffer.isView(
|
|
646
|
-
this.encodeBinary(
|
|
647
|
-
} else if (typeof
|
|
648
|
-
this.encodeMap(
|
|
652
|
+
} else if (Array.isArray(object2)) {
|
|
653
|
+
this.encodeArray(object2, depth);
|
|
654
|
+
} else if (ArrayBuffer.isView(object2)) {
|
|
655
|
+
this.encodeBinary(object2);
|
|
656
|
+
} else if (typeof object2 === "object") {
|
|
657
|
+
this.encodeMap(object2, depth);
|
|
649
658
|
} else {
|
|
650
|
-
throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(
|
|
659
|
+
throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object2)}`);
|
|
651
660
|
}
|
|
652
661
|
}
|
|
653
|
-
encodeBinary(
|
|
654
|
-
const size =
|
|
662
|
+
encodeBinary(object2) {
|
|
663
|
+
const size = object2.byteLength;
|
|
655
664
|
if (size < 256) {
|
|
656
665
|
this.writeU8(196);
|
|
657
666
|
this.writeU8(size);
|
|
@@ -664,11 +673,11 @@ var require_Encoder = __commonJS({
|
|
|
664
673
|
} else {
|
|
665
674
|
throw new Error(`Too large binary: ${size}`);
|
|
666
675
|
}
|
|
667
|
-
const
|
|
668
|
-
this.writeU8a(
|
|
676
|
+
const bytes2 = (0, typedArrays_ts_1.ensureUint8Array)(object2);
|
|
677
|
+
this.writeU8a(bytes2);
|
|
669
678
|
}
|
|
670
|
-
encodeArray(
|
|
671
|
-
const size =
|
|
679
|
+
encodeArray(object2, depth) {
|
|
680
|
+
const size = object2.length;
|
|
672
681
|
if (size < 16) {
|
|
673
682
|
this.writeU8(144 + size);
|
|
674
683
|
} else if (size < 65536) {
|
|
@@ -680,25 +689,25 @@ var require_Encoder = __commonJS({
|
|
|
680
689
|
} else {
|
|
681
690
|
throw new Error(`Too large array: ${size}`);
|
|
682
691
|
}
|
|
683
|
-
for (const item of
|
|
692
|
+
for (const item of object2) {
|
|
684
693
|
this.doEncode(item, depth + 1);
|
|
685
694
|
}
|
|
686
695
|
}
|
|
687
|
-
countWithoutUndefined(
|
|
696
|
+
countWithoutUndefined(object2, keys) {
|
|
688
697
|
let count = 0;
|
|
689
698
|
for (const key of keys) {
|
|
690
|
-
if (
|
|
699
|
+
if (object2[key] !== void 0) {
|
|
691
700
|
count++;
|
|
692
701
|
}
|
|
693
702
|
}
|
|
694
703
|
return count;
|
|
695
704
|
}
|
|
696
|
-
encodeMap(
|
|
697
|
-
const keys = Object.keys(
|
|
705
|
+
encodeMap(object2, depth) {
|
|
706
|
+
const keys = Object.keys(object2);
|
|
698
707
|
if (this.sortKeys) {
|
|
699
708
|
keys.sort();
|
|
700
709
|
}
|
|
701
|
-
const size = this.ignoreUndefined ? this.countWithoutUndefined(
|
|
710
|
+
const size = this.ignoreUndefined ? this.countWithoutUndefined(object2, keys) : keys.length;
|
|
702
711
|
if (size < 16) {
|
|
703
712
|
this.writeU8(128 + size);
|
|
704
713
|
} else if (size < 65536) {
|
|
@@ -711,7 +720,7 @@ var require_Encoder = __commonJS({
|
|
|
711
720
|
throw new Error(`Too large map object: ${size}`);
|
|
712
721
|
}
|
|
713
722
|
for (const key of keys) {
|
|
714
|
-
const value =
|
|
723
|
+
const value = object2[key];
|
|
715
724
|
if (!(this.ignoreUndefined && value === void 0)) {
|
|
716
725
|
this.encodeString(key);
|
|
717
726
|
this.doEncode(value, depth + 1);
|
|
@@ -880,37 +889,37 @@ var require_CachedKeyDecoder = __commonJS({
|
|
|
880
889
|
canBeCached(byteLength2) {
|
|
881
890
|
return byteLength2 > 0 && byteLength2 <= this.maxKeyLength;
|
|
882
891
|
}
|
|
883
|
-
find(
|
|
892
|
+
find(bytes2, inputOffset, byteLength2) {
|
|
884
893
|
const records = this.caches[byteLength2 - 1];
|
|
885
|
-
FIND_CHUNK: for (const
|
|
886
|
-
const recordBytes =
|
|
894
|
+
FIND_CHUNK: for (const record2 of records) {
|
|
895
|
+
const recordBytes = record2.bytes;
|
|
887
896
|
for (let j = 0; j < byteLength2; j++) {
|
|
888
|
-
if (recordBytes[j] !==
|
|
897
|
+
if (recordBytes[j] !== bytes2[inputOffset + j]) {
|
|
889
898
|
continue FIND_CHUNK;
|
|
890
899
|
}
|
|
891
900
|
}
|
|
892
|
-
return
|
|
901
|
+
return record2.str;
|
|
893
902
|
}
|
|
894
903
|
return null;
|
|
895
904
|
}
|
|
896
|
-
store(
|
|
897
|
-
const records = this.caches[
|
|
898
|
-
const
|
|
905
|
+
store(bytes2, value) {
|
|
906
|
+
const records = this.caches[bytes2.length - 1];
|
|
907
|
+
const record2 = { bytes: bytes2, str: value };
|
|
899
908
|
if (records.length >= this.maxLengthPerKey) {
|
|
900
|
-
records[Math.random() * records.length | 0] =
|
|
909
|
+
records[Math.random() * records.length | 0] = record2;
|
|
901
910
|
} else {
|
|
902
|
-
records.push(
|
|
911
|
+
records.push(record2);
|
|
903
912
|
}
|
|
904
913
|
}
|
|
905
|
-
decode(
|
|
906
|
-
const cachedValue = this.find(
|
|
914
|
+
decode(bytes2, inputOffset, byteLength2) {
|
|
915
|
+
const cachedValue = this.find(bytes2, inputOffset, byteLength2);
|
|
907
916
|
if (cachedValue != null) {
|
|
908
917
|
this.hit++;
|
|
909
918
|
return cachedValue;
|
|
910
919
|
}
|
|
911
920
|
this.miss++;
|
|
912
|
-
const str = (0, utf8_ts_1.utf8DecodeJs)(
|
|
913
|
-
const slicedCopyOfBytes = Uint8Array.prototype.slice.call(
|
|
921
|
+
const str = (0, utf8_ts_1.utf8DecodeJs)(bytes2, inputOffset, byteLength2);
|
|
922
|
+
const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes2, inputOffset, inputOffset + byteLength2);
|
|
914
923
|
this.store(slicedCopyOfBytes, str);
|
|
915
924
|
return str;
|
|
916
925
|
}
|
|
@@ -1070,9 +1079,9 @@ var require_Decoder = __commonJS({
|
|
|
1070
1079
|
this.stack.reset();
|
|
1071
1080
|
}
|
|
1072
1081
|
setBuffer(buffer) {
|
|
1073
|
-
const
|
|
1074
|
-
this.bytes =
|
|
1075
|
-
this.view = new DataView(
|
|
1082
|
+
const bytes2 = (0, typedArrays_ts_1.ensureUint8Array)(buffer);
|
|
1083
|
+
this.bytes = bytes2;
|
|
1084
|
+
this.view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
|
|
1076
1085
|
this.pos = 0;
|
|
1077
1086
|
}
|
|
1078
1087
|
appendBuffer(buffer) {
|
|
@@ -1107,11 +1116,11 @@ var require_Decoder = __commonJS({
|
|
|
1107
1116
|
this.entered = true;
|
|
1108
1117
|
this.reinitializeState();
|
|
1109
1118
|
this.setBuffer(buffer);
|
|
1110
|
-
const
|
|
1119
|
+
const object2 = this.doDecodeSync();
|
|
1111
1120
|
if (this.hasRemaining(1)) {
|
|
1112
1121
|
throw this.createExtraByteError(this.pos);
|
|
1113
1122
|
}
|
|
1114
|
-
return
|
|
1123
|
+
return object2;
|
|
1115
1124
|
} finally {
|
|
1116
1125
|
this.entered = false;
|
|
1117
1126
|
}
|
|
@@ -1141,7 +1150,7 @@ var require_Decoder = __commonJS({
|
|
|
1141
1150
|
try {
|
|
1142
1151
|
this.entered = true;
|
|
1143
1152
|
let decoded = false;
|
|
1144
|
-
let
|
|
1153
|
+
let object2;
|
|
1145
1154
|
for await (const buffer of stream) {
|
|
1146
1155
|
if (decoded) {
|
|
1147
1156
|
this.entered = false;
|
|
@@ -1149,7 +1158,7 @@ var require_Decoder = __commonJS({
|
|
|
1149
1158
|
}
|
|
1150
1159
|
this.appendBuffer(buffer);
|
|
1151
1160
|
try {
|
|
1152
|
-
|
|
1161
|
+
object2 = this.doDecodeSync();
|
|
1153
1162
|
decoded = true;
|
|
1154
1163
|
} catch (e) {
|
|
1155
1164
|
if (!(e instanceof RangeError)) {
|
|
@@ -1162,7 +1171,7 @@ var require_Decoder = __commonJS({
|
|
|
1162
1171
|
if (this.hasRemaining(1)) {
|
|
1163
1172
|
throw this.createExtraByteError(this.totalPos);
|
|
1164
1173
|
}
|
|
1165
|
-
return
|
|
1174
|
+
return object2;
|
|
1166
1175
|
}
|
|
1167
1176
|
const { headByte, pos, totalPos } = this;
|
|
1168
1177
|
throw new RangeError(`Insufficient data in parsing ${(0, prettyByte_ts_1.prettyByte)(headByte)} at ${totalPos} (${pos} in the current buffer)`);
|
|
@@ -1217,12 +1226,12 @@ var require_Decoder = __commonJS({
|
|
|
1217
1226
|
doDecodeSync() {
|
|
1218
1227
|
DECODE: while (true) {
|
|
1219
1228
|
const headByte = this.readHeadByte();
|
|
1220
|
-
let
|
|
1229
|
+
let object2;
|
|
1221
1230
|
if (headByte >= 224) {
|
|
1222
|
-
|
|
1231
|
+
object2 = headByte - 256;
|
|
1223
1232
|
} else if (headByte < 192) {
|
|
1224
1233
|
if (headByte < 128) {
|
|
1225
|
-
|
|
1234
|
+
object2 = headByte;
|
|
1226
1235
|
} else if (headByte < 144) {
|
|
1227
1236
|
const size = headByte - 128;
|
|
1228
1237
|
if (size !== 0) {
|
|
@@ -1230,7 +1239,7 @@ var require_Decoder = __commonJS({
|
|
|
1230
1239
|
this.complete();
|
|
1231
1240
|
continue DECODE;
|
|
1232
1241
|
} else {
|
|
1233
|
-
|
|
1242
|
+
object2 = {};
|
|
1234
1243
|
}
|
|
1235
1244
|
} else if (headByte < 160) {
|
|
1236
1245
|
const size = headByte - 144;
|
|
@@ -1239,55 +1248,55 @@ var require_Decoder = __commonJS({
|
|
|
1239
1248
|
this.complete();
|
|
1240
1249
|
continue DECODE;
|
|
1241
1250
|
} else {
|
|
1242
|
-
|
|
1251
|
+
object2 = [];
|
|
1243
1252
|
}
|
|
1244
1253
|
} else {
|
|
1245
1254
|
const byteLength2 = headByte - 160;
|
|
1246
|
-
|
|
1255
|
+
object2 = this.decodeString(byteLength2, 0);
|
|
1247
1256
|
}
|
|
1248
1257
|
} else if (headByte === 192) {
|
|
1249
|
-
|
|
1258
|
+
object2 = null;
|
|
1250
1259
|
} else if (headByte === 194) {
|
|
1251
|
-
|
|
1260
|
+
object2 = false;
|
|
1252
1261
|
} else if (headByte === 195) {
|
|
1253
|
-
|
|
1262
|
+
object2 = true;
|
|
1254
1263
|
} else if (headByte === 202) {
|
|
1255
|
-
|
|
1264
|
+
object2 = this.readF32();
|
|
1256
1265
|
} else if (headByte === 203) {
|
|
1257
|
-
|
|
1266
|
+
object2 = this.readF64();
|
|
1258
1267
|
} else if (headByte === 204) {
|
|
1259
|
-
|
|
1268
|
+
object2 = this.readU8();
|
|
1260
1269
|
} else if (headByte === 205) {
|
|
1261
|
-
|
|
1270
|
+
object2 = this.readU16();
|
|
1262
1271
|
} else if (headByte === 206) {
|
|
1263
|
-
|
|
1272
|
+
object2 = this.readU32();
|
|
1264
1273
|
} else if (headByte === 207) {
|
|
1265
1274
|
if (this.useBigInt64) {
|
|
1266
|
-
|
|
1275
|
+
object2 = this.readU64AsBigInt();
|
|
1267
1276
|
} else {
|
|
1268
|
-
|
|
1277
|
+
object2 = this.readU64();
|
|
1269
1278
|
}
|
|
1270
1279
|
} else if (headByte === 208) {
|
|
1271
|
-
|
|
1280
|
+
object2 = this.readI8();
|
|
1272
1281
|
} else if (headByte === 209) {
|
|
1273
|
-
|
|
1282
|
+
object2 = this.readI16();
|
|
1274
1283
|
} else if (headByte === 210) {
|
|
1275
|
-
|
|
1284
|
+
object2 = this.readI32();
|
|
1276
1285
|
} else if (headByte === 211) {
|
|
1277
1286
|
if (this.useBigInt64) {
|
|
1278
|
-
|
|
1287
|
+
object2 = this.readI64AsBigInt();
|
|
1279
1288
|
} else {
|
|
1280
|
-
|
|
1289
|
+
object2 = this.readI64();
|
|
1281
1290
|
}
|
|
1282
1291
|
} else if (headByte === 217) {
|
|
1283
1292
|
const byteLength2 = this.lookU8();
|
|
1284
|
-
|
|
1293
|
+
object2 = this.decodeString(byteLength2, 1);
|
|
1285
1294
|
} else if (headByte === 218) {
|
|
1286
1295
|
const byteLength2 = this.lookU16();
|
|
1287
|
-
|
|
1296
|
+
object2 = this.decodeString(byteLength2, 2);
|
|
1288
1297
|
} else if (headByte === 219) {
|
|
1289
1298
|
const byteLength2 = this.lookU32();
|
|
1290
|
-
|
|
1299
|
+
object2 = this.decodeString(byteLength2, 4);
|
|
1291
1300
|
} else if (headByte === 220) {
|
|
1292
1301
|
const size = this.readU16();
|
|
1293
1302
|
if (size !== 0) {
|
|
@@ -1295,7 +1304,7 @@ var require_Decoder = __commonJS({
|
|
|
1295
1304
|
this.complete();
|
|
1296
1305
|
continue DECODE;
|
|
1297
1306
|
} else {
|
|
1298
|
-
|
|
1307
|
+
object2 = [];
|
|
1299
1308
|
}
|
|
1300
1309
|
} else if (headByte === 221) {
|
|
1301
1310
|
const size = this.readU32();
|
|
@@ -1304,7 +1313,7 @@ var require_Decoder = __commonJS({
|
|
|
1304
1313
|
this.complete();
|
|
1305
1314
|
continue DECODE;
|
|
1306
1315
|
} else {
|
|
1307
|
-
|
|
1316
|
+
object2 = [];
|
|
1308
1317
|
}
|
|
1309
1318
|
} else if (headByte === 222) {
|
|
1310
1319
|
const size = this.readU16();
|
|
@@ -1313,7 +1322,7 @@ var require_Decoder = __commonJS({
|
|
|
1313
1322
|
this.complete();
|
|
1314
1323
|
continue DECODE;
|
|
1315
1324
|
} else {
|
|
1316
|
-
|
|
1325
|
+
object2 = {};
|
|
1317
1326
|
}
|
|
1318
1327
|
} else if (headByte === 223) {
|
|
1319
1328
|
const size = this.readU32();
|
|
@@ -1322,36 +1331,36 @@ var require_Decoder = __commonJS({
|
|
|
1322
1331
|
this.complete();
|
|
1323
1332
|
continue DECODE;
|
|
1324
1333
|
} else {
|
|
1325
|
-
|
|
1334
|
+
object2 = {};
|
|
1326
1335
|
}
|
|
1327
1336
|
} else if (headByte === 196) {
|
|
1328
1337
|
const size = this.lookU8();
|
|
1329
|
-
|
|
1338
|
+
object2 = this.decodeBinary(size, 1);
|
|
1330
1339
|
} else if (headByte === 197) {
|
|
1331
1340
|
const size = this.lookU16();
|
|
1332
|
-
|
|
1341
|
+
object2 = this.decodeBinary(size, 2);
|
|
1333
1342
|
} else if (headByte === 198) {
|
|
1334
1343
|
const size = this.lookU32();
|
|
1335
|
-
|
|
1344
|
+
object2 = this.decodeBinary(size, 4);
|
|
1336
1345
|
} else if (headByte === 212) {
|
|
1337
|
-
|
|
1346
|
+
object2 = this.decodeExtension(1, 0);
|
|
1338
1347
|
} else if (headByte === 213) {
|
|
1339
|
-
|
|
1348
|
+
object2 = this.decodeExtension(2, 0);
|
|
1340
1349
|
} else if (headByte === 214) {
|
|
1341
|
-
|
|
1350
|
+
object2 = this.decodeExtension(4, 0);
|
|
1342
1351
|
} else if (headByte === 215) {
|
|
1343
|
-
|
|
1352
|
+
object2 = this.decodeExtension(8, 0);
|
|
1344
1353
|
} else if (headByte === 216) {
|
|
1345
|
-
|
|
1354
|
+
object2 = this.decodeExtension(16, 0);
|
|
1346
1355
|
} else if (headByte === 199) {
|
|
1347
1356
|
const size = this.lookU8();
|
|
1348
|
-
|
|
1357
|
+
object2 = this.decodeExtension(size, 1);
|
|
1349
1358
|
} else if (headByte === 200) {
|
|
1350
1359
|
const size = this.lookU16();
|
|
1351
|
-
|
|
1360
|
+
object2 = this.decodeExtension(size, 2);
|
|
1352
1361
|
} else if (headByte === 201) {
|
|
1353
1362
|
const size = this.lookU32();
|
|
1354
|
-
|
|
1363
|
+
object2 = this.decodeExtension(size, 4);
|
|
1355
1364
|
} else {
|
|
1356
1365
|
throw new DecodeError_ts_1.DecodeError(`Unrecognized type byte: ${(0, prettyByte_ts_1.prettyByte)(headByte)}`);
|
|
1357
1366
|
}
|
|
@@ -1360,26 +1369,26 @@ var require_Decoder = __commonJS({
|
|
|
1360
1369
|
while (stack.length > 0) {
|
|
1361
1370
|
const state = stack.top();
|
|
1362
1371
|
if (state.type === STATE_ARRAY) {
|
|
1363
|
-
state.array[state.position] =
|
|
1372
|
+
state.array[state.position] = object2;
|
|
1364
1373
|
state.position++;
|
|
1365
1374
|
if (state.position === state.size) {
|
|
1366
|
-
|
|
1375
|
+
object2 = state.array;
|
|
1367
1376
|
stack.release(state);
|
|
1368
1377
|
} else {
|
|
1369
1378
|
continue DECODE;
|
|
1370
1379
|
}
|
|
1371
1380
|
} else if (state.type === STATE_MAP_KEY) {
|
|
1372
|
-
if (
|
|
1381
|
+
if (object2 === "__proto__") {
|
|
1373
1382
|
throw new DecodeError_ts_1.DecodeError("The key __proto__ is not allowed");
|
|
1374
1383
|
}
|
|
1375
|
-
state.key = this.mapKeyConverter(
|
|
1384
|
+
state.key = this.mapKeyConverter(object2);
|
|
1376
1385
|
state.type = STATE_MAP_VALUE;
|
|
1377
1386
|
continue DECODE;
|
|
1378
1387
|
} else {
|
|
1379
|
-
state.map[state.key] =
|
|
1388
|
+
state.map[state.key] = object2;
|
|
1380
1389
|
state.readCount++;
|
|
1381
1390
|
if (state.readCount === state.size) {
|
|
1382
|
-
|
|
1391
|
+
object2 = state.map;
|
|
1383
1392
|
stack.release(state);
|
|
1384
1393
|
} else {
|
|
1385
1394
|
state.key = null;
|
|
@@ -1388,7 +1397,7 @@ var require_Decoder = __commonJS({
|
|
|
1388
1397
|
}
|
|
1389
1398
|
}
|
|
1390
1399
|
}
|
|
1391
|
-
return
|
|
1400
|
+
return object2;
|
|
1392
1401
|
}
|
|
1393
1402
|
}
|
|
1394
1403
|
readHeadByte() {
|
|
@@ -1445,14 +1454,14 @@ var require_Decoder = __commonJS({
|
|
|
1445
1454
|
throw MORE_DATA;
|
|
1446
1455
|
}
|
|
1447
1456
|
const offset = this.pos + headerOffset;
|
|
1448
|
-
let
|
|
1457
|
+
let object2;
|
|
1449
1458
|
if (this.stateIsMapKey() && this.keyDecoder?.canBeCached(byteLength2)) {
|
|
1450
|
-
|
|
1459
|
+
object2 = this.keyDecoder.decode(this.bytes, offset, byteLength2);
|
|
1451
1460
|
} else {
|
|
1452
|
-
|
|
1461
|
+
object2 = (0, utf8_ts_1.utf8Decode)(this.bytes, offset, byteLength2);
|
|
1453
1462
|
}
|
|
1454
1463
|
this.pos += headerOffset + byteLength2;
|
|
1455
|
-
return
|
|
1464
|
+
return object2;
|
|
1456
1465
|
}
|
|
1457
1466
|
stateIsMapKey() {
|
|
1458
1467
|
if (this.stack.length > 0) {
|
|
@@ -1472,9 +1481,9 @@ var require_Decoder = __commonJS({
|
|
|
1472
1481
|
throw MORE_DATA;
|
|
1473
1482
|
}
|
|
1474
1483
|
const offset = this.pos + headOffset;
|
|
1475
|
-
const
|
|
1484
|
+
const object2 = this.bytes.subarray(offset, offset + byteLength2);
|
|
1476
1485
|
this.pos += headOffset + byteLength2;
|
|
1477
|
-
return
|
|
1486
|
+
return object2;
|
|
1478
1487
|
}
|
|
1479
1488
|
decodeExtension(size, headOffset) {
|
|
1480
1489
|
if (size > this.maxExtLength) {
|
|
@@ -1589,8 +1598,8 @@ var require_stream2 = __commonJS({
|
|
|
1589
1598
|
exports.isAsyncIterable = isAsyncIterable;
|
|
1590
1599
|
exports.asyncIterableFromStream = asyncIterableFromStream;
|
|
1591
1600
|
exports.ensureAsyncIterable = ensureAsyncIterable;
|
|
1592
|
-
function isAsyncIterable(
|
|
1593
|
-
return
|
|
1601
|
+
function isAsyncIterable(object2) {
|
|
1602
|
+
return object2[Symbol.asyncIterator] != null;
|
|
1594
1603
|
}
|
|
1595
1604
|
async function* asyncIterableFromStream(stream) {
|
|
1596
1605
|
const reader = stream.getReader();
|
|
@@ -1713,8 +1722,203 @@ var require_dist = __commonJS({
|
|
|
1713
1722
|
}
|
|
1714
1723
|
});
|
|
1715
1724
|
|
|
1725
|
+
// src/passkey.ts
|
|
1726
|
+
import { createHash, createPrivateKey, sign } from "node:crypto";
|
|
1727
|
+
var signRequest = object({
|
|
1728
|
+
origin: string(),
|
|
1729
|
+
rpId: string().optional(),
|
|
1730
|
+
challenge: string(),
|
|
1731
|
+
allowCredentials: array(string()).optional()
|
|
1732
|
+
});
|
|
1733
|
+
var userPresentVerifiedAndSynced = 1 | 4 | 8 | 16;
|
|
1734
|
+
function relyingParty({ origin, rpId }) {
|
|
1735
|
+
const host = new URL(origin).hostname;
|
|
1736
|
+
const id = rpId ?? host;
|
|
1737
|
+
if (host !== id && !host.endsWith(`.${id}`)) throw new Error(`${origin} can't use passkeys for ${id}`);
|
|
1738
|
+
return id;
|
|
1739
|
+
}
|
|
1740
|
+
function accepts(passkey, request) {
|
|
1741
|
+
const credentialId = Buffer.from(passkey.credentialId, "base64").toString("base64url");
|
|
1742
|
+
return passkey.rpId === relyingParty(request) && (!request.allowCredentials?.length || request.allowCredentials.includes(credentialId));
|
|
1743
|
+
}
|
|
1744
|
+
function signAssertion(passkey, request) {
|
|
1745
|
+
const rpId = relyingParty(request);
|
|
1746
|
+
const clientDataJSON = Buffer.from(
|
|
1747
|
+
JSON.stringify({ type: "webauthn.get", challenge: request.challenge, origin: request.origin, crossOrigin: false })
|
|
1748
|
+
);
|
|
1749
|
+
const authenticatorData = Buffer.concat([
|
|
1750
|
+
sha256(Buffer.from(rpId)),
|
|
1751
|
+
Buffer.from([userPresentVerifiedAndSynced]),
|
|
1752
|
+
Buffer.alloc(4)
|
|
1753
|
+
]);
|
|
1754
|
+
const key = createPrivateKey({ key: Buffer.from(passkey.privateKey, "base64"), format: "der", type: "pkcs8" });
|
|
1755
|
+
const signed = Buffer.concat([authenticatorData, sha256(clientDataJSON)]);
|
|
1756
|
+
return {
|
|
1757
|
+
id: Buffer.from(passkey.credentialId, "base64").toString("base64url"),
|
|
1758
|
+
authenticatorData: authenticatorData.toString("base64url"),
|
|
1759
|
+
clientDataJSON: clientDataJSON.toString("base64url"),
|
|
1760
|
+
signature: sign(key.asymmetricKeyType === "ed25519" ? null : "sha256", signed, key).toString("base64url"),
|
|
1761
|
+
userHandle: Buffer.from(passkey.userHandle, "base64").toString("base64url")
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
function sha256(data) {
|
|
1765
|
+
return createHash("sha256").update(data).digest();
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
// src/store.ts
|
|
1769
|
+
import { randomUUID } from "node:crypto";
|
|
1770
|
+
import { link, mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
1771
|
+
import { join } from "node:path";
|
|
1772
|
+
|
|
1773
|
+
// src/base64url.ts
|
|
1774
|
+
function encode(bytes2) {
|
|
1775
|
+
return btoa(String.fromCharCode(...bytes2)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
1776
|
+
}
|
|
1777
|
+
function decode(text5) {
|
|
1778
|
+
return Uint8Array.from(atob(text5.replaceAll("-", "+").replaceAll("_", "/")), (char) => char.charCodeAt(0));
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
// src/hpke.ts
|
|
1782
|
+
var X25519 = { name: "X25519" };
|
|
1783
|
+
var text = new TextEncoder();
|
|
1784
|
+
var empty = new Uint8Array();
|
|
1785
|
+
var version = text.encode("HPKE-v1");
|
|
1786
|
+
var kemSuite = concat(text.encode("KEM"), [0, 32]);
|
|
1787
|
+
var hpkeSuite = concat(text.encode("HPKE"), [0, 32, 0, 1, 0, 1]);
|
|
1788
|
+
var pkcs8 = [48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32];
|
|
1789
|
+
async function generateKeyPair() {
|
|
1790
|
+
const pair = await crypto.subtle.generateKey(X25519, true, ["deriveBits"]);
|
|
1791
|
+
return {
|
|
1792
|
+
publicKey: new Uint8Array(await crypto.subtle.exportKey("raw", pair.publicKey)),
|
|
1793
|
+
privateKey: new Uint8Array(await crypto.subtle.exportKey("pkcs8", pair.privateKey)).slice(pkcs8.length)
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
async function seal(publicKey, info3, aad, plaintext) {
|
|
1797
|
+
const ephemeral = await crypto.subtle.generateKey(X25519, true, ["deriveBits"]);
|
|
1798
|
+
const enc = new Uint8Array(await crypto.subtle.exportKey("raw", ephemeral.publicKey));
|
|
1799
|
+
const { key, iv } = await setup(await diffieHellman(ephemeral.privateKey, publicKey), enc, publicKey, info3);
|
|
1800
|
+
return concat(
|
|
1801
|
+
enc,
|
|
1802
|
+
new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData: aad }, key, plaintext))
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1805
|
+
async function open(privateKey, info3, aad, sealed) {
|
|
1806
|
+
const recipient = await crypto.subtle.importKey("pkcs8", concat(pkcs8, privateKey), X25519, true, ["deriveBits"]);
|
|
1807
|
+
const { x } = await crypto.subtle.exportKey("jwk", recipient);
|
|
1808
|
+
const enc = sealed.subarray(0, 32);
|
|
1809
|
+
const { key, iv } = await setup(await diffieHellman(recipient, enc), enc, decode(x), info3);
|
|
1810
|
+
return new Uint8Array(
|
|
1811
|
+
await crypto.subtle.decrypt({ name: "AES-GCM", iv, additionalData: aad }, key, sealed.subarray(32))
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
async function diffieHellman(privateKey, publicKey) {
|
|
1815
|
+
const peer = await crypto.subtle.importKey("raw", publicKey, X25519, false, []);
|
|
1816
|
+
return new Uint8Array(await crypto.subtle.deriveBits({ name: "X25519", public: peer }, privateKey, 256));
|
|
1817
|
+
}
|
|
1818
|
+
async function setup(dh, enc, recipient, info3) {
|
|
1819
|
+
const prk = await labeledExtract(kemSuite, empty, "eae_prk", dh);
|
|
1820
|
+
const sharedSecret = await labeledExpand(kemSuite, prk, "shared_secret", concat(enc, recipient), 32);
|
|
1821
|
+
const context = concat(
|
|
1822
|
+
[0],
|
|
1823
|
+
await labeledExtract(hpkeSuite, empty, "psk_id_hash", empty),
|
|
1824
|
+
await labeledExtract(hpkeSuite, empty, "info_hash", info3)
|
|
1825
|
+
);
|
|
1826
|
+
const secret = await labeledExtract(hpkeSuite, sharedSecret, "secret", empty);
|
|
1827
|
+
const key = await labeledExpand(hpkeSuite, secret, "key", context, 16);
|
|
1828
|
+
return {
|
|
1829
|
+
key: await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt", "decrypt"]),
|
|
1830
|
+
iv: await labeledExpand(hpkeSuite, secret, "base_nonce", context, 12)
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
function labeledExtract(suite, salt, label, ikm) {
|
|
1834
|
+
return hmac(salt.length ? salt : new Uint8Array(32), concat(version, suite, text.encode(label), ikm));
|
|
1835
|
+
}
|
|
1836
|
+
async function labeledExpand(suite, prk, label, info3, length) {
|
|
1837
|
+
const block = await hmac(prk, concat([0, length], version, suite, text.encode(label), info3, [1]));
|
|
1838
|
+
return block.slice(0, length);
|
|
1839
|
+
}
|
|
1840
|
+
async function hmac(key, data) {
|
|
1841
|
+
const hmacKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
1842
|
+
return new Uint8Array(await crypto.subtle.sign("HMAC", hmacKey, data));
|
|
1843
|
+
}
|
|
1844
|
+
function concat(...parts) {
|
|
1845
|
+
const bytes2 = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));
|
|
1846
|
+
let offset = 0;
|
|
1847
|
+
for (const part of parts) {
|
|
1848
|
+
bytes2.set(part, offset);
|
|
1849
|
+
offset += part.length;
|
|
1850
|
+
}
|
|
1851
|
+
return bytes2;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
// src/store.ts
|
|
1855
|
+
var text2 = new TextEncoder();
|
|
1856
|
+
var info = text2.encode("enclave item");
|
|
1857
|
+
var extension = ".enclave";
|
|
1858
|
+
var Store = class {
|
|
1859
|
+
dir;
|
|
1860
|
+
keys;
|
|
1861
|
+
constructor(dir) {
|
|
1862
|
+
this.dir = dir;
|
|
1863
|
+
}
|
|
1864
|
+
async get(name) {
|
|
1865
|
+
const sealed = await readFile(this.path(name)).catch(missing);
|
|
1866
|
+
if (!sealed) return void 0;
|
|
1867
|
+
const { privateKey } = await this.key();
|
|
1868
|
+
return JSON.parse(new TextDecoder().decode(await open(privateKey, info, text2.encode(name), new Uint8Array(sealed))));
|
|
1869
|
+
}
|
|
1870
|
+
async put(name, item) {
|
|
1871
|
+
const { publicKey } = await this.key();
|
|
1872
|
+
const sealed = await seal(publicKey, info, text2.encode(name), text2.encode(JSON.stringify(item)));
|
|
1873
|
+
const temporary = await this.temporary(sealed);
|
|
1874
|
+
await rename(temporary, this.path(name));
|
|
1875
|
+
}
|
|
1876
|
+
async remove(name) {
|
|
1877
|
+
await rm(this.path(name), { force: true });
|
|
1878
|
+
}
|
|
1879
|
+
async names() {
|
|
1880
|
+
const files = await readdir(join(this.dir, "items")).catch(missing) ?? [];
|
|
1881
|
+
return files.filter((file) => file.endsWith(extension)).map((file) => decodeURIComponent(file.slice(0, -extension.length)));
|
|
1882
|
+
}
|
|
1883
|
+
path(name) {
|
|
1884
|
+
return join(this.dir, "items", encodeURIComponent(name) + extension);
|
|
1885
|
+
}
|
|
1886
|
+
key() {
|
|
1887
|
+
this.keys ??= this.load().catch((error) => {
|
|
1888
|
+
this.keys = void 0;
|
|
1889
|
+
throw error;
|
|
1890
|
+
});
|
|
1891
|
+
return this.keys;
|
|
1892
|
+
}
|
|
1893
|
+
async load() {
|
|
1894
|
+
const path = join(this.dir, "key.json");
|
|
1895
|
+
const saved = await readFile(path, "utf8").catch(missing);
|
|
1896
|
+
if (saved) {
|
|
1897
|
+
const { publicKey: publicKey2, privateKey: privateKey2 } = JSON.parse(saved);
|
|
1898
|
+
return { publicKey: decode(publicKey2), privateKey: decode(privateKey2) };
|
|
1899
|
+
}
|
|
1900
|
+
const { publicKey, privateKey } = await generateKeyPair();
|
|
1901
|
+
const temporary = await this.temporary(
|
|
1902
|
+
JSON.stringify({ publicKey: encode(publicKey), privateKey: encode(privateKey) })
|
|
1903
|
+
);
|
|
1904
|
+
await link(temporary, path).catch((error) => {
|
|
1905
|
+
if (error.code !== "EEXIST") throw error;
|
|
1906
|
+
}).finally(() => rm(temporary));
|
|
1907
|
+
return this.load();
|
|
1908
|
+
}
|
|
1909
|
+
async temporary(data) {
|
|
1910
|
+
const path = join(this.dir, "items", `${randomUUID()}.tmp`);
|
|
1911
|
+
await mkdir(join(this.dir, "items"), { recursive: true, mode: 448 });
|
|
1912
|
+
await writeFile(path, data, { mode: 384 });
|
|
1913
|
+
return path;
|
|
1914
|
+
}
|
|
1915
|
+
};
|
|
1916
|
+
function missing(error) {
|
|
1917
|
+
if (error.code !== "ENOENT") throw error;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1716
1920
|
// node_modules/convex/dist/esm/index.js
|
|
1717
|
-
var
|
|
1921
|
+
var version2 = "1.46.0";
|
|
1718
1922
|
|
|
1719
1923
|
// node_modules/convex/dist/esm/values/base64.js
|
|
1720
1924
|
var base64_exports = {};
|
|
@@ -1908,13 +2112,13 @@ function slowBigIntToBase64(value) {
|
|
|
1908
2112
|
}
|
|
1909
2113
|
let hex = value.toString(16);
|
|
1910
2114
|
if (hex.length % 2 === 1) hex = "0" + hex;
|
|
1911
|
-
const
|
|
2115
|
+
const bytes2 = new Uint8Array(new ArrayBuffer(8));
|
|
1912
2116
|
let i = 0;
|
|
1913
2117
|
for (const hexByte of hex.match(/.{2}/g).reverse()) {
|
|
1914
|
-
|
|
2118
|
+
bytes2.set([parseInt(hexByte, 16)], i++);
|
|
1915
2119
|
value >>= EIGHT;
|
|
1916
2120
|
}
|
|
1917
|
-
return fromByteArray(
|
|
2121
|
+
return fromByteArray(bytes2);
|
|
1918
2122
|
}
|
|
1919
2123
|
function slowBase64ToBigInt(encoded) {
|
|
1920
2124
|
const integerBytes = toByteArray(encoded);
|
|
@@ -3866,10 +4070,10 @@ var Long = class _Long {
|
|
|
3866
4070
|
return (obj && obj.__isUnsignedLong__) === true;
|
|
3867
4071
|
}
|
|
3868
4072
|
// prettier-ignore
|
|
3869
|
-
static fromBytesLE(
|
|
4073
|
+
static fromBytesLE(bytes2) {
|
|
3870
4074
|
return new _Long(
|
|
3871
|
-
|
|
3872
|
-
|
|
4075
|
+
bytes2[0] | bytes2[1] << 8 | bytes2[2] << 16 | bytes2[3] << 24,
|
|
4076
|
+
bytes2[4] | bytes2[5] << 8 | bytes2[6] << 16 | bytes2[7] << 24
|
|
3873
4077
|
);
|
|
3874
4078
|
}
|
|
3875
4079
|
// prettier-ignore
|
|
@@ -5255,7 +5459,7 @@ var BaseConvexClient = class {
|
|
|
5255
5459
|
} else {
|
|
5256
5460
|
throw new Error(`Unknown parent protocol ${protocol}`);
|
|
5257
5461
|
}
|
|
5258
|
-
const wsUri = `${wsProtocol}://${origin}/api/${
|
|
5462
|
+
const wsUri = `${wsProtocol}://${origin}/api/${version2}/sync`;
|
|
5259
5463
|
this.state = new LocalSyncState();
|
|
5260
5464
|
this.remoteQuerySet = new RemoteQuerySet(
|
|
5261
5465
|
(queryId) => this.state.queryPath(queryId),
|
|
@@ -5867,7 +6071,7 @@ var BaseConvexClient = class {
|
|
|
5867
6071
|
method: "POST",
|
|
5868
6072
|
headers: {
|
|
5869
6073
|
"Content-Type": "application/json",
|
|
5870
|
-
"Convex-Client": `npm-${
|
|
6074
|
+
"Convex-Client": `npm-${version2}`
|
|
5871
6075
|
},
|
|
5872
6076
|
body: JSON.stringify({ event: "LongWebsocketDisconnect" })
|
|
5873
6077
|
}).then((response) => {
|
|
@@ -6761,9 +6965,9 @@ var require_node_gyp_build = __commonJS2({
|
|
|
6761
6965
|
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
6762
6966
|
function resolve(dir2) {
|
|
6763
6967
|
var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
|
|
6764
|
-
var
|
|
6765
|
-
if (!
|
|
6766
|
-
var prebuilds = path.join(dir2, "prebuilds",
|
|
6968
|
+
var tuple2 = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
|
|
6969
|
+
if (!tuple2) return;
|
|
6970
|
+
var prebuilds = path.join(dir2, "prebuilds", tuple2.name);
|
|
6767
6971
|
var parsed = readdirSync(prebuilds).map(parseTags);
|
|
6768
6972
|
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
6769
6973
|
var winner = candidates.sort(compareTags(runtime))[0];
|
|
@@ -6795,10 +6999,10 @@ var require_node_gyp_build = __commonJS2({
|
|
|
6795
6999
|
return { name, platform: platform2, architectures };
|
|
6796
7000
|
}
|
|
6797
7001
|
function matchTuple(platform2, arch2) {
|
|
6798
|
-
return function(
|
|
6799
|
-
if (
|
|
6800
|
-
if (
|
|
6801
|
-
return
|
|
7002
|
+
return function(tuple2) {
|
|
7003
|
+
if (tuple2 == null) return false;
|
|
7004
|
+
if (tuple2.platform !== platform2) return false;
|
|
7005
|
+
return tuple2.architectures.includes(arch2);
|
|
6802
7006
|
};
|
|
6803
7007
|
}
|
|
6804
7008
|
function compareTuples(a, b) {
|
|
@@ -10651,8 +10855,8 @@ var ConvexHttpClient = class {
|
|
|
10651
10855
|
setAdminAuth(token, actingAsIdentity) {
|
|
10652
10856
|
this.clearAuth();
|
|
10653
10857
|
if (actingAsIdentity !== void 0) {
|
|
10654
|
-
const
|
|
10655
|
-
const actingAsIdentityEncoded = btoa(String.fromCodePoint(...
|
|
10858
|
+
const bytes2 = new TextEncoder().encode(JSON.stringify(actingAsIdentity));
|
|
10859
|
+
const actingAsIdentityEncoded = btoa(String.fromCodePoint(...bytes2));
|
|
10656
10860
|
this.adminAuth = `${token}:${actingAsIdentityEncoded}`;
|
|
10657
10861
|
} else {
|
|
10658
10862
|
this.adminAuth = token;
|
|
@@ -10715,7 +10919,7 @@ var ConvexHttpClient = class {
|
|
|
10715
10919
|
const localFetch = this.fetch || specifiedFetch || fetch;
|
|
10716
10920
|
const headers = {
|
|
10717
10921
|
"Content-Type": "application/json",
|
|
10718
|
-
"Convex-Client": `npm-${
|
|
10922
|
+
"Convex-Client": `npm-${version2}`
|
|
10719
10923
|
};
|
|
10720
10924
|
const response = await localFetch(`${this.address}/api/query_ts`, {
|
|
10721
10925
|
...this.fetchOptions,
|
|
@@ -10745,7 +10949,7 @@ var ConvexHttpClient = class {
|
|
|
10745
10949
|
const args = [convexToJson(queryArgs)];
|
|
10746
10950
|
const headers = {
|
|
10747
10951
|
"Content-Type": "application/json",
|
|
10748
|
-
"Convex-Client": `npm-${
|
|
10952
|
+
"Convex-Client": `npm-${version2}`
|
|
10749
10953
|
};
|
|
10750
10954
|
if (this.adminAuth) {
|
|
10751
10955
|
headers["Authorization"] = `Convex ${this.adminAuth}`;
|
|
@@ -10800,7 +11004,7 @@ var ConvexHttpClient = class {
|
|
|
10800
11004
|
});
|
|
10801
11005
|
const headers = {
|
|
10802
11006
|
"Content-Type": "application/json",
|
|
10803
|
-
"Convex-Client": `npm-${
|
|
11007
|
+
"Convex-Client": `npm-${version2}`
|
|
10804
11008
|
};
|
|
10805
11009
|
if (this.adminAuth) {
|
|
10806
11010
|
headers["Authorization"] = `Convex ${this.adminAuth}`;
|
|
@@ -10897,7 +11101,7 @@ var ConvexHttpClient = class {
|
|
|
10897
11101
|
});
|
|
10898
11102
|
const headers = {
|
|
10899
11103
|
"Content-Type": "application/json",
|
|
10900
|
-
"Convex-Client": `npm-${
|
|
11104
|
+
"Convex-Client": `npm-${version2}`
|
|
10901
11105
|
};
|
|
10902
11106
|
if (this.adminAuth) {
|
|
10903
11107
|
headers["Authorization"] = `Convex ${this.adminAuth}`;
|
|
@@ -10956,7 +11160,7 @@ var ConvexHttpClient = class {
|
|
|
10956
11160
|
});
|
|
10957
11161
|
const headers = {
|
|
10958
11162
|
"Content-Type": "application/json",
|
|
10959
|
-
"Convex-Client": `npm-${
|
|
11163
|
+
"Convex-Client": `npm-${version2}`
|
|
10960
11164
|
};
|
|
10961
11165
|
if (this.adminAuth) {
|
|
10962
11166
|
headers["Authorization"] = `Convex ${this.adminAuth}`;
|
|
@@ -11330,123 +11534,16 @@ var _systemSchema = defineSchema({
|
|
|
11330
11534
|
});
|
|
11331
11535
|
|
|
11332
11536
|
// src/vault.ts
|
|
11333
|
-
import {
|
|
11334
|
-
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
11537
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
11538
|
+
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rename as rename2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
11335
11539
|
import { homedir } from "node:os";
|
|
11336
11540
|
import { join as join2 } from "node:path";
|
|
11337
11541
|
|
|
11338
|
-
// src/base64url.ts
|
|
11339
|
-
function encode(bytes) {
|
|
11340
|
-
return btoa(String.fromCharCode(...bytes)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
11341
|
-
}
|
|
11342
|
-
function decode(text4) {
|
|
11343
|
-
return Uint8Array.from(atob(text4.replaceAll("-", "+").replaceAll("_", "/")), (char) => char.charCodeAt(0));
|
|
11344
|
-
}
|
|
11345
|
-
|
|
11346
|
-
// src/hpke.ts
|
|
11347
|
-
var X25519 = { name: "X25519" };
|
|
11348
|
-
var text = new TextEncoder();
|
|
11349
|
-
var empty = new Uint8Array();
|
|
11350
|
-
var version2 = text.encode("HPKE-v1");
|
|
11351
|
-
var kemSuite = concat(text.encode("KEM"), [0, 32]);
|
|
11352
|
-
var hpkeSuite = concat(text.encode("HPKE"), [0, 32, 0, 1, 0, 1]);
|
|
11353
|
-
var pkcs8 = [48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32];
|
|
11354
|
-
async function generateKeyPair() {
|
|
11355
|
-
const pair = await crypto.subtle.generateKey(X25519, true, ["deriveBits"]);
|
|
11356
|
-
return {
|
|
11357
|
-
publicKey: new Uint8Array(await crypto.subtle.exportKey("raw", pair.publicKey)),
|
|
11358
|
-
privateKey: new Uint8Array(await crypto.subtle.exportKey("pkcs8", pair.privateKey)).slice(pkcs8.length)
|
|
11359
|
-
};
|
|
11360
|
-
}
|
|
11361
|
-
async function seal(publicKey, info3, aad, plaintext) {
|
|
11362
|
-
const ephemeral = await crypto.subtle.generateKey(X25519, true, ["deriveBits"]);
|
|
11363
|
-
const enc = new Uint8Array(await crypto.subtle.exportKey("raw", ephemeral.publicKey));
|
|
11364
|
-
const { key, iv } = await setup(await diffieHellman(ephemeral.privateKey, publicKey), enc, publicKey, info3);
|
|
11365
|
-
return concat(enc, new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData: aad }, key, plaintext)));
|
|
11366
|
-
}
|
|
11367
|
-
async function open(privateKey, info3, aad, sealed) {
|
|
11368
|
-
const recipient = await crypto.subtle.importKey("pkcs8", concat(pkcs8, privateKey), X25519, true, ["deriveBits"]);
|
|
11369
|
-
const { x } = await crypto.subtle.exportKey("jwk", recipient);
|
|
11370
|
-
const enc = sealed.subarray(0, 32);
|
|
11371
|
-
const { key, iv } = await setup(await diffieHellman(recipient, enc), enc, decode(x), info3);
|
|
11372
|
-
return new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv, additionalData: aad }, key, sealed.subarray(32)));
|
|
11373
|
-
}
|
|
11374
|
-
async function diffieHellman(privateKey, publicKey) {
|
|
11375
|
-
const peer = await crypto.subtle.importKey("raw", publicKey, X25519, false, []);
|
|
11376
|
-
return new Uint8Array(await crypto.subtle.deriveBits({ name: "X25519", public: peer }, privateKey, 256));
|
|
11377
|
-
}
|
|
11378
|
-
async function setup(dh, enc, recipient, info3) {
|
|
11379
|
-
const prk = await labeledExtract(kemSuite, empty, "eae_prk", dh);
|
|
11380
|
-
const sharedSecret = await labeledExpand(kemSuite, prk, "shared_secret", concat(enc, recipient), 32);
|
|
11381
|
-
const context = concat(
|
|
11382
|
-
[0],
|
|
11383
|
-
await labeledExtract(hpkeSuite, empty, "psk_id_hash", empty),
|
|
11384
|
-
await labeledExtract(hpkeSuite, empty, "info_hash", info3)
|
|
11385
|
-
);
|
|
11386
|
-
const secret = await labeledExtract(hpkeSuite, sharedSecret, "secret", empty);
|
|
11387
|
-
const key = await labeledExpand(hpkeSuite, secret, "key", context, 16);
|
|
11388
|
-
return {
|
|
11389
|
-
key: await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt", "decrypt"]),
|
|
11390
|
-
iv: await labeledExpand(hpkeSuite, secret, "base_nonce", context, 12)
|
|
11391
|
-
};
|
|
11392
|
-
}
|
|
11393
|
-
function labeledExtract(suite, salt, label, ikm) {
|
|
11394
|
-
return hmac(salt.length ? salt : new Uint8Array(32), concat(version2, suite, text.encode(label), ikm));
|
|
11395
|
-
}
|
|
11396
|
-
async function labeledExpand(suite, prk, label, info3, length) {
|
|
11397
|
-
const block = await hmac(prk, concat([0, length], version2, suite, text.encode(label), info3, [1]));
|
|
11398
|
-
return block.slice(0, length);
|
|
11399
|
-
}
|
|
11400
|
-
async function hmac(key, data) {
|
|
11401
|
-
const hmacKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
11402
|
-
return new Uint8Array(await crypto.subtle.sign("HMAC", hmacKey, data));
|
|
11403
|
-
}
|
|
11404
|
-
function concat(...parts) {
|
|
11405
|
-
const bytes = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));
|
|
11406
|
-
let offset = 0;
|
|
11407
|
-
for (const part of parts) {
|
|
11408
|
-
bytes.set(part, offset);
|
|
11409
|
-
offset += part.length;
|
|
11410
|
-
}
|
|
11411
|
-
return bytes;
|
|
11412
|
-
}
|
|
11413
|
-
|
|
11414
11542
|
// src/answer.ts
|
|
11415
|
-
var
|
|
11416
|
-
var
|
|
11543
|
+
var text3 = new TextEncoder();
|
|
11544
|
+
var info2 = text3.encode("enclave answer");
|
|
11417
11545
|
async function openAnswer(privateKey, name, sealed) {
|
|
11418
|
-
return JSON.parse(new TextDecoder().decode(await open(privateKey,
|
|
11419
|
-
}
|
|
11420
|
-
|
|
11421
|
-
// src/passkey.ts
|
|
11422
|
-
import { createHash, createPrivateKey, sign } from "node:crypto";
|
|
11423
|
-
var userPresentVerifiedAndSynced = 1 | 4 | 8 | 16;
|
|
11424
|
-
function relyingParty({ origin, rpId }) {
|
|
11425
|
-
const host = new URL(origin).hostname;
|
|
11426
|
-
const id = rpId ?? host;
|
|
11427
|
-
if (host !== id && !host.endsWith(`.${id}`)) throw new Error(`${origin} can't use passkeys for ${id}`);
|
|
11428
|
-
return id;
|
|
11429
|
-
}
|
|
11430
|
-
function accepts(passkey, request) {
|
|
11431
|
-
const credentialId = Buffer.from(passkey.credentialId, "base64").toString("base64url");
|
|
11432
|
-
return passkey.rpId === relyingParty(request) && (!request.allowCredentials?.length || request.allowCredentials.includes(credentialId));
|
|
11433
|
-
}
|
|
11434
|
-
function signAssertion(passkey, request) {
|
|
11435
|
-
const rpId = relyingParty(request);
|
|
11436
|
-
const clientDataJSON = Buffer.from(JSON.stringify({ type: "webauthn.get", challenge: request.challenge, origin: request.origin, crossOrigin: false }));
|
|
11437
|
-
const authenticatorData = Buffer.concat([sha256(Buffer.from(rpId)), Buffer.from([userPresentVerifiedAndSynced]), Buffer.alloc(4)]);
|
|
11438
|
-
const key = createPrivateKey({ key: Buffer.from(passkey.privateKey, "base64"), format: "der", type: "pkcs8" });
|
|
11439
|
-
const signed = Buffer.concat([authenticatorData, sha256(clientDataJSON)]);
|
|
11440
|
-
return {
|
|
11441
|
-
id: Buffer.from(passkey.credentialId, "base64").toString("base64url"),
|
|
11442
|
-
authenticatorData: authenticatorData.toString("base64url"),
|
|
11443
|
-
clientDataJSON: clientDataJSON.toString("base64url"),
|
|
11444
|
-
signature: sign(key.asymmetricKeyType === "ed25519" ? null : "sha256", signed, key).toString("base64url"),
|
|
11445
|
-
userHandle: Buffer.from(passkey.userHandle, "base64").toString("base64url")
|
|
11446
|
-
};
|
|
11447
|
-
}
|
|
11448
|
-
function sha256(data) {
|
|
11449
|
-
return createHash("sha256").update(data).digest();
|
|
11546
|
+
return JSON.parse(new TextDecoder().decode(await open(privateKey, info2, text3.encode(name), sealed)));
|
|
11450
11547
|
}
|
|
11451
11548
|
|
|
11452
11549
|
// src/proton.ts
|
|
@@ -11454,66 +11551,93 @@ var import_msgpack = __toESM(require_dist(), 1);
|
|
|
11454
11551
|
import { execFile } from "node:child_process";
|
|
11455
11552
|
import { createPrivateKey as createPrivateKey2 } from "node:crypto";
|
|
11456
11553
|
import { promisify } from "node:util";
|
|
11457
|
-
var
|
|
11554
|
+
var bytes = array(number());
|
|
11555
|
+
var text4 = string().min(1);
|
|
11556
|
+
var lines = array(unknown()).transform((values) => values.flatMap((value) => text4.safeParse(value).data ?? []).join("\n"));
|
|
11557
|
+
var section = record(string(), unknown());
|
|
11558
|
+
var passkeys = array(object({ content: bytes }));
|
|
11559
|
+
var protonItem = object({
|
|
11560
|
+
title: string(),
|
|
11561
|
+
content: record(string(), unknown()),
|
|
11562
|
+
note: string().nullish(),
|
|
11563
|
+
extra_fields: array(object({ name: string(), content: record(string(), unknown()) })).nullish()
|
|
11564
|
+
});
|
|
11565
|
+
var vaultList = object({ vaults: array(object({ name: string() })) });
|
|
11566
|
+
var itemList = object({ items: array(object({ id: string(), share_id: string(), content: protonItem })) });
|
|
11567
|
+
var sealedPasskey = object({ v: number(), c: bytes });
|
|
11568
|
+
var passkeyData = object({
|
|
11569
|
+
rid: string(),
|
|
11570
|
+
cid: bytes,
|
|
11571
|
+
uhd: bytes.optional(),
|
|
11572
|
+
un: string().optional(),
|
|
11573
|
+
key: object({
|
|
11574
|
+
kty: object({ c: _enum(["EC2", "OKP"]) }),
|
|
11575
|
+
par: array(tuple([object({ c: number() }), object({ c: unknown() })]))
|
|
11576
|
+
})
|
|
11577
|
+
});
|
|
11578
|
+
var renamed = /* @__PURE__ */ new Map([["totp_uri", "totp"]]);
|
|
11458
11579
|
var run = promisify(execFile);
|
|
11459
|
-
async function
|
|
11460
|
-
const
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
if (attempt >= attempts) throw error;
|
|
11466
|
-
await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 1e3));
|
|
11467
|
-
}
|
|
11580
|
+
async function pass(args) {
|
|
11581
|
+
const { stdout } = await run(process.env.ENCLAVE_PASS_CLI ?? "pass-cli", args, { maxBuffer: 256 << 20 }).catch(
|
|
11582
|
+
(error) => {
|
|
11583
|
+
throw new Error(
|
|
11584
|
+
`pass-cli ${args.slice(0, 2).join(" ")} failed (is it signed in? pass-cli info): ${String(error.stderr || error.message).trim()}`
|
|
11585
|
+
);
|
|
11468
11586
|
}
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11587
|
+
);
|
|
11588
|
+
return JSON.parse(stdout);
|
|
11589
|
+
}
|
|
11590
|
+
async function protonVaults() {
|
|
11591
|
+
return vaultList.parse(await pass(["vault", "list", "--output=json"])).vaults.map((vault2) => vault2.name);
|
|
11592
|
+
}
|
|
11593
|
+
async function readProton(vault2) {
|
|
11594
|
+
const { items } = itemList.parse(
|
|
11595
|
+
await pass(["item", "list", `--vault-name=${vault2}`, "--filter-state=active", "--output=json", "--show-secrets"])
|
|
11596
|
+
);
|
|
11597
|
+
return items.map((item) => ({ id: `${item.share_id}/${item.id}`, vault: vault2, content: item.content }));
|
|
11476
11598
|
}
|
|
11477
11599
|
function* toItems(proton, items = /* @__PURE__ */ new Map()) {
|
|
11478
11600
|
for (const entry of proton) {
|
|
11479
11601
|
const item = toItem(entry);
|
|
11480
11602
|
if (!Object.keys(item).length) continue;
|
|
11481
11603
|
const who = item.email ?? item.username;
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11604
|
+
const title = entry.title.trim() || "Untitled";
|
|
11605
|
+
let name = title;
|
|
11606
|
+
if (items.has(name) && who) name = `${title} (${who})`;
|
|
11607
|
+
for (let n = 2; items.has(name); n++) name = `${title} (${n})`;
|
|
11485
11608
|
items.set(name, item);
|
|
11486
|
-
yield [name, item];
|
|
11609
|
+
yield [name, item, entry];
|
|
11487
11610
|
}
|
|
11488
11611
|
}
|
|
11489
|
-
function toItem({ content, note, extra_fields
|
|
11612
|
+
function toItem({ content, note, extra_fields }) {
|
|
11490
11613
|
const item = {};
|
|
11491
11614
|
const add = (field, value) => {
|
|
11492
|
-
if (
|
|
11615
|
+
if (!value) return;
|
|
11493
11616
|
let name = field;
|
|
11494
11617
|
for (let n = 2; name in item; n++) name = `${field} ${n}`;
|
|
11495
11618
|
item[name] = value;
|
|
11496
11619
|
};
|
|
11497
11620
|
for (const fields of Object.values(content)) {
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
else
|
|
11502
|
-
else add(renamed[field] ?? field, value);
|
|
11621
|
+
for (const [field, value] of Object.entries(section.safeParse(fields).data ?? {})) {
|
|
11622
|
+
if (field === "passkeys")
|
|
11623
|
+
for (const passkey of passkeys.parse(value)) add("passkey", JSON.stringify(readPasskey(passkey.content)));
|
|
11624
|
+
else add(renamed.get(field) ?? field, union([text4, lines]).safeParse(value).data);
|
|
11503
11625
|
}
|
|
11504
11626
|
}
|
|
11505
|
-
for (const extra of extra_fields
|
|
11506
|
-
|
|
11627
|
+
for (const extra of extra_fields ?? []) {
|
|
11628
|
+
const [kind, value] = Object.entries(extra.content)[0] ?? [];
|
|
11629
|
+
add(kind === "Totp" ? "totp" : extra.name.toLowerCase(), text4.safeParse(value).data);
|
|
11630
|
+
}
|
|
11631
|
+
add("note", note ?? void 0);
|
|
11507
11632
|
return item;
|
|
11508
11633
|
}
|
|
11509
11634
|
function readPasskey(content) {
|
|
11510
|
-
const outer = (0, import_msgpack.decode)(Uint8Array.from(content));
|
|
11635
|
+
const outer = sealedPasskey.parse((0, import_msgpack.decode)(Uint8Array.from(content)));
|
|
11511
11636
|
if (outer.v !== 1) throw new Error(`unknown Proton passkey format ${outer.v}`);
|
|
11512
|
-
const passkey = (0, import_msgpack.decode)(Uint8Array.from(outer.c));
|
|
11513
|
-
const
|
|
11514
|
-
const
|
|
11515
|
-
const
|
|
11516
|
-
const jwk = key.kty.c === "EC2" ? { kty: "EC", crv: "P-256", x: bytes(-2), y: bytes(-3), d: bytes(-4) } : { kty: "OKP", crv: "Ed25519", x: bytes(-2), d: bytes(-4) };
|
|
11637
|
+
const passkey = passkeyData.parse((0, import_msgpack.decode)(Uint8Array.from(outer.c)));
|
|
11638
|
+
const parameters = new Map(passkey.key.par.map(([label, value]) => [label.c, value.c]));
|
|
11639
|
+
const parameter = (label) => Buffer.from(bytes.parse(parameters.get(label))).toString("base64url");
|
|
11640
|
+
const jwk = passkey.key.kty.c === "EC2" ? { kty: "EC", crv: "P-256", x: parameter(-2), y: parameter(-3), d: parameter(-4) } : { kty: "OKP", crv: "Ed25519", x: parameter(-2), d: parameter(-4) };
|
|
11517
11641
|
return {
|
|
11518
11642
|
rpId: passkey.rid,
|
|
11519
11643
|
credentialId: Buffer.from(passkey.cid).toString("base64"),
|
|
@@ -11546,16 +11670,16 @@ async function runWithSecrets(command, secrets, stdio = terminal) {
|
|
|
11546
11670
|
function redact(secrets) {
|
|
11547
11671
|
const hidden = Object.entries(secrets).filter(([, value]) => value).sort(([, a], [, b]) => b.length - a.length);
|
|
11548
11672
|
const held = Math.max(0, ...hidden.map(([, value]) => value.length - 1));
|
|
11549
|
-
const hide = (
|
|
11673
|
+
const hide = (text5) => hidden.reduce((text6, [name, value]) => text6.replaceAll(value, `[hidden ${name}]`), text5);
|
|
11550
11674
|
const decoder = new StringDecoder("utf8");
|
|
11551
11675
|
let tail = "";
|
|
11552
11676
|
return new Transform({
|
|
11553
11677
|
transform(chunk, _encoding, done) {
|
|
11554
|
-
const
|
|
11555
|
-
const end = Math.max(0,
|
|
11556
|
-
const split = isHighSurrogate(
|
|
11557
|
-
tail =
|
|
11558
|
-
done(null,
|
|
11678
|
+
const text5 = hide(tail + decoder.write(chunk));
|
|
11679
|
+
const end = Math.max(0, text5.length - held);
|
|
11680
|
+
const split = isHighSurrogate(text5.charCodeAt(end - 1)) ? end - 1 : end;
|
|
11681
|
+
tail = text5.slice(split);
|
|
11682
|
+
done(null, text5.slice(0, split));
|
|
11559
11683
|
},
|
|
11560
11684
|
flush(done) {
|
|
11561
11685
|
done(null, hide(tail + decoder.end()));
|
|
@@ -11566,65 +11690,6 @@ function isHighSurrogate(code2) {
|
|
|
11566
11690
|
return code2 >= 55296 && code2 <= 56319;
|
|
11567
11691
|
}
|
|
11568
11692
|
|
|
11569
|
-
// src/store.ts
|
|
11570
|
-
import { randomUUID } from "node:crypto";
|
|
11571
|
-
import { link, mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
11572
|
-
import { join } from "node:path";
|
|
11573
|
-
var text3 = new TextEncoder();
|
|
11574
|
-
var info2 = text3.encode("enclave item");
|
|
11575
|
-
var extension = ".enclave";
|
|
11576
|
-
var Store = class {
|
|
11577
|
-
dir;
|
|
11578
|
-
constructor(dir) {
|
|
11579
|
-
this.dir = dir;
|
|
11580
|
-
}
|
|
11581
|
-
async get(name) {
|
|
11582
|
-
const sealed = await readFile(this.path(name)).catch(missing);
|
|
11583
|
-
if (!sealed) return void 0;
|
|
11584
|
-
const { privateKey } = await this.key();
|
|
11585
|
-
return JSON.parse(new TextDecoder().decode(await open(privateKey, info2, text3.encode(name), new Uint8Array(sealed))));
|
|
11586
|
-
}
|
|
11587
|
-
async put(name, item) {
|
|
11588
|
-
const { publicKey } = await this.key();
|
|
11589
|
-
const sealed = await seal(publicKey, info2, text3.encode(name), text3.encode(JSON.stringify(item)));
|
|
11590
|
-
const temporary = await this.temporary(sealed);
|
|
11591
|
-
await rename(temporary, this.path(name));
|
|
11592
|
-
}
|
|
11593
|
-
async remove(name) {
|
|
11594
|
-
await rm(this.path(name), { force: true });
|
|
11595
|
-
}
|
|
11596
|
-
async names() {
|
|
11597
|
-
const files = await readdir(join(this.dir, "items")).catch(missing) ?? [];
|
|
11598
|
-
return files.filter((file) => file.endsWith(extension)).map((file) => decodeURIComponent(file.slice(0, -extension.length)));
|
|
11599
|
-
}
|
|
11600
|
-
path(name) {
|
|
11601
|
-
return join(this.dir, "items", encodeURIComponent(name) + extension);
|
|
11602
|
-
}
|
|
11603
|
-
async key() {
|
|
11604
|
-
const path = join(this.dir, "key.json");
|
|
11605
|
-
const saved = await readFile(path, "utf8").catch(missing);
|
|
11606
|
-
if (saved) {
|
|
11607
|
-
const { publicKey: publicKey2, privateKey: privateKey2 } = JSON.parse(saved);
|
|
11608
|
-
return { publicKey: decode(publicKey2), privateKey: decode(privateKey2) };
|
|
11609
|
-
}
|
|
11610
|
-
const { publicKey, privateKey } = await generateKeyPair();
|
|
11611
|
-
const temporary = await this.temporary(JSON.stringify({ publicKey: encode(publicKey), privateKey: encode(privateKey) }));
|
|
11612
|
-
await link(temporary, path).catch((error) => {
|
|
11613
|
-
if (error.code !== "EEXIST") throw error;
|
|
11614
|
-
}).finally(() => rm(temporary));
|
|
11615
|
-
return this.key();
|
|
11616
|
-
}
|
|
11617
|
-
async temporary(data) {
|
|
11618
|
-
const path = join(this.dir, "items", `${randomUUID()}.tmp`);
|
|
11619
|
-
await mkdir(join(this.dir, "items"), { recursive: true, mode: 448 });
|
|
11620
|
-
await writeFile(path, data, { mode: 384 });
|
|
11621
|
-
return path;
|
|
11622
|
-
}
|
|
11623
|
-
};
|
|
11624
|
-
function missing(error) {
|
|
11625
|
-
if (error.code !== "ENOENT") throw error;
|
|
11626
|
-
}
|
|
11627
|
-
|
|
11628
11693
|
// src/totp.ts
|
|
11629
11694
|
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
11630
11695
|
async function totp(setupKey, now = Date.now()) {
|
|
@@ -11640,21 +11705,21 @@ async function totp(setupKey, now = Date.now()) {
|
|
|
11640
11705
|
const code2 = (mac.getUint32(mac.getUint8(mac.byteLength - 1) & 15) & 2147483647) % 10 ** digits;
|
|
11641
11706
|
return String(code2).padStart(digits, "0");
|
|
11642
11707
|
}
|
|
11643
|
-
function decodeBase32(
|
|
11644
|
-
const
|
|
11708
|
+
function decodeBase32(text5) {
|
|
11709
|
+
const bytes2 = [];
|
|
11645
11710
|
let value = 0;
|
|
11646
11711
|
let bits = 0;
|
|
11647
|
-
for (const char of
|
|
11712
|
+
for (const char of text5.toUpperCase().replace(/[\s=-]/g, "")) {
|
|
11648
11713
|
const index = alphabet.indexOf(char);
|
|
11649
11714
|
if (index < 0) throw new Error("that 2FA setup key isn't valid");
|
|
11650
11715
|
value = (value << 5 | index) & 4095;
|
|
11651
11716
|
bits += 5;
|
|
11652
11717
|
if (bits >= 8) {
|
|
11653
11718
|
bits -= 8;
|
|
11654
|
-
|
|
11719
|
+
bytes2.push(value >> bits & 255);
|
|
11655
11720
|
}
|
|
11656
11721
|
}
|
|
11657
|
-
return new Uint8Array(
|
|
11722
|
+
return new Uint8Array(bytes2);
|
|
11658
11723
|
}
|
|
11659
11724
|
|
|
11660
11725
|
// src/vault.ts
|
|
@@ -11667,102 +11732,169 @@ var requests = {
|
|
|
11667
11732
|
function openVault({
|
|
11668
11733
|
from = process.env.ENCLAVE_FROM,
|
|
11669
11734
|
home = process.env.ENCLAVE_HOME ?? join2(homedir(), ".enclave"),
|
|
11670
|
-
relay = process.env.ENCLAVE_RELAY ?? hostedRelay
|
|
11735
|
+
relay = process.env.ENCLAVE_RELAY ?? hostedRelay,
|
|
11736
|
+
store = new Store(home)
|
|
11671
11737
|
} = {}) {
|
|
11672
|
-
const store = new Store(home);
|
|
11673
11738
|
const pendingPath = (name) => join2(home, "pending", `${encodeURIComponent(name)}.json`);
|
|
11674
11739
|
async function readPending(name) {
|
|
11675
11740
|
const json = await readFile2(pendingPath(name), "utf8").catch(() => void 0);
|
|
11676
11741
|
return json ? JSON.parse(json) : void 0;
|
|
11677
11742
|
}
|
|
11678
11743
|
async function ask(name, fields = ["password"]) {
|
|
11744
|
+
if (!fields.length || fields.some((field) => !field.trim()) || new Set(fields).size < fields.length)
|
|
11745
|
+
throw new Error("ask for at least one field, each with its own name");
|
|
11679
11746
|
const token = encode(crypto.getRandomValues(new Uint8Array(32)));
|
|
11680
11747
|
const { publicKey, privateKey } = await generateKeyPair();
|
|
11681
11748
|
const url = await new ConvexHttpClient(relay, { logger: false }).mutation(requests.open, { token });
|
|
11682
11749
|
const previous = await readPending(name);
|
|
11683
|
-
if (previous)
|
|
11750
|
+
if (previous)
|
|
11751
|
+
await new ConvexHttpClient(previous.relay, { logger: false }).mutation(requests.close, { token: previous.token }).catch(() => void 0);
|
|
11752
|
+
const pending = { relay, token, privateKey: encode(privateKey), fields };
|
|
11684
11753
|
await mkdir2(join2(home, "pending"), { recursive: true, mode: 448 });
|
|
11685
|
-
|
|
11754
|
+
const temporary = `${pendingPath(name)}.${randomUUID2()}`;
|
|
11755
|
+
await writeFile2(temporary, JSON.stringify(pending), { mode: 384 });
|
|
11756
|
+
await rename2(temporary, pendingPath(name));
|
|
11686
11757
|
const fragment = new URLSearchParams([
|
|
11687
11758
|
...from ? [["from", from]] : [],
|
|
11688
11759
|
["name", name],
|
|
11689
11760
|
...fields.map((field) => ["field", field]),
|
|
11690
11761
|
["key", encode(publicKey)]
|
|
11691
11762
|
]);
|
|
11692
|
-
return { url: `${url}#${fragment}`, wait: () =>
|
|
11763
|
+
return { url: `${url}#${fragment}`, wait: () => waitFor(name, pending) };
|
|
11693
11764
|
}
|
|
11694
|
-
async function wait(name) {
|
|
11765
|
+
async function wait(name, signal) {
|
|
11695
11766
|
const pending = await readPending(name);
|
|
11696
11767
|
if (!pending) throw new Error(`nothing asked for ${name}`);
|
|
11768
|
+
return waitFor(name, pending, signal);
|
|
11769
|
+
}
|
|
11770
|
+
async function waitFor(name, pending, signal) {
|
|
11697
11771
|
const client = new ConvexClient(pending.relay, { logger: false });
|
|
11772
|
+
const forget = async () => {
|
|
11773
|
+
const current = await readPending(name);
|
|
11774
|
+
if (current?.token === pending.token) await rm2(pendingPath(name), { force: true });
|
|
11775
|
+
return current && current.token !== pending.token;
|
|
11776
|
+
};
|
|
11698
11777
|
try {
|
|
11699
|
-
const sealed = await new Promise(
|
|
11700
|
-
(
|
|
11778
|
+
const sealed = await new Promise((resolve, reject) => {
|
|
11779
|
+
signal?.throwIfAborted();
|
|
11780
|
+
signal?.addEventListener("abort", () => reject(signal.reason));
|
|
11781
|
+
client.onUpdate(
|
|
11701
11782
|
requests.watch,
|
|
11702
11783
|
{ token: pending.token },
|
|
11703
11784
|
(request) => {
|
|
11704
|
-
if (!request)
|
|
11785
|
+
if (!request) resolve(null);
|
|
11705
11786
|
else if (request.answer) resolve(request.answer);
|
|
11706
11787
|
},
|
|
11707
11788
|
reject
|
|
11708
|
-
)
|
|
11709
|
-
);
|
|
11710
|
-
|
|
11711
|
-
|
|
11789
|
+
);
|
|
11790
|
+
});
|
|
11791
|
+
if (!sealed)
|
|
11792
|
+
throw new Error(
|
|
11793
|
+
await forget() ? `a newer link for ${name} replaced this one` : `the link for ${name} expired`
|
|
11794
|
+
);
|
|
11795
|
+
const answer = record(string(), string()).safeParse(await openAnswer(decode(pending.privateKey), name, new Uint8Array(sealed))).data;
|
|
11796
|
+
if (!answer || !pending.fields.every((field) => field in answer))
|
|
11797
|
+
throw new Error(`the answer for ${name} is incomplete`);
|
|
11712
11798
|
const update = Object.fromEntries(pending.fields.map((field) => [field, answer[field]]));
|
|
11713
11799
|
await store.put(name, { ...await store.get(name), ...update });
|
|
11800
|
+
await client.mutation(requests.close, { token: pending.token }).catch(() => void 0);
|
|
11801
|
+
await forget();
|
|
11714
11802
|
return pending.fields;
|
|
11715
11803
|
} finally {
|
|
11716
|
-
await client.mutation(requests.close, { token: pending.token });
|
|
11717
11804
|
await client.close();
|
|
11718
|
-
await rm2(pendingPath(name), { force: true });
|
|
11719
11805
|
}
|
|
11720
11806
|
}
|
|
11721
|
-
async function
|
|
11807
|
+
async function read(name, field) {
|
|
11722
11808
|
const value = (await store.get(name))?.[field];
|
|
11723
11809
|
if (value === void 0) throw new Error(`no ${field} saved for ${name}`);
|
|
11724
|
-
return
|
|
11725
|
-
}
|
|
11726
|
-
async function list() {
|
|
11727
|
-
const names = await store.names();
|
|
11728
|
-
return Promise.all(names.map(async (name) => ({ name, fields: Object.keys(await store.get(name) ?? {}) })));
|
|
11810
|
+
return value;
|
|
11729
11811
|
}
|
|
11730
|
-
async function
|
|
11731
|
-
const
|
|
11732
|
-
|
|
11733
|
-
|
|
11812
|
+
async function get(name, field) {
|
|
11813
|
+
const kind = field.match(/^(totp|passkey)( \d+)?$/)?.[1];
|
|
11814
|
+
if (kind === "passkey")
|
|
11815
|
+
throw new Error(`${name}'s ${field} stays in the vault: sign in with it through \`enclave passkey\``);
|
|
11816
|
+
const value = await read(name, field);
|
|
11817
|
+
return kind === "totp" ? totp(value) : value;
|
|
11818
|
+
}
|
|
11819
|
+
async function list(search) {
|
|
11820
|
+
const term = search?.toLowerCase();
|
|
11821
|
+
const items = await Promise.all(
|
|
11822
|
+
(await store.names()).map(async (name) => ({ name, item: await store.get(name) ?? {} }))
|
|
11823
|
+
);
|
|
11824
|
+
return items.filter(
|
|
11825
|
+
({ name, item }) => !term || name.toLowerCase().includes(term) || sites(item).some((site) => site.includes(term))
|
|
11826
|
+
).map(({ name, item }) => ({ name, fields: Object.keys(item) }));
|
|
11827
|
+
}
|
|
11828
|
+
async function importProton(vaults = []) {
|
|
11829
|
+
const manifest = join2(home, "proton.json");
|
|
11830
|
+
const saved = await readFile2(manifest, "utf8").catch(() => void 0);
|
|
11831
|
+
const before = saved ? JSON.parse(saved) : {};
|
|
11832
|
+
const read2 = vaults.length ? vaults : await protonVaults();
|
|
11833
|
+
const entries = (await Promise.all(read2.map(readProton))).flat();
|
|
11834
|
+
const protonNames = new Set(Object.values(before).map(({ name }) => name));
|
|
11835
|
+
const taken = new Map(
|
|
11836
|
+
saved ? (await store.names()).filter((name) => !protonNames.has(name)).map((name) => [name, true]) : []
|
|
11837
|
+
);
|
|
11838
|
+
const after = {};
|
|
11839
|
+
const fresh = [];
|
|
11840
|
+
for (const entry of entries) {
|
|
11841
|
+
const name = before[entry.id]?.name;
|
|
11842
|
+
const title = entry.content.title.trim() || "Untitled";
|
|
11843
|
+
if (name && (name === title || name.startsWith(`${title} (`)) && !taken.has(name) && Object.keys(toItem(entry.content)).length) {
|
|
11844
|
+
after[entry.id] = { name, vault: entry.vault };
|
|
11845
|
+
taken.set(name, true);
|
|
11846
|
+
} else fresh.push(entry);
|
|
11847
|
+
}
|
|
11848
|
+
const byContent = new Map(fresh.map((entry) => [entry.content, entry]));
|
|
11849
|
+
for (const [name, , content] of toItems(
|
|
11850
|
+
fresh.map((entry) => entry.content),
|
|
11851
|
+
taken
|
|
11852
|
+
))
|
|
11853
|
+
after[byContent.get(content).id] = { name, vault: byContent.get(content).vault };
|
|
11854
|
+
const imported = new Map(
|
|
11855
|
+
entries.filter((entry) => after[entry.id]).map((entry) => [after[entry.id].name, toItem(entry.content)])
|
|
11856
|
+
);
|
|
11857
|
+
for (const [name, item] of imported) await store.put(name, item);
|
|
11858
|
+
const removed = Object.values(before).filter(({ name, vault: vault2 }) => read2.includes(vault2) && !imported.has(name)).map(({ name }) => name);
|
|
11859
|
+
for (const name of removed) await store.remove(name);
|
|
11860
|
+
const kept = Object.fromEntries(Object.entries(before).filter(([, { vault: vault2 }]) => !read2.includes(vault2)));
|
|
11861
|
+
const temporary = `${manifest}.${randomUUID2()}`;
|
|
11862
|
+
await writeFile2(temporary, JSON.stringify({ ...kept, ...after }), { mode: 384 });
|
|
11863
|
+
await rename2(temporary, manifest);
|
|
11864
|
+
return { items: [...imported].map(([name, item]) => ({ name, fields: Object.keys(item) })), removed };
|
|
11734
11865
|
}
|
|
11735
11866
|
const armed = join2(home, "armed");
|
|
11736
11867
|
async function passkey(name, field = "passkey", timeout = 3e5) {
|
|
11737
|
-
await
|
|
11868
|
+
await read(name, field);
|
|
11738
11869
|
await mkdir2(armed, { recursive: true, mode: 448 });
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
const signedIn = new Promise((resolve, reject) => {
|
|
11742
|
-
const watcher = watch(armed, () => readFile2(path).catch(() => done()));
|
|
11743
|
-
const timer = setTimeout(() => done(new Error(`nobody signed in with ${name}'s passkey in time`)), timeout);
|
|
11744
|
-
const done = (error) => {
|
|
11745
|
-
watcher.close();
|
|
11746
|
-
clearTimeout(timer);
|
|
11747
|
-
if (error) rm2(path, { force: true }).then(() => reject(error));
|
|
11748
|
-
else resolve();
|
|
11749
|
-
};
|
|
11870
|
+
await writeFile2(join2(armed, `${randomUUID2()}.json`), JSON.stringify({ name, field, until: Date.now() + timeout }), {
|
|
11871
|
+
mode: 384
|
|
11750
11872
|
});
|
|
11751
|
-
signedIn.catch(() => void 0);
|
|
11752
|
-
return { signedIn };
|
|
11753
11873
|
}
|
|
11754
11874
|
async function sign2(request) {
|
|
11755
|
-
for (const file of await readdir2(armed).catch(() => [])) {
|
|
11875
|
+
for (const file of (await readdir2(armed).catch(() => [])).filter((file2) => file2.endsWith(".json"))) {
|
|
11756
11876
|
const path = join2(armed, file);
|
|
11757
|
-
const
|
|
11758
|
-
if (!name
|
|
11759
|
-
|
|
11877
|
+
const arm = JSON.parse(await readFile2(path, "utf8").catch(() => "{}"));
|
|
11878
|
+
if (!arm.name) continue;
|
|
11879
|
+
if (arm.until < Date.now()) {
|
|
11880
|
+
await rm2(path, { force: true });
|
|
11881
|
+
continue;
|
|
11882
|
+
}
|
|
11883
|
+
const key = JSON.parse(await read(arm.name, arm.field));
|
|
11760
11884
|
if (!accepts(key, request)) continue;
|
|
11761
|
-
await
|
|
11885
|
+
const claimed = await rename2(path, `${path}.used`).then(
|
|
11886
|
+
() => true,
|
|
11887
|
+
() => false
|
|
11888
|
+
);
|
|
11889
|
+
if (!claimed) continue;
|
|
11890
|
+
await rm2(`${path}.used`, { force: true });
|
|
11762
11891
|
return signAssertion(key, request);
|
|
11763
11892
|
}
|
|
11764
11893
|
throw new Error(`no passkey is ready for ${request.rpId ?? new URL(request.origin).hostname}`);
|
|
11765
11894
|
}
|
|
11895
|
+
async function save(name, field, value) {
|
|
11896
|
+
await store.put(name, { ...await store.get(name), [field]: value });
|
|
11897
|
+
}
|
|
11766
11898
|
async function remove(name) {
|
|
11767
11899
|
await store.remove(name);
|
|
11768
11900
|
}
|
|
@@ -11776,11 +11908,16 @@ function openVault({
|
|
|
11776
11908
|
);
|
|
11777
11909
|
return runWithSecrets(command, Object.fromEntries(values), stdio);
|
|
11778
11910
|
}
|
|
11779
|
-
return { ask, wait, get, list, remove, run: run2, importProton, passkey, sign: sign2 };
|
|
11911
|
+
return { ask, wait, get, save, list, remove, run: run2, importProton, passkey, sign: sign2 };
|
|
11780
11912
|
}
|
|
11781
11913
|
var vault = openVault();
|
|
11914
|
+
function sites(item) {
|
|
11915
|
+
return Object.entries(item).filter(([field]) => /^(urls?|website|original login uri)( \d+)?$/.test(field)).flatMap(([, value]) => value.toLowerCase().split(/\s+/));
|
|
11916
|
+
}
|
|
11782
11917
|
|
|
11783
11918
|
export {
|
|
11919
|
+
signRequest,
|
|
11920
|
+
Store,
|
|
11784
11921
|
openVault,
|
|
11785
11922
|
vault
|
|
11786
11923
|
};
|