Skip to content

Commit

Permalink
fix(ref-imp): fixes controller property to have a value
Browse files Browse the repository at this point in the history
* fix(ref-imp): fixes controller property to have a value

This is a bit of a hack that's potentially going to create issues when resolving
a key that's not controlled by the controller of the did document. At this point
though that's an exceptional case that doesn't need to be handled immediately and
this fix allows DID Documents resolved by the sidetree node to be compliant with
the did-test-suite.

BREAKING CHANGE: The controller is no longer an empty string and instead matches
the document id property (e.g. the did being resolved)
  • Loading branch information
kdenhartog authored Sep 13, 2021
1 parent 4d71740 commit 83ef023
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 11 deletions.
4 changes: 2 additions & 2 deletions lib/core/versions/latest/DocumentComposer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class DocumentComposer {
const id = '#' + publicKey.id;
const didDocumentPublicKey = {
id: id,
controller: '',
controller: did.isShortForm ? did.shortForm : did.longForm,
type: publicKey.type,
publicKeyJwk: publicKey.publicKeyJwk
};
Expand All @@ -51,7 +51,7 @@ export default class DocumentComposer {
verificationMethod.push(didDocumentPublicKey);

if (purposeSet.size > 0) {
const reference = didDocumentPublicKey.controller + didDocumentPublicKey.id;
const reference = didDocumentPublicKey.id;

for (const purpose of purposeSet) {
if (!verificationRelationships.has(purpose)) {
Expand Down
70 changes: 66 additions & 4 deletions tests/core/DocumentComposer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SidetreeError from '../../lib/common/SidetreeError';
describe('DocumentComposer', async () => {

describe('transformToExternalDocument', () => {
it('should output the expected resolution result given key(s) across all purpose types.', async () => {
it('should output the expected resolution result with a shortForm identifier given key(s) across all purpose types.', async () => {
const [anySigningPublicKey] = await OperationGenerator.generateKeyPair('anySigningKey'); // All purposes will be included by default.
const [noPurposePublicKey] = await OperationGenerator.generateKeyPair('noPurposePublicKey', []);
const [authPublicKey] = await OperationGenerator.generateKeyPair('authPublicKey', [PublicKeyPurpose.Authentication]);
Expand Down Expand Up @@ -47,19 +47,81 @@ describe('DocumentComposer', async () => {
verificationMethod: [
{
id: '#anySigningKey',
controller: '',
controller: did.shortForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: anySigningPublicKey.publicKeyJwk.x, y: anySigningPublicKey.publicKeyJwk.y }
},
{
id: '#authPublicKey',
controller: '',
controller: did.shortForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: authPublicKey.publicKeyJwk.x, y: authPublicKey.publicKeyJwk.y }
},
{
id: '#noPurposePublicKey',
controller: '',
controller: did.shortForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: noPurposePublicKey.publicKeyJwk.x, y: noPurposePublicKey.publicKeyJwk.y }
}
],
assertionMethod: ['#anySigningKey'],
authentication: [
'#anySigningKey',
'#authPublicKey'
],
capabilityDelegation: ['#anySigningKey'],
capabilityInvocation: ['#anySigningKey'],
keyAgreement: ['#anySigningKey']
});
});

it('should output the expected resolution result with a longForm identifier given key(s) across all purpose types.', async () => {
const [anySigningPublicKey] = await OperationGenerator.generateKeyPair('anySigningKey'); // All purposes will be included by default.
const [noPurposePublicKey] = await OperationGenerator.generateKeyPair('noPurposePublicKey', []);
const [authPublicKey] = await OperationGenerator.generateKeyPair('authPublicKey', [PublicKeyPurpose.Authentication]);
const document = {
publicKeys: [anySigningPublicKey, authPublicKey, noPurposePublicKey]
};
const didState: DidState = {
document,
lastOperationTransactionNumber: 123,
nextRecoveryCommitmentHash: 'EiBfOZdMtU6OBw8Pk879QtZ-2J-9FbbjSZyoaA_bqD4zhA',
nextUpdateCommitmentHash: 'EiDKIkwqO69IPG3pOlHkdb86nYt0aNxSHZu2r-bhEznjdA'
};

const published = false;
const did = await Did.create('did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ', 'sidetree');
const result = DocumentComposer.transformToExternalDocument(didState, did, published);

expect(result['@context']).toEqual('https://w3id.org/did-resolution/v1');
expect(result.didDocumentMetadata).toEqual({
equivalentId: ['did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg'],
method: {
published: false,
recoveryCommitment: 'EiBfOZdMtU6OBw8Pk879QtZ-2J-9FbbjSZyoaA_bqD4zhA',
updateCommitment: 'EiDKIkwqO69IPG3pOlHkdb86nYt0aNxSHZu2r-bhEznjdA'
}
});
expect(result.didDocument).toEqual({
id: did.longForm,
'@context': ['https://www.w3.org/ns/did/v1', { '@base': did.longForm }],
service: undefined,
verificationMethod: [
{
id: '#anySigningKey',
controller: did.longForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: anySigningPublicKey.publicKeyJwk.x, y: anySigningPublicKey.publicKeyJwk.y }
},
{
id: '#authPublicKey',
controller: did.longForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: authPublicKey.publicKeyJwk.x, y: authPublicKey.publicKeyJwk.y }
},
{
id: '#noPurposePublicKey',
controller: did.longForm,
type: 'EcdsaSecp256k1VerificationKey2019',
publicKeyJwk: { kty: 'EC', crv: 'secp256k1', x: noPurposePublicKey.publicKeyJwk.x, y: noPurposePublicKey.publicKeyJwk.y }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/vectors/resolution/afterCreate.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"verificationMethod": [
{
"id": "#publicKeyModel1Id",
"controller": "",
"controller": "did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"kty": "EC",
Expand Down
2 changes: 1 addition & 1 deletion tests/vectors/resolution/afterRecover.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"verificationMethod": [
{
"id": "#newKey",
"controller": "",
"controller": "did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"kty": "EC",
Expand Down
4 changes: 2 additions & 2 deletions tests/vectors/resolution/afterUpdate.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"verificationMethod": [
{
"id": "#publicKeyModel1Id",
"controller": "",
"controller": "did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"kty": "EC",
Expand All @@ -29,7 +29,7 @@
},
{
"id": "#additional-key",
"controller": "",
"controller": "did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"kty": "EC",
Expand Down
2 changes: 1 addition & 1 deletion tests/vectors/resolution/longFormResponseDidDocument.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"verificationMethod": [
{
"id": "#publicKeyModel1Id",
"controller": "",
"controller": "did:sidetree:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJwdWJsaWNLZXlNb2RlbDFJZCIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJ0WFNLQl9ydWJYUzdzQ2pYcXVwVkpFelRjVzNNc2ptRXZxMVlwWG45NlpnIiwieSI6ImRPaWNYcWJqRnhvR0otSzAtR0oxa0hZSnFpY19EX09NdVV3a1E3T2w2bmsifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJrZXlBZ3JlZW1lbnQiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoic2VydmljZTFJZCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly93d3cuc2VydmljZTEuY29tIiwidHlwZSI6InNlcnZpY2UxVHlwZSJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpREtJa3dxTzY5SVBHM3BPbEhrZGI4Nm5ZdDBhTnhTSFp1MnItYmhFem5qZEEifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUNmRFdSbllsY0Q5RUdBM2RfNVoxQUh1LWlZcU1iSjluZmlxZHo1UzhWRGJnIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlCZk9aZE10VTZPQnc4UGs4NzlRdFotMkotOUZiYmpTWnlvYUFfYnFENHpoQSJ9fQ",
"type": "EcdsaSecp256k1VerificationKey2019",
"publicKeyJwk": {
"crv": "secp256k1",
Expand Down

0 comments on commit 83ef023

Please sign in to comment.