@twin.org/trust-verifiers 0.0.3-next.1 → 0.0.3-next.11

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.
@@ -1,6 +1,7 @@
1
1
  // Copyright 2025 IOTA Stiftung.
2
2
  // SPDX-License-Identifier: Apache-2.0.
3
3
  import { BaseError, Coerce, ComponentFactory, GeneralError, Is } from "@twin.org/core";
4
+ import { JsonLdHelper } from "@twin.org/data-json-ld";
4
5
  import { Jwt } from "@twin.org/web";
5
6
  /**
6
7
  * Class to verify a JWT Verifiable Credential.
@@ -38,51 +39,59 @@ export class JwtVerifiableCredentialVerifier {
38
39
  /**
39
40
  * Verify a payload by checking the validity of its structure and content.
40
41
  * @param payload The payload to verify.
41
- * @returns Whether the payload is verified and any additional information extracted from the payload, or verification failures.
42
+ * @param info Information extracted from previous verifiers and to be added by this verifier.
43
+ * @param info.identity The identity associated with the payload.
44
+ * @param errors Array to collect verification errors.
45
+ * @returns Whether the payload is verified, returns undefined if payload was not processed.
42
46
  */
43
- async verify(payload) {
44
- const info = [];
45
- const failures = [];
47
+ async verify(payload, info, errors) {
46
48
  if (Is.stringValue(payload)) {
47
49
  const jwt = await Jwt.decode(payload);
48
- if (Is.objectValue(jwt.header) &&
49
- Is.objectValue(jwt.payload) &&
50
- Is.uint8Array(jwt.signature)) {
50
+ if (Is.objectValue(jwt.header) && Is.object(jwt.payload) && Is.uint8Array(jwt.signature)) {
51
+ let isVerified = true;
51
52
  try {
52
53
  const expiredMs = (Coerce.number(jwt.payload.exp) ?? 0) * 1000;
53
54
  if (expiredMs > 0 && expiredMs < Date.now()) {
54
- failures.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenExpired"));
55
+ errors.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenExpired"));
56
+ isVerified = false;
55
57
  }
56
58
  const verificationResult = await this._identityComponent.verifiableCredentialVerify(payload);
57
59
  const verifiableCredential = verificationResult.verifiableCredential;
58
60
  if (Is.empty(verifiableCredential)) {
59
- failures.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingCredential"));
61
+ errors.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingCredential"));
62
+ isVerified = false;
63
+ }
64
+ else {
65
+ info.data ??= {};
66
+ info.data.verifiableCredential = JsonLdHelper.toNodeObject(verifiableCredential);
60
67
  }
61
68
  const issuer = Is.stringValue(verifiableCredential?.issuer)
62
69
  ? verifiableCredential?.issuer
63
70
  : undefined;
64
71
  if (Is.empty(issuer)) {
65
- failures.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingIssuer"));
72
+ errors.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingIssuer"));
73
+ isVerified = false;
74
+ }
75
+ else {
76
+ info.identity = issuer;
66
77
  }
67
78
  const subject = verifiableCredential?.credentialSubject;
68
79
  if (Is.empty(subject)) {
69
- failures.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingSubject"));
80
+ errors.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenMissingSubject"));
81
+ isVerified = false;
70
82
  }
71
83
  else {
72
- const subjectArray = Array.isArray(subject) ? subject : [subject];
73
- info.push(...subjectArray);
84
+ info.data ??= {};
85
+ info.data.subject = JsonLdHelper.toNodeObject(subject);
74
86
  }
75
87
  }
76
88
  catch (err) {
77
- failures.push(BaseError.fromError(err));
89
+ isVerified = false;
90
+ errors.push(new GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, "tokenDecodingFailed", undefined, BaseError.fromError(err)));
78
91
  }
92
+ return isVerified;
79
93
  }
80
94
  }
81
- return {
82
- verified: failures.length === 0,
83
- info,
84
- failures
85
- };
86
95
  }
87
96
  }
