Skip to content

Commit

Permalink
Merge pull request #310 from jolocom/308/did-document-update
Browse files Browse the repository at this point in the history
Update DID Document implementation
  • Loading branch information
chunningham authored Aug 28, 2019
2 parents 59f7cd8 + 1584f1b commit 6a0f900
Show file tree
Hide file tree
Showing 20 changed files with 447 additions and 264 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"base64url": "^3.0.1",
"bip32": "^1.0.2",
"bip39": "^3.0.1",
"class-transformer": "^0.1.10",
"class-transformer": "^0.2.3",
"create-hash": "^1.2.0",
"cred-types-jolocom-core": "^0.0.11",
"dark-crystal-secrets": "^1.0.0",
Expand All @@ -77,7 +77,7 @@
"form-data": "^2.3.3",
"jolocom-registry-contract": "^0.1.7",
"json-logic-js": "^1.2.2",
"jsonld": "^1.5.3",
"jsonld": "^1.6.1",
"jsontokens": "^1.0.0",
"node-fetch": "^2.3.0",
"qrcode": "^1.3.3",
Expand Down
75 changes: 66 additions & 9 deletions tests/data/didDocument.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ export const mockDid =
'did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777'
export const mockIpfsHash = 'QmZCEmfiKZhRPB88cEqmcHzQu6siSmVpieG6HTQse4e4Js'
export const mockKeyId = `${mockDid}#keys-1`
export const mockKeyId2 = `${mockDid}#keys-2`
export const mockPublicKeyHex =
'03848af62bffceb57631780ac0e0726106ee1c23262d6fd7ef906559d68f53a551'

/* JSON form to ensure toJSON and fromJSON work as intended */

