npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

credentials-polyfill

v1.1.6

Published

A browser polyfill that provides the Identity Credentials Browser API.

Downloads

12

Readme

Identity Credentials Browser API

A browser polyfill that provides the Identity Credentials Browser API, which supports:

  • Registration of decentralized identifiers (DIDs)
  • Storing credentials
  • Getting credentials

This polyfill works in conjunction with authorization.io. A demo on authorization.io is here.

The API it provides is meant to eventually extend the Credential Management API.

Documentation

This API enables a developer to write Web applications that can create new DIDs for an entity, get credentials, and store credentials through the browser. The API is outlined below, separated by different actors in the system:

APIs called by credential issuers:

  • navigator.credentials.store( credential )

APIs called by credential consumers:

  • navigator.credentials.get( options )

APIs called by credential repository (previously known as identity providers):

  • IdentityCredentialRegistration.register( options )
  • navigator.credentials.getPendingOperation( options )
  • CredentialOperation.complete( result )

Registering a new decentralized identity

The IdentityCredentialRegistration object can be used to register a new decentralized identifier and link it to the entity's credential repository.

The object can be instantiated with the following options:

  • options (required object)
  • repository (string) - A URL identifier for the credential repository (previously known as identity provider) that should be associated with the newly created decentralized identifier.
  • name (string) - a friendly, human-meaningful identifier, such as an email address, that can be shown in UIs to help the user make identity selections.

Once instantiated, the object's register() method can be called. The call returns a Promise that resolves to the document associated with the registered DID.

Example:

var registration = new IdentityCredentialRegistration({
  repository: 'did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1',
  name: '[email protected]'
});

registration.register().then(function(didDocument) {
  // ...
});

The example above will result in an a JSON-LD document that looks like the following:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f",
  "idp": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
  "accessControl": {
    "writePermission": [{
      "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
      "type": "CryptographicKey"
    }, {
      "id": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
      "type": "Identity"
    }]
  },
  "publicKey": [{
    "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
    "type": "CryptographicKey",
    "owner": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\r\nMIIBI...AQAB\r\n-----END PUBLIC KEY-----\r\n"
  }],
  "signature": {
    "type": "LinkedDataSignature2015",
    "created": "2015-07-02T16:54:27Z",
    "creator": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
    "signatureValue": "JukNUu...I0g=="
  }
}

Registering a new public key for an existing decentralized identity

The IdentityCredentialRegistration object can be used to register a new public key on a new device/browser for an existing decentralized identifier, provided that credential repository has sufficient authority to update the entity's decentralized identifier document.

The object should be instantiated using these options:

  • options (required object)
  • repository (string) - A URL identifier for the credential repository (previously known as identity provider) that should be associated with the newly created decentralized identifier.
  • name (string) - a friendly, human-meaningful identifier, such as an email address, that can be shown in UIs to help the user make identity selections.
  • id (string) - the decentralized identifier to use.

Once instantiated, the object's addEventListener( event , listener ) method can be called using registerIdentityCredential for event and a function that will receive a RegisterIdentityCredentialEvent object as a parameter. Once an event listener has been added, a call to register() on the object should be made. Once the user has approved the registration operation, the event listener will be called with a RegisterIdentityCredentialEvent, which includes:

  • publicKey (PublicKey) - An object including owner and publicKeyPem.
  • respondWith( Promise identity ) - Called from an event listener to respond with the registered identity information.

The register() call returns a Promise that resolves to the document associated with the registered DID.

Example:

var registration = new IdentityCredentialRegistration({
  repository: 'did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1',
  name: '[email protected]'
});

registration.addEventListener('registerIdentityCredential', function(event) {
  var publicKey = event.publicKey;

  // async register public key with `publicKey.owner`'s' DID document;
  // response returns public key with its new ID
  event.respondWith($http.post('/some-register-endpoint', publicKey)
    .then(function(response) {
      return {
        '@context': 'https://w3id.org/identity/v1',
        id: publicKey.owner,
        publicKey: response.data
      };
    }));
});

registration.register().then(function(didDocument) {
  // ...
}).catch(function(err) {
  // ... handle error case
})

The example above will result in an a JSON-LD document that looks like the following:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f",
  "idp": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
  "accessControl": {
    "writePermission": [{
      "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
      "type": "CryptographicKey"
    }, {
      "id": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
      "type": "Identity"
    }]
  },
  "publicKey": [{
    "id": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
    "type": "CryptographicKey",
    "owner": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\r\nMIIBI...AQAB\r\n-----END PUBLIC KEY-----\r\n"
  }],
  "signature": {
    "type": "LinkedDataSignature2015",
    "created": "2015-07-02T16:54:27Z",
    "creator": "did:59cf8ba9-70f6-456e-aa7f-6e898c3a3e5f/keys/1",
    "signatureValue": "JukNUu...I0g=="
  }
}

Storing a Credential

The navigator.credentials.store( credential ) call can be used to store a set of attributes about an entity, backed by credentials, at an entity's credential repository.

