@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
232 lines (228 loc) • 10.6 kB
JavaScript
import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/index.mjs";
import { asArray } from "../../../utils/array.mjs";
import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
import "../../../utils/index.mjs";
import { injectable } from "../../../plugins/index.mjs";
import { __decorateMetadata } from "../../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorateMetadata.mjs";
import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorate.mjs";
import "../../kms/index.mjs";
import { parseDid } from "../../dids/domain/parse.mjs";
import { VerificationMethod } from "../../dids/domain/verificationMethod/VerificationMethod.mjs";
import { getPublicJwkFromVerificationMethod } from "../../dids/domain/key-type/keyDidMapping.mjs";
import "../../dids/domain/key-type/index.mjs";
import { DidsApi } from "../../dids/DidsApi.mjs";
import "../../dids/index.mjs";
import jsonld_default from "./libraries/jsonld.mjs";
import { W3cJsonLdVerifiableCredential } from "./models/W3cJsonLdVerifiableCredential.mjs";
import { assertOnlyW3cJsonLdVerifiableCredentials } from "./jsonldUtil.mjs";
import vc_default from "./libraries/vc.mjs";
import { w3cDate } from "../util.mjs";
import { W3cJsonLdVerifiablePresentation } from "./models/W3cJsonLdVerifiablePresentation.mjs";
import "./models/index.mjs";
import { SignatureSuiteRegistry } from "./SignatureSuiteRegistry.mjs";
import { createKmsKeyPairClass } from "../../../crypto/KmsKeyPair.mjs";
import { W3cCredentialsModuleConfig } from "../W3cCredentialsModuleConfig.mjs";
//#region src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts
var _ref, _ref2;
let W3cJsonLdCredentialService = class W3cJsonLdCredentialService {
constructor(signatureSuiteRegistry, w3cCredentialsModuleConfig) {
this.signatureSuiteRegistry = signatureSuiteRegistry;
this.w3cCredentialsModuleConfig = w3cCredentialsModuleConfig;
}
/**
* Signs a credential
*/
async signCredential(agentContext, options) {
const WalletKeyPair = createKmsKeyPairClass(agentContext);
const signingKey = await this.getPublicJwkFromVerificationMethod(agentContext, options.verificationMethod);
const suiteInfo = this.signatureSuiteRegistry.getByProofType(options.proofType);
if (!this.signatureSuiteRegistry.getAllByPublicJwkType(signingKey).some(({ suiteClass }) => suiteClass === suiteInfo.suiteClass)) throw new CredoError("The key type of the verification method does not match the suite");
const keyPair = new WalletKeyPair({
controller: options.credential.issuerId,
id: options.verificationMethod,
publicJwk: signingKey
});
const SuiteClass = suiteInfo.suiteClass;
const suite = new SuiteClass({
key: keyPair,
LDKeyClass: WalletKeyPair,
proof: { verificationMethod: options.verificationMethod },
useNativeCanonize: false,
date: options.created ?? w3cDate()
});
try {
const result = await vc_default.issue({
credential: JsonTransformer.toJSON(options.credential),
suite,
purpose: options.proofPurpose,
documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
});
return JsonTransformer.fromJSON(result, W3cJsonLdVerifiableCredential);
} catch (error) {
throw new CredoError(`Error issuing W3C JSON-LD VC. ${error.message}`, { cause: error });
}
}
/**
* Verifies the signature(s) of a credential
*
* @param credential the credential to be verified
* @returns the verification result
*/
async verifyCredential(agentContext, options) {
try {
const verifyCredentialStatus = options.verifyCredentialStatus ?? true;
const suites = this.getSignatureSuitesForCredential(agentContext, options.credential);
const verifyOptions = {
credential: JsonTransformer.toJSON(options.credential),
suite: suites,
documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext),
checkStatus: ({ credential }) => {
if (verifyCredentialStatus && "credentialStatus" in credential) throw new CredoError("Verifying credential status for JSON-LD credentials is currently not supported");
return { verified: true };
}
};
if (options.proofPurpose) verifyOptions.purpose = options.proofPurpose;
const result = await vc_default.verifyCredential(verifyOptions);
const { verified: isValid, ...remainingResult } = result;
if (!isValid) agentContext.config.logger.debug(`Credential verification failed: ${result.error?.message}`, { stack: result.error?.stack });
return {
isValid,
validations: { vcJs: {
isValid,
...remainingResult
} },
error: result.error
};
} catch (error) {
return {
isValid: false,
validations: {},
error
};
}
}
/**
* Signs a presentation including the credentials it includes
*
* @param presentation the presentation to be signed
* @returns the signed presentation
*/
async signPresentation(agentContext, options) {
const WalletKeyPair = createKmsKeyPairClass(agentContext);
const suiteInfo = this.signatureSuiteRegistry.getByProofType(options.proofType);
if (!suiteInfo) throw new CredoError(`The requested proofType ${options.proofType} is not supported`);
const signingKey = await this.getPublicJwkFromVerificationMethod(agentContext, options.verificationMethod);
if (!this.signatureSuiteRegistry.getAllByPublicJwkType(signingKey).some(({ suiteClass }) => suiteClass === suiteInfo.suiteClass)) throw new CredoError("The key type of the verification method does not match the suite");
const verificationMethodObject = (await this.w3cCredentialsModuleConfig.documentLoader(agentContext)(options.verificationMethod)).document;
const keyPair = new WalletKeyPair({
controller: verificationMethodObject.controller,
id: options.verificationMethod,
publicJwk: signingKey
});
const suite = new suiteInfo.suiteClass({
LDKeyClass: WalletKeyPair,
proof: { verificationMethod: options.verificationMethod },
date: (/* @__PURE__ */ new Date()).toISOString(),
key: keyPair,
useNativeCanonize: false
});
const signOptions = {
presentation: JsonTransformer.toJSON(options.presentation),
suite,
challenge: options.challenge,
domain: options.domain,
documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
};
if (options.proofPurpose) signOptions.purpose = options.proofPurpose;
const result = await vc_default.signPresentation(signOptions);
return JsonTransformer.fromJSON(result, W3cJsonLdVerifiablePresentation);
}
/**
* Verifies a presentation including the credentials it includes
*
* @param presentation the presentation to be verified
* @returns the verification result
*/
async verifyPresentation(agentContext, options) {
try {
const WalletKeyPair = createKmsKeyPairClass(agentContext);
let proofs = options.presentation.proof;
if (!Array.isArray(proofs)) proofs = [proofs];
if (options.purpose) proofs = proofs.filter((proof) => proof.proofPurpose === options.purpose.term);
const presentationSuites = proofs.map((proof) => {
const SuiteClass = this.signatureSuiteRegistry.getByProofType(proof.type).suiteClass;
return new SuiteClass({
LDKeyClass: WalletKeyPair,
proof: { verificationMethod: proof.verificationMethod },
date: proof.created,
useNativeCanonize: false
});
});
const credentials = asArray(options.presentation.verifiableCredential);
assertOnlyW3cJsonLdVerifiableCredentials(credentials);
const credentialSuites = credentials.map((credential) => this.getSignatureSuitesForCredential(agentContext, credential));
const allSuites = presentationSuites.concat(...credentialSuites);
const verifyOptions = {
presentation: JsonTransformer.toJSON(options.presentation),
suite: allSuites,
challenge: options.challenge,
domain: options.domain,
documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
};
if (options.purpose) verifyOptions.presentationPurpose = options.purpose;
const result = await vc_default.verify(verifyOptions);
const { verified: isValid, ...remainingResult } = result;
return {
isValid,
validations: { vcJs: {
isValid,
...remainingResult
} },
error: result.error
};
} catch (error) {
return {
isValid: false,
validations: {},
error
};
}
}
getVerificationMethodTypesByProofType(proofType) {
return this.signatureSuiteRegistry.getByProofType(proofType).verificationMethodTypes;
}
async getExpandedTypesForCredential(agentContext, credential) {
const expandedTypes = (await jsonld_default.expand(JsonTransformer.toJSON(credential), { documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext) }))[0]["@type"];
return asArray(expandedTypes);
}
async getPublicJwkFromVerificationMethod(agentContext, verificationMethod) {
const dids = agentContext.resolve(DidsApi);
const verificationMethodObject = await this.w3cCredentialsModuleConfig.documentLoader(agentContext)(verificationMethod);
const verificationMethodInstance = JsonTransformer.fromJSON(verificationMethodObject.document, VerificationMethod);
const did = parseDid(verificationMethod);
const publicJwk = getPublicJwkFromVerificationMethod(verificationMethodInstance);
const [didRecord] = await dids.getCreatedDids({ did: did.did });
if (didRecord) publicJwk.keyId = didRecord.keys?.find(({ didDocumentRelativeKeyId }) => didDocumentRelativeKeyId === `#${did.fragment}`)?.kmsKeyId ?? publicJwk.legacyKeyId;
else publicJwk.keyId = publicJwk.legacyKeyId;
return publicJwk;
}
getSignatureSuitesForCredential(agentContext, credential) {
const WalletKeyPair = createKmsKeyPairClass(agentContext);
let proofs = credential.proof;
if (!Array.isArray(proofs)) proofs = [proofs];
return proofs.map((proof) => {
const SuiteClass = this.signatureSuiteRegistry.getByProofType(proof.type).suiteClass;
return new SuiteClass({
LDKeyClass: WalletKeyPair,
proof: { verificationMethod: proof.verificationMethod },
date: proof.created,
useNativeCanonize: false
});
});
}
};
W3cJsonLdCredentialService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof SignatureSuiteRegistry !== "undefined" && SignatureSuiteRegistry) === "function" ? _ref : Object, typeof (_ref2 = typeof W3cCredentialsModuleConfig !== "undefined" && W3cCredentialsModuleConfig) === "function" ? _ref2 : Object])], W3cJsonLdCredentialService);
//#endregion
export { W3cJsonLdCredentialService };
//# sourceMappingURL=W3cJsonLdCredentialService.mjs.map