UNPKG

@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

117 lines (113 loc) • 8.07 kB
import { CredoError } from "../error/CredoError.mjs"; import "../agent/index.mjs"; import { CredentialMultiInstanceState, CredentialMultiInstanceUseMode, CredentialMultiInstanceUseUpdateMode } from "./credentialUseTypes.mjs"; import { W3cJsonLdVerifiableCredential } from "../modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.mjs"; import { W3cV2JwtVerifiableCredential } from "../modules/vc/jwt-vc/W3cV2JwtVerifiableCredential.mjs"; import { W3cV2SdJwtVerifiableCredential } from "../modules/vc/sd-jwt-vc/W3cV2SdJwtVerifiableCredential.mjs"; import { W3cJwtVerifiableCredential } from "../modules/vc/jwt-vc/W3cJwtVerifiableCredential.mjs"; import { W3cCredentialRecord } from "../modules/vc/repository/W3cCredentialRecord.mjs"; import { W3cCredentialRepository } from "../modules/vc/repository/W3cCredentialRepository.mjs"; import { W3cV2CredentialRecord } from "../modules/vc/repository/W3cV2CredentialRecord.mjs"; import { W3cV2CredentialRepository } from "../modules/vc/repository/W3cV2CredentialRepository.mjs"; import "../modules/vc/repository/index.mjs"; import "../modules/vc/index.mjs"; import { Mdoc } from "../modules/mdoc/Mdoc.mjs"; import { MdocRecord } from "../modules/mdoc/repository/MdocRecord.mjs"; import { MdocRepository } from "../modules/mdoc/repository/MdocRepository.mjs"; import "../modules/mdoc/repository/index.mjs"; import { decodeSdJwtVc } from "../modules/sd-jwt-vc/decodeSdJwtVc.mjs"; import { SdJwtVcRecord } from "../modules/sd-jwt-vc/repository/SdJwtVcRecord.mjs"; import { SdJwtVcRepository } from "../modules/sd-jwt-vc/repository/SdJwtVcRepository.mjs"; import "../modules/sd-jwt-vc/repository/index.mjs"; //#region src/utils/credentialUse.ts /** * Checks whether an instance can be used from the provided record based on * the required credential use mode. */ function canUseInstanceFromCredentialRecord({ credentialRecord, useMode }) { if (useMode === CredentialMultiInstanceUseMode.First || useMode === CredentialMultiInstanceUseMode.NewOrFirst || useMode === CredentialMultiInstanceUseMode.NewIfReceivedInBatch && [CredentialMultiInstanceState.SingleInstanceUnused, CredentialMultiInstanceState.SingleInstanceUsed].includes(credentialRecord.multiInstanceState)) return true; return credentialRecord.multiInstanceState === CredentialMultiInstanceState.MultiInstanceFirstUnused || credentialRecord.multiInstanceState === CredentialMultiInstanceState.SingleInstanceUnused; } /** * Extract an instance with the correct kms key id from the credential instances * on the record. Note that if an instance is extracted (that is not reused) it * will remove the instance from the record, and the record should be updated in * storage after usage. * * Note that the last credential instance is never removed from the record. So if the * method indicates the last instance has been used, you should remove the credential * from storage if you don't want it to be used anymore in the future. */ async function useInstanceFromCredentialRecord({ credentialRecord, useMode, agentContext, updateMode }) { let extractResult = extractInstanceAndUpdateRecord({ credentialRecord, useMode }); if ((!extractResult.isReused || extractResult.isLastNewInstance) && updateMode === CredentialMultiInstanceUseUpdateMode.Update) await updateCredentialRecord(agentContext, credentialRecord); if ((!extractResult.isReused || extractResult.isLastNewInstance) && updateMode === CredentialMultiInstanceUseUpdateMode.RefetchAndUpdateWithLock) await repositoryForRecord(agentContext, credentialRecord).updateByIdWithLock(agentContext, credentialRecord.id, async (freshCredentialRecord) => { extractResult = extractInstanceAndUpdateRecord({ credentialRecord: freshCredentialRecord, useMode }); return freshCredentialRecord; }); let transformedCredentialInstance; if (credentialRecord instanceof MdocRecord) { const { issuerSignedBase64Url, kmsKeyId } = extractResult.credentialInstance; transformedCredentialInstance = Mdoc.fromBase64Url(issuerSignedBase64Url); transformedCredentialInstance.deviceKeyId = kmsKeyId ?? transformedCredentialInstance.deviceKey.legacyKeyId; } else if (credentialRecord instanceof SdJwtVcRecord) { const { compactSdJwtVc, kmsKeyId } = extractResult.credentialInstance; transformedCredentialInstance = { ...decodeSdJwtVc(compactSdJwtVc, credentialRecord.typeMetadata), kmsKeyId }; } else if (credentialRecord instanceof W3cCredentialRecord) { const { credential } = extractResult.credentialInstance; transformedCredentialInstance = typeof credential === "string" ? W3cJwtVerifiableCredential.fromSerializedJwt(credential) : W3cJsonLdVerifiableCredential.fromJson(credential); } else if (credentialRecord instanceof W3cV2CredentialRecord) { const { credential } = extractResult.credentialInstance; transformedCredentialInstance = credential.includes("~") ? W3cV2SdJwtVerifiableCredential.fromCompact(credential) : W3cV2JwtVerifiableCredential.fromCompact(credential); } else throw new CredoError("Unsupported record type"); return { credentialInstance: transformedCredentialInstance, isReused: extractResult.isReused, isLastNewInstance: extractResult.isLastNewInstance }; } function extractInstanceAndUpdateRecord({ credentialRecord, useMode }) { if (credentialRecord.credentialInstances.length === 1 || useMode === CredentialMultiInstanceUseMode.First) { const isFirstUnused = credentialRecord.multiInstanceState === CredentialMultiInstanceState.MultiInstanceFirstUnused || credentialRecord.multiInstanceState === CredentialMultiInstanceState.SingleInstanceUnused; const isMultiInstance = credentialRecord.multiInstanceState === CredentialMultiInstanceState.MultiInstanceFirstUnused || credentialRecord.multiInstanceState === CredentialMultiInstanceState.MultiInstanceFirstUsed; const allowsReuse = useMode === CredentialMultiInstanceUseMode.New ? false : useMode === CredentialMultiInstanceUseMode.NewIfReceivedInBatch ? !isMultiInstance : true; if (isFirstUnused) credentialRecord.multiInstanceState = credentialRecord.multiInstanceState === CredentialMultiInstanceState.SingleInstanceUnused ? CredentialMultiInstanceState.SingleInstanceUsed : CredentialMultiInstanceState.MultiInstanceFirstUsed; else if (!allowsReuse) throw new CredoError(`Unable to extract new credential instance from ${credentialRecord.type} with id '${credentialRecord.id}', since it only contains a single credential instance but using a new instance is required due to use mode '${useMode}'.`); return { isReused: !isFirstUnused, credentialInstance: credentialRecord.credentialInstances[0], isLastNewInstance: isFirstUnused }; } const _credentialInstance = credentialRecord.credentialInstances.pop(); if (!_credentialInstance) throw new CredoError(`Unable to extract credential instance from ${credentialRecord.type} with id '${credentialRecord.id}', since the credential record does not contain any credential instances.`); return { credentialInstance: _credentialInstance, isReused: false, isLastNewInstance: false }; } function repositoryForRecord(agentContext, record) { if (record instanceof W3cCredentialRecord) return agentContext.resolve(W3cCredentialRepository); if (record instanceof W3cV2CredentialRecord) return agentContext.resolve(W3cV2CredentialRepository); if (record instanceof MdocRecord) return agentContext.resolve(MdocRepository); return agentContext.resolve(SdJwtVcRepository); } function updateCredentialRecord(agentContext, record) { if (record instanceof W3cCredentialRecord) return agentContext.resolve(W3cCredentialRepository).update(agentContext, record); if (record instanceof W3cV2CredentialRecord) return agentContext.resolve(W3cV2CredentialRepository).update(agentContext, record); if (record instanceof MdocRecord) return agentContext.resolve(MdocRepository).update(agentContext, record); return agentContext.resolve(SdJwtVcRepository).update(agentContext, record); } //#endregion export { canUseInstanceFromCredentialRecord, useInstanceFromCredentialRecord }; //# sourceMappingURL=credentialUse.mjs.map