88
97
  //# sourceMappingURL=jwtVerifiableCredentialVerifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwtVerifiableCredentialVerifier.js","sourceRoot":"","sources":["../../../src/verifiers/jwtVerifiableCredentialVerifier.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseError, Coerce, ComponentFactory, GeneralError, type IError, Is } from \"@twin.org/core\";\nimport type { IJsonLdNodeObject } from \"@twin.org/data-json-ld\";\nimport type { IIdentityComponent } from \"@twin.org/identity-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { ITrustVerifier } from \"@twin.org/trust-models\";\nimport { Jwt } from \"@twin.org/web\";\nimport type { IJwtVerifiableCredentialVerifierConstructorOptions } from \"../models/IJwtVerifiableCredentialVerifierConstructorOptions.js\";\n\n/**\n * Class to verify a JWT Verifiable Credential.\n */\nexport class JwtVerifiableCredentialVerifier implements ITrustVerifier {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<JwtVerifiableCredentialVerifier>();\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponent?: ILoggingComponent;\n\n\t/**\n\t * The identity component.\n\t * @internal\n\t */\n\tprivate readonly _identityComponent: IIdentityComponent;\n\n\t/**\n\t * Create a new instance of JwtVerifiableCredentialVerifier.\n\t * @param options The options for the service.\n\t */\n\tconstructor(options?: IJwtVerifiableCredentialVerifierConstructorOptions) {\n\t\tthis._loggingComponent = ComponentFactory.getIfExists(\n\t\t\toptions?.loggingComponentType ?? \"logging\"\n\t\t);\n\n\t\tthis._identityComponent = ComponentFactory.get(options?.identityComponentType ?? \"identity\");\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn JwtVerifiableCredentialVerifier.CLASS_NAME;\n\t}\n\n\t/**\n\t * Verify a payload by checking the validity of its structure and content.\n\t * @param payload The payload to verify.\n\t * @returns Whether the payload is verified and any additional information extracted from the payload, or verification failures.\n\t */\n\tpublic async verify(payload: unknown): Promise<{\n\t\tverified: boolean;\n\t\tinfo?: IJsonLdNodeObject[];\n\t\tfailures?: IError[];\n\t}> {\n\t\tconst info: IJsonLdNodeObject[] = [];\n\t\tconst failures: IError[] = [];\n\n\t\tif (Is.stringValue(payload)) {\n\t\t\tconst jwt = await Jwt.decode(payload);\n\n\t\t\tif (\n\t\t\t\tIs.objectValue(jwt.header) &&\n\t\t\t\tIs.objectValue(jwt.payload) &&\n\t\t\t\tIs.uint8Array(jwt.signature)\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tconst expiredMs = (Coerce.number(jwt.payload.exp) ?? 0) * 1000;\n\t\t\t\t\tif (expiredMs > 0 && expiredMs < Date.now()) {\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenExpired\")\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst verificationResult =\n\t\t\t\t\t\tawait this._identityComponent.verifiableCredentialVerify(payload);\n\n\t\t\t\t\tconst verifiableCredential = verificationResult.verifiableCredential;\n\t\t\t\t\tif (Is.empty(verifiableCredential)) {\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingCredential\")\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst issuer: string | undefined = Is.stringValue(verifiableCredential?.issuer)\n\t\t\t\t\t\t? verifiableCredential?.issuer\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (Is.empty(issuer)) {\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingIssuer\")\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subject = verifiableCredential?.credentialSubject;\n\t\t\t\t\tif (Is.empty(subject)) {\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingSubject\")\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst subjectArray = Array.isArray(subject) ? subject : [subject];\n\t\t\t\t\t\tinfo.push(...subjectArray);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tfailures.push(BaseError.fromError(err));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tverified: failures.length === 0,\n\t\t\tinfo,\n\t\t\tfailures\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"jwtVerifiableCredentialVerifier.js","sourceRoot":"","sources":["../../../src/verifiers/jwtVerifiableCredentialVerifier.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,EAAe,MAAM,gBAAgB,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGpC;;GAEG;AACH,MAAM,OAAO,+BAA+B;IAC3C;;OAEG;IACI,MAAM,CAAU,UAAU,qCAAqD;IAEtF;;;OAGG;IACc,iBAAiB,CAAqB;IAEvD;;;OAGG;IACc,kBAAkB,CAAqB;IAExD;;;OAGG;IACH,YAAY,OAA4D;QACvE,IAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,WAAW,CACpD,OAAO,EAAE,oBAAoB,IAAI,SAAS,CAC1C,CAAC;QAEF,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,IAAI,UAAU,CAAC,CAAC;IAC9F,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,+BAA+B,CAAC,UAAU,CAAC;IACnD,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,MAAM,CAClB,OAAgB,EAChB,IAA4B,EAC5B,MAAgB;QAEhB,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEtC,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1F,IAAI,UAAU,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC;oBACJ,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;oBAC/D,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;wBAC7C,MAAM,CAAC,IAAI,CACV,IAAI,YAAY,CAAC,+BAA+B,CAAC,UAAU,EAAE,cAAc,CAAC,CAC5E,CAAC;wBACF,UAAU,GAAG,KAAK,CAAC;oBACpB,CAAC;oBAED,MAAM,kBAAkB,GACvB,MAAM,IAAI,CAAC,kBAAkB,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;oBAEnE,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,oBAAoB,CAAC;oBACrE,IAAI,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC;wBACpC,MAAM,CAAC,IAAI,CACV,IAAI,YAAY,CAAC,+BAA+B,CAAC,UAAU,EAAE,wBAAwB,CAAC,CACtF,CAAC;wBACF,UAAU,GAAG,KAAK,CAAC;oBACpB,CAAC;yBAAM,CAAC;wBACP,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;wBACjB,IAAI,CAAC,IAAI,CAAC,oBAAoB,GAAG,YAAY,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;oBAClF,CAAC;oBAED,MAAM,MAAM,GAAuB,EAAE,CAAC,WAAW,CAAC,oBAAoB,EAAE,MAAM,CAAC;wBAC9E,CAAC,CAAC,oBAAoB,EAAE,MAAM;wBAC9B,CAAC,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;wBACtB,MAAM,CAAC,IAAI,CACV,IAAI,YAAY,CAAC,+BAA+B,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAClF,CAAC;wBACF,UAAU,GAAG,KAAK,CAAC;oBACpB,CAAC;yBAAM,CAAC;wBACP,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC;oBACxB,CAAC;oBAED,MAAM,OAAO,GAAG,oBAAoB,EAAE,iBAAiB,CAAC;oBACxD,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;wBACvB,MAAM,CAAC,IAAI,CACV,IAAI,YAAY,CAAC,+BAA+B,CAAC,UAAU,EAAE,qBAAqB,CAAC,CACnF,CAAC;wBACF,UAAU,GAAG,KAAK,CAAC;oBACpB,CAAC;yBAAM,CAAC;wBACP,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;wBACjB,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;oBACxD,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,UAAU,GAAG,KAAK,CAAC;oBACnB,MAAM,CAAC,IAAI,CACV,IAAI,YAAY,CACf,+BAA+B,CAAC,UAAU,EAC1C,qBAAqB,EACrB,SAAS,EACT,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CACxB,CACD,CAAC;gBACH,CAAC;gBAED,OAAO,UAAU,CAAC;YACnB,CAAC;QACF,CAAC;IACF,CAAC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseError, Coerce, ComponentFactory, GeneralError, Is, type IError } from \"@twin.org/core\";\nimport { JsonLdHelper } from \"@twin.org/data-json-ld\";\nimport type { IIdentityComponent } from \"@twin.org/identity-models\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { ITrustVerificationInfo, ITrustVerifier } from \"@twin.org/trust-models\";\nimport { Jwt } from \"@twin.org/web\";\nimport type { IJwtVerifiableCredentialVerifierConstructorOptions } from \"../models/IJwtVerifiableCredentialVerifierConstructorOptions.js\";\n\n/**\n * Class to verify a JWT Verifiable Credential.\n */\nexport class JwtVerifiableCredentialVerifier implements ITrustVerifier {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<JwtVerifiableCredentialVerifier>();\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponent?: ILoggingComponent;\n\n\t/**\n\t * The identity component.\n\t * @internal\n\t */\n\tprivate readonly _identityComponent: IIdentityComponent;\n\n\t/**\n\t * Create a new instance of JwtVerifiableCredentialVerifier.\n\t * @param options The options for the service.\n\t */\n\tconstructor(options?: IJwtVerifiableCredentialVerifierConstructorOptions) {\n\t\tthis._loggingComponent = ComponentFactory.getIfExists(\n\t\t\toptions?.loggingComponentType ?? \"logging\"\n\t\t);\n\n\t\tthis._identityComponent = ComponentFactory.get(options?.identityComponentType ?? \"identity\");\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn JwtVerifiableCredentialVerifier.CLASS_NAME;\n\t}\n\n\t/**\n\t * Verify a payload by checking the validity of its structure and content.\n\t * @param payload The payload to verify.\n\t * @param info Information extracted from previous verifiers and to be added by this verifier.\n\t * @param info.identity The identity associated with the payload.\n\t * @param errors Array to collect verification errors.\n\t * @returns Whether the payload is verified, returns undefined if payload was not processed.\n\t */\n\tpublic async verify(\n\t\tpayload: unknown,\n\t\tinfo: ITrustVerificationInfo,\n\t\terrors: IError[]\n\t): Promise<boolean | undefined> {\n\t\tif (Is.stringValue(payload)) {\n\t\t\tconst jwt = await Jwt.decode(payload);\n\n\t\t\tif (Is.objectValue(jwt.header) && Is.object(jwt.payload) && Is.uint8Array(jwt.signature)) {\n\t\t\t\tlet isVerified = true;\n\t\t\t\ttry {\n\t\t\t\t\tconst expiredMs = (Coerce.number(jwt.payload.exp) ?? 0) * 1000;\n\t\t\t\t\tif (expiredMs > 0 && expiredMs < Date.now()) {\n\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenExpired\")\n\t\t\t\t\t\t);\n\t\t\t\t\t\tisVerified = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst verificationResult =\n\t\t\t\t\t\tawait this._identityComponent.verifiableCredentialVerify(payload);\n\n\t\t\t\t\tconst verifiableCredential = verificationResult.verifiableCredential;\n\t\t\t\t\tif (Is.empty(verifiableCredential)) {\n\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingCredential\")\n\t\t\t\t\t\t);\n\t\t\t\t\t\tisVerified = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinfo.data ??= {};\n\t\t\t\t\t\tinfo.data.verifiableCredential = JsonLdHelper.toNodeObject(verifiableCredential);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst issuer: string | undefined = Is.stringValue(verifiableCredential?.issuer)\n\t\t\t\t\t\t? verifiableCredential?.issuer\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (Is.empty(issuer)) {\n\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingIssuer\")\n\t\t\t\t\t\t);\n\t\t\t\t\t\tisVerified = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinfo.identity = issuer;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subject = verifiableCredential?.credentialSubject;\n\t\t\t\t\tif (Is.empty(subject)) {\n\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\tnew GeneralError(JwtVerifiableCredentialVerifier.CLASS_NAME, \"tokenMissingSubject\")\n\t\t\t\t\t\t);\n\t\t\t\t\t\tisVerified = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinfo.data ??= {};\n\t\t\t\t\t\tinfo.data.subject = JsonLdHelper.toNodeObject(subject);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tisVerified = false;\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tnew GeneralError(\n\t\t\t\t\t\t\tJwtVerifiableCredentialVerifier.CLASS_NAME,\n\t\t\t\t\t\t\t\"tokenDecodingFailed\",\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn isVerified;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import { type IError } from "@twin.org/core";