The call takes the following arguments:

  • credential (required IdentityCredential) - An IdentityCredential containing a JSON-LD document that contains at least one valid credential entry.

The call returns a Promise that resolves to an IdentityCredential containing a JSON-LD document that contains the credentials that were stored.

navigator.credentials.store(new IdentityCredential({
  "@context": "https://w3id.org/identity/v1",
  "id": "did:04054703-8c94-46a3-bae7-7ffd07c0c962",
  "credential": [{
    "@graph": {
      "@context": "https://w3id.org/identity/v1",
      "id": "https://issuer.example.com/creds/1",
      "type": ["Credential", "EmailCredential"],
      "claim": {
        "id": "did:04054703-8c94-46a3-bae7-7ffd07c0c962",
        "email": "[email protected]"
      },
      "signature": {
        "type": "LinkedDataSignature2015",
        "created": "2015-07-02T17:41:39Z",
        "creator": "https://issuer.example.com/keys/1",
        "signatureValue": "Tyd5S0A...nx33Yg=="
      }
    }
  }]
})).then(function(credential) {
  // ...
});

The example above will result in an IdentityCredential containing a JSON-LD document that looks like the one that was passed via the credential parameter. Optionally, the recipient of the credentials may choose to not store some of the credentials and can notify the issuer that those credentials were not stored by omitting them from the response.

Getting a Credential

The navigator.credentials.get( options ) call can be used to request a set of properties about an entity that are backed by credentials from an entity's credential repository.

The call takes the following arguments:

  • options (required object)
  • identity (required object)
    • query (required object) - A JSON-LD document that is a "query by example". The query consists of the attributes associated with an entity that the credential consumer would like to see.

The call returns a Promise that resolves to an IdentityCredential containing a JSON-LD document that contains the credentials that were retrieved.

navigator.credentials.get({
  identity: {
    query: {
      '@context': 'https://w3id.org/identity/v1',
      id: '',
      email: ''
    }
  }
}).then(function(credential) {
  if(credential === null) {
    // no credential found/selected
    // ...
  }
  // get JSON-LD identity document from credential
  var identity = credential.identity;
  // ...
});

The example above will eventually result in the following JSON-LD document:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "did:04054703-8c94-46a3-bae7-7ffd07c0c962",
  "type": "Identity",
  "credential": [{
    "@graph": {
      "@context": "https://w3id.org/identity/v1",
      "id": "urn:credential-1",
      "type": ["Credential", "CryptographicKeyCredential"],
      "claim": {
        "id": "did:04054703-8c94-46a3-bae7-7ffd07c0c962",
        "email": "[email protected]",
        "publicKey": {
          "id": "did:04054703-8c94-46a3-bae7-7ffd07c0c962/keys/1",
          "publicKeyPem": "-----BEGIN PUBLIC KEY-----\r\nMIIBIj...IDAQAB\r\n-----END PUBLIC KEY-----\r\n"
        }
      },
      "signature": {
        "type": "LinkedDataSignature2015",
        "created": "2015-07-02T17:45:21Z",
        "creator": "https://authorization.dev:33443/idp/keys/1",
        "signatureValue": "S33Qcs...zWDqQQ=="
      }
    }
  }],
  "signature": {
    "type": "LinkedDataSignature2015",
    "created": "2015-07-02T17:46:04Z",
    "creator": "did:04054703-8c94-46a3-bae7-7ffd07c0c962/keys/1",
    "signatureValue": "LpoVj...LP2A=="
  }
}

Getting a Pending Credential Operation

The getPendingOperation method is only used by credential repositories to complete a pending get or store credentials operation once authorization has been provided by the entity.

The call takes no arguments. It returns a Promise that resolves to a CredentialOperation. A CredentialOperation has the following properties:

  • name (string) - The name of the pending operation (ie: get or store).
  • options (object)
  • query (object) - Present if the operation name is get. The query passed to navigator.credentials.get.
  • store (object) - Present if operation name is store. Contains the identity document contained in the IdentityCredential passed to navigator.credentials.store.
  • identity (object) - The entity's signed identity for the device they are using, including a CryptographicKeyCredential.
  • registerKey (boolean) - True if an attempt should be made to register the entity's public key (provided in the CryptographicKeyCredential) with its decentralized identity. This will only be possible if the entity has granted permission to their identity provider to write new keys to their decentralized identity.

The credential repository can now help the entity to fulfill the credentials query or ask it to accept the storage request. Once the credential repository has completed the operation, it must call complete on the CredentialOperation instance, passing the result of the operation. This call will cause the browser to navigate away from the credential repository with the result.

**Note: getPendingOperation may be changed to use MessageChannels. **

navigator.credentials.getPendingOperation().then(function(operation) {
  // ...

  // operation now complete
  operation.complete(result);
});

Source

The source code for the JavaScript implementation is available at:

https://github.com/digitalbazaar/credentials-polyfill