Skip to content
/ nzcp-js Public

A verification library for COVID-19 Vaccine Passes in New Zealand

License

Notifications You must be signed in to change notification settings

haxxnz/nzcp-js

Repository files navigation

NZCP.js   latest version badge license badge downloads badge

A JavaScript implementation of NZ COVID Pass verification, New Zealand's proof of COVID-19 vaccination solution, written in TypeScript. All contributions welcome 🥳

We also have a Rust implementation available.

This library can be used for both in browser and Node.js.

Install

# NPM
npm i @vaxxnz/nzcp

# Yarn
yarn add @vaxxnz/nzcp

Projects

This library is current used in

  • Vaxxed.as An offline NZ COVID Pass verifier by @rafcontreras
  • Hello Club A club and member management platform with self verification of vaccination status

Demo

Usage

Online

import { verifyPassURI } from "@vaxxnz/nzcp";

// Verify a live New Zealand COVID-19 Pass, resolving the DID document
const result = await verifyPassURI("NZCP:/1/2KCEVIQEIVVWK6...");

Offline

import { verifyPassURIOffline } from "@vaxxnz/nzcp";

// Verify a live New Zealand COVID-19 Pass, using a prefetched DID document
const result = verifyPassURIOffline("NZCP:/1/2KCEVIQEIVVWK6...");

Successful Verification

On successful verification of the given pass, the verifyPassURI method returns the following result:

{
  "success": true,                       // Verification Outcome
  "violates": null,                      // Error object if code is invalid
  "expires": 2031-11-02T20:05:30.000Z,   // Expiration date
  "validFrom": 2021-11-02T20:05:30.000Z, // Date when pass becomes valid
  "credentialSubject": {                 // Pass holder's details
    "givenName": "Emily",                // Pass holder's given name
    "familyName": "Example",             // Pass holder's family name
    "dob": "1970-01-01"                  // Pass holder's date of birth
  },           
  "raw": {                               // raw data returned by CWTClaims
    "jti": "urn:uuid:...",
    "iss": "did:web:nzcp.identity.health.nz",
    "nbf": 1635883530,
    "exp": 1951416330,
    "vc": {
      '@context': [ ... ],
      "version": '1.0.0',
      "type": [ ... ],
      "credentialSubject": { ... }
    }
  }
}

Unsuccessful Verification

On unsuccessful verification of the given pass, the verifyPassURI method returns the following result:

{
  "success": false,           // Verification Outcome
  "violates": {               // Error information
    "message": "Error..",     // Friendly Error Message
    "section": "0.0",         // Section of official specs under violation
    "link": "https://..",     // Link to specifications breached
    "description": "The QR.." // Simplified error message
  },
  "expires": null,            // Nothing due to error
  "validFrom": null,          // Nothing due to error
  "credentialSubject": null   // No pass holder data due to error
  "raw": null                 // No raw data due to error
}

Advanced Usage

These examples show how to configure the library to supply your own trusted issuers or DID documents. This will allow you to use the library with the example COVID Passes from the spec.

The following example shows how to use the example trusted issuer for online verification:

import { verifyPassURI, TRUSTED_ISSUERS } from "@vaxxnz/nzcp";

// Trusted issuer for the example COVID Passes
// "did:web:nzcp.covid19.health.nz"
const exampleTrustedIssuer = TRUSTED_ISSUERS.MOH_EXAMPLE;

// Alternatively you could supply a trusted issuer for live COVID Passes
// If you omit the trusted issuer, the library will use the live DID document
// "did:web:nzcp.identity.health.nz"
const liveTrustedIssuer = TRUSTED_ISSUERS.MOH_LIVE;

const result = await verifyPassURI(
  "NZCP:/1/2KCEVIQEIVVWK6...",            // COVID-19 Pass to be verified
  { trustedIssuer: exampleTrustedIssuer } // Supply your own trusted issuer to overwrite the default
);

The following example shows how use the example DID document for offline verification:

import { verifyPassURIOffline, DID_DOCUMENTS } from "@vaxxnz/nzcp";

// DID Document for the example COVID Passes
// Prefetched version of https://nzcp.covid19.health.nz/.well-known/did.json
const exampleDIDDocument = DID_DOCUMENTS.MOH_EXAMPLE;

// Alternatively you could supply a DID document for live COVID Passes
// If you omit the DID Document, the library will use the live DID document
// Prefetched version of https://nzcp.identity.health.nz/.well-known/did.json
const liveTrustedIssuer = DID_DOCUMENTS.MOH_LIVE;

const result = verifyPassURIOffline(
  "NZCP:/1/2KCEVIQEIVVWK6...",          // COVID-19 Pass to be verified
  { didDocument: exampleDIDDocument }   // Supply your own DID document to overwrite the default
);

Online VS Offline

Currently for a Node.js/React Native project we recomend using verifyPassURI and for a browser based application to use verifyPassURIOffline.

The difference between the verifyPassURI and verifyPassURIOffline interfaces is:

There is a CORS policy on https://nzcp.identity.health.nz/.well-known/did.json which makes it currently unable to be fetched from the browser. The only option for browser based verifiers is currently to use the verifyPassURIOffline function. The Ministry Of Health is aware of this issue and is working to resolve it.

Offline scanners or scanners opperating in poor network conditions will also need to use verifyPassURIOffline. Since verifyPassURI requires an Internet connection to resolve the DID document.

NZCP.js has decided to support both use cases but which one to use is a decision that the user of this library is in the best position to make. If you have a network connection and want to be completely correct (and to specification) use verifyPassURI. If you want speed, don't have a network connection or don't mind using a prefetched DID document, use verifyPassURIOffline.

If you want to supply your own trusted issuer or DID document parameters, you can follow the Advanced Usage guide above.

React Native

The library runs well with a few polyfills. An example of which polyfills you might have to set up can be found here.

Support

See something that can be improved? Report an Issue or contact us to report a security concern.

Want to help us build a better library? We welcome contributions via pull requests and welcome you to our wider Vaxx.nz community on Discord: Join our Discord community.


NPM

@vaxxnz/nzcp

Contribute

# Install dependencies
yarn install
# Use developer scripts
yarn lint
yarn build-all

Run tests

  • Create .env in the root directory of the project
    • see .env.example for an example.
  • Run yarn test or yarn test-watch