2
- import type { IJsonLdNodeObject } from "@twin.org/data-json-ld";
3
- import type { ITrustVerifier } from "@twin.org/trust-models";
2
+ import type { ITrustVerificationInfo, ITrustVerifier } from "@twin.org/trust-models";
4
3
  import type { IJwtVerifiableCredentialVerifierConstructorOptions } from "../models/IJwtVerifiableCredentialVerifierConstructorOptions.js";
5
4
  /**
6
5
  * Class to verify a JWT Verifiable Credential.
@@ -23,11 +22,10 @@ export declare class JwtVerifiableCredentialVerifier implements ITrustVerifier {
23
22
  /**
24
23
  * Verify a payload by checking the validity of its structure and content.
25
24
  * @param payload The payload to verify.
26
- * @returns Whether the payload is verified and any additional information extracted from the payload, or verification failures.
25
+ * @param info Information extracted from previous verifiers and to be added by this verifier.
26
+ * @param info.identity The identity associated with the payload.
27
+ * @param errors Array to collect verification errors.
28
+ * @returns Whether the payload is verified, returns undefined if payload was not processed.
27
29
  */
28
- verify(payload: unknown): Promise<{
29
- verified: boolean;
30
- info?: IJsonLdNodeObject[];
31
- failures?: IError[];
32
- }>;
30
+ verify(payload: unknown, info: ITrustVerificationInfo, errors: IError[]): Promise<boolean | undefined>;
33
31
  }
