diff --git a/packages/web5/lib/src/pexv2/presentation_definition.dart b/packages/web5/lib/src/pexv2/presentation_definition.dart index b7c3359..2b0b307 100644 --- a/packages/web5/lib/src/pexv2/presentation_definition.dart +++ b/packages/web5/lib/src/pexv2/presentation_definition.dart @@ -5,6 +5,7 @@ import 'package:collection/collection.dart'; import 'package:convert/convert.dart'; import 'package:json_path/json_path.dart'; import 'package:json_schema/json_schema.dart'; +import 'package:web5/web5.dart'; class _JsonSchema { String schema = 'http://json-schema.org/draft-07/schema#'; @@ -21,7 +22,7 @@ class _JsonSchema { Map toJson() { return { - '/$schema': schema, + '\$schema': schema, 'type': type, 'properties': properties, 'required': required, @@ -147,21 +148,19 @@ class InputDescriptor { // Tokenize each vcJwt and validate it against the JSON schema for (var vcJwt in vcJwts) { - final decoded = json.decode(vcJwt); + final decodedVcJwt = DecodedVcJwt.decode(vcJwt); + final payloadJsonString = + utf8.decode(Base64Url.decode(decodedVcJwt.jwt.parts[1])); + final payloadJson = json.decode(payloadJsonString); final selectionCandidate = {}; for (final tokenizedPath in tokenizedPaths) { selectionCandidate[tokenizedPath.token] ??= - JsonPath(tokenizedPath.path).read(decoded).firstOrNull; + JsonPath(tokenizedPath.path).read(payloadJson).firstOrNull?.value; } selectionCandidate.removeWhere((_, value) => value == null); - if (selectionCandidate.keys.length < tokenizedPaths.length) { - // Did not find values for all `field`s in the input desciptor - continue; - } - final validationResult = jsonSchema.validate(selectionCandidate); if (validationResult.isValid) { answer.add(vcJwt); @@ -258,9 +257,9 @@ class Filter { ); Map toJson() => { - 'type': type, - 'pattern': pattern, - 'const': constValue, - 'contains': contains?.toJson(), + if (type != null) 'type': type, + if (pattern != null) 'pattern': pattern, + if (constValue != null) 'const': constValue, + if (contains != null) 'contains': contains?.toJson(), }; } diff --git a/packages/web5/lib/src/vc/vc.dart b/packages/web5/lib/src/vc/vc.dart index 29d368b..8be6359 100644 --- a/packages/web5/lib/src/vc/vc.dart +++ b/packages/web5/lib/src/vc/vc.dart @@ -110,9 +110,12 @@ class VerifiableCredential { factory VerifiableCredential.fromJson(Map json) { final credentialSubject = json['credentialSubject'] as Map; final subject = credentialSubject.remove('id'); - final credentialSchema = (json['credentialSchema'] as List) - .map((e) => CredentialSchema(id: e['id'], type: e['type'])) - .toList(); + var credentialSchema = null as List?; + if (json['credentialSchema'] != null) { + credentialSchema = (json['credentialSchema'] as List) + .map((e) => CredentialSchema(id: e['id'], type: e['type'])) + .toList(); + } final context = (json['@context'] as List).cast(); final type = (json['type'] as List).cast(); diff --git a/packages/web5/test/pexv2/presentation_definition_test.dart b/packages/web5/test/pexv2/presentation_definition_test.dart index b826f19..c4c5e83 100644 --- a/packages/web5/test/pexv2/presentation_definition_test.dart +++ b/packages/web5/test/pexv2/presentation_definition_test.dart @@ -36,34 +36,46 @@ class SelectCredentialTestVector { void main() { group('select credentials', () { group('vectors', () { - final vectorsJson = - getJsonVectors('presentation_exchange/select_credentials.json'); + late List vectors; + setUp(() { + final vectorsJson = + getJsonVectors('presentation_exchange/select_credentials.json'); + final vectorsDynamic = vectorsJson['vectors'] as List; - final vectors = vectorsJson['vectors'] - .map((e) => SelectCredentialTestVector.fromJson(e)) - .toList(); + vectors = vectorsDynamic + .map((e) => SelectCredentialTestVector.fromJson(e)) + .toList(); + }); + + test('web5 test vectors', () async { + for (final vector in vectors) { + late List matchingVcJwts; - for (final vector in vectors) { - test(vector.description, () async { try { - final matchingVcJwts = vector.inputPresentationDefinition + matchingVcJwts = vector.inputPresentationDefinition .selectCredentials(vector.inputVcJwts); - - if (vector.errors == true) { - fail('Expected an error but none was thrown'); + } catch (e) { + if (vector.errors != true) { + fail( + 'Expected no error for vector (${vector.description}) but got: $e', + ); } + return; + } - expect( - Set.from(matchingVcJwts), - Set.from(vector.outputSelectedCredentials), + if (vector.errors == true) { + fail( + 'Expected an error for vector (${vector.description}) but none was thrown ', ); - } catch (e) { - if (vector.errors == false) { - fail('Expected no error but got: $e'); - } } - }); - } + + expect( + Set.from(matchingVcJwts), + Set.from(vector.outputSelectedCredentials), + reason: 'Test vector (${vector.description}) has mismatched output', + ); + } + }); }); }); }