digitalbazaar / jsonld-signatures

An implementation of the Linked Data Signatures specification for JSON-LD. Works in the browser and Node.js.
BSD 3-Clause "New" or "Revised" License
136 stars 41 forks source link

Add more documentation about the usage of `documentLoader`. #61

Open gannan08 opened 5 years ago

dlongley commented 5 years ago

To resolve this issue, we need to see updates to the README for the top-level sign and verify APIs that provide clear examples for how and when a documentLoader needs to be passed.

OR13 commented 5 years ago

I use this documentLoader in fixtures:

import jsonld from 'jsonld';
import contexts from './contexts';
import resolver from './resolver';

const nodeDocumentLoader = jsonld.documentLoaders.node();

export default (url: string, callback: any) => {
  // console.log(url);
  // are we handling a DID?
  if (url.indexOf('did:example') === 0) {
    const doc = resolver.resolve(url);
    if (!doc) {
      throw new Error('Could not resolve: ' + url);
    }
    // iterate public keys, find the correct id...
    for (const publicKey of doc.publicKey) {
      if (publicKey.id === url) {
        return callback(null, {
          contextUrl: null, // this is for a context via a link header
          document: publicKey, // this is the actual document that was loaded
          documentUrl: url, // this is the actual context URL after redirects
        });
      }
    }
  }

  //   are we handling a custom context?
  if (url in contexts) {
    const document = contexts[url];
    return callback(null, {
      contextUrl: null, // this is for a context via a link header
      document, // this is the actual document that was loaded
      documentUrl: url, // this is the actual context URL after redirects
    });
  }

  //   is this a published (public) context?
  return nodeDocumentLoader(url, callback);
};

With small amount of cleanup, it might help resolve this issue.

When I first started with JSON-LD I spent a lot of time being confused by this.

Since a lot of people are trying to work with DIDs, I think the example / documentation should include some opinion on DID Resolvers.

OR13 commented 4 years ago

This is still an issue which is preventing wider adoption of linked data signatures in the DID community. You should provide an example.

OR13 commented 4 years ago

Be especially aware, that if you are relying on

https://w3id.org/security/v1 https://w3id.org/security/v2

And using a custom document loader, you will need to make sure that these have been updated, to support any properties you are working with....

OR13 commented 4 years ago

also note that the example I provided above is not correct.... when loading a document of the form:

did:example:123#WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU

You should get the same result as:

did:example:123

... examples would really, really, really help here.

OR13 commented 4 years ago

something as simple as:

const customLoader = (url: string) => {
  console.log(url);
  const context = contexts[url];

  if (context) {
    return {
      contextUrl: null, // this is for a context via a link header
      document: context, // this is the actual document that was loaded
      documentUrl: url, // this is the actual context URL after redirects
    };
  }

  if (url === 'did:example:123') {
    return {
      contextUrl: null, // this is for a context via a link header
      document: fixtures.didDoc, // this is the actual document that was loaded
      documentUrl: url, // this is the actual context URL after redirects
    };
  }

  if (url === 'did:example:123#WqzaOweASs78whhl_YvCEvj1nd89IycryVlmZMefcjU') {
    return {
      contextUrl: null, // this is for a context via a link header
      document: fixtures.didDoc, // this is the actual document that was loaded
      documentUrl: 'did:example:123', // this is the actual context URL after redirects
    };
  }
  throw new Error('No custom context support for ' + url);
};

would go miles.

aljones15 commented 4 years ago

I'm kind of popping in on this out of the blue, but I do agree better documentation on documentLoaders should be in each library that provides one. I did not know that vc-js' documentLoader was restricted to just the documents it loads at run time and more frustratingly it does not even expose it's contexts meaning that in order to even get my context to load I had to write a wrapper around the default document loader. There there is the other pitfall which is that a documentLoader returns a context in the following format:

    return {
      contextUrl: null,
      documentUrl: url,
      document: schemaContext
    };

Basically libraries should tell you if their documentLoader will fetch from the internet (most do not) and if not how to add a new context for them to load (usually you just need to set a constant in bedrock).

Also one more thing: have we considered making all of the vocabularies / contexts for the project into one github repo? This would allow us to easily see all the potential schemas/ contexts being used in this project and also to create a documentLoader for all those contexts in one place.

Anyways love the documentLoader above and good luck on your project.

OR13 commented 4 years ago

Also one more thing: have we considered making all of the vocabularies / contexts for the project into one github repo?

I just did this yesterday: https://github.com/decentralized-identity/context

For testing interoperability between DID Methods in the Universal Resolver, and JSON-LD Signatures.

It is crazy hard to make sense of these things without a consolidated and centralized view as the starting point.