@tinycloud/sdk-services 2.2.1-beta.0 → 2.3.0-beta.5
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/dist/encryption/index.cjs +70 -27
- package/dist/encryption/index.cjs.map +1 -1
- package/dist/encryption/index.d.cts +25 -25
- package/dist/encryption/index.d.ts +25 -25
- package/dist/encryption/index.js +70 -27
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +70 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +70 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -452,6 +452,7 @@ function canonicalHashHex(sha256, value) {
|
|
|
452
452
|
// src/encryption/networkId.ts
|
|
453
453
|
var URN_PREFIX = "urn:tinycloud:encryption:";
|
|
454
454
|
var NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
455
|
+
var PKH_EIP155_DID_RE = /^did:pkh:eip155:(\d+):(0x[a-fA-F0-9]{40})$/;
|
|
455
456
|
var NetworkIdError = class extends Error {
|
|
456
457
|
constructor(message) {
|
|
457
458
|
super(message);
|
|
@@ -471,20 +472,20 @@ function parseNetworkId(networkId) {
|
|
|
471
472
|
const lastColon = body.lastIndexOf(":");
|
|
472
473
|
if (lastColon <= 0 || lastColon === body.length - 1) {
|
|
473
474
|
throw new NetworkIdError(
|
|
474
|
-
`networkId missing
|
|
475
|
+
`networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`
|
|
475
476
|
);
|
|
476
477
|
}
|
|
477
|
-
const
|
|
478
|
+
const ownerDid = body.slice(0, lastColon);
|
|
478
479
|
const name = body.slice(lastColon + 1);
|
|
479
|
-
if (!
|
|
480
|
+
if (!ownerDid.startsWith("did:")) {
|
|
480
481
|
throw new NetworkIdError(
|
|
481
|
-
`networkId
|
|
482
|
+
`networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`
|
|
482
483
|
);
|
|
483
484
|
}
|
|
484
|
-
const didParts =
|
|
485
|
+
const didParts = ownerDid.split(":");
|
|
485
486
|
if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {
|
|
486
487
|
throw new NetworkIdError(
|
|
487
|
-
`networkId
|
|
488
|
+
`networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`
|
|
488
489
|
);
|
|
489
490
|
}
|
|
490
491
|
if (!NETWORK_NAME_RE.test(name)) {
|
|
@@ -492,18 +493,18 @@ function parseNetworkId(networkId) {
|
|
|
492
493
|
`networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`
|
|
493
494
|
);
|
|
494
495
|
}
|
|
495
|
-
return { networkId,
|
|
496
|
+
return { networkId, ownerDid, name };
|
|
496
497
|
}
|
|
497
|
-
function buildNetworkId(
|
|
498
|
-
if (typeof
|
|
499
|
-
throw new NetworkIdError("
|
|
498
|
+
function buildNetworkId(ownerDid, name) {
|
|
499
|
+
if (typeof ownerDid !== "string" || !ownerDid.startsWith("did:")) {
|
|
500
|
+
throw new NetworkIdError("ownerDid must be a DID");
|
|
500
501
|
}
|
|
501
502
|
if (typeof name !== "string" || !NETWORK_NAME_RE.test(name)) {
|
|
502
503
|
throw new NetworkIdError(
|
|
503
504
|
`network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`
|
|
504
505
|
);
|
|
505
506
|
}
|
|
506
|
-
const networkId = `${URN_PREFIX}${
|
|
507
|
+
const networkId = `${URN_PREFIX}${ownerDid}:${name}`;
|
|
507
508
|
parseNetworkId(networkId);
|
|
508
509
|
return networkId;
|
|
509
510
|
}
|
|
@@ -518,6 +519,22 @@ function isNetworkId(networkId) {
|
|
|
518
519
|
return false;
|
|
519
520
|
}
|
|
520
521
|
}
|
|
522
|
+
function parsePkhOwnerDid(ownerDid) {
|
|
523
|
+
const match = ownerDid.match(PKH_EIP155_DID_RE);
|
|
524
|
+
if (!match) return null;
|
|
525
|
+
return {
|
|
526
|
+
chainId: match[1],
|
|
527
|
+
address: match[2].toLowerCase()
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function ownerDidMatches(a, b) {
|
|
531
|
+
const aPkh = parsePkhOwnerDid(a);
|
|
532
|
+
const bPkh = parsePkhOwnerDid(b);
|
|
533
|
+
if (aPkh && bPkh) {
|
|
534
|
+
return aPkh.chainId === bPkh.chainId && aPkh.address === bPkh.address;
|
|
535
|
+
}
|
|
536
|
+
return a === b;
|
|
537
|
+
}
|
|
521
538
|
function networkDiscoveryKey(name) {
|
|
522
539
|
if (!NETWORK_NAME_RE.test(name)) {
|
|
523
540
|
throw new NetworkIdError(
|
|
@@ -580,27 +597,27 @@ function toError(error) {
|
|
|
580
597
|
// src/encryption/discovery.ts
|
|
581
598
|
async function discoverNetwork(input) {
|
|
582
599
|
let networkId;
|
|
583
|
-
let
|
|
600
|
+
let ownerDid;
|
|
584
601
|
let name;
|
|
585
602
|
try {
|
|
586
603
|
if (input.identifier.startsWith("urn:tinycloud:encryption:")) {
|
|
587
604
|
const parsed = parseNetworkId(input.identifier);
|
|
588
605
|
networkId = parsed.networkId;
|
|
589
|
-
|
|
606
|
+
ownerDid = parsed.ownerDid;
|
|
590
607
|
name = parsed.name;
|
|
591
608
|
} else {
|
|
592
|
-
if (input.
|
|
609
|
+
if (input.ownerDid === void 0) {
|
|
593
610
|
return {
|
|
594
611
|
ok: false,
|
|
595
612
|
error: encryptionError({
|
|
596
613
|
code: "INVALID_INPUT",
|
|
597
|
-
message: "discoverNetwork requires `
|
|
614
|
+
message: "discoverNetwork requires `ownerDid` when identifier is a bare network name"
|
|
598
615
|
})
|
|
599
616
|
};
|
|
600
617
|
}
|
|
601
|
-
networkId = `urn:tinycloud:encryption:${input.
|
|
618
|
+
networkId = `urn:tinycloud:encryption:${input.ownerDid}:${input.identifier}`;
|
|
602
619
|
const parsed = parseNetworkId(networkId);
|
|
603
|
-
|
|
620
|
+
ownerDid = parsed.ownerDid;
|
|
604
621
|
name = parsed.name;
|
|
605
622
|
}
|
|
606
623
|
} catch (err2) {
|
|
@@ -619,7 +636,7 @@ async function discoverNetwork(input) {
|
|
|
619
636
|
try {
|
|
620
637
|
const descriptor = await input.node.fetchByNetworkId(networkId);
|
|
621
638
|
if (descriptor !== null) {
|
|
622
|
-
const validated = validateDescriptor(descriptor, networkId,
|
|
639
|
+
const validated = validateDescriptor(descriptor, networkId, ownerDid, name);
|
|
623
640
|
if (!validated.ok) return validated;
|
|
624
641
|
return { ok: true, data: { descriptor: validated.data, source: "node" } };
|
|
625
642
|
}
|
|
@@ -629,11 +646,11 @@ async function discoverNetwork(input) {
|
|
|
629
646
|
if (input.wellKnown !== void 0) {
|
|
630
647
|
try {
|
|
631
648
|
const descriptor = await input.wellKnown.fetchWellKnown(
|
|
632
|
-
|
|
649
|
+
ownerDid,
|
|
633
650
|
networkDiscoveryKey(name)
|
|
634
651
|
);
|
|
635
652
|
if (descriptor !== null) {
|
|
636
|
-
const validated = validateDescriptor(descriptor, networkId,
|
|
653
|
+
const validated = validateDescriptor(descriptor, networkId, ownerDid, name);
|
|
637
654
|
if (!validated.ok) return validated;
|
|
638
655
|
return {
|
|
639
656
|
ok: true,
|
|
@@ -652,8 +669,20 @@ async function discoverNetwork(input) {
|
|
|
652
669
|
})
|
|
653
670
|
};
|
|
654
671
|
}
|
|
655
|
-
function validateDescriptor(descriptor, networkId,
|
|
656
|
-
|
|
672
|
+
function validateDescriptor(descriptor, networkId, ownerDid, name) {
|
|
673
|
+
let descriptorNetwork;
|
|
674
|
+
try {
|
|
675
|
+
descriptorNetwork = parseNetworkId(descriptor.networkId);
|
|
676
|
+
} catch (err2) {
|
|
677
|
+
return {
|
|
678
|
+
ok: false,
|
|
679
|
+
error: encryptionError({
|
|
680
|
+
code: "INVALID_NETWORK_ID",
|
|
681
|
+
message: `descriptor networkId is malformed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
682
|
+
})
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
if (descriptorNetwork.name !== name || !ownerDidMatches(descriptorNetwork.ownerDid, ownerDid)) {
|
|
657
686
|
return {
|
|
658
687
|
ok: false,
|
|
659
688
|
error: encryptionError({
|
|
@@ -662,12 +691,13 @@ function validateDescriptor(descriptor, networkId, principal, name) {
|
|
|
662
691
|
})
|
|
663
692
|
};
|
|
664
693
|
}
|
|
665
|
-
|
|
694
|
+
const descriptorOwnerDid = descriptorOwner(descriptor);
|
|
695
|
+
if (descriptorOwnerDid === void 0 || !ownerDidMatches(descriptorOwnerDid, ownerDid) || !ownerDidMatches(descriptorOwnerDid, descriptorNetwork.ownerDid)) {
|
|
666
696
|
return {
|
|
667
697
|
ok: false,
|
|
668
698
|
error: encryptionError({
|
|
669
699
|
code: "INVALID_NETWORK_ID",
|
|
670
|
-
message: "descriptor
|
|
700
|
+
message: "descriptor ownerDid does not match networkId ownerDid"
|
|
671
701
|
})
|
|
672
702
|
};
|
|
673
703
|
}
|
|
@@ -689,7 +719,20 @@ function validateDescriptor(descriptor, networkId, principal, name) {
|
|
|
689
719
|
})
|
|
690
720
|
};
|
|
691
721
|
}
|
|
692
|
-
return {
|
|
722
|
+
return {
|
|
723
|
+
ok: true,
|
|
724
|
+
data: {
|
|
725
|
+
...descriptor,
|
|
726
|
+
ownerDid: descriptorOwnerDid
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
function descriptorOwner(descriptor) {
|
|
731
|
+
if (typeof descriptor.ownerDid === "string" && descriptor.ownerDid.length > 0) {
|
|
732
|
+
return descriptor.ownerDid;
|
|
733
|
+
}
|
|
734
|
+
const legacyDescriptor = descriptor;
|
|
735
|
+
return typeof legacyDescriptor.principal === "string" && legacyDescriptor.principal.length > 0 ? legacyDescriptor.principal : void 0;
|
|
693
736
|
}
|
|
694
737
|
function ensureNetworkUsableForDecrypt(descriptor) {
|
|
695
738
|
if (descriptor.state === "active" || descriptor.state === "rotating") {
|
|
@@ -1159,10 +1202,10 @@ var EncryptionService = class extends BaseService {
|
|
|
1159
1202
|
get crypto() {
|
|
1160
1203
|
return this._config.crypto;
|
|
1161
1204
|
}
|
|
1162
|
-
async discoverNetwork(identifier,
|
|
1205
|
+
async discoverNetwork(identifier, ownerDid) {
|
|
1163
1206
|
const result = await discoverNetwork({
|
|
1164
1207
|
identifier,
|
|
1165
|
-
...
|
|
1208
|
+
...ownerDid !== void 0 ? { ownerDid } : {},
|
|
1166
1209
|
...this._config.node !== void 0 ? { node: this._config.node } : {},
|
|
1167
1210
|
...this._config.wellKnown !== void 0 ? { wellKnown: this._config.wellKnown } : {}
|
|
1168
1211
|
});
|