Instantly share code, notes, and snippets.
Created
February 12, 2020 15:05
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save gjgd/11cac221f51a8a29c41af9ea482a18fe to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Ed25519KeyPair } = require('crypto-ld'); | |
const { EdvClient } = require('edv-client'); | |
const EdvInvoker = require('./EdvInvoker').default; | |
const EdvKak = require('./EdvKak').default; | |
const EdvHmac = require('./EdvHmac').default; | |
const axios = require('axios'); | |
const { CapabilityDelegation } = require('ocapld'); | |
const documentLoader = require('../../networking/documentLoader'); | |
const jsigs = require('jsonld-signatures'); | |
const { SECURITY_CONTEXT_V2_URL, sign, suites } = jsigs; | |
const { Ed25519Signature2018 } = suites; | |
// Use these if you're running "npm run serve:standalone" in packages/edv-server | |
const edvUrl = 'http://localhost:9876/edvs'; | |
const resetUrl = 'http://localhost:9876/.well-known/reset'; | |
// Use these if you're running "npm run start" in packages/edv-server | |
// const edvUrl = 'http://localhost:5010/did-edv/us-central1/main/edvs'; | |
// const resetUrl = 'http://localhost:5010/did-edv/us-central1/main/.well-known/reset'; | |
jest.setTimeout(10 * 1000); | |
const payload = { | |
'@context': [ | |
'https://w3id.org/did/v1', | |
{ | |
schema: 'http://schema.org/', | |
action: 'schema:action', | |
}, | |
], | |
action: 'AuthenticateMe', | |
}; | |
const keyAlice = { | |
controller: 'did:key:z6MknGnhiF3q3hFiZPMz5VaLPgea4dVcf86dPhmRkUF4UsBd', | |
id: | |
'did:key:z6MknGnhiF3q3hFiZPMz5VaLPgea4dVcf86dPhmRkUF4UsBd#z6MknGnhiF3q3hFiZPMz5VaLPgea4dVcf86dPhmRkUF4UsBd', | |
privateKeyBase58: | |
'5ciLFMSrPLAv5Kjw5PLTPTAindrSDgKSyTRJeQ3tafZJCy9je8aTWQe3aajUbcGWr5yMEz3r6Dni9gjvqGCkZkGP', | |
publicKeyBase58: '8pXf7zoPi9mFStXHPvcVYb6aF4DmFErGhgrVvCH3ZeQF', | |
type: 'Ed25519VerificationKey2018', | |
}; | |
const keyBob = { | |
controller: 'did:key:z6Mkv6Cj2frAFsJgWuDByjBAecqqRdoNQ9SewqrRngKmgo6w', | |
id: | |
'did:key:z6Mkv6Cj2frAFsJgWuDByjBAecqqRdoNQ9SewqrRngKmgo6w#z6Mkv6Cj2frAFsJgWuDByjBAecqqRdoNQ9SewqrRngKmgo6w', | |
privateKeyBase58: | |
'33f4WHXwx9cgL4q8gbiYGr6TnY2CsQeo6Yibuhog6gaiTAmLWMfGd7NqDWHnJmSJ8hrVX5cJVZDDyPCU1AnTMtg7', | |
publicKeyBase58: 'GdwgSRbivKpDQQNVJADKoXHqc4XWzGCJFpwVxQMkmaKZ', | |
type: 'Ed25519VerificationKey2018', | |
}; | |
describe('share', () => { | |
let clientAlice; | |
let encryptedDoc; | |
let keyAgreementKeyAlice; | |
let keyAgreementKeyBob; | |
let sharedWithBob; | |
const keyResolver = ({ id }) => { | |
if (keyAgreementKeyAlice.id === id) { | |
return keyAgreementKeyAlice; | |
} | |
if (keyAgreementKeyBob.id === id) { | |
return keyAgreementKeyBob; | |
} | |
throw new Error(`Key ${id} not found`); | |
}; | |
beforeAll(async () => { | |
await axios.delete(resetUrl); | |
keyAgreementKeyAlice = new EdvKak(await Ed25519KeyPair.from(keyAlice)); | |
keyAgreementKeyBob = new EdvKak(await Ed25519KeyPair.from(keyBob)); | |
}); | |
it('Alice creates an EDV', async () => { | |
const hmac = await EdvHmac.create(); | |
const config = await EdvClient.createEdv({ | |
url: edvUrl, | |
config: { | |
sequence: 0, | |
controller: keyAlice.controller, | |
keyAgreementKey: { | |
id: keyAgreementKeyAlice.id, | |
type: keyAgreementKeyAlice.type, | |
}, | |
hmac: { id: hmac.id, type: hmac.type }, | |
referenceId: 'primary', | |
}, | |
}); | |
clientAlice = new EdvClient({ | |
id: config.id, | |
keyResolver, | |
keyAgreementKey: keyAgreementKeyAlice, | |
hmac, | |
}); | |
expect(clientAlice).toBeDefined(); | |
}); | |
it('Alice creates a document in shared edv', async () => { | |
const docId = await EdvClient.generateId(); | |
const doc = { | |
id: docId, | |
content: { payload: payload }, | |
}; | |
const invocationSigner = new EdvInvoker(keyAlice); | |
encryptedDoc = await clientAlice.update({ | |
keyResolver, | |
invocationSigner, | |
recipients: [ | |
{ | |
header: { | |
kid: keyAgreementKeyAlice.id, | |
alg: 'ECDH-ES+A256KW', | |
}, | |
}, | |
{ | |
header: { | |
kid: keyAgreementKeyBob.id, | |
alg: 'ECDH-ES+A256KW', | |
}, | |
}, | |
], | |
doc, | |
}); | |
expect(encryptedDoc).toBeDefined(); | |
expect(encryptedDoc.jwe.recipients).toHaveLength(2); | |
}); | |
it('Bob can decrypt the encrypted document', async () => { | |
const clientBob = new EdvClient(); | |
const decryptedDoc = await clientBob._decrypt({ | |
encryptedDoc, | |
keyAgreementKey: keyAgreementKeyBob, | |
}); | |
expect(decryptedDoc.content).toBeDefined(); | |
expect(decryptedDoc.content.payload).toEqual(payload); | |
}); | |
it('Alice generates a zcap for Bob to access her EDV', async () => { | |
const unsignedCapability = { | |
'@context': SECURITY_CONTEXT_V2_URL, | |
id: `urn:zcap:${await EdvClient.generateId()}`, | |
invocationTarget: `${clientAlice.id}/documents/${encryptedDoc.id}`, | |
invoker: keyBob.id, | |
allowedAction: 'read', | |
parentCapability: `${clientAlice.id}/zcaps/documents/${encryptedDoc.id}`, | |
}; | |
const invocationSigner = new EdvInvoker(keyAlice); | |
const suite = new Ed25519Signature2018({ | |
signer: invocationSigner, | |
verificationMethod: invocationSigner.id, | |
}); | |
const purpose = new CapabilityDelegation({ | |
capabilityChain: [unsignedCapability.parentCapability], | |
}); | |
const zcap = await sign(unsignedCapability, { | |
documentLoader, | |
suite, | |
purpose, | |
}); | |
await clientAlice.enableCapability({ | |
capabilityToEnable: zcap, | |
invocationSigner, | |
}); | |
sharedWithBob = { | |
clientId: clientAlice.id, | |
encryptedDocId: encryptedDoc.id, | |
capabilityId: zcap.id, | |
} | |
}); | |
it('Bob can access the encrypted documents directly in the Edv', async () => { | |
const { clientId, encryptedDocId, capabilityId } = sharedWithBob; | |
const invocationSigner = new EdvInvoker(keyBob); | |
const clientBob = new EdvClient({ | |
id: clientId, | |
keyResolver, | |
keyAgreementKey: keyAgreementKeyBob, | |
}); | |
const delegatedDoc = await clientBob.get({ | |
id: encryptedDocId, | |
invocationSigner, | |
capability: capabilityId, | |
}); | |
expect(delegatedDoc).toBeDefined(); | |
expect(delegatedDoc.content.payload).toEqual(payload); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment