@originator-profile/verify 0.5.5 → 0.6.0-beta.2
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 +27 -0
- package/dist/{index.d.mts → index.d.ts} +22 -3
- package/dist/{index.mjs → index.js} +149 -29
- package/package.json +24 -30
- package/dist/index-D-j8gXz_.cjs +0 -772
- package/dist/index.cjs +0 -1245
- package/dist/index.d.cts +0 -471
- /package/dist/{index-CQxI_8IG.mjs → index-CQxI_8IG.js} +0 -0
package/README.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
1
|
# Profile Verify
|
|
2
2
|
|
|
3
3
|
署名を検証するためのパッケージです。
|
|
4
|
+
|
|
5
|
+
<!-- prettier-ignore-start -->
|
|
6
|
+
<!-- environments-start -->
|
|
7
|
+
|
|
8
|
+
<!-- NOTE: Auto-generated by ../../scripts/update-readme-environments.ts from package.json, .github/workflows/test.yml, Dockerfile, and manifest.json. Edit the source, not this section. -->
|
|
9
|
+
|
|
10
|
+
## Environment
|
|
11
|
+
|
|
12
|
+
### Verified
|
|
13
|
+
|
|
14
|
+
- OS: Ubuntu 24.04
|
|
15
|
+
|
|
16
|
+
### Development
|
|
17
|
+
|
|
18
|
+
- Node.js: `^22.18.0 || ^24.10.0 || ^26.2.0`
|
|
19
|
+
- pnpm: `11.0.9`
|
|
20
|
+
|
|
21
|
+
<!-- environments-stop -->
|
|
22
|
+
<!-- prettier-ignore-end -->
|
|
23
|
+
|
|
24
|
+
### Verified
|
|
25
|
+
|
|
26
|
+
- Browser: Modern browsers with Web Crypto API (bundled in OP Inspector)
|
|
27
|
+
|
|
28
|
+
### Incompatible
|
|
29
|
+
|
|
30
|
+
- Environments without Web Crypto API: Requires Web Crypto API (SubtleCrypto).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContentAttestation, Image, Target, ContentAttestationSet, OpVc, Jwk, ArticleCA, Certificate as Certificate$1, CoreProfile, WebMediaProfile, WebsiteProfile, JapaneseExistenceCertificate, OriginatorProfileSet, Jwks, SiteProfile, AllowedOrigin } from '@originator-profile/model';
|
|
1
|
+
import { ContentAttestation, Image, Target, ContentAttestationSet, OpVc, Jwk, ArticleCA, Certificate as Certificate$1, CoreProfile, WebMediaProfile, WebsiteProfile, JapaneseExistenceCertificate, ProfileAnnotation, JapaneseExistencePA, ProfileAnnotationIssuerRegistration, OriginatorProfileSet, ProfileAnnotationPolicy, CertificationSystem, Jwks, SiteProfile, AllowedOrigin } from '@originator-profile/model';
|
|
2
2
|
import { JwtVcDecodingResult, UnverifiedJwtVc, JwtVcVerificationResult, VerifiedJwtVc, VcValidator } from '@originator-profile/securing-mechanism';
|
|
3
3
|
import { Keys } from '@originator-profile/cryptography';
|
|
4
4
|
import { DigestSriResult, ContentFetcher, ElementSelector } from '@originator-profile/sign';
|
|
@@ -344,7 +344,8 @@ declare class CertificateExpired<T extends OpVc> extends Error {
|
|
|
344
344
|
constructor(message: string, result: VerifiedJwtVc<T>);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
|
|
347
|
+
/** @deprecated Profile Annotation とその派生として整理する可能性あるため "Certificate" の利用は非推奨 */
|
|
348
|
+
type Certificate = Certificate$1 | JapaneseExistenceCertificate | ProfileAnnotation | JapaneseExistencePA | ProfileAnnotationIssuerRegistration;
|
|
348
349
|
/** Originator Profile 復号失敗 */
|
|
349
350
|
type OpDecodingFailure = {
|
|
350
351
|
core: JwtVcDecodingResult<CoreProfile>;
|
|
@@ -393,6 +394,24 @@ type OpsVerificationResult = VerifiedOps | OpsInvalid | OpsVerifyFailed;
|
|
|
393
394
|
*/
|
|
394
395
|
declare function decodeOps(ops: OriginatorProfileSet): OpsDecodingResult;
|
|
395
396
|
|
|
397
|
+
/** 新形式 PA の `credentialSubject.annotation` と旧 Certificate 形式の `credentialSubject.certificationSystem` 存在するほうを返す */
|
|
398
|
+
declare function getAnnotationPolicy(doc: Certificate): ProfileAnnotationPolicy | CertificationSystem;
|
|
399
|
+
/** Profile Annotation Issuer 登録証 PA かどうか */
|
|
400
|
+
declare function isProfileAnnotationIssuerRegistration(doc: Certificate): doc is ProfileAnnotationIssuerRegistration;
|
|
401
|
+
/**
|
|
402
|
+
* Profile Annotation Issuer 登録証 PA に基づく発行者の認可を確認
|
|
403
|
+
*
|
|
404
|
+
* 各 Profile Annotation の発行者が、Core Profile Issuer から発行された登録証 PA によって、その PA が準拠する 認証制度(Profile Annotation Policy)の発行を認可されているかを検証
|
|
405
|
+
*
|
|
406
|
+
* (2027年まで) 後方互換性のため、認可を確認できない場合も検証は失敗させず console.warn に留める。
|
|
407
|
+
*
|
|
408
|
+
* @param verifiedOps 検証済み Originator Profile Set
|
|
409
|
+
* @param cpIssuer 基底となる Core Profile Issuer の OP ID
|
|
410
|
+
*
|
|
411
|
+
* @see https://docs.originator-profile.org/opb/pa-model/profile-annotation-issuer-registration/
|
|
412
|
+
*/
|
|
413
|
+
declare function verifyAnnotationIssuerRegistration(verifiedOps: VerifiedOps, cpIssuer: string | string[]): VerifiedOps;
|
|
414
|
+
|
|
396
415
|
/**
|
|
397
416
|
* Originator Profile Set の検証者の作成
|
|
398
417
|
* @param ops Originator Profile Set
|
|
@@ -467,5 +486,5 @@ declare function SpVerifier(sp: SiteProfile, keys: Keys, issuer: string | string
|
|
|
467
486
|
*/
|
|
468
487
|
declare function verifyAllowedOrigin(origin: URL["origin"], allowedOrigins: AllowedOrigin): boolean;
|
|
469
488
|
|
|
470
|
-
export { CaInvalid, CaVerifier, CaVerifyFailed, CasVerifyFailed, CertificateExpired, CoreProfileNotFound, IntegrityFetchFailed, IntegrityVerificationFailed, OpInvalid, OpVerifyFailed, OpsInvalid, OpsVerifier, OpsVerifyFailed, SiteProfileInvalid, SiteProfileVerifyFailed, SpVerifier, TargetIntegrityAlgorithm, VerifyResultFactory, article, caId, caUrl, certificate, cp, decodeOps, getMappedKeys, getTupledKeys, normalizeCasItem, opId, patch, verifyAllowedOrigin, verifyCas, verifyDigestSri, verifyImageDigestSri, verifyIntegrity, wmp, wsp };
|
|
489
|
+
export { CaInvalid, CaVerifier, CaVerifyFailed, CasVerifyFailed, CertificateExpired, CoreProfileNotFound, IntegrityFetchFailed, IntegrityVerificationFailed, OpInvalid, OpVerifyFailed, OpsInvalid, OpsVerifier, OpsVerifyFailed, SiteProfileInvalid, SiteProfileVerifyFailed, SpVerifier, TargetIntegrityAlgorithm, VerifyResultFactory, article, caId, caUrl, certificate, cp, decodeOps, getAnnotationPolicy, getMappedKeys, getTupledKeys, isProfileAnnotationIssuerRegistration, normalizeCasItem, opId, patch, verifyAllowedOrigin, verifyAnnotationIssuerRegistration, verifyCas, verifyDigestSri, verifyImageDigestSri, verifyIntegrity, wmp, wsp };
|
|
471
490
|
export type { CaDecodingFailure, CaDecodingResult, CaVerificationFailure, CaVerificationResult, CasItem, CasVerificationFailure, CasVerificationResult, Certificate, DecodedCa, DecodedOp, DecodedOps, FetchIntegrityResult, IntegrityVerifyResult, MappedKeys, OpDecodingFailure, OpDecodingResult, OpVerificationFailure, OpVerificationResult, OpsDecodingFailure, OpsDecodingResult, OpsVerificationFailure, OpsVerificationResult, SpVerificationFailure, SpVerificationResult, TupledKeys, VerifiedCa, VerifiedCas, VerifiedOp, VerifiedOps, VerifiedSp, VerifyIntegrity };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JwtVcVerifier, VcValidateFailed, VcVerifyFailed, JwtVcDecoder } from '@originator-profile/securing-mechanism';
|
|
2
2
|
import { createDigestSri, selectByIntegrity, fetchExternalResource, selectByCss, fetchVisibleTextContent, fetchTextContent, fetchHtmlContent, FetchFailed } from '@originator-profile/sign';
|
|
3
3
|
import { LocalKeys } from '@originator-profile/cryptography';
|
|
4
|
-
import { ContentAttestation,
|
|
4
|
+
import { ContentAttestation, JapaneseExistencePA, ProfileAnnotationIssuerRegistration, ProfileAnnotation, JapaneseExistenceCertificate, Certificate, WebMediaProfile, CoreProfile, WebsiteProfile } from '@originator-profile/model';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
class CaInvalid extends Error {
|
|
@@ -422,7 +422,7 @@ function verifyAllowedOrigin(origin, allowedOrigins) {
|
|
|
422
422
|
|
|
423
423
|
async function importURLPatternPolyfill() {
|
|
424
424
|
if (typeof URLPattern === "undefined") {
|
|
425
|
-
await import('./index-CQxI_8IG.
|
|
425
|
+
await import('./index-CQxI_8IG.js');
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
428
|
function ReplaceEncode(url) {
|
|
@@ -912,29 +912,48 @@ class CertificateExpired extends Error {
|
|
|
912
912
|
|
|
913
913
|
const isEveryDecodedPa = (annotations) => annotations.every((annotation) => "doc" in annotation);
|
|
914
914
|
const isEveryDecodedWmp = (media) => media.every((m) => "doc" in m);
|
|
915
|
-
const
|
|
915
|
+
const failedPaths = (items, opIndex, prefix, isFailed) => items.map(
|
|
916
|
+
(item, index) => isFailed(item) ? `OP[${opIndex}].${prefix}[${index}]` : null
|
|
917
|
+
).filter((path) => path !== null);
|
|
918
|
+
const validateDecodedOp = (core, annotations, media, resultOp, opIndex) => {
|
|
916
919
|
if (annotations && !isEveryDecodedPa(annotations)) {
|
|
917
|
-
|
|
920
|
+
const paths = failedPaths(annotations, opIndex, "PA", (a) => !("doc" in a));
|
|
921
|
+
return new OpInvalid(
|
|
922
|
+
`Profile Annotation decode failed (${paths.join(", ")})`,
|
|
923
|
+
resultOp
|
|
924
|
+
);
|
|
918
925
|
}
|
|
919
926
|
if (media && !isEveryDecodedWmp(media)) {
|
|
920
|
-
|
|
927
|
+
const paths = failedPaths(media, opIndex, "WMP", (m) => !("doc" in m));
|
|
928
|
+
return new OpInvalid(
|
|
929
|
+
`Web Media Profile decode failed (${paths.join(", ")})`,
|
|
930
|
+
resultOp
|
|
931
|
+
);
|
|
921
932
|
}
|
|
933
|
+
const subjectMismatchErrors = [];
|
|
922
934
|
if (media && media.some(
|
|
923
935
|
(m) => core.doc.credentialSubject.id !== m.doc.credentialSubject.id
|
|
924
936
|
)) {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
937
|
+
const details = media.map(
|
|
938
|
+
(m, index) => core.doc.credentialSubject.id !== m.doc.credentialSubject.id ? `OP[${opIndex}].WMP[${index}] issuer: ${m.doc.issuer}, subject: ${m.doc.credentialSubject.id}` : null
|
|
939
|
+
).filter((d) => d !== null);
|
|
940
|
+
subjectMismatchErrors.push(
|
|
941
|
+
`Subject mismatch between Core Profile and Web Media Profile (${details.join(", ")})`
|
|
928
942
|
);
|
|
929
943
|
}
|
|
930
944
|
if (annotations && annotations.some(
|
|
931
945
|
(annotation) => core.doc.credentialSubject.id !== annotation.doc.credentialSubject.id
|
|
932
946
|
)) {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
947
|
+
const details = annotations.map(
|
|
948
|
+
(a, index) => core.doc.credentialSubject.id !== a.doc.credentialSubject.id ? `OP[${opIndex}].PA[${index}] issuer: ${a.doc.issuer}, subject: ${a.doc.credentialSubject.id}` : null
|
|
949
|
+
).filter((d) => d !== null);
|
|
950
|
+
subjectMismatchErrors.push(
|
|
951
|
+
`Subject mismatch between Core Profile and Profile Annotation (${details.join(", ")})`
|
|
936
952
|
);
|
|
937
953
|
}
|
|
954
|
+
if (subjectMismatchErrors.length > 0) {
|
|
955
|
+
return new OpInvalid(subjectMismatchErrors.join("\n"), resultOp);
|
|
956
|
+
}
|
|
938
957
|
return { type: "valid", annotations, media };
|
|
939
958
|
};
|
|
940
959
|
const isDecodedOps = (ops) => ops.every((op) => !(op instanceof OpInvalid));
|
|
@@ -942,7 +961,7 @@ function decodeOps(ops) {
|
|
|
942
961
|
const decodeCp = JwtVcDecoder();
|
|
943
962
|
const decodePa = JwtVcDecoder();
|
|
944
963
|
const decodeWmp = JwtVcDecoder();
|
|
945
|
-
const resultOps = ops.map((op) => {
|
|
964
|
+
const resultOps = ops.map((op, opIndex) => {
|
|
946
965
|
const core = decodeCp(op.core);
|
|
947
966
|
const annotations = op.annotations ? op.annotations.map(decodePa) : void 0;
|
|
948
967
|
const mediaInput = op.media;
|
|
@@ -950,9 +969,18 @@ function decodeOps(ops) {
|
|
|
950
969
|
const media = mediaArray ? mediaArray.map(decodeWmp) : void 0;
|
|
951
970
|
const resultOp = { core, annotations, media };
|
|
952
971
|
if (core instanceof Error) {
|
|
953
|
-
return new OpInvalid(
|
|
972
|
+
return new OpInvalid(
|
|
973
|
+
`Core Profile decode failed (OP[${opIndex}])`,
|
|
974
|
+
resultOp
|
|
975
|
+
);
|
|
954
976
|
}
|
|
955
|
-
const validated = validateDecodedOp(
|
|
977
|
+
const validated = validateDecodedOp(
|
|
978
|
+
core,
|
|
979
|
+
annotations,
|
|
980
|
+
media,
|
|
981
|
+
resultOp,
|
|
982
|
+
opIndex
|
|
983
|
+
);
|
|
956
984
|
if (validated instanceof OpInvalid) {
|
|
957
985
|
return validated;
|
|
958
986
|
}
|
|
@@ -963,11 +991,75 @@ function decodeOps(ops) {
|
|
|
963
991
|
};
|
|
964
992
|
});
|
|
965
993
|
if (!isDecodedOps(resultOps)) {
|
|
966
|
-
|
|
994
|
+
const invalidIndexes = resultOps.map((op, index) => op instanceof OpInvalid ? index : null).filter((i) => i !== null);
|
|
995
|
+
const msg = invalidIndexes.length > 0 ? `Invalid Originator Profile Set (${invalidIndexes.map((i) => `OP[${i}]`).join(", ")})` : "Invalid Originator Profile Set";
|
|
996
|
+
return new OpsInvalid(msg, resultOps);
|
|
967
997
|
}
|
|
968
998
|
return resultOps;
|
|
969
999
|
}
|
|
970
1000
|
|
|
1001
|
+
function getAnnotationPolicy(doc) {
|
|
1002
|
+
return "annotation" in doc.credentialSubject ? doc.credentialSubject.annotation : doc.credentialSubject.certificationSystem;
|
|
1003
|
+
}
|
|
1004
|
+
const isProfileAnnotation = (doc) => doc.type.includes("ProfileAnnotation");
|
|
1005
|
+
function isProfileAnnotationIssuerRegistration(doc) {
|
|
1006
|
+
return doc.credentialSubject.type === "ProfileAnnotationIssuerRegistration";
|
|
1007
|
+
}
|
|
1008
|
+
function buildProfileAnnotationPolicy(verifiedOps, cpIssuers) {
|
|
1009
|
+
const policy = /* @__PURE__ */ new Map();
|
|
1010
|
+
const annotations = verifiedOps.flatMap((op) => op.annotations ?? []);
|
|
1011
|
+
for (const { doc } of annotations) {
|
|
1012
|
+
if (!isProfileAnnotationIssuerRegistration(doc)) continue;
|
|
1013
|
+
if (!cpIssuers.has(doc.issuer)) continue;
|
|
1014
|
+
const { id: registrationIssuer, annotationScheme } = doc.credentialSubject;
|
|
1015
|
+
const allowedPolicy = policy.get(registrationIssuer) ?? /* @__PURE__ */ new Set();
|
|
1016
|
+
for (const scheme of annotationScheme) allowedPolicy.add(scheme);
|
|
1017
|
+
policy.set(registrationIssuer, allowedPolicy);
|
|
1018
|
+
}
|
|
1019
|
+
return policy;
|
|
1020
|
+
}
|
|
1021
|
+
function reportUnauthorizedAnnotation({
|
|
1022
|
+
annotation,
|
|
1023
|
+
opIndex,
|
|
1024
|
+
paIndex,
|
|
1025
|
+
policy,
|
|
1026
|
+
cpIssuers
|
|
1027
|
+
}) {
|
|
1028
|
+
const { doc } = annotation;
|
|
1029
|
+
const { issuer: profileAnnotationIssuer } = doc;
|
|
1030
|
+
const location = `OP[${opIndex}].PA[${paIndex}]`;
|
|
1031
|
+
if (!isProfileAnnotation(doc)) {
|
|
1032
|
+
console.warn(`Certificate is deprecated (${location})`);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
if (isProfileAnnotationIssuerRegistration(doc) && cpIssuers.has(profileAnnotationIssuer)) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
const policyId = getAnnotationPolicy(doc)?.id;
|
|
1039
|
+
const isAllowed = policyId && policy.get(profileAnnotationIssuer)?.has(policyId);
|
|
1040
|
+
if (!isAllowed) {
|
|
1041
|
+
console.warn(
|
|
1042
|
+
`Profile Annotation Issuer is not registered for this annotation scheme (${location} issuer: ${profileAnnotationIssuer}, scheme: ${policyId ?? "unknown"})`
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
function verifyAnnotationIssuerRegistration(verifiedOps, cpIssuer) {
|
|
1047
|
+
const cpIssuers = new Set([cpIssuer].flat());
|
|
1048
|
+
const policy = buildProfileAnnotationPolicy(verifiedOps, cpIssuers);
|
|
1049
|
+
for (const [opIndex, op] of verifiedOps.entries()) {
|
|
1050
|
+
for (const [paIndex, annotation] of op.annotations?.entries() ?? []) {
|
|
1051
|
+
reportUnauthorizedAnnotation({
|
|
1052
|
+
annotation,
|
|
1053
|
+
opIndex,
|
|
1054
|
+
paIndex,
|
|
1055
|
+
policy,
|
|
1056
|
+
cpIssuers
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return verifiedOps;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
971
1063
|
function OpVerifier(paOrWmpIssuerKeys, vc, validator) {
|
|
972
1064
|
const issuer = vc.doc.issuer;
|
|
973
1065
|
const jwks = paOrWmpIssuerKeys[issuer];
|
|
@@ -977,6 +1069,7 @@ function OpVerifier(paOrWmpIssuerKeys, vc, validator) {
|
|
|
977
1069
|
const cpKeys = LocalKeys(jwks);
|
|
978
1070
|
return JwtVcVerifier(cpKeys, issuer, validator);
|
|
979
1071
|
}
|
|
1072
|
+
|
|
980
1073
|
function validateCertificateExpiry(verifiedVc) {
|
|
981
1074
|
const now = /* @__PURE__ */ new Date();
|
|
982
1075
|
const validFrom = verifiedVc.doc.validFrom ? new Date(verifiedVc.doc.validFrom) : null;
|
|
@@ -996,7 +1089,16 @@ async function verifyAnnotations(paIssuerKeys, annotations, validator) {
|
|
|
996
1089
|
const verify = OpVerifier(
|
|
997
1090
|
paIssuerKeys,
|
|
998
1091
|
annotation,
|
|
999
|
-
validator?.(
|
|
1092
|
+
validator?.(
|
|
1093
|
+
// TODO: Profile Annotation とその派生のスキーマとして整理
|
|
1094
|
+
z.union([
|
|
1095
|
+
JapaneseExistencePA,
|
|
1096
|
+
ProfileAnnotationIssuerRegistration,
|
|
1097
|
+
ProfileAnnotation,
|
|
1098
|
+
JapaneseExistenceCertificate,
|
|
1099
|
+
Certificate
|
|
1100
|
+
])
|
|
1101
|
+
)
|
|
1000
1102
|
);
|
|
1001
1103
|
const result = await verify(annotation.source);
|
|
1002
1104
|
if (result instanceof Error) {
|
|
@@ -1006,13 +1108,12 @@ async function verifyAnnotations(paIssuerKeys, annotations, validator) {
|
|
|
1006
1108
|
if (valid instanceof CertificateExpired) {
|
|
1007
1109
|
return valid;
|
|
1008
1110
|
}
|
|
1009
|
-
await verifyImageDigestSri(
|
|
1010
|
-
valid.doc.credentialSubject.image
|
|
1011
|
-
);
|
|
1111
|
+
await verifyImageDigestSri(valid.doc.credentialSubject.image);
|
|
1012
1112
|
return valid;
|
|
1013
1113
|
})
|
|
1014
1114
|
);
|
|
1015
1115
|
}
|
|
1116
|
+
|
|
1016
1117
|
async function verifyMedia(wmpIssuerKeys, media, validator) {
|
|
1017
1118
|
if (!media) return;
|
|
1018
1119
|
return await Promise.all(
|
|
@@ -1031,6 +1132,16 @@ async function verifyMedia(wmpIssuerKeys, media, validator) {
|
|
|
1031
1132
|
})
|
|
1032
1133
|
);
|
|
1033
1134
|
}
|
|
1135
|
+
|
|
1136
|
+
function generateErrorDetails(items, opIndex, prefix, sources) {
|
|
1137
|
+
if (!items) return [];
|
|
1138
|
+
return items.map((item, index) => {
|
|
1139
|
+
if (!(item instanceof Error)) return null;
|
|
1140
|
+
const src = sources?.[index];
|
|
1141
|
+
const info = src ? ` issuer: ${src.doc.issuer}, subject: ${src.doc.credentialSubject.id}` : "";
|
|
1142
|
+
return `OP[${opIndex}].${prefix}[${index}]${info}`;
|
|
1143
|
+
}).filter((d) => d !== null);
|
|
1144
|
+
}
|
|
1034
1145
|
const isVerifiedOps = (ops) => ops.every((op) => !(op instanceof OpVerifyFailed));
|
|
1035
1146
|
function OpsVerifier(ops, keys, issuer, validator) {
|
|
1036
1147
|
const decoded = decodeOps(ops);
|
|
@@ -1045,7 +1156,7 @@ function OpsVerifier(ops, keys, issuer, validator) {
|
|
|
1045
1156
|
}
|
|
1046
1157
|
const paOrWmpIssuerKeys = getMappedKeys(decoded);
|
|
1047
1158
|
const resultOps = await Promise.all(
|
|
1048
|
-
decoded.map(async (op) => {
|
|
1159
|
+
decoded.map(async (op, opIndex) => {
|
|
1049
1160
|
const core = await verifyCp(op.core.source);
|
|
1050
1161
|
const annotations = await verifyAnnotations(
|
|
1051
1162
|
paOrWmpIssuerKeys,
|
|
@@ -1055,17 +1166,27 @@ function OpsVerifier(ops, keys, issuer, validator) {
|
|
|
1055
1166
|
const media = await verifyMedia(paOrWmpIssuerKeys, op.media, validator);
|
|
1056
1167
|
const resultOp = { core, annotations, media };
|
|
1057
1168
|
if (core instanceof Error) {
|
|
1058
|
-
return new OpVerifyFailed(
|
|
1169
|
+
return new OpVerifyFailed(
|
|
1170
|
+
`Core Profile verify failed (OP[${opIndex}])`,
|
|
1171
|
+
resultOp
|
|
1172
|
+
);
|
|
1059
1173
|
}
|
|
1060
1174
|
if (annotations && annotations.some((annotation) => annotation instanceof Error)) {
|
|
1175
|
+
const details = generateErrorDetails(
|
|
1176
|
+
annotations,
|
|
1177
|
+
opIndex,
|
|
1178
|
+
"PA",
|
|
1179
|
+
op.annotations
|
|
1180
|
+
);
|
|
1061
1181
|
return new OpVerifyFailed(
|
|
1062
|
-
|
|
1182
|
+
`Profile Annotation verify failed (${details.join(", ")})`,
|
|
1063
1183
|
resultOp
|
|
1064
1184
|
);
|
|
1065
1185
|
}
|
|
1066
1186
|
if (media && media.some((m) => m instanceof Error)) {
|
|
1187
|
+
const details = generateErrorDetails(media, opIndex, "WMP", op.media);
|
|
1067
1188
|
return new OpVerifyFailed(
|
|
1068
|
-
|
|
1189
|
+
`Web Media Profile verify failed (${details.join(", ")})`,
|
|
1069
1190
|
resultOp
|
|
1070
1191
|
);
|
|
1071
1192
|
}
|
|
@@ -1073,12 +1194,11 @@ function OpsVerifier(ops, keys, issuer, validator) {
|
|
|
1073
1194
|
})
|
|
1074
1195
|
);
|
|
1075
1196
|
if (!isVerifiedOps(resultOps)) {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
);
|
|
1197
|
+
const verifyFailedIndexes = resultOps.map((op, index) => op instanceof OpVerifyFailed ? index : null).filter((i) => i !== null);
|
|
1198
|
+
const msg = verifyFailedIndexes.length > 0 ? `Originator Profile Set verify failed (${verifyFailedIndexes.map((i) => `OP[${i}]`).join(", ")})` : "Originator Profile Set verify failed";
|
|
1199
|
+
return new OpsVerifyFailed(msg, resultOps);
|
|
1080
1200
|
}
|
|
1081
|
-
return resultOps;
|
|
1201
|
+
return verifyAnnotationIssuerRegistration(resultOps, issuer);
|
|
1082
1202
|
}
|
|
1083
1203
|
return verify;
|
|
1084
1204
|
}
|
|
@@ -1205,4 +1325,4 @@ function SpVerifier(sp, keys, issuer, origin, verifyOrigin = true, validator) {
|
|
|
1205
1325
|
return verify;
|
|
1206
1326
|
}
|
|
1207
1327
|
|
|
1208
|
-
export { CaInvalid, CaVerifier, CaVerifyFailed, CasVerifyFailed, CertificateExpired, CoreProfileNotFound, IntegrityFetchFailed, IntegrityVerificationFailed, OpInvalid, OpVerifyFailed, OpsInvalid, OpsVerifier, OpsVerifyFailed, SiteProfileInvalid, SiteProfileVerifyFailed, SpVerifier, TargetIntegrityAlgorithm, VerifyResultFactory, article, caId, caUrl, certificate, cp, decodeOps, getMappedKeys, getTupledKeys, normalizeCasItem, opId, patch, verifyAllowedOrigin, verifyCas, verifyDigestSri, verifyImageDigestSri, verifyIntegrity, wmp, wsp };
|
|
1328
|
+
export { CaInvalid, CaVerifier, CaVerifyFailed, CasVerifyFailed, CertificateExpired, CoreProfileNotFound, IntegrityFetchFailed, IntegrityVerificationFailed, OpInvalid, OpVerifyFailed, OpsInvalid, OpsVerifier, OpsVerifyFailed, SiteProfileInvalid, SiteProfileVerifyFailed, SpVerifier, TargetIntegrityAlgorithm, VerifyResultFactory, article, caId, caUrl, certificate, cp, decodeOps, getAnnotationPolicy, getMappedKeys, getTupledKeys, isProfileAnnotationIssuerRegistration, normalizeCasItem, opId, patch, verifyAllowedOrigin, verifyAnnotationIssuerRegistration, verifyCas, verifyDigestSri, verifyImageDigestSri, verifyIntegrity, wmp, wsp };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@originator-profile/verify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-beta.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://docs.originator-profile.org",
|
|
6
6
|
"repository": {
|
|
@@ -13,14 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
15
|
"exports": {
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"default": "./dist/index.cjs"
|
|
19
|
-
},
|
|
20
|
-
"import": {
|
|
21
|
-
"types": "./dist/index.d.mts",
|
|
22
|
-
"default": "./dist/index.mjs"
|
|
23
|
-
}
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
24
18
|
},
|
|
25
19
|
"files": [
|
|
26
20
|
"dist",
|
|
@@ -33,31 +27,31 @@
|
|
|
33
27
|
"jose": "^6.2.2",
|
|
34
28
|
"jsonld": "^9.0.0",
|
|
35
29
|
"zod": "^4.3.6",
|
|
36
|
-
"@originator-profile/core": "0.
|
|
37
|
-
"@originator-profile/
|
|
38
|
-
"@originator-profile/
|
|
39
|
-
"@originator-profile/
|
|
40
|
-
"@originator-profile/
|
|
30
|
+
"@originator-profile/core": "0.6.0-beta.2",
|
|
31
|
+
"@originator-profile/cryptography": "0.6.0-beta.2",
|
|
32
|
+
"@originator-profile/model": "0.6.0-beta.2",
|
|
33
|
+
"@originator-profile/sign": "0.6.0-beta.2",
|
|
34
|
+
"@originator-profile/securing-mechanism": "0.6.0-beta.2"
|
|
41
35
|
},
|
|
42
36
|
"devDependencies": {
|
|
43
|
-
"@playwright/test": "
|
|
44
|
-
"date-fns": "
|
|
45
|
-
"eslint": "
|
|
46
|
-
"happy-dom": "
|
|
47
|
-
"just-diff-apply": "
|
|
48
|
-
"just-typeof": "
|
|
49
|
-
"pkgroll": "
|
|
50
|
-
"playwright": "
|
|
51
|
-
"typescript": "
|
|
52
|
-
"urlpattern-polyfill": "
|
|
53
|
-
"vite": "
|
|
54
|
-
"vitest": "
|
|
55
|
-
"websri": "
|
|
56
|
-
"@originator-profile/tsconfig": "0.
|
|
57
|
-
"eslint-config-originator-profile": "0.
|
|
37
|
+
"@playwright/test": "1.59.1",
|
|
38
|
+
"date-fns": "4.1.0",
|
|
39
|
+
"eslint": "10.2.0",
|
|
40
|
+
"happy-dom": "20.8.9",
|
|
41
|
+
"just-diff-apply": "5.5.0",
|
|
42
|
+
"just-typeof": "3.2.0",
|
|
43
|
+
"pkgroll": "2.27.0",
|
|
44
|
+
"playwright": "1.59.1",
|
|
45
|
+
"typescript": "6.0.2",
|
|
46
|
+
"urlpattern-polyfill": "10.1.0",
|
|
47
|
+
"vite": "8.0.8",
|
|
48
|
+
"vitest": "4.1.4",
|
|
49
|
+
"websri": "1.0.1",
|
|
50
|
+
"@originator-profile/tsconfig": "0.6.0-beta.2",
|
|
51
|
+
"eslint-config-originator-profile": "0.6.0-beta.2"
|
|
58
52
|
},
|
|
59
53
|
"scripts": {
|
|
60
|
-
"build": "pkgroll --clean-dist
|
|
54
|
+
"build": "pkgroll --clean-dist",
|
|
61
55
|
"test": "vitest run",
|
|
62
56
|
"e2e": "playwright test",
|
|
63
57
|
"e2e:update": "playwright test --update-snapshots",
|