@originator-profile/opvc 0.5.0-beta.2 → 0.5.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/README.md CHANGED
@@ -122,7 +122,7 @@ FLAG DESCRIPTIONS
122
122
  }
123
123
  ```
124
124
 
125
- _See code: [src/commands/ca/sign.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0-beta.2/packages/opvc/src/commands/ca/sign.ts)_
125
+ _See code: [src/commands/ca/sign.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0/packages/opvc/src/commands/ca/sign.ts)_
126
126
 
127
127
  ## `opvc ca:unsigned`
128
128
 
@@ -207,7 +207,7 @@ FLAG DESCRIPTIONS
207
207
  }
208
208
  ```
209
209
 
210
- _See code: [src/commands/ca/unsigned.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0-beta.2/packages/opvc/src/commands/ca/unsigned.ts)_
210
+ _See code: [src/commands/ca/unsigned.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0/packages/opvc/src/commands/ca/unsigned.ts)_
211
211
 
212
212
  ## `opvc help [COMMAND]`
213
213
 
@@ -218,7 +218,7 @@ USAGE
218
218
  $ opvc help [COMMAND...] [-n]
219
219
 
220
220
  ARGUMENTS
221
- COMMAND... Command to show help for.
221
+ [COMMAND...] Command to show help for.
222
222
 
223
223
  FLAGS
224
224
  -n, --nested-commands Include all nested commands in the output.
@@ -227,7 +227,7 @@ DESCRIPTION
227
227
  Display help for opvc.
228
228
  ```
229
229
 
230
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.37/src/commands/help.ts)_
230
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.2.41/src/commands/help.ts)_
231
231
 
232
232
  ## `opvc key-gen`
233
233
 
@@ -245,7 +245,7 @@ DESCRIPTION
245
245
  鍵ペアの生成
246
246
  ```
247
247
 
248
- _See code: [src/commands/key-gen/index.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0-beta.2/packages/opvc/src/commands/key-gen/index.ts)_
248
+ _See code: [src/commands/key-gen/index.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0/packages/opvc/src/commands/key-gen/index.ts)_
249
249
 
250
250
  ## `opvc sign`
251
251
 
@@ -412,7 +412,7 @@ FLAG DESCRIPTIONS
412
412
  }
413
413
  ```
414
414
 
415
- _See code: [src/commands/sign.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0-beta.2/packages/opvc/src/commands/sign.ts)_
415
+ _See code: [src/commands/sign.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0/packages/opvc/src/commands/sign.ts)_
416
416
 
417
417
  ## `opvc wsp:unsigned`
418
418
 
@@ -477,10 +477,56 @@ FLAG DESCRIPTIONS
477
477
  }
478
478
  ```
479
479
 
