From a510a0dc69f54800d913715bcaaa68fc9dd7e2d4 Mon Sep 17 00:00:00 2001 From: "A.G.J. Cate" Date: Wed, 4 Jan 2023 11:32:43 +0100 Subject: [PATCH 1/6] WAL-142 retrieve vcs from context --- .../__tests__/restAgent.test.ts | 5 +- .../didAuthSiopOpAuthenticatorAgentLogic.ts | 51 ++-- .../__tests__/shared/mockedData.ts | 235 ------------------ .../vc_vp_examples/pd/pd_multiple.json | 32 +++ .../vc_vp_examples/pd/pd_single.json | 29 +++ .../vc_vp_examples/vc/vc_driverLicense.json | 23 ++ .../vc/vc_idCardCredential.json | 29 +++ .../vc_vp_examples/vp/vp_multiple.json | 90 +++++++ .../vc_vp_examples/vp/vp_single.json | 56 +++++ .../did-auth-siop-op-authenticator/agent.yml | 20 ++ .../plugin.schema.json | 13 +- .../src/agent/DidAuthSiopOpAuthenticator.ts | 16 +- .../src/session/OpSession.ts | 1 - .../src/types/IDidAuthSiopOpAuthenticator.ts | 6 +- packages/ssi-types/__tests__/encoding.test.ts | 2 +- packages/ssi-types/__tests__/internal.test.ts | 72 ++++++ ...iverLicense.json => vc_driverLicense.json} | 0 .../vc_vp_examples/vc/vc_internal.json | 33 +++ packages/ssi-types/package.json | 1 + .../ssi-types/src/mapper/credential-mapper.ts | 36 +++ 20 files changed, 479 insertions(+), 271 deletions(-) delete mode 100644 packages/did-auth-siop-op-authenticator/__tests__/shared/mockedData.ts create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json create mode 100644 packages/ssi-types/__tests__/internal.test.ts rename packages/ssi-types/__tests__/vc_vp_examples/vc/{vc-driverLicense.json => vc_driverLicense.json} (100%) create mode 100644 packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json diff --git a/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts b/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts index 0966f6277..d4753fe6d 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts @@ -1,6 +1,7 @@ import 'cross-fetch/polyfill' +// @ts-ignore import express from 'express' -import { IAgent, createAgent, IAgentOptions } from '@veramo/core' +import { IAgent, createAgent, IAgentOptions, IDataStore } from '@veramo/core' import { AgentRestClient } from '@veramo/remote-client' import { Server } from 'http' import { AgentRouter, RequestWithAgentRouter } from '@veramo/remote-server' @@ -22,7 +23,7 @@ let serverAgent: IAgent let restServer: Server const getAgent = (options?: IAgentOptions) => - createAgent({ + createAgent({ ...options, plugins: [ new DidAuthSiopOpAuthenticator(), diff --git a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts index aed2728a0..7ca737e23 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts @@ -1,8 +1,10 @@ -import { TAgent } from '@veramo/core' -import { OP } from '@sphereon/did-auth-siop' -import { IDidAuthSiopOpAuthenticator } from '../../src' +import * as fs from 'fs' +import { IDataStore, TAgent, VerifiableCredential } from '@veramo/core' +import { OP, SIOP } from '@sphereon/did-auth-siop' +import { IAuthRequestDetails, IDidAuthSiopOpAuthenticator } from '../../src' import { + PresentationDefinitionWithLocation, ResponseContext, ResponseMode, ResponseType, @@ -12,7 +14,14 @@ import { VerifiedAuthenticationRequestWithJWT, } from '@sphereon/did-auth-siop/dist/main/types/SIOP.types' import { mapIdentifierKeysToDoc } from '@veramo/utils' -import { pdMultiple, pdSingle, vcs, vpMultiple, vpSingle } from './mockedData' + +function getFile(path: string) { + return fs.readFileSync(path, 'utf-8') +} + +function getFileAsJson(path: string) { + return JSON.parse(getFile(path)) +} const nock = require('nock') jest.mock('@veramo/utils', () => ({ @@ -20,7 +29,7 @@ jest.mock('@veramo/utils', () => ({ mapIdentifierKeysToDoc: jest.fn(), })) -type ConfiguredAgent = TAgent +type ConfiguredAgent = TAgent const didMethod = 'ethr' const did = 'did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a' @@ -153,6 +162,12 @@ export default (testContext: { await testContext.setup() agent = testContext.getAgent() + const idCardCredential: VerifiableCredential = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json') + await agent.dataStoreSaveVerifiableCredential({ verifiableCredential: idCardCredential }) + + const driverLicenseCredential: VerifiableCredential = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json') + await agent.dataStoreSaveVerifiableCredential({ verifiableCredential: driverLicenseCredential }) + nock(redirectUrl).get(`?stateId=${stateId}`).times(5).reply(200, requestResultMockedText) const mockedMapIdentifierKeysToDocMethod = mapIdentifierKeysToDoc as jest.Mock @@ -295,35 +310,41 @@ export default (testContext: { }) it('should get authentication details with single credential', async () => { - const result = await agent.getSiopAuthenticationRequestDetails({ + const pd_single: PresentationDefinitionWithLocation = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json') + const vp_single: SIOP.VerifiablePresentationResponseOpts = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json') + vp_single.presentation.presentation_submission!.id = expect.any(String) + + const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ sessionId, verifiedAuthenticationRequest: { ...createAuthenticationResponseMockedResult, - presentationDefinitions: pdSingle, - }, - verifiableCredentials: vcs, + presentationDefinitions: [pd_single], + } }) expect(result).toEqual({ id: 'did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a', - vpResponseOpts: vpSingle, + vpResponseOpts: [vp_single] }) }) it('should get authentication details with multiple credentials', async () => { - const result = await agent.getSiopAuthenticationRequestDetails({ + const pd_multiple: PresentationDefinitionWithLocation = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json') + const vp_multiple: SIOP.VerifiablePresentationResponseOpts = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json') + vp_multiple.presentation.presentation_submission!.id = expect.any(String) + + const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ sessionId, verifiedAuthenticationRequest: { ...createAuthenticationResponseMockedResult, - presentationDefinitions: pdMultiple, - }, - verifiableCredentials: vcs, + presentationDefinitions: [pd_multiple], + } }) expect(result).toEqual({ alsoKnownAs: undefined, id: 'did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a', - vpResponseOpts: vpMultiple, + vpResponseOpts: [vp_multiple], }) }) diff --git a/packages/did-auth-siop-op-authenticator/__tests__/shared/mockedData.ts b/packages/did-auth-siop-op-authenticator/__tests__/shared/mockedData.ts deleted file mode 100644 index 44142322b..000000000 --- a/packages/did-auth-siop-op-authenticator/__tests__/shared/mockedData.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { PresentationDefinitionWithLocation, PresentationLocation } from '@sphereon/did-auth-siop/dist/main/types/SIOP.types' - -export const pdSingle: PresentationDefinitionWithLocation[] = [ - { - definition: { - id: 'Credentials', - input_descriptors: [ - { - id: 'ID Card Credential', - schema: [ - { - uri: 'https://www.w3.org/2018/credentials/examples/v1/IDCardCredential', - }, - ], - constraints: { - fields: [ - { - path: ['$.issuer.id'], - filter: { - type: 'string', - pattern: 'did:example:issuer', - }, - }, - ], - }, - }, - ], - }, - location: PresentationLocation.ID_TOKEN, - }, -] - -export const pdMultiple: PresentationDefinitionWithLocation[] = [ - { - definition: { - id: 'Credentials', - input_descriptors: [ - { - id: "ID Card Credential and Driver's License", - schema: [ - { - uri: 'https://www.w3.org/2018/credentials/examples/v1/IDCardCredential', - }, - { - uri: 'https://www.w3.org/2018/credentials/examples/v1/DriversLicense', - }, - ], - constraints: { - fields: [ - { - path: ['$.issuer.id'], - filter: { - type: 'string', - pattern: 'did:example:[issuer|ebfeb1f712ebc6f1c276e12ec21]', - }, - }, - ], - }, - }, - ], - }, - location: PresentationLocation.ID_TOKEN, - }, -] - -export const vcs = [ - { - id: 'https://example.com/credentials/1872', - type: ['VerifiableCredential', 'IDCardCredential'], - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1/IDCardCredential'], - issuer: { - id: 'did:example:issuer', - }, - issuanceDate: '2010-01-01T19:23:24Z', - credentialSubject: { - given_name: 'Fredrik', - family_name: 'Stremberg', - birthdate: '1949-01-22', - }, - proof: { - type: 'RsaSignature2018', - created: '2018-09-14T21:19:10Z', - proofPurpose: 'authentication', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', - }, - }, - { - id: 'https://example.com/credentials/1873', - type: ['VerifiableCredential', 'DriversLicense'], - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1/DriversLicense'], - issuer: { - id: 'did:example:ebfeb1f712ebc6f1c276e12ec21', - }, - issuanceDate: '2010-01-01T19:23:24Z', - credentialSubject: { - given_name: 'John', - family_name: 'Doe', - birthdate: '1975-01-05', - }, - proof: { - type: 'RsaSignature2018', - created: '2018-09-14T21:19:10Z', - proofPurpose: 'authentication', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', - }, - }, -] - -export const vpSingle = [ - { - format: 'ldp_vp', - location: 'id_token', - presentation: { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://identity.foundation/presentation-exchange/submission/v1'], - presentation_submission: { - definition_id: 'Credentials', - descriptor_map: [ - { - format: 'ldp_vc', - id: 'ID Card Credential', - path: '$.verifiableCredential[0]', - }, - ], - id: expect.any(String), - }, - type: ['VerifiablePresentation', 'PresentationSubmission'], - verifiableCredential: [ - { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1/IDCardCredential'], - credentialSubject: { - birthdate: '1949-01-22', - family_name: 'Stremberg', - given_name: 'Fredrik', - }, - id: 'https://example.com/credentials/1872', - issuanceDate: '2010-01-01T19:23:24Z', - issuer: { - id: 'did:example:issuer', - }, - proof: { - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - created: '2018-09-14T21:19:10Z', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', - proofPurpose: 'authentication', - type: 'RsaSignature2018', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - }, - type: ['VerifiableCredential', 'IDCardCredential'], - }, - ], - }, - }, -] - -export const vpMultiple = [ - { - format: 'ldp_vp', - location: 'id_token', - presentation: { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://identity.foundation/presentation-exchange/submission/v1'], - presentation_submission: { - definition_id: 'Credentials', - descriptor_map: [ - { - format: 'ldp_vc', - id: "ID Card Credential and Driver's License", - path: '$.verifiableCredential[0]', - }, - { - format: 'ldp_vc', - id: "ID Card Credential and Driver's License", - path: '$.verifiableCredential[1]', - }, - ], - id: expect.any(String), - }, - type: ['VerifiablePresentation', 'PresentationSubmission'], - verifiableCredential: [ - { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1/IDCardCredential'], - credentialSubject: { - birthdate: '1949-01-22', - family_name: 'Stremberg', - given_name: 'Fredrik', - }, - id: 'https://example.com/credentials/1872', - issuanceDate: '2010-01-01T19:23:24Z', - issuer: { - id: 'did:example:issuer', - }, - proof: { - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - created: '2018-09-14T21:19:10Z', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', - proofPurpose: 'authentication', - type: 'RsaSignature2018', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - }, - type: ['VerifiableCredential', 'IDCardCredential'], - }, - { - id: 'https://example.com/credentials/1873', - type: ['VerifiableCredential', 'DriversLicense'], - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1/DriversLicense'], - issuer: { - id: 'did:example:ebfeb1f712ebc6f1c276e12ec21', - }, - issuanceDate: '2010-01-01T19:23:24Z', - credentialSubject: { - given_name: 'John', - family_name: 'Doe', - birthdate: '1975-01-05', - }, - proof: { - type: 'RsaSignature2018', - created: '2018-09-14T21:19:10Z', - proofPurpose: 'authentication', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', - }, - }, - ], - }, - }, -] diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json new file mode 100644 index 000000000..c4df8b145 --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json @@ -0,0 +1,32 @@ +{ + "definition":{ + "id":"Credentials", + "input_descriptors":[ + { + "id":"ID Card Credential and Driver's License", + "schema":[ + { + "uri":"https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + }, + { + "uri":"https://www.w3.org/2018/credentials/examples/v1/DriversLicense" + } + ], + "constraints":{ + "fields":[ + { + "path":[ + "$.issuer.id" + ], + "filter":{ + "type":"string", + "pattern":"did:example:[issuer|ebfeb1f712ebc6f1c276e12ec21]" + } + } + ] + } + } + ] + }, + "location":"id_token" +} diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json new file mode 100644 index 000000000..9f8768397 --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json @@ -0,0 +1,29 @@ +{ + "definition":{ + "id":"Credentials", + "input_descriptors":[ + { + "id":"ID Card Credential", + "schema":[ + { + "uri":"https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + } + ], + "constraints":{ + "fields":[ + { + "path":[ + "$.issuer.id" + ], + "filter":{ + "type":"string", + "pattern":"did:example:issuer" + } + } + ] + } + } + ] + }, + "location":"id_token" +} diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json new file mode 100644 index 000000000..daa0f0f2b --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json @@ -0,0 +1,23 @@ +{ + "id": "https://example.com/credentials/1873", + "type": ["VerifiableCredential", "DriversLicense"], + "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1/DriversLicense"], + "issuer": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21" + }, + "issuanceDate": "2010-01-01T19:23:24Z", + "credentialSubject": { + "given_name": "John", + "family_name": "Doe", + "birthdate": "1975-01-05" + }, + "proof": { + "type": "RsaSignature2018", + "created": "2018-09-14T21:19:10Z", + "proofPurpose": "authentication", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + } +} diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json new file mode 100644 index 000000000..1f6ea8cd1 --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json @@ -0,0 +1,29 @@ +{ + "id":"https://example.com/credentials/1872", + "type":[ + "VerifiableCredential", + "IDCardCredential" + ], + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + ], + "issuer":{ + "id":"did:example:issuer" + }, + "issuanceDate":"2010-01-01T19:23:24Z", + "credentialSubject":{ + "given_name":"Fredrik", + "family_name":"Stremberg", + "birthdate":"1949-01-22" + }, + "proof":{ + "type":"RsaSignature2018", + "created":"2018-09-14T21:19:10Z", + "proofPurpose":"authentication", + "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge":"1f44d55f-f161-4938-a659-f8026467f126", + "domain":"4jt78h47fh47", + "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + } +} diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json new file mode 100644 index 000000000..79fd20fb5 --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json @@ -0,0 +1,90 @@ +{ + "format":"ldp_vp", + "location":"id_token", + "presentation":{ + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "presentation_submission":{ + "definition_id":"Credentials", + "descriptor_map":[ + { + "format":"ldp_vc", + "id":"ID Card Credential and Driver's License", + "path":"$.verifiableCredential[0]" + }, + { + "format":"ldp_vc", + "id":"ID Card Credential and Driver's License", + "path":"$.verifiableCredential[1]" + } + ], + "id": "8oBenRGlNXd0Sp770bCb3" + }, + "type":[ + "VerifiablePresentation", + "PresentationSubmission" + ], + "verifiableCredential":[ + { + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + ], + "credentialSubject":{ + "birthdate":"1949-01-22", + "family_name":"Stremberg", + "given_name":"Fredrik" + }, + "id":"https://example.com/credentials/1872", + "issuanceDate":"2010-01-01T19:23:24Z", + "issuer":{ + "id":"did:example:issuer" + }, + "proof":{ + "challenge":"1f44d55f-f161-4938-a659-f8026467f126", + "created":"2018-09-14T21:19:10Z", + "domain":"4jt78h47fh47", + "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", + "proofPurpose":"authentication", + "type":"RsaSignature2018", + "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" + }, + "type":[ + "VerifiableCredential", + "IDCardCredential" + ] + }, + { + "id":"https://example.com/credentials/1873", + "type":[ + "VerifiableCredential", + "DriversLicense" + ], + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1/DriversLicense" + ], + "issuer":{ + "id":"did:example:ebfeb1f712ebc6f1c276e12ec21" + }, + "issuanceDate":"2010-01-01T19:23:24Z", + "credentialSubject":{ + "given_name":"John", + "family_name":"Doe", + "birthdate":"1975-01-05" + }, + "proof":{ + "type":"RsaSignature2018", + "created":"2018-09-14T21:19:10Z", + "proofPurpose":"authentication", + "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge":"1f44d55f-f161-4938-a659-f8026467f126", + "domain":"4jt78h47fh47", + "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + } + } + ] + } +} diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json new file mode 100644 index 000000000..cc811b863 --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json @@ -0,0 +1,56 @@ +{ + "format":"ldp_vp", + "location":"id_token", + "presentation":{ + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "presentation_submission":{ + "definition_id":"Credentials", + "descriptor_map":[ + { + "format":"ldp_vc", + "id":"ID Card Credential", + "path":"$.verifiableCredential[0]" + } + ], + "id": "8oBenRGlNXd0Sp770bCb3" + }, + "type":[ + "VerifiablePresentation", + "PresentationSubmission" + ], + "verifiableCredential":[ + { + "@context":[ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + ], + "credentialSubject":{ + "birthdate":"1949-01-22", + "family_name":"Stremberg", + "given_name":"Fredrik" + }, + "id":"https://example.com/credentials/1872", + "issuanceDate":"2010-01-01T19:23:24Z", + "issuer":{ + "id":"did:example:issuer" + }, + "proof":{ + "challenge":"1f44d55f-f161-4938-a659-f8026467f126", + "created":"2018-09-14T21:19:10Z", + "domain":"4jt78h47fh47", + "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", + "proofPurpose":"authentication", + "type":"RsaSignature2018", + "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" + }, + "type":[ + "VerifiableCredential", + "IDCardCredential" + ] + } + ] + } +} diff --git a/packages/did-auth-siop-op-authenticator/agent.yml b/packages/did-auth-siop-op-authenticator/agent.yml index c4fb5eb54..2c7a0e588 100644 --- a/packages/did-auth-siop-op-authenticator/agent.yml +++ b/packages/did-auth-siop-op-authenticator/agent.yml @@ -12,6 +12,20 @@ constants: - verifySiopAuthenticationRequestURI - sendSiopAuthenticationResponse +# Database +dbConnection: + $require: typeorm#DataSource + $args: + - type: sqlite + database: ':memory:' + synchronize: false + migrationsRun: true + migrations: + $require: '@veramo/data-store?t=object#migrations' + logging: false + entities: + $require: '@veramo/data-store?t=object#Entities' + server: baseUrl: $ref: /constants/baseUrl @@ -104,3 +118,9 @@ agent: plugins: - $ref: /didResolver - $require: ./packages/did-auth-siop-op-authenticator/dist#DidAuthSiopOpAuthenticator + - $require: '@veramo/data-store#DataStore' + $args: + - $ref: /dbConnection + - $require: '@veramo/data-store#DataStoreORM' + $args: + - $ref: /dbConnection diff --git a/packages/did-auth-siop-op-authenticator/plugin.schema.json b/packages/did-auth-siop-op-authenticator/plugin.schema.json index 8c3d67ca7..0269c700e 100644 --- a/packages/did-auth-siop-op-authenticator/plugin.schema.json +++ b/packages/did-auth-siop-op-authenticator/plugin.schema.json @@ -155,18 +155,15 @@ "additionalProperties": true } }, - "verifiableCredentials": { - "type": "array", - "items": { - "type": "object", - "properties": { - "additionalProperties": true - } + "credentialFilter": { + "type": "object", + "properties": { + "additionalProperties": true } }, "additionalProperties": false }, - "required": ["sessionId", "verifiedAuthenticationRequest", "verifiableCredentials"], + "required": ["sessionId", "verifiedAuthenticationRequest"], "description": "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } " }, "IAuthRequestDetails": { diff --git a/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts b/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts index 5b76c8b06..5b07f8b5d 100644 --- a/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts +++ b/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts @@ -1,5 +1,5 @@ import { schema } from '../index' -import { IAgentPlugin } from '@veramo/core' +import { IAgentPlugin, UniqueVerifiableCredential } from '@veramo/core' import { OpSession } from '../session/OpSession' import { v4 as uuidv4 } from 'uuid' @@ -20,6 +20,7 @@ import { IVerifySiopAuthenticationRequestUriArgs, } from '../types/IDidAuthSiopOpAuthenticator' import { SIOP } from '@sphereon/did-auth-siop' +import { CredentialMapper, IVerifiableCredential } from '@sphereon/ssi-types'; /** * {@inheritDoc IDidAuthSiopOpAuthenticator} @@ -106,7 +107,7 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { /** {@inheritDoc IDidAuthSiopOpAuthenticator.authenticateWithSiop} */ private async authenticateWithSiop(args: IAuthenticateWithSiopArgs, context: IRequiredContext): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session) => + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.authenticateWithSiop({ ...args, customApprovals: this.customApprovals }).then(async (response: Response) => { await context.agent.emit(events.DID_SIOP_AUTHENTICATED, response) return response @@ -119,7 +120,7 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { args: IGetSiopAuthenticationRequestFromRpArgs, context: IRequiredContext ): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session) => session.getSiopAuthenticationRequestFromRP(args)) + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.getSiopAuthenticationRequestFromRP(args)) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails} */ @@ -127,7 +128,10 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { args: IGetSiopAuthenticationRequestDetailsArgs, context: IRequiredContext ): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session) => session.getSiopAuthenticationRequestDetails(args)) + const uniqueVcs: Array = await context.agent.dataStoreORMGetVerifiableCredentials(args.credentialFilter) + const verifiableCredentials: Array = uniqueVcs.map((uniqueVc: UniqueVerifiableCredential) => CredentialMapper.toExternalVerifiableCredential(uniqueVc.verifiableCredential)) + + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.getSiopAuthenticationRequestDetails({ ...args, verifiableCredentials })) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI} */ @@ -135,12 +139,12 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { args: IVerifySiopAuthenticationRequestUriArgs, context: IRequiredContext ): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session) => session.verifySiopAuthenticationRequestURI(args)) + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.verifySiopAuthenticationRequestURI(args)) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse} */ private async sendSiopAuthenticationResponse(args: ISendSiopAuthenticationResponseArgs, context: IRequiredContext): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session) => + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.sendSiopAuthenticationResponse(args).then(async (response: Response) => { await context.agent.emit(events.DID_SIOP_AUTHENTICATED, response) return response diff --git a/packages/did-auth-siop-op-authenticator/src/session/OpSession.ts b/packages/did-auth-siop-op-authenticator/src/session/OpSession.ts index 10faabe50..81e5288ae 100644 --- a/packages/did-auth-siop-op-authenticator/src/session/OpSession.ts +++ b/packages/did-auth-siop-op-authenticator/src/session/OpSession.ts @@ -91,7 +91,6 @@ export class OpSession { } public async getSiopAuthenticationRequestDetails(args: IOpsGetSiopAuthenticationRequestDetailsArgs): Promise { - // TODO fix vc retrievement https://sphereon.atlassian.net/browse/MYC-142 const presentationDefs = args.verifiedAuthenticationRequest.presentationDefinitions const verifiablePresentations = presentationDefs && presentationDefs.length > 0 ? await this.matchPresentationDefinitions(presentationDefs, args.verifiableCredentials) : [] diff --git a/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts b/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts index 17123b52e..25d0984a7 100644 --- a/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts +++ b/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts @@ -1,4 +1,4 @@ -import { DIDDocumentSection, IAgentContext, IIdentifier, IPluginMethodMap, IResolver, IKeyManager } from '@veramo/core' +import { DIDDocumentSection, IAgentContext, IIdentifier, IPluginMethodMap, IResolver, IKeyManager, IDataStoreORM, FindCredentialsArgs } from '@veramo/core' import { IVerifiableCredential, IVerifiablePresentation } from '@sphereon/ssi-types' import { OpSession } from '../session/OpSession' import { SIOP } from '@sphereon/did-auth-siop' @@ -54,7 +54,7 @@ export interface IGetSiopAuthenticationRequestFromRpArgs { export interface IGetSiopAuthenticationRequestDetailsArgs { sessionId: string verifiedAuthenticationRequest: SIOP.VerifiedAuthenticationRequestWithJWT - verifiableCredentials: IVerifiableCredential[] + credentialFilter?: FindCredentialsArgs } export interface IVerifySiopAuthenticationRequestUriArgs { @@ -138,4 +138,4 @@ export enum events { DID_SIOP_AUTHENTICATED = 'didSiopAuthenticated', } -export type IRequiredContext = IAgentContext +export type IRequiredContext = IAgentContext diff --git a/packages/ssi-types/__tests__/encoding.test.ts b/packages/ssi-types/__tests__/encoding.test.ts index 2b69b5cd8..ad70e2298 100644 --- a/packages/ssi-types/__tests__/encoding.test.ts +++ b/packages/ssi-types/__tests__/encoding.test.ts @@ -21,7 +21,7 @@ describe('Encoding - Decoding', () => { const jwtVp: OriginalVerifiablePresentation = getFile('packages/ssi-types/__tests__/vc_vp_examples/vp/vp_universityDegree.jwt') const jwtVc: OriginalVerifiableCredential = getFile('packages/ssi-types/__tests__/vc_vp_examples/vc/vc_universityDegree.jwt') const ldpVp: OriginalVerifiablePresentation = getFileAsJson('packages/ssi-types/__tests__/vc_vp_examples/vp/vp_general.json') - const ldpVc: OriginalVerifiableCredential = getFileAsJson('packages/ssi-types/__tests__/vc_vp_examples/vc/vc-driverLicense.json') + const ldpVc: OriginalVerifiableCredential = getFileAsJson('packages/ssi-types/__tests__/vc_vp_examples/vc/vc_driverLicense.json') const decodedJwtVp = CredentialMapper.decodeVerifiablePresentation(jwtVp) as JwtDecodedVerifiablePresentation const decodedJwtVc = CredentialMapper.decodeVerifiableCredential(jwtVc) as JwtDecodedVerifiableCredential diff --git a/packages/ssi-types/__tests__/internal.test.ts b/packages/ssi-types/__tests__/internal.test.ts new file mode 100644 index 000000000..1bd04300c --- /dev/null +++ b/packages/ssi-types/__tests__/internal.test.ts @@ -0,0 +1,72 @@ +import * as fs from 'fs' +import { CredentialMapper, IVerifiableCredential } from '../src' +import { VerifiableCredential } from '@veramo/core' + +function getFile(path: string) { + return fs.readFileSync(path, 'utf-8') +} + +function getFileAsJson(path: string) { + return JSON.parse(getFile(path)) +} + +describe('Internal', () => { + it('Should set type to VerifiableCredential when none is present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + delete internalVerifiableCredential.type + const externalVerifiableCredential: IVerifiableCredential = CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + + expect(externalVerifiableCredential.type).toEqual(['VerifiableCredential']) + }) + + it('Should set correct type when type is present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + const externalVerifiableCredential: IVerifiableCredential = CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + + expect(externalVerifiableCredential.type).toEqual(['VerifiableCredential', 'PermanentResidentCard']) + }) + + it('Should set type array when type is a string', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + internalVerifiableCredential.type = 'VerifiableCredential' + const externalVerifiableCredential: IVerifiableCredential = CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + + expect(externalVerifiableCredential.type).toEqual(['VerifiableCredential']) + }) + + it('Should throw error when proof type is not present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + delete internalVerifiableCredential.proof.type + + expect(function () { + CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + }).toThrow('Verifiable credential proof is missing a type') + }) + + it('Should throw error when proof created date is not present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + delete internalVerifiableCredential.proof.created + + expect(function () { + CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + }).toThrow('Verifiable credential proof is missing a created date') + }) + + it('Should throw error when proof purpose is not present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + delete internalVerifiableCredential.proof.proofPurpose + + expect(function () { + CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + }).toThrow('Verifiable credential proof is missing a proof purpose') + }) + + it('Should throw error when proof verification method is not present', () => { + const internalVerifiableCredential: VerifiableCredential = getFileAsJson('./packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json') + delete internalVerifiableCredential.proof.verificationMethod + + expect(function () { + CredentialMapper.toExternalVerifiableCredential(internalVerifiableCredential) + }).toThrow('Verifiable credential proof is missing a verification method') + }) +}) diff --git a/packages/ssi-types/__tests__/vc_vp_examples/vc/vc-driverLicense.json b/packages/ssi-types/__tests__/vc_vp_examples/vc/vc_driverLicense.json similarity index 100% rename from packages/ssi-types/__tests__/vc_vp_examples/vc/vc-driverLicense.json rename to packages/ssi-types/__tests__/vc_vp_examples/vc/vc_driverLicense.json diff --git a/packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json b/packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json new file mode 100644 index 000000000..9bf1e9138 --- /dev/null +++ b/packages/ssi-types/__tests__/vc_vp_examples/vc/vc_internal.json @@ -0,0 +1,33 @@ +{ + "description": "Government of Example Permanent Resident Card.", + "expirationDate": "2029-12-03T12:19:52Z", + "issuanceDate": "2019-12-03T12:19:52Z", + "id": "https://issuer.oidp.uscis.gov/credentials/83627465", + "name": "Permanent Resident Card", + "identifier": "83627465", + "credentialSubject": { + "birthDate": "1958-07-17", + "lprCategory": "C09", + "lprNumber": "999-999-999", + "image": "data:image/png;base64,iVBORw0KGgokJggg==", + "type": ["PermanentResident", "Person"], + "commuterClassification": "C1", + "familyName": "SMITH", + "id": "did:example:b34ca6cd37bbf23", + "givenName": "JANE", + "gender": "Female", + "residentSince": "2015-01-01", + "birthCountry": "Bahamas" + }, + "type": ["VerifiableCredential", "PermanentResidentCard"], + "@context": ["https://www.w3.org/2018/credentials/v1", "https://w3id.org/security/suites/ed25519-2020/v1", "https://w3id.org/citizenship/v1"], + "issuer": "did:key:z6MkuDyqwjCVhFFQEZdS5utguwYD2KRig2PEb9qbfP9iqwn9", + "proof": { + "type": "BbsBlsSignatureProof2020", + "created": "2020-04-25", + "verificationMethod": "did:example:489398593#test", + "proofPurpose": "assertionMethod", + "proofValue": "kTTbA3pmDa6Qia/JkOnIXDLmoBz3vsi7L5t3DWySI/VLmBqleJ/Tbus5RoyiDERDBEh5rnACXlnOqJ/U8yFQFtcp/mBCc2FtKNPHae9jKIv1dm9K9QK1F3GI1AwyGoUfjLWrkGDObO1ouNAhpEd0+et+qiOf2j8p3MTTtRRx4Hgjcl0jXCq7C7R5/nLpgimHAAAAdAx4ouhMk7v9dXijCIMaG0deicn6fLoq3GcNHuH5X1j22LU/hDu7vvPnk/6JLkZ1xQAAAAIPd1tu598L/K3NSy0zOy6obaojEnaqc1R5Ih/6ZZgfEln2a6tuUp4wePExI1DGHqwj3j2lKg31a/6bSs7SMecHBQdgIYHnBmCYGNQnu/LZ9TFV56tBXY6YOWZgFzgLDrApnrFpixEACM9rwrJ5ORtxAAAAAgE4gUIIC9aHyJNa5TBklMOh6lvQkMVLXa/vEl+3NCLXblxjgpM7UEMqBkE9/QcoD3Tgmy+z0hN+4eky1RnJsEg=", + "nonce": "6i3dTz5yFfWJ8zgsamuyZa4yAHPm75tUOOXddR6krCvCYk77sbCOuEVcdBCDd/l6tIY=" + } +} diff --git a/packages/ssi-types/package.json b/packages/ssi-types/package.json index 10e2698d1..085ea8a2a 100644 --- a/packages/ssi-types/package.json +++ b/packages/ssi-types/package.json @@ -8,6 +8,7 @@ "build": "tsc --build" }, "dependencies": { + "@veramo/core": "4.2.0", "jwt-decode": "^3.1.2" }, "devDependencies": { diff --git a/packages/ssi-types/src/mapper/credential-mapper.ts b/packages/ssi-types/src/mapper/credential-mapper.ts index b4a158be2..22550e190 100644 --- a/packages/ssi-types/src/mapper/credential-mapper.ts +++ b/packages/ssi-types/src/mapper/credential-mapper.ts @@ -14,6 +14,7 @@ import { } from '../types' import jwt_decode from 'jwt-decode' import { ObjectUtils } from '../utils' +import { VerifiableCredential } from '@veramo/core' export class CredentialMapper { static decodeVerifiablePresentation(presentation: OriginalVerifiablePresentation): JwtDecodedVerifiablePresentation | IVerifiablePresentation { @@ -272,4 +273,39 @@ export class CredentialMapper { } return credential } + + static toExternalVerifiableCredential(verifiableCredential: VerifiableCredential): IVerifiableCredential { + if (!verifiableCredential.proof.type) { + throw new Error('Verifiable credential proof is missing a type') + } + + if (!verifiableCredential.proof.created) { + throw new Error('Verifiable credential proof is missing a created date') + } + + if (!verifiableCredential.proof.proofPurpose) { + throw new Error('Verifiable credential proof is missing a proof purpose') + } + + if (!verifiableCredential.proof.verificationMethod) { + throw new Error('Verifiable credential proof is missing a verification method') + } + + return { + ...verifiableCredential, + type: verifiableCredential.type + ? typeof verifiableCredential.type === 'string' + ? [verifiableCredential.type] + : verifiableCredential.type + : ['VerifiableCredential'], + proof: { + ...verifiableCredential.proof, + type: verifiableCredential.proof.type, + created: verifiableCredential.proof.created, + proofPurpose: verifiableCredential.proof.proofPurpose, + verificationMethod: verifiableCredential.proof.verificationMethod + } + } + } + } From f0d2711c98ad73a078c7493d2e71448c37c3c122 Mon Sep 17 00:00:00 2001 From: "A.G.J. Cate" Date: Wed, 4 Jan 2023 11:33:49 +0100 Subject: [PATCH 2/6] WAL-142 prettier --- .../shared/connectionManagerAgentLogic.ts | 4 +- .../didAuthSiopOpAuthenticatorAgentLogic.ts | 32 +++-- .../vc_vp_examples/pd/pd_multiple.json | 30 ++--- .../vc_vp_examples/pd/pd_single.json | 28 ++-- .../vc/vc_idCardCredential.json | 42 +++--- .../vc_vp_examples/vp/vp_multiple.json | 120 ++++++++---------- .../vc_vp_examples/vp/vp_single.json | 72 +++++------ .../src/agent/DidAuthSiopOpAuthenticator.ts | 18 ++- .../src/types/IDidAuthSiopOpAuthenticator.ts | 11 +- .../ssi-types/src/mapper/credential-mapper.ts | 13 +- 10 files changed, 179 insertions(+), 191 deletions(-) diff --git a/packages/connection-manager/__tests__/shared/connectionManagerAgentLogic.ts b/packages/connection-manager/__tests__/shared/connectionManagerAgentLogic.ts index 28fc6cf15..835b1cb13 100644 --- a/packages/connection-manager/__tests__/shared/connectionManagerAgentLogic.ts +++ b/packages/connection-manager/__tests__/shared/connectionManagerAgentLogic.ts @@ -125,7 +125,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const party = { name, alias, - uri: 'example.com' + uri: 'example.com', } await expect(agent.cmAddParty(party)).rejects.toThrow('Blank aliases are not allowed') @@ -137,7 +137,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const party = { name, alias, - uri: 'example.com' + uri: 'example.com', } await expect(agent.cmAddParty(party)).rejects.toThrow('Blank names are not allowed') diff --git a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts index 7ca737e23..cac487ed8 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts @@ -162,10 +162,14 @@ export default (testContext: { await testContext.setup() agent = testContext.getAgent() - const idCardCredential: VerifiableCredential = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json') + const idCardCredential: VerifiableCredential = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json' + ) await agent.dataStoreSaveVerifiableCredential({ verifiableCredential: idCardCredential }) - const driverLicenseCredential: VerifiableCredential = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json') + const driverLicenseCredential: VerifiableCredential = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_driverLicense.json' + ) await agent.dataStoreSaveVerifiableCredential({ verifiableCredential: driverLicenseCredential }) nock(redirectUrl).get(`?stateId=${stateId}`).times(5).reply(200, requestResultMockedText) @@ -310,8 +314,12 @@ export default (testContext: { }) it('should get authentication details with single credential', async () => { - const pd_single: PresentationDefinitionWithLocation = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json') - const vp_single: SIOP.VerifiablePresentationResponseOpts = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json') + const pd_single: PresentationDefinitionWithLocation = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json' + ) + const vp_single: SIOP.VerifiablePresentationResponseOpts = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json' + ) vp_single.presentation.presentation_submission!.id = expect.any(String) const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ @@ -319,26 +327,30 @@ export default (testContext: { verifiedAuthenticationRequest: { ...createAuthenticationResponseMockedResult, presentationDefinitions: [pd_single], - } + }, }) expect(result).toEqual({ id: 'did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a', - vpResponseOpts: [vp_single] + vpResponseOpts: [vp_single], }) }) it('should get authentication details with multiple credentials', async () => { - const pd_multiple: PresentationDefinitionWithLocation = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json') - const vp_multiple: SIOP.VerifiablePresentationResponseOpts = getFileAsJson('./packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json') + const pd_multiple: PresentationDefinitionWithLocation = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json' + ) + const vp_multiple: SIOP.VerifiablePresentationResponseOpts = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json' + ) vp_multiple.presentation.presentation_submission!.id = expect.any(String) - const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ + const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ sessionId, verifiedAuthenticationRequest: { ...createAuthenticationResponseMockedResult, presentationDefinitions: [pd_multiple], - } + }, }) expect(result).toEqual({ diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json index c4df8b145..dde126dec 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json @@ -1,26 +1,24 @@ { - "definition":{ - "id":"Credentials", - "input_descriptors":[ + "definition": { + "id": "Credentials", + "input_descriptors": [ { - "id":"ID Card Credential and Driver's License", - "schema":[ + "id": "ID Card Credential and Driver's License", + "schema": [ { - "uri":"https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + "uri": "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" }, { - "uri":"https://www.w3.org/2018/credentials/examples/v1/DriversLicense" + "uri": "https://www.w3.org/2018/credentials/examples/v1/DriversLicense" } ], - "constraints":{ - "fields":[ + "constraints": { + "fields": [ { - "path":[ - "$.issuer.id" - ], - "filter":{ - "type":"string", - "pattern":"did:example:[issuer|ebfeb1f712ebc6f1c276e12ec21]" + "path": ["$.issuer.id"], + "filter": { + "type": "string", + "pattern": "did:example:[issuer|ebfeb1f712ebc6f1c276e12ec21]" } } ] @@ -28,5 +26,5 @@ } ] }, - "location":"id_token" + "location": "id_token" } diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json index 9f8768397..cac952060 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json @@ -1,23 +1,21 @@ { - "definition":{ - "id":"Credentials", - "input_descriptors":[ + "definition": { + "id": "Credentials", + "input_descriptors": [ { - "id":"ID Card Credential", - "schema":[ + "id": "ID Card Credential", + "schema": [ { - "uri":"https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" + "uri": "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" } ], - "constraints":{ - "fields":[ + "constraints": { + "fields": [ { - "path":[ - "$.issuer.id" - ], - "filter":{ - "type":"string", - "pattern":"did:example:issuer" + "path": ["$.issuer.id"], + "filter": { + "type": "string", + "pattern": "did:example:issuer" } } ] @@ -25,5 +23,5 @@ } ] }, - "location":"id_token" + "location": "id_token" } diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json index 1f6ea8cd1..01abcea0e 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vc/vc_idCardCredential.json @@ -1,29 +1,23 @@ { - "id":"https://example.com/credentials/1872", - "type":[ - "VerifiableCredential", - "IDCardCredential" - ], - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" - ], - "issuer":{ - "id":"did:example:issuer" + "id": "https://example.com/credentials/1872", + "type": ["VerifiableCredential", "IDCardCredential"], + "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential"], + "issuer": { + "id": "did:example:issuer" }, - "issuanceDate":"2010-01-01T19:23:24Z", - "credentialSubject":{ - "given_name":"Fredrik", - "family_name":"Stremberg", - "birthdate":"1949-01-22" + "issuanceDate": "2010-01-01T19:23:24Z", + "credentialSubject": { + "given_name": "Fredrik", + "family_name": "Stremberg", + "birthdate": "1949-01-22" }, - "proof":{ - "type":"RsaSignature2018", - "created":"2018-09-14T21:19:10Z", - "proofPurpose":"authentication", - "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", - "challenge":"1f44d55f-f161-4938-a659-f8026467f126", - "domain":"4jt78h47fh47", - "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + "proof": { + "type": "RsaSignature2018", + "created": "2018-09-14T21:19:10Z", + "proofPurpose": "authentication", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" } } diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json index 79fd20fb5..067a49a9a 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_multiple.json @@ -1,88 +1,70 @@ { - "format":"ldp_vp", - "location":"id_token", - "presentation":{ - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://identity.foundation/presentation-exchange/submission/v1" - ], - "presentation_submission":{ - "definition_id":"Credentials", - "descriptor_map":[ + "format": "ldp_vp", + "location": "id_token", + "presentation": { + "@context": ["https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1"], + "presentation_submission": { + "definition_id": "Credentials", + "descriptor_map": [ { - "format":"ldp_vc", - "id":"ID Card Credential and Driver's License", - "path":"$.verifiableCredential[0]" + "format": "ldp_vc", + "id": "ID Card Credential and Driver's License", + "path": "$.verifiableCredential[0]" }, { - "format":"ldp_vc", - "id":"ID Card Credential and Driver's License", - "path":"$.verifiableCredential[1]" + "format": "ldp_vc", + "id": "ID Card Credential and Driver's License", + "path": "$.verifiableCredential[1]" } ], "id": "8oBenRGlNXd0Sp770bCb3" }, - "type":[ - "VerifiablePresentation", - "PresentationSubmission" - ], - "verifiableCredential":[ + "type": ["VerifiablePresentation", "PresentationSubmission"], + "verifiableCredential": [ { - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" - ], - "credentialSubject":{ - "birthdate":"1949-01-22", - "family_name":"Stremberg", - "given_name":"Fredrik" + "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential"], + "credentialSubject": { + "birthdate": "1949-01-22", + "family_name": "Stremberg", + "given_name": "Fredrik" }, - "id":"https://example.com/credentials/1872", - "issuanceDate":"2010-01-01T19:23:24Z", - "issuer":{ - "id":"did:example:issuer" + "id": "https://example.com/credentials/1872", + "issuanceDate": "2010-01-01T19:23:24Z", + "issuer": { + "id": "did:example:issuer" }, - "proof":{ - "challenge":"1f44d55f-f161-4938-a659-f8026467f126", - "created":"2018-09-14T21:19:10Z", - "domain":"4jt78h47fh47", - "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", - "proofPurpose":"authentication", - "type":"RsaSignature2018", - "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" + "proof": { + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "created": "2018-09-14T21:19:10Z", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", + "proofPurpose": "authentication", + "type": "RsaSignature2018", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" }, - "type":[ - "VerifiableCredential", - "IDCardCredential" - ] + "type": ["VerifiableCredential", "IDCardCredential"] }, { - "id":"https://example.com/credentials/1873", - "type":[ - "VerifiableCredential", - "DriversLicense" - ], - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1/DriversLicense" - ], - "issuer":{ - "id":"did:example:ebfeb1f712ebc6f1c276e12ec21" + "id": "https://example.com/credentials/1873", + "type": ["VerifiableCredential", "DriversLicense"], + "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1/DriversLicense"], + "issuer": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21" }, - "issuanceDate":"2010-01-01T19:23:24Z", - "credentialSubject":{ - "given_name":"John", - "family_name":"Doe", - "birthdate":"1975-01-05" + "issuanceDate": "2010-01-01T19:23:24Z", + "credentialSubject": { + "given_name": "John", + "family_name": "Doe", + "birthdate": "1975-01-05" }, - "proof":{ - "type":"RsaSignature2018", - "created":"2018-09-14T21:19:10Z", - "proofPurpose":"authentication", - "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", - "challenge":"1f44d55f-f161-4938-a659-f8026467f126", - "domain":"4jt78h47fh47", - "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + "proof": { + "type": "RsaSignature2018", + "created": "2018-09-14T21:19:10Z", + "proofPurpose": "authentication", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" } } ] diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json index cc811b863..8d42464ad 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json @@ -1,55 +1,43 @@ { - "format":"ldp_vp", - "location":"id_token", - "presentation":{ - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://identity.foundation/presentation-exchange/submission/v1" - ], - "presentation_submission":{ - "definition_id":"Credentials", - "descriptor_map":[ + "format": "ldp_vp", + "location": "id_token", + "presentation": { + "@context": ["https://www.w3.org/2018/credentials/v1", "https://identity.foundation/presentation-exchange/submission/v1"], + "presentation_submission": { + "definition_id": "Credentials", + "descriptor_map": [ { - "format":"ldp_vc", - "id":"ID Card Credential", - "path":"$.verifiableCredential[0]" + "format": "ldp_vc", + "id": "ID Card Credential", + "path": "$.verifiableCredential[0]" } ], "id": "8oBenRGlNXd0Sp770bCb3" }, - "type":[ - "VerifiablePresentation", - "PresentationSubmission" - ], - "verifiableCredential":[ + "type": ["VerifiablePresentation", "PresentationSubmission"], + "verifiableCredential": [ { - "@context":[ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential" - ], - "credentialSubject":{ - "birthdate":"1949-01-22", - "family_name":"Stremberg", - "given_name":"Fredrik" + "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1/IDCardCredential"], + "credentialSubject": { + "birthdate": "1949-01-22", + "family_name": "Stremberg", + "given_name": "Fredrik" }, - "id":"https://example.com/credentials/1872", - "issuanceDate":"2010-01-01T19:23:24Z", - "issuer":{ - "id":"did:example:issuer" + "id": "https://example.com/credentials/1872", + "issuanceDate": "2010-01-01T19:23:24Z", + "issuer": { + "id": "did:example:issuer" }, - "proof":{ - "challenge":"1f44d55f-f161-4938-a659-f8026467f126", - "created":"2018-09-14T21:19:10Z", - "domain":"4jt78h47fh47", - "jws":"eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", - "proofPurpose":"authentication", - "type":"RsaSignature2018", - "verificationMethod":"did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" + "proof": { + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "created": "2018-09-14T21:19:10Z", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78", + "proofPurpose": "authentication", + "type": "RsaSignature2018", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1" }, - "type":[ - "VerifiableCredential", - "IDCardCredential" - ] + "type": ["VerifiableCredential", "IDCardCredential"] } ] } diff --git a/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts b/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts index 5b07f8b5d..6a309c75f 100644 --- a/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts +++ b/packages/did-auth-siop-op-authenticator/src/agent/DidAuthSiopOpAuthenticator.ts @@ -20,7 +20,7 @@ import { IVerifySiopAuthenticationRequestUriArgs, } from '../types/IDidAuthSiopOpAuthenticator' import { SIOP } from '@sphereon/did-auth-siop' -import { CredentialMapper, IVerifiableCredential } from '@sphereon/ssi-types'; +import { CredentialMapper, IVerifiableCredential } from '@sphereon/ssi-types' /** * {@inheritDoc IDidAuthSiopOpAuthenticator} @@ -120,7 +120,9 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { args: IGetSiopAuthenticationRequestFromRpArgs, context: IRequiredContext ): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.getSiopAuthenticationRequestFromRP(args)) + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => + session.getSiopAuthenticationRequestFromRP(args) + ) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails} */ @@ -129,9 +131,13 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { context: IRequiredContext ): Promise { const uniqueVcs: Array = await context.agent.dataStoreORMGetVerifiableCredentials(args.credentialFilter) - const verifiableCredentials: Array = uniqueVcs.map((uniqueVc: UniqueVerifiableCredential) => CredentialMapper.toExternalVerifiableCredential(uniqueVc.verifiableCredential)) + const verifiableCredentials: Array = uniqueVcs.map((uniqueVc: UniqueVerifiableCredential) => + CredentialMapper.toExternalVerifiableCredential(uniqueVc.verifiableCredential) + ) - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.getSiopAuthenticationRequestDetails({ ...args, verifiableCredentials })) + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => + session.getSiopAuthenticationRequestDetails({ ...args, verifiableCredentials }) + ) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI} */ @@ -139,7 +145,9 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin { args: IVerifySiopAuthenticationRequestUriArgs, context: IRequiredContext ): Promise { - return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => session.verifySiopAuthenticationRequestURI(args)) + return this.getSessionForSiop({ sessionId: args.sessionId }, context).then((session: OpSession) => + session.verifySiopAuthenticationRequestURI(args) + ) } /** {@inheritDoc IDidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse} */ diff --git a/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts b/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts index 25d0984a7..77e30c6ab 100644 --- a/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts +++ b/packages/did-auth-siop-op-authenticator/src/types/IDidAuthSiopOpAuthenticator.ts @@ -1,4 +1,13 @@ -import { DIDDocumentSection, IAgentContext, IIdentifier, IPluginMethodMap, IResolver, IKeyManager, IDataStoreORM, FindCredentialsArgs } from '@veramo/core' +import { + DIDDocumentSection, + IAgentContext, + IIdentifier, + IPluginMethodMap, + IResolver, + IKeyManager, + IDataStoreORM, + FindCredentialsArgs, +} from '@veramo/core' import { IVerifiableCredential, IVerifiablePresentation } from '@sphereon/ssi-types' import { OpSession } from '../session/OpSession' import { SIOP } from '@sphereon/did-auth-siop' diff --git a/packages/ssi-types/src/mapper/credential-mapper.ts b/packages/ssi-types/src/mapper/credential-mapper.ts index 22550e190..078f70754 100644 --- a/packages/ssi-types/src/mapper/credential-mapper.ts +++ b/packages/ssi-types/src/mapper/credential-mapper.ts @@ -294,18 +294,17 @@ export class CredentialMapper { return { ...verifiableCredential, type: verifiableCredential.type - ? typeof verifiableCredential.type === 'string' - ? [verifiableCredential.type] - : verifiableCredential.type - : ['VerifiableCredential'], + ? typeof verifiableCredential.type === 'string' + ? [verifiableCredential.type] + : verifiableCredential.type + : ['VerifiableCredential'], proof: { ...verifiableCredential.proof, type: verifiableCredential.proof.type, created: verifiableCredential.proof.created, proofPurpose: verifiableCredential.proof.proofPurpose, - verificationMethod: verifiableCredential.proof.verificationMethod - } + verificationMethod: verifiableCredential.proof.verificationMethod, + }, } } - } From 3c9fde4d1f33777e6013cb1e571d5a7e0537387e Mon Sep 17 00:00:00 2001 From: "A.G.J. Cate" Date: Wed, 4 Jan 2023 11:47:14 +0100 Subject: [PATCH 3/6] WAL-142 readme update --- packages/did-auth-siop-op-authenticator/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/did-auth-siop-op-authenticator/README.md b/packages/did-auth-siop-op-authenticator/README.md index f04103c34..15c495310 100644 --- a/packages/did-auth-siop-op-authenticator/README.md +++ b/packages/did-auth-siop-op-authenticator/README.md @@ -176,8 +176,7 @@ For more detailed information see: [Self Issued OpenID Provider v2 (SIOP)](https const sessionId = 'example_session_id' const authenticationRequestDetailsResponse = await agent.getSiopAuthenticationRequestDetails({ sessionId, - verifiedAuthenticationRequest: createAuthenticationResponse, - verifiableCredentials: [credential], + verifiedAuthenticationRequest: createAuthenticationResponse }) ``` From ee4fd0e346d1fdc85196c260a293e2ff4a465567 Mon Sep 17 00:00:00 2001 From: "A.G.J. Cate" Date: Wed, 4 Jan 2023 16:34:33 +0100 Subject: [PATCH 4/6] WAL-142 added credential filter test --- .../didAuthSiopOpAuthenticatorAgentLogic.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts index cac487ed8..5d9e9e17b 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/shared/didAuthSiopOpAuthenticatorAgentLogic.ts @@ -336,6 +336,36 @@ export default (testContext: { }) }) + it('should get authentication details with getting specific credentials', async () => { + const pd_single: PresentationDefinitionWithLocation = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_single.json' + ) + const vp_single: SIOP.VerifiablePresentationResponseOpts = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/vp/vp_single.json' + ) + vp_single.presentation.presentation_submission!.id = expect.any(String) + + const result: IAuthRequestDetails = await agent.getSiopAuthenticationRequestDetails({ + sessionId, + verifiedAuthenticationRequest: { + ...createAuthenticationResponseMockedResult, + presentationDefinitions: [pd_single], + }, + credentialFilter: { + where: [{ + column: 'id', + value: ['https://example.com/credentials/1872'] + }] + } + }) + + expect(result).toEqual({ + id: 'did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a', + alsoKnownAs: undefined, + vpResponseOpts: [vp_single], + }) + }) + it('should get authentication details with multiple credentials', async () => { const pd_multiple: PresentationDefinitionWithLocation = getFileAsJson( './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/pd/pd_multiple.json' From 65a3191db31c3d5269a6ab4e4f10b5beef8b48d2 Mon Sep 17 00:00:00 2001 From: Bram ten Cate Date: Thu, 12 Jan 2023 13:31:07 +0100 Subject: [PATCH 5/6] WAL-142 code cleanup --- .../__tests__/localAgent.test.ts | 32 +++++++++++-------- .../__tests__/restAgent.test.ts | 29 ++++++++++------- .../__tests__/vc_vp_examples/psc/psc.json | 11 +++++++ 3 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json diff --git a/packages/did-auth-siop-op-authenticator/__tests__/localAgent.test.ts b/packages/did-auth-siop-op-authenticator/__tests__/localAgent.test.ts index 54a50f17e..d7fee9606 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/localAgent.test.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/localAgent.test.ts @@ -1,25 +1,31 @@ +import * as fs from 'fs' import { getConfig } from '@veramo/cli/build/setup' import { createObjects } from '@veramo/cli/build/lib/objectCreator' +import didAuthSiopOpAuthenticatorAgentLogic from './shared/didAuthSiopOpAuthenticatorAgentLogic' +import { PresentationSignCallback } from '@sphereon/did-auth-siop' jest.setTimeout(30000) -import didAuthSiopOpAuthenticatorAgentLogic from './shared/didAuthSiopOpAuthenticatorAgentLogic' -import { PresentationSignCallback } from '@sphereon/did-auth-siop' +function getFile(path: string) { + return fs.readFileSync(path, 'utf-8') +} + +function getFileAsJson(path: string) { + return JSON.parse(getFile(path)) +} let agent: any -const presentationSignCallback: PresentationSignCallback = async (args) => ({ - ...args.presentation, - proof: { - type: 'RsaSignature2018', - created: '2018-09-14T21:19:10Z', - proofPurpose: 'authentication', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78' +const presentationSignCallback: PresentationSignCallback = async (args) => { + const presentationSignProof = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json' + ) + + return { + ...args.presentation, + ...presentationSignProof } -}) +} const setup = async (): Promise => { const config = getConfig('packages/did-auth-siop-op-authenticator/agent.yml') diff --git a/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts b/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts index ea21f4781..62e47543d 100644 --- a/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts +++ b/packages/did-auth-siop-op-authenticator/__tests__/restAgent.test.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs' import 'cross-fetch/polyfill' // @ts-ignore import express from 'express' @@ -17,23 +18,29 @@ import { PresentationSignCallback } from '@sphereon/did-auth-siop' jest.setTimeout(30000) +function getFile(path: string) { + return fs.readFileSync(path, 'utf-8') +} + +function getFileAsJson(path: string) { + return JSON.parse(getFile(path)) +} + const port = 3002 const basePath = '/agent' let serverAgent: IAgent let restServer: Server -const presentationSignCallback: PresentationSignCallback = async (args) => ({ - ...args.presentation, - proof: { - type: 'RsaSignature2018', - created: '2018-09-14T21:19:10Z', - proofPurpose: 'authentication', - verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', - challenge: '1f44d55f-f161-4938-a659-f8026467f126', - domain: '4jt78h47fh47', - jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78' +const presentationSignCallback: PresentationSignCallback = async (args) => { + const presentationSignProof = getFileAsJson( + './packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json' + ) + + return { + ...args.presentation, + ...presentationSignProof } -}) +} const getAgent = (options?: IAgentOptions) => createAgent({ diff --git a/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json new file mode 100644 index 000000000..9755bd33f --- /dev/null +++ b/packages/did-auth-siop-op-authenticator/__tests__/vc_vp_examples/psc/psc.json @@ -0,0 +1,11 @@ +{ + "proof": { + "type": "RsaSignature2018", + "created": "2018-09-14T21:19:10Z", + "proofPurpose": "authentication", + "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1", + "challenge": "1f44d55f-f161-4938-a659-f8026467f126", + "domain": "4jt78h47fh47", + "jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78" + } +} From 9de66e47c66ec8a9e6ba18d90ed32c641181185b Mon Sep 17 00:00:00 2001 From: Bram ten Cate Date: Thu, 12 Jan 2023 13:53:36 +0100 Subject: [PATCH 6/6] WAL-142 moved dep to dev --- packages/ssi-types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ssi-types/package.json b/packages/ssi-types/package.json index 085ea8a2a..b77d5673f 100644 --- a/packages/ssi-types/package.json +++ b/packages/ssi-types/package.json @@ -8,10 +8,10 @@ "build": "tsc --build" }, "dependencies": { - "@veramo/core": "4.2.0", "jwt-decode": "^3.1.2" }, "devDependencies": { + "@veramo/core": "4.2.0", "typescript": "4.6.4", "@types/jest": "^27.0.2", "jest": "^27.3.1",