@originator-profile/verify 0.6.1 → 0.7.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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Profile Verify
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@originator-profile/verify)](https://www.npmjs.com/package/@originator-profile/verify) [![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue)](https://www.jsdocs.io/package/@originator-profile/verify)
4
+
3
5
  署名を検証するためのパッケージです。
4
6
 
5
7
  <!-- prettier-ignore-start -->
package/dist/index.d.ts CHANGED
@@ -39,6 +39,15 @@ declare class CaVerifyFailed extends Error {
39
39
  constructor(message: string, result: CaVerificationFailure);
40
40
  }
41
41
 
42
+ /**
43
+ * 検証中の警告メッセージを受け取るハンドラー
44
+ *
45
+ * 検証を失敗とはしない後方互換性のための警告 (非推奨 Certificate や
46
+ * digestSRI の欠落・不一致など) の通知に使用する。
47
+ * デフォルトは `console.warn`。
48
+ */
49
+ type WarnHandler = (message: string) => void;
50
+
42
51
  /**
43
52
  * `digestSRI` の検証
44
53
  * @see {@link https://www.w3.org/TR/SRI/#the-integrity-attribute}
@@ -55,9 +64,14 @@ declare class CaVerifyFailed extends Error {
55
64
  declare function verifyDigestSri(content: DigestSriResult, fetcher?: typeof fetch): Promise<boolean>;
56
65
  /**
57
66
  * Image の digestSRI を検証する。
58
- * 後方互換性の観点で、2027年までは検証失敗時に console.warn のみで処理を中断しない。
67
+ * 後方互換性の観点で、2027年までは検証失敗時に warn のみで処理を中断しない。
59
68
  */
60
- declare function verifyImageDigestSri(value: Image | undefined, fetcher?: typeof fetch): Promise<void>;
69
+ declare function verifyImageDigestSri(value: Image | undefined, options?: {
70
+ /** コンテンツの取得に用いる fetch 実装 */
71
+ fetcher?: typeof fetch;
72
+ /** 警告ハンドラー (デフォルト: `console.warn`) */
73
+ warn?: WarnHandler;
74
+ }): Promise<void>;
61
75
 
62
76
  declare class IntegrityFetchFailed extends Error {
63
77
  static get code(): "ERR_INTEGRITY_FETCH_FAILED";
@@ -403,24 +417,30 @@ declare function isProfileAnnotationIssuerRegistration(doc: Certificate): doc is
403
417
  *
404
418
  * 各 Profile Annotation の発行者が、Core Profile Issuer から発行された登録証 PA によって、その PA が準拠する 認証制度(Profile Annotation Policy)の発行を認可されているかを検証
405
419
  *
406
- * (2027年まで) 後方互換性のため、認可を確認できない場合も検証は失敗させず console.warn に留める。
420
+ * (2027年まで) 後方互換性のため、認可を確認できない場合も検証は失敗させず warn に留める。
407
421
  *
408
422
  * @param verifiedOps 検証済み Originator Profile Set
409
423
  * @param cpIssuer 基底となる Core Profile Issuer の OP ID
424
+ * @param warn 警告ハンドラー (デフォルト: `console.warn`)
410
425
  *
411
426
  * @see https://docs.originator-profile.org/opb/pa-model/profile-annotation-issuer-registration/
412
427
  */
413
- declare function verifyAnnotationIssuerRegistration(verifiedOps: VerifiedOps, cpIssuer: string | string[]): VerifiedOps;
428
+ declare function verifyAnnotationIssuerRegistration(verifiedOps: VerifiedOps, cpIssuer: string | string[], warn?: WarnHandler): VerifiedOps;
414
429
 
415
430
  /**
416
431
  * Originator Profile Set の検証者の作成
417
432
  * @param ops Originator Profile Set
418
433
  * @param keys Core Profile の発行者の検証鍵
419
434
  * @param issuer Core Profile の発行者
420
- * @param validator バリデーター
435
+ * @param options バリデーターと警告ハンドラー
421
436
  * @returns 検証者
422
437
  */
423
- declare function OpsVerifier(ops: OriginatorProfileSet, keys: Keys, issuer: string | string[], validator?: typeof VcValidator): () => Promise<OpsVerificationResult>;
438
+ declare function OpsVerifier(ops: OriginatorProfileSet, keys: Keys, issuer: string | string[], options?: {
439
+ /** バリデーター */
440
+ validator?: typeof VcValidator;
441
+ /** 警告ハンドラー (デフォルト: `console.warn`) */
442
+ warn?: WarnHandler;
443
+ }): () => Promise<OpsVerificationResult>;
424
444
 
425
445
  type OpId = string;
426
446
  /**
@@ -472,11 +492,17 @@ type SpVerificationResult = VerifiedSp | SiteProfileInvalid | SiteProfileVerifyF
472
492
  * @param keys Core Profile の発行者の検証鍵
473
493
  * @param issuer Core Profile の発行者
474
494
  * @param origin 提示するWebサイトを識別するための RFC 6454 オリジン
475
- * @param verifyOrigin WSPが提示されたWebサイトのorigin引数との一致性検証の可否 (デフォルト: 有効)
476
- * @param validator バリデーター
495
+ * @param options オリジン検証の可否・バリデーター・警告ハンドラー
477
496
  * @returns 検証者
478
497
  */
479
- declare function SpVerifier(sp: SiteProfile, keys: Keys, issuer: string | string[], origin: URL["origin"], verifyOrigin?: boolean, validator?: typeof VcValidator): () => Promise<SpVerificationResult>;
498
+ declare function SpVerifier(sp: SiteProfile, keys: Keys, issuer: string | string[], origin: URL["origin"], options?: {
499
+ /** WSPが提示されたWebサイトのorigin引数との一致性検証の可否 (デフォルト: 有効) */
500
+ verifyOrigin?: boolean;
501
+ /** バリデーター */
502
+ validator?: typeof VcValidator;
503
+ /** 警告ハンドラー (デフォルト: `console.warn`) */
504
+ warn?: WarnHandler;
505
+ }): () => Promise<SpVerificationResult>;
480
506
 
481
507
  /**
482
508
  * URLオリジンが対象のオリジンの中に含まれているのか検証する
@@ -487,4 +513,4 @@ declare function SpVerifier(sp: SiteProfile, keys: Keys, issuer: string | string
487
513
  declare function verifyAllowedOrigin(origin: URL["origin"], allowedOrigins: AllowedOrigin): boolean;
488
514
 
489
515
  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 };
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 };
516
+ 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, WarnHandler };
package/dist/index.js CHANGED
@@ -315,10 +315,11 @@ async function verifyDigestSri(content, fetcher = fetch) {
315
315
  return false;
316
316
  }
317
317
  }
318
- async function verifyImageDigestSri(value, fetcher = fetch) {
318
+ async function verifyImageDigestSri(value, options = {}) {
319
+ const { fetcher = fetch, warn = console.warn } = options;
319
320
  if (!value) return;
320
321
  if (!value.digestSRI) {
321
- console.warn(`digestSRI is missing. ${WARN_SUFFIX}`);
322
+ warn(`digestSRI is missing. ${WARN_SUFFIX}`);
322
323
  return;
323
324
  }
324
325
  const valid = await verifyDigestSri(
@@ -326,7 +327,7 @@ async function verifyImageDigestSri(value, fetcher = fetch) {
326
327
  fetcher
327
328
  );
328
329
  if (!valid) {
329
- console.warn(`digestSRI verification failed. ${WARN_SUFFIX}`);
330
+ warn(`digestSRI verification failed. ${WARN_SUFFIX}`);
330
331
  }
331
332
  }
332
333
 
@@ -1023,13 +1024,14 @@ function reportUnauthorizedAnnotation({
1023
1024
  opIndex,
1024
1025
  paIndex,
1025
1026
  policy,
1026
- cpIssuers
1027
+ cpIssuers,
1028
+ warn
1027
1029
  }) {
1028
1030
  const { doc } = annotation;
1029
1031
  const { issuer: profileAnnotationIssuer } = doc;
1030
1032
  const location = `OP[${opIndex}].PA[${paIndex}]`;
1031
1033
  if (!isProfileAnnotation(doc)) {
1032
- console.warn(`Certificate is deprecated (${location})`);
1034
+ warn(`Certificate is deprecated (${location})`);
1033
1035
  return;
1034
1036
  }
1035
1037
  if (isProfileAnnotationIssuerRegistration(doc) && cpIssuers.has(profileAnnotationIssuer)) {
@@ -1038,12 +1040,12 @@ function reportUnauthorizedAnnotation({
1038
1040
  const policyId = getAnnotationPolicy(doc)?.id;
1039
1041
  const isAllowed = policyId && policy.get(profileAnnotationIssuer)?.has(policyId);
1040
1042
  if (!isAllowed) {
1041
- console.warn(
1043
+ warn(
1042
1044
  `Profile Annotation Issuer is not registered for this annotation scheme (${location} issuer: ${profileAnnotationIssuer}, scheme: ${policyId ?? "unknown"})`
1043
1045
  );
1044
1046
  }
1045
1047
  }
1046
- function verifyAnnotationIssuerRegistration(verifiedOps, cpIssuer) {
1048
+ function verifyAnnotationIssuerRegistration(verifiedOps, cpIssuer, warn = console.warn) {
1047
1049
  const cpIssuers = new Set([cpIssuer].flat());
1048
1050
  const policy = buildProfileAnnotationPolicy(verifiedOps, cpIssuers);
1049
1051
  for (const [opIndex, op] of verifiedOps.entries()) {
@@ -1053,7 +1055,8 @@ function verifyAnnotationIssuerRegistration(verifiedOps, cpIssuer) {
1053
1055
  opIndex,
1054
1056
  paIndex,
1055
1057
  policy,
1056
- cpIssuers
1058
+ cpIssuers,
1059
+ warn
1057
1060
  });
1058
1061
  }
1059
1062
  }
@@ -1082,7 +1085,8 @@ function validateCertificateExpiry(verifiedVc) {
1082
1085
  }
1083
1086
  return verifiedVc;
1084
1087
  }
1085
- async function verifyAnnotations(paIssuerKeys, annotations, validator) {
1088
+ async function verifyAnnotations(paIssuerKeys, annotations, options = {}) {
1089
+ const { validator, warn } = options;
1086
1090
  if (!annotations) return;
1087
1091
  return await Promise.all(
1088
1092
  annotations.map(async (annotation) => {
@@ -1108,13 +1112,14 @@ async function verifyAnnotations(paIssuerKeys, annotations, validator) {
1108
1112
  if (valid instanceof CertificateExpired) {
1109
1113
  return valid;
1110
1114
  }
1111
- await verifyImageDigestSri(valid.doc.credentialSubject.image);
1115
+ await verifyImageDigestSri(valid.doc.credentialSubject.image, { warn });
1112
1116
  return valid;
1113
1117
  })
1114
1118
  );
1115
1119
  }
1116
1120
 
1117
- async function verifyMedia(wmpIssuerKeys, media, validator) {
1121
+ async function verifyMedia(wmpIssuerKeys, media, options = {}) {
1122
+ const { validator, warn } = options;
1118
1123
  if (!media) return;
1119
1124
  return await Promise.all(
1120
1125
  media.map(async (m) => {
@@ -1127,7 +1132,7 @@ async function verifyMedia(wmpIssuerKeys, media, validator) {
1127
1132
  if (result instanceof Error) {
1128
1133
  return result;
1129
1134
  }
1130
- await verifyImageDigestSri(result.doc.credentialSubject.logo);
1135
+ await verifyImageDigestSri(result.doc.credentialSubject.logo, { warn });
1131
1136
  return result;
1132
1137
  })
1133
1138
  );
@@ -1143,7 +1148,8 @@ function generateErrorDetails(items, opIndex, prefix, sources) {
1143
1148
  }).filter((d) => d !== null);
1144
1149
  }
1145
1150
  const isVerifiedOps = (ops) => ops.every((op) => !(op instanceof OpVerifyFailed));
1146
- function OpsVerifier(ops, keys, issuer, validator) {
1151
+ function OpsVerifier(ops, keys, issuer, options = {}) {
1152
+ const { validator, warn } = options;
1147
1153
  const decoded = decodeOps(ops);
1148
1154
  const verifyCp = JwtVcVerifier(
1149
1155
  keys,
@@ -1161,9 +1167,12 @@ function OpsVerifier(ops, keys, issuer, validator) {
1161
1167
  const annotations = await verifyAnnotations(
1162
1168
  paOrWmpIssuerKeys,
1163
1169
  op.annotations,
1164
- validator
1170
+ { validator, warn }
1165
1171
  );
1166
- const media = await verifyMedia(paOrWmpIssuerKeys, op.media, validator);
1172
+ const media = await verifyMedia(paOrWmpIssuerKeys, op.media, {
1173
+ validator,
1174
+ warn
1175
+ });
1167
1176
  const resultOp = { core, annotations, media };
1168
1177
  if (core instanceof Error) {
1169
1178
  return new OpVerifyFailed(
@@ -1198,7 +1207,7 @@ function OpsVerifier(ops, keys, issuer, validator) {
1198
1207
  const msg = verifyFailedIndexes.length > 0 ? `Originator Profile Set verify failed (${verifyFailedIndexes.map((i) => `OP[${i}]`).join(", ")})` : "Originator Profile Set verify failed";
1199
1208
  return new OpsVerifyFailed(msg, resultOps);
1200
1209
  }
1201
- return verifyAnnotationIssuerRegistration(resultOps, issuer);
1210
+ return verifyAnnotationIssuerRegistration(resultOps, issuer, warn);
1202
1211
  }
1203
1212
  return verify;
1204
1213
  }
@@ -1246,9 +1255,13 @@ const decodeWebsiteProfiles = (sp, opsVerified) => {
1246
1255
  wspSources
1247
1256
  };
1248
1257
  };
1249
- function SpVerifier(sp, keys, issuer, origin, verifyOrigin = true, validator) {
1258
+ function SpVerifier(sp, keys, issuer, origin, options = {}) {
1259
+ const { verifyOrigin = true, validator, warn } = options;
1250
1260
  async function verify() {
1251
- const verifyOps = OpsVerifier(sp.originators, keys, issuer, validator);
1261
+ const verifyOps = OpsVerifier(sp.originators, keys, issuer, {
1262
+ validator,
1263
+ warn
1264
+ });
1252
1265
  const opsVerified = await verifyOps();
1253
1266
  if (opsVerified instanceof OpsInvalid) {
1254
1267
  return new SiteProfileInvalid("Originator Profile Set invalid", {
@@ -1297,7 +1310,9 @@ function SpVerifier(sp, keys, issuer, origin, verifyOrigin = true, validator) {
1297
1310
  return new Error("Origin not allowed");
1298
1311
  }
1299
1312
  }
1300
- await verifyImageDigestSri(verified.doc.credentialSubject.image);
1313
+ await verifyImageDigestSri(verified.doc.credentialSubject.image, {
1314
+ warn
1315
+ });
1301
1316
  return verified;
1302
1317
  })
1303
1318
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@originator-profile/verify",
3
- "version": "0.6.1",
3
+ "version": "0.7.0-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://docs.originator-profile.org",
6
6
  "repository": {
@@ -27,35 +27,34 @@
27
27
  "jose": "^6.2.2",
28
28
  "jsonld": "^9.0.0",
29
29
  "zod": "^4.3.6",
30
- "@originator-profile/core": "0.6.1",
31
- "@originator-profile/cryptography": "0.6.1",
32
- "@originator-profile/securing-mechanism": "0.6.1",
33
- "@originator-profile/model": "0.6.1",
34
- "@originator-profile/sign": "0.6.1"
30
+ "@originator-profile/core": "0.7.0-beta.2",
31
+ "@originator-profile/securing-mechanism": "0.7.0-beta.2",
32
+ "@originator-profile/cryptography": "0.7.0-beta.2",
33
+ "@originator-profile/sign": "0.7.0-beta.2",
34
+ "@originator-profile/model": "0.7.0-beta.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@playwright/test": "1.59.1",
38
38
  "date-fns": "4.1.0",
39
- "eslint": "10.2.0",
40
39
  "happy-dom": "20.8.9",
41
40
  "just-diff-apply": "5.5.0",
42
41
  "just-typeof": "3.2.0",
42
+ "oxlint": "^1.73.0",
43
+ "oxlint-tsgolint": "^0.24.0",
43
44
  "pkgroll": "2.27.0",
44
45
  "playwright": "1.59.1",
45
46
  "typescript": "6.0.2",
46
47
  "urlpattern-polyfill": "10.1.0",
47
- "vite": "8.0.8",
48
+ "vite": "8.0.16",
48
49
  "vitest": "4.1.4",
49
50
  "websri": "1.0.1",
50
- "@originator-profile/tsconfig": "0.6.1",
51
- "eslint-config-originator-profile": "0.6.1"
51
+ "@originator-profile/tsconfig": "0.7.0-beta.2"
52
52
  },
53
53
  "scripts": {
54
54
  "build": "pkgroll --clean-dist",
55
55
  "test": "vitest run",
56
56
  "e2e": "playwright test",
57
57
  "e2e:update": "playwright test --update-snapshots",
58
- "lint": "eslint --fix .",
59
- "type-check": "tsc --noEmit"
58
+ "lint": "oxlint --fix ."
60
59
  }
61
60
  }