480
- _See code: [src/commands/wsp/unsigned.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0-beta.2/packages/opvc/src/commands/wsp/unsigned.ts)_
480
+ _See code: [src/commands/wsp/unsigned.ts](https://github.com/originator-profile/originator-profile/blob/v0.5.0/packages/opvc/src/commands/wsp/unsigned.ts)_
481
481
  <!-- commandsstop -->
482
482
  <!-- prettier-ignore-end -->
483
483
 
484
+ ## Node.js から利用する
485
+
486
+ `@originator-profile/opvc` は TypeScript/JavaScript からも利用できます。
487
+
488
+ ### ローカル環境でのContent Attestationの署名
489
+
490
+ ローカルのプライベート鍵で署名する場合は `ContentAttestation.sign()` を使います。
491
+
492
+ ```ts
493
+ import { ContentAttestation } from "@originator-profile/opvc";
494
+
495
+ const jwt = await ContentAttestation.sign(input, privateKey, {
496
+ issuedAt: new Date(),
497
+ expiredAt: "2027-03-31",
498
+ });
499
+ ```
500
+
501
+ ### 未署名 Content Attestation の取得
502
+
503
+ 未署名の Content Attestation が必要な場合は `ContentAttestation.unsignedCa()` を使えます。
504
+
505
+ ```ts
506
+ import { ContentAttestation } from "@originator-profile/opvc";
507
+
508
+ const uca = await ContentAttestation.unsignedCa(input, {
509
+ issuedAt: new Date(),
510
+ expiredAt: "2027-03-31",
511
+ });
512
+ ```
513
+
514
+ ### CA Server経由での署名
515
+
516
+ CA Server で署名する場合は `ContentAttestation.signByServer()` を使います。
517
+ 内部では未署名 Content Attestation を組み立てて CA server に送信し、返却された JWT を受け取ります。
518
+
519
+ ```ts
520
+ import { ContentAttestation } from "@originator-profile/opvc";
521
+
522
+ const jwt = await ContentAttestation.signByServer(input, {
523
+ endpoint: "https://example.com/ca",
524
+ accessToken: process.env.CA_SERVER_ACCESS_TOKEN!,
525
+ issuedAt: new Date(),
526
+ expiredAt: "2027-03-31",
527
+ });
528
+ ```
529
+
484
530
  ## Development
485
531
 
486
532
  ```sh
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll as t };
@@ -1,12 +1,12 @@
1
1
  import { Command } from "@oclif/core";
2
- import * as _oclif_core_interfaces5 from "@oclif/core/interfaces";
2
+ import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
3
 
4
4
  //#region src/commands/ca/sign.d.ts
5
5
  declare class CaSign extends Command {
6
6
  static summary: string;
7
7
  static description: string;
8
8
  static flags: {
9
- identity: _oclif_core_interfaces5.OptionFlag<{
9
+ identity: _$_oclif_core_interfaces0.OptionFlag<{
10
10
  [x: string]: unknown;
11
11
  kty: string;
12
12
  kid: string;
@@ -17,10 +17,10 @@ declare class CaSign extends Command {
17
17
  x5c?: string[] | undefined;
18
18
  x5t?: string | undefined;
19
19
  "x5t#S256"?: string | undefined;
20
- }, _oclif_core_interfaces5.CustomOptions>;
21
- input: _oclif_core_interfaces5.OptionFlag<string, _oclif_core_interfaces5.CustomOptions>;
22
- "issued-at": _oclif_core_interfaces5.OptionFlag<string | undefined, _oclif_core_interfaces5.CustomOptions>;
23
- "expired-at": _oclif_core_interfaces5.OptionFlag<Date | undefined, _oclif_core_interfaces5.CustomOptions>;
20
+ }, _$_oclif_core_interfaces0.CustomOptions>;
21
+ input: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
22
+ "issued-at": _$_oclif_core_interfaces0.OptionFlag<string | undefined, _$_oclif_core_interfaces0.CustomOptions>;
23
+ "expired-at": _$_oclif_core_interfaces0.OptionFlag<Date | undefined, _$_oclif_core_interfaces0.CustomOptions>;
24
24
  };
25
25
  static examples: string[];
26
26
  run(): Promise<void>;
@@ -1,8 +1,7 @@
1
- import { n as sign } from "../../content-attestation-rNiF6uH4.mjs";
2
- import { r as privateKey, t as expirationDate } from "../../flags-CFmMpf5A.mjs";
1
+ import { n as sign } from "../../content-attestation-duY49Hxp.mjs";
2
+ import { r as privateKey, t as expirationDate } from "../../flags-BGhMpQzg.mjs";
3
3
  import { Command, Flags } from "@oclif/core";
4
4
  import fs from "node:fs/promises";
5
-
6
5
  //#region src/commands/ca/sign.ts
7
6
  const exampleArticleContentAttestation = {
8
7
  "@context": [
@@ -66,6 +65,5 @@ $ <%= config.bin %> <%= command.id %> \\
66
65
  this.log(ca);
67
66
  }
68
67
  };
69
-
70
68
  //#endregion
71
- export { CaSign };
69
+ export { CaSign };
@@ -1,14 +1,14 @@
1
1
  import { Command } from "@oclif/core";
2
- import * as _oclif_core_interfaces13 from "@oclif/core/interfaces";
2
+ import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
3
 
4
4
  //#region src/commands/ca/unsigned.d.ts
5
5
  declare class CaUnsigned extends Command {
6
6
  static summary: string;
7
7
  static description: string;
8
8
  static flags: {
9
- input: _oclif_core_interfaces13.OptionFlag<string, _oclif_core_interfaces13.CustomOptions>;
10
- "issued-at": _oclif_core_interfaces13.OptionFlag<string | undefined, _oclif_core_interfaces13.CustomOptions>;
11
- "expired-at": _oclif_core_interfaces13.OptionFlag<Date | undefined, _oclif_core_interfaces13.CustomOptions>;
9
+ input: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
10
+ "issued-at": _$_oclif_core_interfaces0.OptionFlag<string | undefined, _$_oclif_core_interfaces0.CustomOptions>;
11
+ "expired-at": _$_oclif_core_interfaces0.OptionFlag<Date | undefined, _$_oclif_core_interfaces0.CustomOptions>;
12
12
  };
13
13
  static examples: string[];
14
14
  run(): Promise<void>;
@@ -1,8 +1,7 @@
1
- import { r as unsignedCa } from "../../content-attestation-rNiF6uH4.mjs";
2
- import { t as expirationDate } from "../../flags-CFmMpf5A.mjs";
1
+ import { r as unsignedCa } from "../../content-attestation-duY49Hxp.mjs";
2
+ import { t as expirationDate } from "../../flags-BGhMpQzg.mjs";
3
3
  import { Command, Flags } from "@oclif/core";
4
4
  import fs from "node:fs/promises";
5
-
6
5
  //#region src/commands/ca/unsigned.ts
7
6
  const exampleArticleContentAttestation = {
8
7
  "@context": [
@@ -69,6 +68,5 @@ $ <%= config.bin %> <%= command.id %> \\
69
68
  this.logJson(uca);
70
69
  }
71
70
  };
72
-
73
71
  //#endregion
74
- export { CaUnsigned };
72
+ export { CaUnsigned };
@@ -1,11 +1,11 @@
1
1
  import { Command } from "@oclif/core";
2
- import * as _oclif_core_interfaces29 from "@oclif/core/interfaces";
2
+ import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
3
 
4
4
  //#region src/commands/key-gen/index.d.ts
5
5
  declare class KeyGen extends Command {
6
6
  static description: string;
7
7
  static flags: {
8
- output: _oclif_core_interfaces29.OptionFlag<string, _oclif_core_interfaces29.CustomOptions>;
8
+ output: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
9
9
  };
10
10
  run(): Promise<void>;
11
11
  }
@@ -1,7 +1,6 @@
1
1
  import { Command, Flags } from "@oclif/core";
2
2
  import fs from "node:fs/promises";
3
3
  import { generateKey } from "@originator-profile/cryptography";
4
-
5
4
  //#region src/commands/key-gen/index.ts
6
5
  var KeyGen = class KeyGen extends Command {
7
6
  static description = "鍵ペアの生成";
@@ -19,6 +18,5 @@ var KeyGen = class KeyGen extends Command {
19
18
  await fs.writeFile(privateKeyFilename, JSON.stringify(privateKey, null, 2));
20
19
  }
21
20
  };
22
-
23
21
  //#endregion
24
- export { KeyGen };
22
+ export { KeyGen };
@@ -1,12 +1,12 @@
1
1
  import { Command } from "@oclif/core";
2
- import * as _oclif_core_interfaces19 from "@oclif/core/interfaces";
2
+ import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
3
 
4
4
  //#region src/commands/sign.d.ts
5
5
  declare class VcSign extends Command {
6
6
  static summary: string;
7
7
  static description: string;
8
8
  static flags: {
9
- identity: _oclif_core_interfaces19.OptionFlag<{
9
+ identity: _$_oclif_core_interfaces0.OptionFlag<{
10
10
  [x: string]: unknown;
11
11
  kty: string;
12
12
  kid: string;
@@ -17,11 +17,11 @@ declare class VcSign extends Command {
17
17
  x5c?: string[] | undefined;
18
18
  x5t?: string | undefined;
19
19
  "x5t#S256"?: string | undefined;
20
- }, _oclif_core_interfaces19.CustomOptions>;
21
- id: _oclif_core_interfaces19.OptionFlag<string | undefined, _oclif_core_interfaces19.CustomOptions>;
22
- input: _oclif_core_interfaces19.OptionFlag<string, _oclif_core_interfaces19.CustomOptions>;
23
- "issued-at": _oclif_core_interfaces19.OptionFlag<string | undefined, _oclif_core_interfaces19.CustomOptions>;
24
- "expired-at": _oclif_core_interfaces19.OptionFlag<Date | undefined, _oclif_core_interfaces19.CustomOptions>;
20
+ }, _$_oclif_core_interfaces0.CustomOptions>;
21
+ id: _$_oclif_core_interfaces0.OptionFlag<string | undefined, _$_oclif_core_interfaces0.CustomOptions>;
22
+ input: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
23
+ "issued-at": _$_oclif_core_interfaces0.OptionFlag<string | undefined, _$_oclif_core_interfaces0.CustomOptions>;
24
+ "expired-at": _$_oclif_core_interfaces0.OptionFlag<Date | undefined, _$_oclif_core_interfaces0.CustomOptions>;
25
25
  };
26
26
  static examples: string[];
27
27
  run(): Promise<void>;
@@ -1,10 +1,9 @@
1
- import { n as opId, r as privateKey, t as expirationDate } from "../flags-CFmMpf5A.mjs";
1
+ import { n as opId, r as privateKey, t as expirationDate } from "../flags-BGhMpQzg.mjs";
2
2
  import { fetchAndSetDigestSri } from "@originator-profile/sign";
3
3
  import { addYears } from "date-fns";
4
4
  import { Command, Flags } from "@oclif/core";
5
5
  import { signJwtVc } from "@originator-profile/securing-mechanism";
6
6
  import fs from "node:fs/promises";
7
-
8
7
  //#region src/commands/sign.ts
9
8
  function isValidVc(vc) {
10
9
  return typeof vc === "object" && vc !== null && "credentialSubject" in vc && typeof vc.credentialSubject === "object" && vc.credentialSubject !== null;
@@ -153,6 +152,5 @@ $ <%= config.bin %> <%= command.id %> \\
153
152
  this.log(vc);
154
153
  }
155
154
  };
156
-
157
155
  //#endregion
158
- export { VcSign };
156
+ export { VcSign };
@@ -1,14 +1,14 @@
1
1
  import { Command } from "@oclif/core";
2
- import * as _oclif_core_interfaces0 from "@oclif/core/interfaces";
2
+ import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
3
 
4
4
  //#region src/commands/wsp/unsigned.d.ts
5
5
  declare class WspUnsigned extends Command {
6
6
  static summary: string;
7
7
  static description: string;
8
8
  static flags: {
9
- input: _oclif_core_interfaces0.OptionFlag<string, _oclif_core_interfaces0.CustomOptions>;
10
- "issued-at": _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
11
- "expired-at": _oclif_core_interfaces0.OptionFlag<Date | undefined, _oclif_core_interfaces0.CustomOptions>;
9
+ input: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
10
+ "issued-at": _$_oclif_core_interfaces0.OptionFlag<string | undefined, _$_oclif_core_interfaces0.CustomOptions>;
11
+ "expired-at": _$_oclif_core_interfaces0.OptionFlag<Date | undefined, _$_oclif_core_interfaces0.CustomOptions>;
12
12
  };
13
13
  static examples: string[];
14
14
  run(): Promise<void>;
@@ -1,8 +1,7 @@
1
- import { t as unsignedWsp } from "../../website-profile-Dhto-mS2.mjs";
2
- import { t as expirationDate } from "../../flags-CFmMpf5A.mjs";
1
+ import { t as unsignedWsp } from "../../website-profile-B3Q2-h2n.mjs";
2
+ import { t as expirationDate } from "../../flags-BGhMpQzg.mjs";
3
3
  import { Command, Flags } from "@oclif/core";
4
4
  import fs from "node:fs/promises";
5
-
6
5
  //#region src/commands/wsp/unsigned.ts
7
6
  const exampleWebsiteProfile = {
8
7
  "@context": [
@@ -54,6 +53,5 @@ $ <%= config.bin %> <%= command.id %> \\
54
53
  this.logJson(uwsp);
55
54
  }
56
55
  };
57
-
58
56
  //#endregion
59
- export { WspUnsigned };
57
+ export { WspUnsigned };
@@ -0,0 +1,129 @@
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
+ import { JSDOM } from "jsdom";
3
+ import { parseExpirationDate } from "@originator-profile/core";
4
+ import { UnsignedContentAttestation } from "@originator-profile/model";
5
+ import { fetchAndSetDigestSri, fetchAndSetTargetIntegrity, signCa } from "@originator-profile/sign";
6
+ import { addYears, getUnixTime } from "date-fns";
7
+ import { BadRequestError } from "http-errors-enhanced";
8
+ //#region src/document-provider.ts
9
+ async function documentProvider({ type, content = "" }) {
10
+ if (type === "ExternalResourceTargetIntegrity") throw new Error("ExternalResourceTargetIntegrity is not supported in this context.");
11
+ if (Array.isArray(content) && content.length > 1) throw new Error("Multiple contents are not supported in this context.");
12
+ [content] = [content].flat();
13
+ let url;
14
+ let html;
15
+ if (URL.canParse(content)) {
16
+ url = content;
17
+ html = await fetch(url).then((res) => res.text());
18
+ } else {
19
+ url = void 0;
20
+ html = content;
21
+ }
22
+ return new JSDOM(html, { url }).window.document;
23
+ }
24
+ //#endregion
25
+ //#region src/content-attestation.ts
26
+ var content_attestation_exports = /* @__PURE__ */ __exportAll({
27
+ sign: () => sign,
28
+ signByServer: () => signByServer,
29
+ unsignedCa: () => unsignedCa
30
+ });
31
+ function assertValidDate(value, fieldName) {
32
+ if (Number.isNaN(value.getTime())) throw new BadRequestError(`${fieldName} must be a valid date.`);
33
+ }
34
+ function parseDates({ issuedAt: issuedAtDateOrString = /* @__PURE__ */ new Date(), expiredAt: expiredAtDateOrString = addYears(/* @__PURE__ */ new Date(), 1) }) {
35
+ const issuedAt = new Date(issuedAtDateOrString);
36
+ const expiredAt = typeof expiredAtDateOrString === "string" ? parseExpirationDate(expiredAtDateOrString) : new Date(expiredAtDateOrString);
37
+ assertValidDate(issuedAt, "issuedAt");
38
+ assertValidDate(expiredAt, "expiredAt");
39
+ return {
40
+ issuedAt,
41
+ expiredAt
42
+ };
43
+ }
44
+ /**
45
+ * 未署名 Content Attestation の取得
46
+ * @param uca 未署名 Content Attestation オブジェクト
47
+ * @throws {BadRequestError} 入力が UnsignedContentAttestation スキーマに適合しない場合/検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
48
+ * @return 未署名 Content Attestation オブジェクト
49
+ */
50
+ async function unsignedCa(uca, { integrityAlg = "sha256", documentProvider: documentProvider$1 = documentProvider, ...timingOptions }) {
51
+ const { issuedAt, expiredAt } = parseDates(timingOptions);
52
+ uca.credentialSubject.id ??= `urn:uuid:${crypto.randomUUID()}`;
53
+ try {
54
+ UnsignedContentAttestation.parse(uca);
55
+ await Promise.all([fetchAndSetDigestSri(integrityAlg, uca.credentialSubject.image), fetchAndSetTargetIntegrity(integrityAlg, uca, documentProvider$1)]);
56
+ } catch (e) {
57
+ throw new BadRequestError(e.message);
58
+ }
59
+ return {
60
+ ...uca,
61
+ iss: uca.issuer,
62
+ sub: uca.credentialSubject.id,
63
+ iat: getUnixTime(issuedAt),
64
+ exp: getUnixTime(expiredAt)
65
+ };
66
+ }
67
+ /**
68
+ * Content Attestation への署名
69
+ * @param uca 未署名 Content Attestation オブジェクト
70
+ * @param privateKey プライベート鍵
71
+ * @throws {BadRequestError} 入力が UnsignedContentAttestation スキーマに適合しない場合/検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
72
+ * @return Content Attestation
73
+ */
74
+ async function sign(uca, privateKey, options = {}) {
75
+ const { issuedAt, expiredAt } = parseDates(options);
76
+ return await signCa(await unsignedCa(uca, {
77
+ issuedAt,
78
+ expiredAt
79
+ }), privateKey, {
80
+ issuedAt,
81
+ expiredAt,
82
+ documentProvider
83
+ });
84
+ }
85
+ /**
86
+ * CA server 経由で Content Attestation を作成
87
+ * @param uca 未署名 Content Attestation オブジェクト
88
+ * @param options Content Attestation の生成オプション
89
+ * @param options.endpoint CA server のエンドポイント URL
90
+ * @param options.accessToken CA server 呼び出しに利用する Bearer トークン
91
+ * @return JWT でエンコードされた Content Attestation
92
+ */
93
+ async function signByServer(uca, { endpoint, accessToken, ...options }) {
94
+ const { issuedAt, expiredAt } = parseDates(options);
95
+ const payload = await unsignedCa(uca, {
96
+ ...options,
97
+ issuedAt,
98
+ expiredAt
99
+ });
100
+ const response = await fetch(endpoint, {
101
+ method: "POST",
102
+ headers: {
103
+ "Content-Type": "application/json",
104
+ Authorization: `Bearer ${accessToken}`
105
+ },
106
+ body: JSON.stringify({
107
+ ...payload,
108
+ issuedAt: issuedAt.toISOString(),
109
+ expiredAt: expiredAt.toISOString()
110
+ })
111
+ });
112
+ if (!response.ok) {
113
+ const responseBody = await response.text();
114
+ throw new Error(`CA API error: ${response.status} ${response.statusText}: ${responseBody}`);
115
+ }
116
+ const responseBody = (await response.text()).trim();
117
+ if (responseBody === "") throw new Error("CA API returned no JWT.");
118
+ let result;
119
+ try {
120
+ result = JSON.parse(responseBody);
121
+ } catch {
122
+ return responseBody;
123
+ }
124
+ if (typeof result === "string") return result;
125
+ if (Array.isArray(result) && typeof result[0] === "string") return result[0];
126
+ throw new Error("CA API returned no JWT.");
127
+ }
128
+ //#endregion
129
+ export { documentProvider as i, sign as n, unsignedCa as r, content_attestation_exports as t };
@@ -2,7 +2,6 @@ import { parseExpirationDate } from "@originator-profile/core";
2
2
  import { Flags } from "@oclif/core";
3
3
  import fs from "node:fs/promises";
4
4
  import { exportJWK, importPKCS8 } from "jose";
5
-
6
5
  //#region src/flags.ts
7
6
  const opId = Flags.custom({
8
7
  summary: "OP ID (ドメイン名)",
@@ -33,6 +32,5 @@ const expirationDate = Flags.custom({
33
32
  return parseExpirationDate(input);
34
33
  }
35
34
  });
36
-
37
35
  //#endregion
38
- export { opId as n, privateKey as r, expirationDate as t };
36
+ export { opId as n, privateKey as r, expirationDate as t };
package/dist/index.d.mts CHANGED
@@ -1,45 +1,76 @@
1
1
  import { Jwk, RawTarget, UnsignedContentAttestation, UnsignedWebsiteProfile } from "@originator-profile/model";
2
+ import { DocumentProvider } from "@originator-profile/sign";
2
3
 
3
4
  //#region src/document-provider.d.ts
4
- declare function documentProvider({
5
+ declare function documentProvider$1({
5
6
  type,
6
7
  content
7
8
  }: RawTarget): Promise<Document>;
9
+ //#endregion
10
+ //#region ../../node_modules/.pnpm/websri@1.0.1/node_modules/websri/dist/index.d.ts
11
+ /**
12
+ * Represents the available hash algorithms used for Subresource Integrity.
13
+ * @see {@link https://www.w3.org/TR/CSP2/#hash_algo}
14
+ */
15
+ type HashAlgorithm = "sha256" | "sha384" | "sha512";
16
+ /**
17
+ * A constant object defining the supported hash algorithms and their corresponding string
18
+ * representations for cryptographic operations. These algorithms are referenced by name when
19
+ * working with hashing functions in Web Crypto APIs.
20
+ */
8
21
  declare namespace content_attestation_d_exports {
9
- export { sign, unsignedCa };
22
+ export { sign, signByServer, unsignedCa };
10
23
  }
24
+ type ContentAttestationTimingOptions = {
25
+ issuedAt?: Date | string;
26
+ expiredAt?: Date | string;
27
+ };
28
+ type UnsignedCaOptions = ContentAttestationTimingOptions & {
29
+ integrityAlg?: HashAlgorithm;
30
+ documentProvider?: DocumentProvider;
31
+ };
32
+ /**
33
+ * 未署名 Content Attestation の取得
34
+ * @param uca 未署名 Content Attestation オブジェクト
35
+ * @throws {BadRequestError} 入力が UnsignedContentAttestation スキーマに適合しない場合/検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
36
+ * @return 未署名 Content Attestation オブジェクト
37
+ */
38
+ declare function unsignedCa(uca: UnsignedContentAttestation, {
39
+ integrityAlg,
40
+ documentProvider,
41
+ ...timingOptions
42
+ }: UnsignedCaOptions): Promise<UnsignedContentAttestation>;
11
43
  /**
12
44
  * Content Attestation への署名
13
45
  * @param uca 未署名 Content Attestation オブジェクト
14
46
  * @param privateKey プライベート鍵
47
+ * @throws {BadRequestError} 入力が UnsignedContentAttestation スキーマに適合しない場合/検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
15
48
  * @return Content Attestation
16
49
  */
17
- declare function sign(uca: UnsignedContentAttestation, privateKey: Jwk, {
18
- issuedAt: issuedAtDateOrString,
19
- expiredAt: expiredAtDateOrString
20
- }: {
21
- issuedAt?: Date | string;
22
- expiredAt?: Date | string;
23
- }): Promise<string>;
50
+ declare function sign(uca: UnsignedContentAttestation, privateKey: Jwk, options?: ContentAttestationTimingOptions): Promise<string>;
24
51
  /**
25
- * 未署名 Content Attestation の取得
52
+ * CA server 経由で Content Attestation を作成
26
53
  * @param uca 未署名 Content Attestation オブジェクト
27
- * @throws {BadRequestError} 検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
28
- * @return 未署名 Content Attestation オブジェクト
54
+ * @param options Content Attestation の生成オプション
55
+ * @param options.endpoint CA server のエンドポイント URL
56
+ * @param options.accessToken CA server 呼び出しに利用する Bearer トークン
57
+ * @return JWT でエンコードされた Content Attestation
29
58
  */
30
- declare function unsignedCa(uca: UnsignedContentAttestation, {
31
- issuedAt: issuedAtDateOrString,
32
- expiredAt: expiredAtDateOrString
33
- }: {
34
- issuedAt?: Date | string;
35
- expiredAt?: Date | string;
36
- }): Promise<UnsignedContentAttestation>;
59
+ declare function signByServer(uca: UnsignedContentAttestation, {
60
+ endpoint,
61
+ accessToken,
62
+ ...options
63
+ }: UnsignedCaOptions & {
64
+ endpoint: string;
65
+ accessToken: string;
66
+ }): Promise<string>;
37
67
  declare namespace website_profile_d_exports {
38
68
  export { unsignedWsp };
39
69
  }
40
70
  /**
41
71
  * 未署名 Website Profile の取得
42
72
  * @param uwsp 未署名 Website Profile オブジェクト
73
+ * @throws {Error} 入力が UnsignedWebsiteProfile スキーマに適合しない場合
43
74
  * @return 未署名 Website Profile オブジェクト
44
75
  */
45
76
  declare function unsignedWsp(uwsp: UnsignedWebsiteProfile, {
@@ -50,4 +81,4 @@ declare function unsignedWsp(uwsp: UnsignedWebsiteProfile, {
50
81
  expiredAt?: Date | string;
51
82
  }): Promise<UnsignedWebsiteProfile>;
52
83
  //#endregion
53
- export { content_attestation_d_exports as ContentAttestation, website_profile_d_exports as WebsiteProfile, documentProvider };
84
+ export { content_attestation_d_exports as ContentAttestation, website_profile_d_exports as WebsiteProfile, documentProvider$1 as documentProvider };
package/dist/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import { i as documentProvider, t as content_attestation_exports } from "./content-attestation-rNiF6uH4.mjs";
2
- import { n as website_profile_exports } from "./website-profile-Dhto-mS2.mjs";
3
-
4
- export { content_attestation_exports as ContentAttestation, website_profile_exports as WebsiteProfile, documentProvider };
1
+ import { i as documentProvider, t as content_attestation_exports } from "./content-attestation-duY49Hxp.mjs";
2
+ import { n as website_profile_exports } from "./website-profile-B3Q2-h2n.mjs";
3
+ export { content_attestation_exports as ContentAttestation, website_profile_exports as WebsiteProfile, documentProvider };
@@ -1,16 +1,18 @@
1
- import { t as __export } from "./chunk-DJTHdtxa.mjs";
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
2
  import { parseExpirationDate } from "@originator-profile/core";
3
+ import { UnsignedWebsiteProfile } from "@originator-profile/model";
3
4
  import { fetchAndSetDigestSri } from "@originator-profile/sign";
4
5
  import { addYears, getUnixTime } from "date-fns";
5
-
6
6
  //#region src/website-profile.ts
7
- var website_profile_exports = /* @__PURE__ */ __export({ unsignedWsp: () => unsignedWsp });
7
+ var website_profile_exports = /* @__PURE__ */ __exportAll({ unsignedWsp: () => unsignedWsp });
8
8
  /**
9
9
  * 未署名 Website Profile の取得
10
10
  * @param uwsp 未署名 Website Profile オブジェクト
11
+ * @throws {Error} 入力が UnsignedWebsiteProfile スキーマに適合しない場合
11
12
  * @return 未署名 Website Profile オブジェクト
12
13
  */
13
14
  async function unsignedWsp(uwsp, { issuedAt: issuedAtDateOrString = /* @__PURE__ */ new Date(), expiredAt: expiredAtDateOrString = addYears(/* @__PURE__ */ new Date(), 1) }) {
15
+ UnsignedWebsiteProfile.parse(uwsp);
14
16
  const issuedAt = new Date(issuedAtDateOrString);
15
17
  const expiredAt = typeof expiredAtDateOrString === "string" ? parseExpirationDate(expiredAtDateOrString) : expiredAtDateOrString;
16
18
  await fetchAndSetDigestSri("sha256", uwsp.credentialSubject.image);
@@ -22,6 +24,5 @@ async function unsignedWsp(uwsp, { issuedAt: issuedAtDateOrString = /* @__PURE__
22
24
  ...uwsp
23
25
  };
24
26
  }
25
-
26
27
  //#endregion
27
- export { website_profile_exports as n, unsignedWsp as t };
28
+ export { website_profile_exports as n, unsignedWsp as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@originator-profile/opvc",
3
- "version": "0.5.0-beta.2",
3
+ "version": "0.5.0",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://docs.originator-profile.org",
6
6
  "repository": {
@@ -33,27 +33,27 @@
33
33
  ]
34
34
  },
35
35
  "dependencies": {
36
- "@oclif/core": "^4.4.0",
37
- "@oclif/plugin-help": "^6.2.29",
36
+ "@oclif/core": "^4.10.3",
37
+ "@oclif/plugin-help": "^6.2.41",
38
38
  "date-fns": "^4.1.0",
39
- "http-errors-enhanced": "^4.0.0",
40
- "jose": "^6.0.11",
41
- "jsdom": "^27.0.0",
42
- "@originator-profile/core": "0.5.0-beta.2",
43
- "@originator-profile/securing-mechanism": "0.5.0-beta.2",
44
- "@originator-profile/cryptography": "0.5.0-beta.2",
45
- "@originator-profile/sign": "0.5.0-beta.2",
46
- "@originator-profile/model": "0.5.0-beta.2"
39
+ "http-errors-enhanced": "^4.0.2",
40
+ "jose": "^6.2.2",
41
+ "jsdom": "^29.0.1",
42
+ "@originator-profile/core": "0.5.0",
43
+ "@originator-profile/model": "0.5.0",
44
+ "@originator-profile/securing-mechanism": "0.5.0",
45
+ "@originator-profile/sign": "0.5.0",
46
+ "@originator-profile/cryptography": "0.5.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@types/node": "^24.3.1",
50
- "eslint": "^9.25.1",
51
- "oclif": "^4.20.1",
52
- "tsdown": "^0.16.7",
53
- "typescript": "^5.8.3",
49
+ "@types/node": "^25.5.0",
50
+ "eslint": "^10.1.0",
51
+ "oclif": "^4.22.96",
52
+ "tsdown": "^0.21.7",
53
+ "typescript": "^6.0.2",
54
54
  "websri": "^1.0.1",
55
- "eslint-config-originator-profile": "0.5.0-beta.2",
56
- "@originator-profile/tsconfig": "0.5.0-beta.2"
55
+ "eslint-config-originator-profile": "0.5.0",
56
+ "@originator-profile/tsconfig": "0.5.0"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsdown && oclif manifest && oclif readme",
@@ -1,18 +0,0 @@
1
- //#region rolldown:runtime
2
- var __defProp = Object.defineProperty;
3
- var __export = (all, symbols) => {
4
- let target = {};
5
- for (var name in all) {
6
- __defProp(target, name, {
7
- get: all[name],
8
- enumerable: true
9
- });
10
- }
11
- if (symbols) {
12
- __defProp(target, Symbol.toStringTag, { value: "Module" });
13
- }
14
- return target;
15
- };
16
-
17
- //#endregion
18
- export { __export as t };
@@ -1,73 +0,0 @@
1
- import { t as __export } from "./chunk-DJTHdtxa.mjs";
2
- import { JSDOM } from "jsdom";
3
- import { parseExpirationDate } from "@originator-profile/core";
4
- import { fetchAndSetDigestSri, fetchAndSetTargetIntegrity, signCa } from "@originator-profile/sign";
5
- import { addYears, getUnixTime } from "date-fns";
6
- import { BadRequestError } from "http-errors-enhanced";
7
-
8
- //#region src/document-provider.ts
9
- async function documentProvider({ type, content = "" }) {
10
- if (type === "ExternalResourceTargetIntegrity") throw new Error("ExternalResourceTargetIntegrity is not supported in this context.");
11
- if (Array.isArray(content) && content.length > 1) throw new Error("Multiple contents are not supported in this context.");
12
- [content] = [content].flat();
13
- let url;
14
- let html = "";
15
- if (URL.canParse(content)) {
16
- url = content;
17
- html = await fetch(url).then((res) => res.text());
18
- } else {
19
- url = void 0;
20
- html = content;
21
- }
22
- return new JSDOM(html, { url }).window.document;
23
- }
24
-
25
- //#endregion
26
- //#region src/content-attestation.ts
27
- var content_attestation_exports = /* @__PURE__ */ __export({
28
- sign: () => sign,
29
- unsignedCa: () => unsignedCa
30
- });
31
- /**
32
- * Content Attestation への署名
33
- * @param uca 未署名 Content Attestation オブジェクト
34
- * @param privateKey プライベート鍵
35
- * @return Content Attestation
36
- */
37
- async function sign(uca, privateKey, { issuedAt: issuedAtDateOrString = /* @__PURE__ */ new Date(), expiredAt: expiredAtDateOrString = addYears(/* @__PURE__ */ new Date(), 1) }) {
38
- const issuedAt = new Date(issuedAtDateOrString);
39
- const expiredAt = typeof expiredAtDateOrString === "string" ? parseExpirationDate(expiredAtDateOrString) : expiredAtDateOrString;
40
- uca.credentialSubject.id ??= `urn:uuid:${crypto.randomUUID()}`;
41
- return await signCa(uca, privateKey, {
42
- issuedAt,
43
- expiredAt,
44
- documentProvider
45
- });
46
- }
47
- /**
48
- * 未署名 Content Attestation の取得
49
- * @param uca 未署名 Content Attestation オブジェクト
50
- * @throws {BadRequestError} 検証対象のコンテンツが存在しない/コンテンツにアクセスできない/Integrityの計算に失敗
51
- * @return 未署名 Content Attestation オブジェクト
52
- */
53
- async function unsignedCa(uca, { issuedAt: issuedAtDateOrString = /* @__PURE__ */ new Date(), expiredAt: expiredAtDateOrString = addYears(/* @__PURE__ */ new Date(), 1) }) {
54
- const issuedAt = new Date(issuedAtDateOrString);
55
- const expiredAt = typeof expiredAtDateOrString === "string" ? parseExpirationDate(expiredAtDateOrString) : expiredAtDateOrString;
56
- uca.credentialSubject.id ??= `urn:uuid:${crypto.randomUUID()}`;
57
- try {
58
- await fetchAndSetDigestSri("sha256", uca.credentialSubject.image);
59
- await fetchAndSetTargetIntegrity("sha256", uca, documentProvider);
60
- } catch (e) {
61
- throw new BadRequestError(e.message);
62
- }
63
- return {
64
- iss: uca.issuer,
65
- sub: uca.credentialSubject.id,
66
- iat: getUnixTime(issuedAt),
67
- exp: getUnixTime(expiredAt),
68
- ...uca
69
- };
70
- }
71
-
72
- //#endregion
73
- export { documentProvider as i, sign as n, unsignedCa as r, content_attestation_exports as t };