From 4b1768936a173844e8710993a42600eab4051f9c Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Thu, 30 Apr 2020 19:36:35 +0200 Subject: [PATCH] feat: Reinstate `credentialStatus` as top level attribute it needs to exist for presentations as well --- jest.json | 4 +- packages/daf-w3c/package.json | 2 +- .../src/__tests__/credentialStatus.test.ts | 105 ++++++++++++++++++ .../src/__tests__/message-handler.test.ts | 37 ++++++ packages/daf-w3c/src/action-handler.ts | 3 - packages/daf-w3c/src/message-handler.ts | 6 +- yarn.lock | 8 +- 7 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 packages/daf-w3c/src/__tests__/credentialStatus.test.ts diff --git a/jest.json b/jest.json index ceb46a104..987198c2f 100644 --- a/jest.json +++ b/jest.json @@ -22,7 +22,5 @@ }, "testEnvironment": "node", "automock": false, - "setupFiles": [ - "./setupJest.js" - ] + "setupFiles": ["./setupJest.js"] } diff --git a/packages/daf-w3c/package.json b/packages/daf-w3c/package.json index 53b2a1461..7321483d5 100644 --- a/packages/daf-w3c/package.json +++ b/packages/daf-w3c/package.json @@ -12,7 +12,7 @@ "daf-core": "^4.4.0", "daf-did-jwt": "^4.4.0", "debug": "^4.1.1", - "did-jwt-vc": "^0.1.6", + "did-jwt-vc": "0.2.0", "did-resolver": "^1.1.0" }, "devDependencies": { diff --git a/packages/daf-w3c/src/__tests__/credentialStatus.test.ts b/packages/daf-w3c/src/__tests__/credentialStatus.test.ts new file mode 100644 index 000000000..11d931785 --- /dev/null +++ b/packages/daf-w3c/src/__tests__/credentialStatus.test.ts @@ -0,0 +1,105 @@ +import { W3cActionHandler, ActionTypes, ActionSignW3cVc } from '../index' +import { SimpleSigner } from 'did-jwt' +import { Resolver } from 'did-resolver' +import { ActionSignW3cVp } from '../action-handler' + +const privateKey = 'a285ab66393c5fdda46d6fbad9e27fafd438254ab72ad5acb681a0e9f20f5d7b' +const signerAddress = '0x2036c6cd85692f0fb2c26e6c6b2eced9e4478dfd' +const mockDid: string = `did:ethr:${signerAddress}` + +const mockAgent = { + identityManager: { + getIdentity: async (did: string) => ({ + did: mockDid, + keyByType: async (type: string) => ({ + signer: () => { + return SimpleSigner(privateKey) + }, + }), + }), + }, + didResolver: { + resolve: async (did: string) => { + return { + '@context': 'https://w3id.org/did/v1', + id: 'did:ethr:rinkeby:0x42ba71c59a22a037e54f8d5b13d7b3721daa18c3', + publicKey: [ + { + id: 'did:ethr:rinkeby:0x42ba71c59a22a037e54f8d5b13d7b3721daa18c3#owner', + type: 'Secp256k1VerificationKey2018', + owner: 'did:ethr:rinkeby:0x42ba71c59a22a037e54f8d5b13d7b3721daa18c3', + ethereumAddress: '0x42ba71c59a22a037e54f8d5b13d7b3721daa18c3', + }, + ], + authentication: [ + { + type: 'Secp256k1SignatureAuthentication2018', + publicKey: 'did:ethr:rinkeby:0x42ba71c59a22a037e54f8d5b13d7b3721daa18c3#owner', + }, + ], + } + }, + }, +} + +describe('daf-w3c', () => { + // it('handles signing a presentation with credentialStatus', async () => { + // expect.assertions(1) + + // const actionHandler = new W3cActionHandler() + + // const data = { + // issuer: mockDid, + // audience: 'did:web:uport.me', + // '@context': ['https://www.w3.org/2018/credentials/v1'], + // type: ['VerifiablePresentation'], + // verifiableCredential: ['eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1ODU4MTEyNTksInN1YiI6ImRpZDp3ZWI6dXBvcnQubWUiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7Im5hbWUiOiJCb2IifX0sImlzcyI6ImRpZDpldGhyOnJpbmtlYnk6MHg0MmJhNzFjNTlhMjJhMDM3ZTU0ZjhkNWIxM2Q3YjM3MjFkYWExOGMzIn0.lSuP2V-xr0RaW-M_egBXnhv0cUuM7Vp54wz1A_f3zCXjR7-bcfk1HqvweQsX-m7mXx9J9sn2vNS6YcJhWk2oBAE'], + // credentialStatus: { + // type: 'TestStatusMethod', + // id: 'local' + // } + // } + + // let result = await actionHandler.handleAction( + // { + // type: ActionTypes.signPresentationJwt, + // data, + // } as ActionSignW3cVp, + // mockAgent as any, + // ) + + // console.log("gigel", result) + + // expect(result.credentialStatus).toMatchObject({ type: 'TestStatusMethod', id: 'local' }) + // }) + + it('handles sign.w3c.vc.jwt with credentialStatus', async () => { + // expect.assertions(1) + + const actionHandler = new W3cActionHandler() + + const data = { + issuer: mockDid, + '@context': ['https://www.w3.org/2018/credentials/v1'], + type: ['VerifiableCredential'], + credentialSubject: { + id: 'did:web:uport.me', + you: 'Rock', + }, + credentialStatus: { + type: 'TestStatusMethod', + id: 'local', + }, + } + + let result = await actionHandler.handleAction( + { + type: ActionTypes.signCredentialJwt, + data, + } as ActionSignW3cVc, + mockAgent as any, + ) + + expect(result.credentialStatus).toMatchObject({ type: 'TestStatusMethod', id: 'local' }) + }) +}) diff --git a/packages/daf-w3c/src/__tests__/message-handler.test.ts b/packages/daf-w3c/src/__tests__/message-handler.test.ts index e6c3c5e42..d0a1b52f2 100644 --- a/packages/daf-w3c/src/__tests__/message-handler.test.ts +++ b/packages/daf-w3c/src/__tests__/message-handler.test.ts @@ -101,4 +101,41 @@ describe('daf-w3c', () => { expect(handled.threadId).toEqual(vpPayload.tag) // expect(handled.timestamp).toEqual(vpPayload.iat) }) + + it('should return handled VC message with credentialStatus', async () => { + const token = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE1ODgyNDkyNTgsInN1YiI6ImRpZDp3ZWI6dXBvcnQubWUiLCJub25jZSI6IjM4NzE4Njc0NTMiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiQXdlc29tZW5lc3NDcmVkZW50aWFsIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7Iml0IjoicmVhbGx5IHdoaXBzIHRoZSBsbGFtbWEncyBhc3MhIn19LCJjcmVkZW50aWFsU3RhdHVzIjp7InR5cGUiOiJFdGhyU3RhdHVzUmVnaXN0cnkyMDE5IiwiaWQiOiJyaW5rZWJ5OjB4OTdmZDI3ODkyY2RjRDAzNWRBZTFmZTcxMjM1YzYzNjA0NEI1OTM0OCJ9LCJpc3MiOiJkaWQ6ZXRocjoweDU0ZDU5ZTNmZmQ3NjkxN2Y2MmRiNzAyYWMzNTRiMTdmMzg0Mjk1NWUifQ.mtMt6-sJdaKH_sPUFPan1FzvWPtlrdKLRCHrh1aOS_zSVyTGHynA0-5AHcEujB1Rz1SuzuM3rkhHRO8eX2IAYg' + const message = new Message({ + raw: token, + metaData: [{ type: 'test' }], + }) + // This would be done by 'daf-did-jwt': + message.data = { + iat: 1588249258, + sub: 'did:web:uport.me', + vc: { + '@context': ['https://www.w3.org/2018/credentials/v1'], + type: ['VerifiableCredential', 'AwesomenessCredential'], + credentialSubject: { + it: "really whips the llamma's ass!", + }, + }, + credentialStatus: { + type: 'EthrStatusRegistry2019', + id: 'rinkeby:0x97fd27892cdcD035dAe1fe71235c636044B59348', + }, + iss: 'did:ethr:0x54d59e3ffd76917f62db702ac354b17f3842955e', + } + message.addMetaData({ type: 'JWT', value: 'ES256K' }) + + const handled = await handler.handle(message, agent) + + expect(handled.isValid()).toEqual(true) + expect(handled.id).toEqual(blake2bHex(token)) + expect(handled.raw).toEqual(token) + expect(handled.type).toEqual(MessageTypes.vc) + expect(handled.from.did).toEqual('did:ethr:0x54d59e3ffd76917f62db702ac354b17f3842955e') + expect(handled.to.did).toEqual('did:web:uport.me') + expect(handled.credentials[0].credentialStatus).toEqual(message.data['credentialStatus']) + }) }) diff --git a/packages/daf-w3c/src/action-handler.ts b/packages/daf-w3c/src/action-handler.ts index 1d9d09369..b6d9dbf2f 100644 --- a/packages/daf-w3c/src/action-handler.ts +++ b/packages/daf-w3c/src/action-handler.ts @@ -146,9 +146,6 @@ const transformCredentialInput = (input: CredentialInput): VerifiableCredentialP case 'id': result['jti'] = input[key] break - case 'credentialStatus': - result['vc']['credentialStatus'] = input[key] - break case 'issuer': // remove issuer break diff --git a/packages/daf-w3c/src/message-handler.ts b/packages/daf-w3c/src/message-handler.ts index c3e91eefa..802f04e30 100644 --- a/packages/daf-w3c/src/message-handler.ts +++ b/packages/daf-w3c/src/message-handler.ts @@ -21,7 +21,7 @@ export class W3cMessageHandler extends AbstractMessageHandler { async handle(message: Message, agent: Agent): Promise { const meta = message.getLastMetaData() - if (meta?.type === 'JWT' && meta?.value === 'ES256K-R') { + if (meta?.type === 'JWT') { const { data } = message try { @@ -106,10 +106,6 @@ export function createCredential(payload: VerifiableCredentialPayload, jwt: stri vc.expirationDate = timestampToDate(payload.exp) } - if (payload.vc.credentialStatus) { - vc.credentialStatus = payload.vc.credentialStatus - } - vc.context = payload.vc['@context'] vc.type = payload.vc.type diff --git a/yarn.lock b/yarn.lock index ccb00b068..7008bf7bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3929,10 +3929,10 @@ dicer@0.3.0: dependencies: streamsearch "0.1.2" -did-jwt-vc@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/did-jwt-vc/-/did-jwt-vc-0.1.6.tgz#e07900c55bd56f90ab3868d96f03d9ae008fd0a2" - integrity sha512-sRqUlCYKTygJ45aH0A5GSEH76NhCxIRoDIqty+pCu1KhxUbXxJgpY8+TTfffjdlitXZKt3m9Twh4LSCJpW920Q== +did-jwt-vc@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/did-jwt-vc/-/did-jwt-vc-0.2.0.tgz#a3592217622d4eccbe1c6b2ea68ba41fe79d7e5d" + integrity sha512-YlIXA3GLryD9nlHOUAzYaU6UMVvZ3103HVBILuGLvRTnE9YVmlfc6nMuYOcIzbgLW2P8pZgIgZsyEFzRdkDRFg== dependencies: did-jwt "^4.3.2"