generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring credentials api interface (#255)
* refactoring credentials api interface * fix comment * remove comments * fix lint * fix vuln * adding unit tests * fix linnt * removed unused dep
- Loading branch information
1 parent
29860a4
commit a2758b9
Showing
13 changed files
with
2,480 additions
and
5,335 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export * from './types.js'; | ||
export * as utils from './utils.js'; | ||
export * from './ssi.js'; | ||
export * from './verifiable-credential.js'; | ||
export * from './presentation-exchange.js'; | ||
export * as utils from './utils.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import type { EvaluationResults, PresentationResult, SelectResults, Validated as PexValidated } from '@sphereon/pex'; | ||
import { PEX } from '@sphereon/pex'; | ||
|
||
import type { PresentationDefinitionV2 as PexPresDefV2 } from '@sphereon/pex-models'; | ||
|
||
import type { | ||
IPresentation, | ||
PresentationSubmission, | ||
} from '@sphereon/ssi-types'; | ||
|
||
export type Validated = PexValidated; | ||
export type PresentationDefinitionV2 = PexPresDefV2 | ||
|
||
export class PresentationExchange { | ||
/** | ||
* The Presentation Exchange (PEX) Library implements the functionality described in the DIF Presentation Exchange specification | ||
*/ | ||
private static pex: PEX = new PEX(); | ||
|
||
/** | ||
* Selects credentials that satisfy a given presentation definition. | ||
* | ||
* @param vcJwts The list of Verifiable Credentials to select from. | ||
* @param presentationDefinition The Presentation Definition to match against. | ||
* @return A list of Verifiable Credentials that satisfy the Presentation Definition. | ||
*/ | ||
public static selectCredentials( | ||
vcJwts: string[], | ||
presentationDefinition: PresentationDefinitionV2 | ||
): string[] { | ||
this.resetPex(); | ||
const selectResults: SelectResults = this.pex.selectFrom(presentationDefinition, vcJwts); | ||
return selectResults.verifiableCredential as string[] ?? []; | ||
} | ||
|
||
public static satisfiesPresentationDefinition( | ||
vcJwts: string[], | ||
presentationDefinition: PresentationDefinitionV2 | ||
): void { | ||
this.resetPex(); | ||
const evaluationResults: EvaluationResults = this.pex.evaluateCredentials(presentationDefinition, vcJwts); | ||
if (evaluationResults.warnings?.length) { | ||
console.warn('Warnings were generated during the evaluation process: ' + JSON.stringify(evaluationResults.warnings)); | ||
} | ||
|
||
if (evaluationResults.areRequiredCredentialsPresent.toString() !== 'info' || evaluationResults.errors?.length) { | ||
let errorMessage = 'Failed to create Verifiable Presentation JWT due to: '; | ||
if(evaluationResults.areRequiredCredentialsPresent) { | ||
errorMessage += 'Required Credentials Not Present: ' + JSON.stringify(evaluationResults.areRequiredCredentialsPresent); | ||
} | ||
|
||
if (evaluationResults.errors?.length) { | ||
errorMessage += 'Errors: ' + JSON.stringify(evaluationResults.errors); | ||
} | ||
|
||
throw new Error(errorMessage); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a presentation from a list of Verifiable Credentials that satisfy a given presentation definition. | ||
* This function initializes the Presentation Exchange (PEX) process, validates the presentation definition, | ||
* evaluates the credentials against the definition, and finally constructs the presentation result if the | ||
* evaluation is successful. | ||
* | ||
* @param {string[]} vcJwts The list of Verifiable Credentials (VCs) in JWT format to be evaluated. | ||
* @param {PresentationDefinitionV2} presentationDefinition The Presentation Definition V2 to match the VCs against. | ||
* @returns {PresentationResult} The result of the presentation creation process, containing a presentation submission | ||
* that satisfies the presentation definition criteria. | ||
* @throws {Error} If the evaluation results in warnings or errors, or if the required credentials are not present, | ||
* an error is thrown with a descriptive message. | ||
*/ | ||
public static createPresentationFromCredentials( | ||
vcJwts: string[], | ||
presentationDefinition: PresentationDefinitionV2 | ||
): PresentationResult { | ||
this.resetPex(); | ||
|
||
const pdValidated: Validated = PEX.validateDefinition(presentationDefinition); | ||
isValid(pdValidated); | ||
|
||
const evaluationResults: EvaluationResults = this.pex.evaluateCredentials(presentationDefinition, vcJwts); | ||
|
||
if (evaluationResults.warnings?.length) { | ||
console.warn('Warnings were generated during the evaluation process: ' + JSON.stringify(evaluationResults.warnings)); | ||
} | ||
|
||
if (evaluationResults.areRequiredCredentialsPresent.toString() !== 'info' || evaluationResults.errors?.length) { | ||
let errorMessage = 'Failed to create Verifiable Presentation JWT due to: '; | ||
if(evaluationResults.areRequiredCredentialsPresent) { | ||
errorMessage += 'Required Credentials Not Present: ' + JSON.stringify(evaluationResults.areRequiredCredentialsPresent); | ||
} | ||
|
||
if (evaluationResults.errors?.length) { | ||
errorMessage += 'Errors: ' + JSON.stringify(evaluationResults.errors); | ||
} | ||
|
||
throw new Error(errorMessage); | ||
} | ||
|
||
const presentationResult: PresentationResult = this.pex.presentationFrom(presentationDefinition, vcJwts); | ||
|
||
const submissionValidated: Validated = PEX.validateSubmission(presentationResult.presentationSubmission); | ||
isValid(submissionValidated); | ||
|
||
return presentationResult; | ||
} | ||
|
||
/** | ||
* This method validates whether an object is usable as a presentation definition or not. | ||
* | ||
* @param presentationDefinition: presentationDefinition to be validated. | ||
* | ||
* @return the validation results to reveal what is acceptable/unacceptable about the passed object to be considered a valid presentation definition | ||
*/ | ||
public static validateDefinition(presentationDefinition: PresentationDefinitionV2): Validated { | ||
return PEX.validateDefinition(presentationDefinition); | ||
} | ||
|
||
/** | ||
* This method validates whether an object is usable as a presentation submission or not. | ||
* | ||
* @param presentationSubmission the object to be validated. | ||
* | ||
* @return the validation results to reveal what is acceptable/unacceptable about the passed object to be considered a valid presentation submission | ||
*/ | ||
public static validateSubmission(presentationSubmission: PresentationSubmission): Validated { | ||
return PEX.validateSubmission(presentationSubmission); | ||
} | ||
|
||
/** | ||
* Evaluates a presentation against a presentation definition. | ||
* @returns {EvaluationResults} The result of the evaluation process. | ||
*/ | ||
public static evaluatePresentation( | ||
presentationDefinition: PresentationDefinitionV2, | ||
presentation: IPresentation | ||
): EvaluationResults { | ||
this.resetPex(); | ||
return this.pex.evaluatePresentation(presentationDefinition, presentation); | ||
} | ||
|
||
private static resetPex() { | ||
this.pex = new PEX(); | ||
} | ||
} | ||
|
||
function isValid(validated: Validated) { | ||
let errorMessage = 'Failed to pass validation check due to: '; | ||
if (Array.isArray(validated)) { | ||
if (!validated.every(item => item.status === 'info')) { | ||
errorMessage += 'Validation Errors: ' + JSON.stringify(validated); | ||
throw new Error(errorMessage); | ||
} | ||
} else { | ||
if (validated.status !== 'info') { | ||
errorMessage += 'Validation Errors: ' + JSON.stringify(validated); | ||
throw new Error(errorMessage); | ||
} | ||
} | ||
} |
Oops, something went wrong.