@sphereon/ssi-types 0.37.2-next.34 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +84 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +84 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/mapper/credential-mapper.ts +34 -29
- package/src/types/sd-jwt-type-metadata.ts +25 -0
- package/src/utils/mdoc.ts +93 -9
package/dist/index.cjs
CHANGED
|
@@ -692,27 +692,63 @@ function decodeMdocDeviceResponse(vpToken) {
|
|
|
692
692
|
return deviceResponse;
|
|
693
693
|
}
|
|
694
694
|
__name(decodeMdocDeviceResponse, "decodeMdocDeviceResponse");
|
|
695
|
+
function bytesToImageDataUri(value, mimeType = "image/jpeg") {
|
|
696
|
+
if (typeof value === "string") {
|
|
697
|
+
if (value.startsWith("data:image/")) return value;
|
|
698
|
+
let b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
699
|
+
const pad = b64.length % 4;
|
|
700
|
+
if (pad) b64 += "=".repeat(4 - pad);
|
|
701
|
+
return `data:${mimeType};base64,${b64}`;
|
|
702
|
+
}
|
|
703
|
+
if (value && typeof value === "object" && ("length" in value || Symbol.iterator in Object(value))) {
|
|
704
|
+
try {
|
|
705
|
+
const int8 = value instanceof Int8Array ? value : new Int8Array(value);
|
|
706
|
+
const base64 = com.sphereon.kmp.encodeTo(int8, com.sphereon.kmp.Encoding.BASE64);
|
|
707
|
+
return `data:${mimeType};base64,${base64}`;
|
|
708
|
+
} catch {
|
|
709
|
+
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
710
|
+
let binary = "";
|
|
711
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
712
|
+
const base64 = typeof btoa === "function" ? btoa(binary) : com.sphereon.kmp.encodeTo(new Int8Array(bytes), com.sphereon.kmp.Encoding.BASE64);
|
|
713
|
+
return `data:${mimeType};base64,${base64}`;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return String(value);
|
|
717
|
+
}
|
|
718
|
+
__name(bytesToImageDataUri, "bytesToImageDataUri");
|
|
695
719
|
var mdocDecodedCredentialToUniformCredential = /* @__PURE__ */ __name((decoded, opts) => {
|
|
696
720
|
const document = decoded.toJson();
|
|
697
721
|
const json = document.toJsonDTO();
|
|
698
|
-
const type = "Personal Identification Data";
|
|
699
722
|
const MSO = document.MSO;
|
|
700
723
|
if (!MSO || !json.issuerSigned?.nameSpaces) {
|
|
701
724
|
throw Error(`Cannot access Mobile Security Object or Issuer Signed items from the Mdoc`);
|
|
702
725
|
}
|
|
703
726
|
const nameSpaces = json.issuerSigned.nameSpaces;
|
|
704
|
-
|
|
705
|
-
|
|
727
|
+
const nameSpaceKeys = Object.keys(nameSpaces);
|
|
728
|
+
if (nameSpaceKeys.length === 0) {
|
|
729
|
+
throw Error(`No namespaces found in issuer signed items`);
|
|
730
|
+
}
|
|
731
|
+
const items = [];
|
|
732
|
+
for (const ns of nameSpaceKeys) {
|
|
733
|
+
items.push(...nameSpaces[ns] || []);
|
|
706
734
|
}
|
|
707
|
-
|
|
708
|
-
if (!items || items.length === 0) {
|
|
735
|
+
if (items.length === 0) {
|
|
709
736
|
throw Error(`No issuer signed items were found`);
|
|
710
737
|
}
|
|
738
|
+
const IMAGE_CLAIMS = /* @__PURE__ */ new Set([
|
|
739
|
+
"portrait",
|
|
740
|
+
"signature_usual_mark"
|
|
741
|
+
]);
|
|
711
742
|
const credentialSubject = items.reduce((acc, item) => {
|
|
712
743
|
if (Array.isArray(item.value)) {
|
|
713
744
|
acc[item.key] = item.value.map((val) => val.value).join(", ");
|
|
714
745
|
} else {
|
|
715
|
-
|
|
746
|
+
const value = item.value.value;
|
|
747
|
+
if (IMAGE_CLAIMS.has(item.key) && value != null) {
|
|
748
|
+
acc[item.key] = bytesToImageDataUri(value);
|
|
749
|
+
} else {
|
|
750
|
+
acc[item.key] = value;
|
|
751
|
+
}
|
|
716
752
|
}
|
|
717
753
|
return acc;
|
|
718
754
|
}, {});
|
|
@@ -725,13 +761,50 @@ var mdocDecodedCredentialToUniformCredential = /* @__PURE__ */ __name((decoded,
|
|
|
725
761
|
if (!issuanceDate) {
|
|
726
762
|
throw Error(`JWT issuance date is required but was not present`);
|
|
727
763
|
}
|
|
764
|
+
let issuer = opts?.issuer ?? docType;
|
|
765
|
+
if (credentialSubject.issuing_authority) {
|
|
766
|
+
issuer = credentialSubject.issuing_authority;
|
|
767
|
+
}
|
|
768
|
+
try {
|
|
769
|
+
const x5chain = json.issuerSigned?.issuerAuth?.unprotectedHeader?.x5chain ?? json.issuerSigned?.issuerAuth?.protectedHeader?.x5chain;
|
|
770
|
+
if (x5chain && x5chain.length > 0) {
|
|
771
|
+
const b64 = x5chain[0];
|
|
772
|
+
let bytes;
|
|
773
|
+
if (typeof atob === "function") {
|
|
774
|
+
const binaryStr = atob(b64);
|
|
775
|
+
bytes = new Uint8Array(binaryStr.length);
|
|
776
|
+
for (let i = 0; i < binaryStr.length; i++) bytes[i] = binaryStr.charCodeAt(i);
|
|
777
|
+
} else {
|
|
778
|
+
const int8 = com.sphereon.kmp.decodeFrom(b64, com.sphereon.kmp.Encoding.BASE64);
|
|
779
|
+
bytes = new Uint8Array(int8);
|
|
780
|
+
}
|
|
781
|
+
let lastCn;
|
|
782
|
+
for (let i = 0; i < bytes.length - 5; i++) {
|
|
783
|
+
if (bytes[i] === 85 && bytes[i + 1] === 4 && bytes[i + 2] === 3) {
|
|
784
|
+
const tag = bytes[i + 3];
|
|
785
|
+
if (tag === 12 || tag === 19) {
|
|
786
|
+
const len = bytes[i + 4];
|
|
787
|
+
if (i + 5 + len <= bytes.length) {
|
|
788
|
+
const cn = String.fromCharCode(...bytes.slice(i + 5, i + 5 + len));
|
|
789
|
+
lastCn = cn;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
if (lastCn) {
|
|
795
|
+
issuer = lastCn;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
} catch {
|
|
799
|
+
}
|
|
728
800
|
const credential = {
|
|
729
801
|
type: [
|
|
730
802
|
docType
|
|
731
803
|
],
|
|
732
804
|
"@context": [],
|
|
805
|
+
issuer,
|
|
733
806
|
credentialSubject: {
|
|
734
|
-
type,
|
|
807
|
+
type: docType,
|
|
735
808
|
...credentialSubject
|
|
736
809
|
},
|
|
737
810
|
issuanceDate,
|
|
@@ -1127,6 +1200,10 @@ var CredentialMapper = class _CredentialMapper {
|
|
|
1127
1200
|
return decodeSdJwtVc(credential, hasher ?? sha2562);
|
|
1128
1201
|
} else if (_CredentialMapper.isSdJwtDecodedCredential(credential)) {
|
|
1129
1202
|
return credential;
|
|
1203
|
+
} else if (_CredentialMapper.isMsoMdocOid4VPEncoded(credential)) {
|
|
1204
|
+
return decodeMdocIssuerSigned(credential);
|
|
1205
|
+
} else if (_CredentialMapper.isMsoMdocDecodedCredential(credential)) {
|
|
1206
|
+
return credential;
|
|
1130
1207
|
} else {
|
|
1131
1208
|
return credential;
|
|
1132
1209
|
}
|