package/docs/changelog.md CHANGED
@@ -1,5 +1,145 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.3-next.11](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.10...trust-verifiers-v0.0.3-next.11) (2026-03-04)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **trust-verifiers:** Synchronize repo versions
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/trust-models bumped from 0.0.3-next.10 to 0.0.3-next.11
16
+
17
+ ## [0.0.3-next.10](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.9...trust-verifiers-v0.0.3-next.10) (2026-02-27)
18
+
19
+
20
+ ### Miscellaneous Chores
21
+
22
+ * **trust-verifiers:** Synchronize repo versions
23
+
24
+
25
+ ### Dependencies
26
+
27
+ * The following workspace dependencies were updated
28
+ * dependencies
29
+ * @twin.org/trust-models bumped from 0.0.3-next.9 to 0.0.3-next.10
30
+
31
+ ## [0.0.3-next.9](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.8...trust-verifiers-v0.0.3-next.9) (2026-02-26)
32
+
33
+
34
+ ### Miscellaneous Chores
35
+
36
+ * **trust-verifiers:** Synchronize repo versions
37
+
38
+
39
+ ### Dependencies
40
+
41
+ * The following workspace dependencies were updated
42
+ * dependencies
43
+ * @twin.org/trust-models bumped from 0.0.3-next.8 to 0.0.3-next.9
44
+
45
+ ## [0.0.3-next.8](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.7...trust-verifiers-v0.0.3-next.8) (2026-01-30)
46
+
47
+
48
+ ### Features
49
+
50
+ * verification info structure ([#10](https://github.com/twinfoundation/trust/issues/10)) ([8b09ec8](https://github.com/twinfoundation/trust/commit/8b09ec8128214b659f427fc3a985eb8ced9ed5dc))
51
+
52
+
53
+ ### Dependencies
54
+
55
+ * The following workspace dependencies were updated
56
+ * dependencies
57
+ * @twin.org/trust-models bumped from 0.0.3-next.7 to 0.0.3-next.8
58
+
59
+ ## [0.0.3-next.7](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.6...trust-verifiers-v0.0.3-next.7) (2025-12-04)
60
+
61
+
62
+ ### Miscellaneous Chores
63
+
64
+ * **trust-verifiers:** Synchronize repo versions
65
+
66
+
67
+ ### Dependencies
68
+
69
+ * The following workspace dependencies were updated
70
+ * dependencies
71
+ * @twin.org/trust-models bumped from 0.0.3-next.6 to 0.0.3-next.7
72
+
73
+ ## [0.0.3-next.6](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.5...trust-verifiers-v0.0.3-next.6) (2025-12-04)
74
+
75
+
76
+ ### Features
77
+
78
+ * always include identity in verification info ([9594d19](https://github.com/twinfoundation/trust/commit/9594d19e9d718bd42b82964750ae3bcfb7df51bf))
79
+
80
+
81
+ ### Dependencies
82
+
83
+ * The following workspace dependencies were updated
84
+ * dependencies
85
+ * @twin.org/trust-models bumped from 0.0.3-next.5 to 0.0.3-next.6
86
+
87
+ ## [0.0.3-next.5](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.4...trust-verifiers-v0.0.3-next.5) (2025-12-04)
88
+
89
+
90
+ ### Miscellaneous Chores
91
+
92
+ * **trust-verifiers:** Synchronize repo versions
93
+
94
+
95
+ ### Dependencies
96
+
97
+ * The following workspace dependencies were updated
98
+ * dependencies
99
+ * @twin.org/trust-models bumped from 0.0.3-next.4 to 0.0.3-next.5
100
+
101
+ ## [0.0.3-next.4](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.3...trust-verifiers-v0.0.3-next.4) (2025-12-04)
102
+
103
+
104
+ ### Features
105
+
106
+ * add generators ([6228c88](https://github.com/twinfoundation/trust/commit/6228c88a8f0244b7bdfc76b8624c427c81d23f7b))
107
+
108
+
109
+ ### Dependencies
110
+
111
+ * The following workspace dependencies were updated
112
+ * dependencies
113
+ * @twin.org/trust-models bumped from 0.0.3-next.3 to 0.0.3-next.4
114
+
115
+ ## [0.0.3-next.3](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.2...trust-verifiers-v0.0.3-next.3) (2025-12-04)
116
+
117
+
118
+ ### Features
119
+
120
+ * flatten error structure ([5fdd665](https://github.com/twinfoundation/trust/commit/5fdd665d0fc523a655563a0c20d1d82b634534e2))
121
+
122
+
123
+ ### Dependencies
124
+
125
+ * The following workspace dependencies were updated
126
+ * dependencies
127
+ * @twin.org/trust-models bumped from 0.0.3-next.2 to 0.0.3-next.3
128
+
129
+ ## [0.0.3-next.2](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.1...trust-verifiers-v0.0.3-next.2) (2025-12-03)
130
+
131
+
132
+ ### Features
133
+
134
+ * support pass through of info between verifiers ([1ce64b9](https://github.com/twinfoundation/trust/commit/1ce64b97a949278b447cc12b576ce5de537f30f3))
135
+
136
+
137
+ ### Dependencies
138
+
139
+ * The following workspace dependencies were updated
140
+ * dependencies
141
+ * @twin.org/trust-models bumped from 0.0.3-next.1 to 0.0.3-next.2
142
+
3
143
  ## [0.0.3-next.1](https://github.com/twinfoundation/trust/compare/trust-verifiers-v0.0.3-next.0...trust-verifiers-v0.0.3-next.1) (2025-12-02)
4
144
 
5
145
 
@@ -56,7 +56,7 @@ The class name of the component.
56
56
 
57
57
  ### verify()
58
58
 
59
- > **verify**(`payload`): `Promise`\<\{ `verified`: `boolean`; `info?`: `IJsonLdNodeObject`[]; `failures?`: `IError`[]; \}\>
59
+ > **verify**(`payload`, `info`, `errors`): `Promise`\<`boolean` \| `undefined`\>
60
60
 
61
61
  Verify a payload by checking the validity of its structure and content.
62
62
 
@@ -68,11 +68,23 @@ Verify a payload by checking the validity of its structure and content.
68
68
 
69
69
  The payload to verify.
70
70
 
71
+ ##### info
72
+
73
+ `ITrustVerificationInfo`
74
+
75
+ Information extracted from previous verifiers and to be added by this verifier.
76
+
77
+ ##### errors
78
+
79
+ `IError`[]
80
+
81
+ Array to collect verification errors.
82
+
71
83
  #### Returns
72
84
 
73
- `Promise`\<\{ `verified`: `boolean`; `info?`: `IJsonLdNodeObject`[]; `failures?`: `IError`[]; \}\>
85
+ `Promise`\<`boolean` \| `undefined`\>
74
86
 
75
- Whether the payload is verified and any additional information extracted from the payload, or verification failures.
87
+ Whether the payload is verified, returns undefined if payload was not processed.
76
88
 
77
89
  #### Implementation of
78
90
 
package/locales/en.json CHANGED
@@ -4,7 +4,8 @@
4
4
  "tokenMissingCredential": "The JWT token does not contain a verifiable credential.",
5
5
  "tokenMissingIssuer": "The verifiable credential in the JWT does not contain an issuer.",
6
6
  "tokenExpired": "The JWT token has expired.",
7
- "tokenMissingSubject": "The verifiable credential in the JWT does not contain a subject."
7
+ "tokenMissingSubject": "The verifiable credential in the JWT does not contain a subject.",
8
+ "tokenDecodingFailed": "Failed to decode the JWT token."
8
9
  }
9
10
  }
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/trust-verifiers",
3
- "version": "0.0.3-next.1",
3
+ "version": "0.0.3-next.11",
4
4
  "description": "Verifiers for trust",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "@twin.org/identity-models": "next",
20
20
  "@twin.org/logging-models": "next",
21
21
  "@twin.org/nameof": "next",
22
- "@twin.org/trust-models": "0.0.3-next.1",
22
+ "@twin.org/trust-models": "0.0.3-next.11",
23
23
  "@twin.org/web": "next"
24
24
  },
25
25
  "main": "./dist/es/index.js",