Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/vc-api/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,7 @@
"ProofPurpose": {
"type": "string",
"enum": [
"verificationMethod",
"assertionMethod",
"authentication",
"keyAgreement",
Expand Down
7 changes: 4 additions & 3 deletions apps/vc-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"@nestjs/typeorm": "^11.0.0",
"@openwallet-foundation/askar-nodejs": "catalog:",
"@openwallet-foundation/askar-shared": "catalog:",
"@sphereon/pex": "1.1.3",
"axios": "~1.18.1",
"class-transformer": "~0.5.1",
"class-validator": "~0.14.3",
Expand All @@ -53,13 +52,15 @@
"sqlite3": "~5.1.7",
"swagger-ui-express": "~5.0.1",
"typeorm": "^0.3.17",
"uuid": "~9.0.0"
"uuid": "~9.0.0",
"@animo-id/pex": "catalog:",
"@sphereon/ssi-types": "catalog:"
},
"devDependencies": {
"@nestjs/cli": "^11.0.0",
"@nestjs/schematics": "^11.0.0",
"@nestjs/testing": "catalog:",
"@sphereon/pex-models": "~2.0.2",
"@sphereon/pex-models": "catalog:",
"@types/express": "^5.0.0",
"@types/jest": "catalog:",
"@types/node": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { IssueOptionsDto } from './dtos/issue-options.dto';
import { VerifyOptionsDto } from './dtos/verify-options.dto';
import { DIDService } from '../../did/did.service';
import { KeyService } from '../../key/key.service';
import { IPresentationDefinition, ProofPurpose } from '@sphereon/pex';
import { IPresentationDefinition } from '@animo-id/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { VerifiableCredential } from '../exchanges/types/verifiable-credential';
import { CredentialDto } from './dtos/credential.dto';
import {
Expand Down
11 changes: 8 additions & 3 deletions apps/vc-api/src/vc-api/credentials/credentials.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { VerificationResultDto } from './dtos/verification-result.dto';
import { ProvePresentationDto } from './dtos/prove-presentation.dto';
import { CredentialVerifier } from './types/credential-verifier';
import { PresentationDto } from './dtos/presentation.dto';
import { IPresentationDefinition, IVerifiableCredential, PEX, ProofPurpose, Status } from '@sphereon/pex';
import { IPresentationDefinition, PEX, PresentationSubmissionLocation, Status } from '@animo-id/pex';
import { IProofPurpose as ProofPurpose, IVerifiableCredential } from '@sphereon/ssi-types';
import { VerificationMethod } from 'did-resolver';
import { CredoService } from '../../credo/credo.service';
import {
Expand Down Expand Up @@ -89,9 +90,13 @@ export class CredentialsService implements CredentialVerifier {
if (areRequiredCredentialsPresent !== Status.INFO) {
throw new InternalServerErrorException('Credentials do not satisfy defintion');
}
const presentation = pex.presentationFrom(presentationDefinition, verifiableCredential);
// keep the presentation submission embedded in the presentation, as
// returned by pex 1.x
const { presentations } = pex.presentationFrom(presentationDefinition, verifiableCredential, {
presentationSubmissionLocation: PresentationSubmissionLocation.PRESENTATION
});

return presentation as PresentationDto;
return presentations[0] as PresentationDto;
}

async provePresentation(provePresentationDto: ProvePresentationDto): Promise<VerifiablePresentationDto> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { IsEnum, IsObject, IsOptional, IsString } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { IsOptional, IsString } from 'class-validator';
import { VerifyOptions } from '../types/verify-options';
import { ApiPropertyOptional } from '@nestjs/swagger';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { IPresentationDefinition, PEX, Status } from '@sphereon/pex';
import { IPresentationDefinition, PEX, Status } from '@animo-id/pex';
import {
registerDecorator,
ValidationArguments,
Expand All @@ -19,9 +19,8 @@ import {
@ValidatorConstraint({ async: false })
export class IsPresentationDefinitionCredentialQueryConstraint implements ValidatorConstraintInterface {
validate(value: IPresentationDefinition): boolean {
const pex = new PEX();
try {
const validated = pex.validateDefinition(value);
const validated = PEX.validateDefinition(value);
const resultArray = Array.isArray(validated) ? validated : [validated];
const statuses = resultArray.map((checked) => checked.status);
if (statuses.includes(Status.ERROR) || statuses.includes(Status.WARN)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { IProof } from '@sphereon/pex';
import { IProof } from '@sphereon/ssi-types';
import { Credential } from './credential';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

import { Injectable, Logger } from '@nestjs/common';
import { ProofPurpose, IPresentationDefinition, PEX, IPresentation } from '@sphereon/pex';
import { IPresentationDefinition, PEX } from '@animo-id/pex';
import { IPresentation, IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { CredentialsService } from '../credentials/credentials.service';
import { VpRequestEntity } from './entities/vp-request.entity';
import { SubmissionVerifier } from './types/submission-verifier';
Expand Down Expand Up @@ -111,7 +112,12 @@ export class VpSubmissionVerifierService implements SubmissionVerifier {
let partialErrors;

try {
const { errors } = pex.evaluatePresentation(presentationDefinition, presentation as IPresentation);
const { errors } = pex.evaluatePresentation(presentationDefinition, presentation as IPresentation, {
// pex 1.x evaluated presentations without an embedded submission;
// pex 6.x requires one unless asked to generate it
generatePresentationSubmission:
(presentation as IPresentation).presentation_submission === undefined
});
partialErrors = errors;
} catch (err) {
if (typeof err === 'string') {
Expand Down
2 changes: 1 addition & 1 deletion apps/vc-api/src/vc-api/vc-api.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { BadRequestErrorResponseDto } from '../dtos/bad-request-error-response.d
import { ConflictErrorResponseDto } from '../dtos/conflict-error-response.dto';
import { NotFoundErrorResponseDto } from '../dtos/not-found-error-response.dto';
import { InternalServerErrorResponseDto } from '../dtos/internal-server-error-response.dto';
import { IPresentationDefinition } from '@sphereon/pex';
import { IPresentationDefinition } from '@animo-id/pex';
import { AuthenticateDto } from './credentials/dtos/authenticate.dto';
import { CreateWorkflowRequestDto } from './workflows/dtos/create-workflow-request.dto';
import { WorkflowService } from './workflows/workflow.service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { IPresentationDefinition, PEX, Status } from '@sphereon/pex';
import { IPresentationDefinition, PEX, Status } from '@animo-id/pex';
import {
registerDecorator,
ValidationArguments,
Expand All @@ -19,9 +19,8 @@ import {
@ValidatorConstraint({ async: false })
export class IsPresentationDefinitionCredentialQueryConstraint implements ValidatorConstraintInterface {
validate(value: IPresentationDefinition): boolean {
const pex = new PEX();
try {
const validated = pex.validateDefinition(value);
const validated = PEX.validateDefinition(value);
const resultArray = Array.isArray(validated) ? validated : [validated];
const statuses = resultArray.map((checked) => checked.status);
if (statuses.includes(Status.ERROR) || statuses.includes(Status.WARN)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { IProof } from '@sphereon/pex';
import { IProof } from '@sphereon/ssi-types';
import { Credential } from './credential';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

import { Injectable, Logger } from '@nestjs/common';
import { ProofPurpose, IPresentationDefinition, PEX, IPresentation } from '@sphereon/pex';
import { IPresentationDefinition, PEX } from '@animo-id/pex';
import { IPresentation, IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { CredentialsService } from '../credentials/credentials.service';
import { SubmissionVerifier } from './types/submission-verifier';
import { VerifiablePresentation } from './types/verifiable-presentation';
Expand Down Expand Up @@ -112,7 +113,12 @@ export class VpSubmissionVerifierService implements SubmissionVerifier {
let partialErrors;

try {
const { errors } = pex.evaluatePresentation(presentationDefinition, presentation as IPresentation);
const { errors } = pex.evaluatePresentation(presentationDefinition, presentation as IPresentation, {
// pex 1.x evaluated presentations without an embedded submission;
// pex 6.x requires one unless asked to generate it
generatePresentationSubmission:
(presentation as IPresentation).presentation_submission === undefined
});
partialErrors = errors;
} catch (err) {
if (typeof err === 'string') {
Expand Down
6 changes: 6 additions & 0 deletions apps/vc-api/test/app.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ describe('App (e2e)', () => {
await workflowRepository.clear();
});

// Drop any interceptors a failed test left behind; otherwise they absorb
// the next test's callback requests and its scope assertions fail too
afterEach(() => {
nock.cleanAll();
});

describe('DID (e2e)', didSuite);
describe('Key (e2e)', keySuite);
describe('VC-API (e2e)', vcApiSuite);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,52 +86,31 @@ export class ConsentAndResidentCardPresentation {
const: 'urn:uuid:49f69fb8-f256-4b2e-b15d-c7ebec3a507e'
}
},
// pex 6 validates filters against the DIF PE filter schema, which
// does not allow free-form json-schema keywords such as "properties"
// or "$ref"; reach into the context and subject with json paths instead
{
path: ['$.@context'],
path: ["$['@context'][0]"],
filter: {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'array',
items: [
{
const: 'https://www.w3.org/2018/credentials/v1'
},
{
$ref: '#/definitions/eliaGroupContext'
}
],
additionalItems: false,
minItems: 2,
maxItems: 2,
definitions: {
eliaGroupContext: {
type: 'object',
properties: {
elia: {
const: 'https://www.eliagroup.eu/ld-context-2022#'
},
consent: {
const: 'elia:consent'
},
ConsentCredential: {
const: 'elia:ConsentCredential'
}
},
additionalProperties: false,
required: ['elia', 'consent']
}
}
const: 'https://www.w3.org/2018/credentials/v1'
}
},
{
path: ['$.credentialSubject'],
path: ["$['@context'][1].elia"],
filter: {
type: 'object',
properties: {
consent: {
const: 'I consent to such and such'
}
},
additionalProperties: true
const: 'https://www.eliagroup.eu/ld-context-2022#'
}
},
{
path: ["$['@context'][1].consent"],
filter: {
const: 'elia:consent'
}
},
{
path: ['$.credentialSubject.consent'],
filter: {
const: 'I consent to such and such'
}
},
{
Expand Down Expand Up @@ -223,52 +202,31 @@ export class ConsentAndResidentCardPresentation {
const: 'urn:uuid:49f69fb8-f256-4b2e-b15d-c7ebec3a507e'
}
},
// pex 6 validates filters against the DIF PE filter schema, which
// does not allow free-form json-schema keywords such as "properties"
// or "$ref"; reach into the context and subject with json paths instead
{
path: ['$.@context'],
path: ["$['@context'][0]"],
filter: {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'array',
items: [
{
const: 'https://www.w3.org/2018/credentials/v1'
},
{
$ref: '#/definitions/eliaGroupContext'
}
],
additionalItems: false,
minItems: 2,
maxItems: 2,
definitions: {
eliaGroupContext: {
type: 'object',
properties: {
elia: {
const: 'https://www.eliagroup.eu/ld-context-2022#'
},
consent: {
const: 'elia:consent'
},
ConsentCredential: {
const: 'elia:ConsentCredential'
}
},
additionalProperties: false,
required: ['elia', 'consent']
}
}
const: 'https://www.w3.org/2018/credentials/v1'
}
},
{
path: ['$.credentialSubject'],
path: ["$['@context'][1].elia"],
filter: {
type: 'object',
properties: {
consent: {
const: 'I consent to such and such'
}
},
additionalProperties: true
const: 'https://www.eliagroup.eu/ld-context-2022#'
}
},
{
path: ["$['@context'][1].consent"],
filter: {
const: 'elia:consent'
}
},
{
path: ['$.credentialSubject.consent'],
filter: {
const: 'I consent to such and such'
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import * as request from 'supertest';
import * as nock from 'nock';
import { PresentationDto } from '../../../../src/vc-api/credentials/dtos/presentation.dto';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as request from 'supertest';
import * as nock from 'nock';
import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import { RebeamCpoNode } from './rebeam-cpo-node';
import { app, getContinuationEndpoint, vcApiBaseUrl, walletClient } from '../../../app.e2e-spec';
import { RebeamSupplier } from './rebeam-supplier';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import * as request from 'supertest';
import * as nock from 'nock';
import { PresentationDto } from '../../../../src/vc-api/credentials/dtos/presentation.dto';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ProofPurpose } from '@sphereon/pex';
import { IProofPurpose as ProofPurpose } from '@sphereon/ssi-types';
import * as request from 'supertest';
import * as nock from 'nock';
import { PresentationDto } from '../../../../src/vc-api/credentials/dtos/presentation.dto';
Expand Down
Loading
Loading