export const didDocumentJSON = {
export const didDocumentJSONv0 = {
authentication: [
{
publicKey: mockKeyId,
Expand All @@ -24,23 +25,79 @@ export const didDocumentJSON = {
publicKeyHex: mockPublicKeyHex,
},
],
service: [],
service: [
{
id: `${mockDid};jolocomPubProfile`,
type: 'JolocomPublicProfile',
serviceEndpoint: `ipfs://${mockIpfsHash}`,
description: 'Verifiable Credential describing entity profile',
},
],
created: '1970-01-01T00:00:00.000Z',
proof: {
type: 'EcdsaKoblitzSignature2016',
creator: mockKeyId,
nonce: '1842fb5f567dd532',
signatureValue:
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
created: '1970-01-01T00:00:00.000Z',
},
'@context': defaultContextIdentity,
id: mockDid,
}

export const didDocumentJSON = {
specVersion: 0.13,
authentication: [
mockKeyId,
{
id: mockKeyId2,
type: 'Secp256k1VerificationKey2018',
controller: mockDid,
publicKeyHex: mockPublicKeyHex,
},
],
publicKey: [
{
id: mockKeyId,
type: 'Secp256k1VerificationKey2018',
controller: mockDid,
publicKeyHex: mockPublicKeyHex,
},
],
service: [
{
id: `${mockDid}#jolocomPubProfile`,
type: 'JolocomPublicProfile',
serviceEndpoint: 'ipfs://QmZCEmfiKZhRPB88cEqmcHzQu6siSmVpieG6HTQse4e4Js',
description: 'Verifiable Credential describing entity profile',
},
],
created: '1970-01-01T00:00:00.000Z',
updated: '1970-01-01T00:00:00.000Z',
proof: {
type: 'EcdsaKoblitzSignature2016',
creator: mockKeyId,
nonce: '1842fb5f567dd532',
signatureValue: '',
signatureValue:
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
created: '1970-01-01T00:00:00.000Z',
},
'@context': defaultContextIdentity,
id: mockDid,
}

export const normalizedDidDocument =
'\
<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> <https://w3id.org/security#owner> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> .\n\
<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <http://purl.org/dc/terms/created> "1970-01-01T00:00:00.000Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .\n\
<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#authenticationMethod> _:c14n0 .\n\
<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#publicKey> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> .\n\
_:c14n0 <https://w3id.org/security#publicKey> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> .\n'
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#jolocomPubProfile> <http://schema.org/description> "Verifiable Credential describing entity profile" .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#jolocomPubProfile> <https://w3id.org/security#dfn-service-endpoints> "ipfs://QmZCEmfiKZhRPB88cEqmcHzQu6siSmVpieG6HTQse4e4Js" .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> <https://w3id.org/security#controller> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> <https://w3id.org/security#publicKeyHex> "03848af62bffceb57631780ac0e0726106ee1c23262d6fd7ef906559d68f53a551" .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-2> <https://w3id.org/security#controller> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-2> <https://w3id.org/security#publicKeyHex> "03848af62bffceb57631780ac0e0726106ee1c23262d6fd7ef906559d68f53a551" .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <http://purl.org/dc/terms/created> "1970-01-01T00:00:00.000Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <http://schema.org/version> "1.3E-1"^^<http://www.w3.org/2001/XMLSchema#double> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/did#updated> "1970-01-01T00:00:00.000Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#authenticationMethod> "did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1" .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#authenticationMethod> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-2> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#publicKey> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1> .\n' +
'<did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777> <https://w3id.org/security#service-endpoints> <did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#jolocomPubProfile> .\n'
16 changes: 9 additions & 7 deletions tests/data/didDocumentSections.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { testPublicIdentityKey } from './keys.data'
import {
mockDid,
mockKeyId,
mockKeyId2,
mockPublicKeyHex,
mockIpfsHash,
} from './didDocument.data'
Expand All @@ -12,20 +13,21 @@ export const mockPubKeySectionCreationAttrs = {
keyId: mockKeyId,
}

export const mockPubKeySectionJSON = {
export const mockPublicKey = {
id: mockKeyId,
type: 'Secp256k1VerificationKey2018',
owner: mockDid,
controller: mockDid,
publicKeyHex: mockPublicKeyHex,
}

export const mockAuthSectionJSON = {
publicKey: mockKeyId,
type: 'Secp256k1SignatureAuthentication2018',
export const mockPublicKey2 = {
id: mockKeyId2,
type: 'Secp256k1VerificationKey2018',
controller: mockDid,
publicKeyHex: mockPublicKeyHex,
}

export const mockPubProfServiceEndpointJSON = {
id: `${mockDid};jolocomPubProfile`,
id: `${mockDid}#jolocomPubProfile`,
serviceEndpoint: `ipfs://${mockIpfsHash}`,
description: 'Verifiable Credential describing entity profile',
type: 'JolocomPublicProfile',
Expand Down
90 changes: 77 additions & 13 deletions tests/identity/didDocument.test.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,121 @@
import * as chai from 'chai'
import * as sinon from 'sinon'
import * as crypto from 'crypto'
import * as jsonld from 'jsonld'
import { testPublicIdentityKey } from '../data/keys.data'
import { testPublicIdentityKey, testSeed } from '../data/keys.data'
import {
didDocumentJSONv0,
didDocumentJSON,
mockDid,
mockKeyId,
normalizedDidDocument,
} from '../data/didDocument.data'
import { DidDocument } from '../../ts/identity/didDocument/didDocument'
import { IDidDocumentAttrs } from '../../ts/identity/didDocument/types'
import {
mockPublicKey2,
mockPubProfServiceEndpointJSON,
} from '../data/didDocumentSections.data'
import {
ServiceEndpointsSection,
PublicKeySection,
} from '../../ts/identity/didDocument/sections'
import { SoftwareKeyProvider } from '../../ts/vaultedKeyProvider/softwareProvider'
import { KeyTypes } from '../../ts/vaultedKeyProvider/types'

const expect = chai.expect

describe('DidDocument', () => {
const sandbox = sinon.createSandbox()
const vault = SoftwareKeyProvider.fromSeed(testSeed, 'password')
const derivationArgs = {
derivationPath: KeyTypes.jolocomIdentityKey,
encryptionPass: 'password',
}

let referenceDidDocument = DidDocument.fromPublicKey(testPublicIdentityKey)
let referenceDidDocument
let clock

before(() => {
clock = sinon.useFakeTimers()
sandbox.stub(jsonld, 'canonize').returns(normalizedDidDocument)
sandbox
.stub(crypto, 'randomBytes')
.returns(Buffer.from('1842fb5f567dd532', 'hex'))
})

beforeEach(() => {
referenceDidDocument = DidDocument.fromPublicKey(testPublicIdentityKey)
beforeEach(async () => {
referenceDidDocument = await DidDocument.fromPublicKey(
testPublicIdentityKey,
)
referenceDidDocument.addAuthKey(mockPublicKey2)
referenceDidDocument.addServiceEndpoint(
ServiceEndpointsSection.fromJSON(mockPubProfServiceEndpointJSON),
)
await referenceDidDocument.sign(vault, derivationArgs, mockKeyId)
})

after(() => {
sandbox.restore()
clock.restore()
})

it('Should not try to migrate if DID is not "did:jolo:*"', () => {
const didDocJSON = {
'@context': 'https://w3id.org/did/v1',
id: 'did:uknow:d34db33f',
publicKey: [
{
id: 'did:uknow:d34db33f#cooked',
type: 'Secp256k1VerificationKey2018',
owner: 'did:uknow:d34db33f',
publicKeyHex: 'b9c5714089478a327f09197987f16f9e5d936e8a',
},
],
authentication: [
{
type: 'Secp256k1SignatureAuthentication2018',
publicKey: 'did:uknow:d34db33f#cooked',
},
],
service: [],
created: '',
}
expect(() => DidDocument.fromJSON(didDocJSON)).to.not.throw()
})

it('Should correctly implement fromJSON for version 0', () => {
const didDocumentv0 = DidDocument.fromJSON(didDocumentJSONv0)

didDocumentv0.addAuthKey(mockPublicKey2 as PublicKeySection)
expect(didDocumentv0).to.deep.eq(referenceDidDocument)
})

it('Should correctly implement fromJSON', () => {
const didDocFromJSON = DidDocument.fromJSON(didDocumentJSON)
expect(referenceDidDocument).to.deep.eq(didDocFromJSON)
expect(didDocFromJSON).to.deep.eq(referenceDidDocument)
})

it('Should correctly implement toJSON', () => {
expect(referenceDidDocument.toJSON()).to.deep.eq(didDocumentJSON)
})

it('Should correctly implement normalize', async () => {
await referenceDidDocument.digest()
const normalized = await referenceDidDocument.normalize()

expect(normalized).to.deep.eq(normalizedDidDocument)
})

const excludingProof = { ...didDocumentJSON } as IDidDocumentAttrs
delete excludingProof.proof
it('should correctly sign the DID document', async () => {
await referenceDidDocument.sign(
vault,
{
derivationPath: KeyTypes.jolocomIdentityKey,
encryptionPass: 'password',
},
mockKeyId,
)

sandbox.assert.calledWith(jsonld.canonize, excludingProof)
expect(referenceDidDocument.signature).to.eq(
'3e4bca6a08643c4a67c02abd109accd19f2f9ad1c93cd9f39d3f23edc122de7a72d1de44420b456c20b1875ed254417efdf8dd16fb8ded818d830dac475ec55a',
)
})

it('implements getters', () => {
Expand All @@ -64,7 +128,7 @@ describe('DidDocument', () => {
service,
created,
} = didDocumentJSON
const auth = referenceDidDocument.authentication.map(auth => auth.toJSON())
const auth = referenceDidDocument.authentication
const pub = referenceDidDocument.publicKey.map(pub => pub.toJSON())
const serv = referenceDidDocument.service.map(ser => ser.toJSON())

Expand Down
19 changes: 3 additions & 16 deletions tests/identity/didDocumentSections.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import * as chai from 'chai'
import * as sinon from 'sinon'
import * as crypto from 'crypto'
import {
PublicKeySection,
AuthenticationSection,
} from '../../ts/identity/didDocument/sections'
import { PublicKeySection } from '../../ts/identity/didDocument/sections'
import {
mockPubKeySectionCreationAttrs,
mockPubKeySectionJSON,
mockAuthSectionJSON,
mockPublicKey,
mockPubProfServiceEndpointJSON,
} from '../data/didDocumentSections.data'
import {
Expand Down Expand Up @@ -39,16 +35,7 @@ describe('DidDocumentSections', () => {
it('Should correctly instantiate from secp256k1 public key', () => {
const { publicKey, keyId, did } = mockPubKeySectionCreationAttrs
const section = PublicKeySection.fromEcdsa(publicKey, keyId, did)
expect(section.toJSON()).to.deep.eq(mockPubKeySectionJSON)
})
})

describe('AuthenticationSection', () => {
it('Should correctly instantiate from public key section', () => {
const { publicKey, keyId, did } = mockPubKeySectionCreationAttrs
const pubKeySection = PublicKeySection.fromEcdsa(publicKey, keyId, did)
const authSection = AuthenticationSection.fromEcdsa(pubKeySection)
expect(authSection.toJSON()).to.deep.eq(mockAuthSectionJSON)
expect(section.toJSON()).to.deep.eq(mockPublicKey)
})
})

Expand Down
4 changes: 2 additions & 2 deletions tests/identity/identity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Identity } from '../../ts/identity/identity'
import { DidDocument } from '../../ts/identity/didDocument/didDocument'
const expect = chai.expect

describe('Identity', () => {
describe('Identity', async () => {
let clock
const mockDidDocument = DidDocument.fromPublicKey(testPublicIdentityKey)
const mockDidDocument = await DidDocument.fromPublicKey(testPublicIdentityKey)
const mockPublicProfile = SignedCredential.fromJSON(publicProfileCredJSON)

before(() => {
Expand Down
Loading

0 comments on commit 6a0f900

Please sign in to comment.