nz-covid-pass-verifier
Version:
TypeScript implementation of [NZ COVID Pass - Technical Specification v1](https://nzcp.covid19.health.nz/).
71 lines • 5.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Verifier = void 0;
const cbor = require("cbor");
const resolvePublicKey_1 = require("./resolvePublicKey");
const parseURI_1 = require("./parseURI");
const toJwt_1 = require("./toJwt");
const verifySignature_1 = require("./verifySignature");
const requiredClaims = ["iss", "nbf", "exp", "vc"];
const headers = { alg: 1, kid: 4 };
function validJwt(jwt) {
const keys = Object.keys(jwt);
if (!requiredClaims.every((c) => keys.includes(c))) {
return false;
}
if (jwt.exp < Math.floor(Date.now() / 1000)) {
return false;
}
if (jwt.nbf > Math.floor(Date.now() / 1000)) {
return false;
}
return true;
}
class Verifier {
constructor(options) {
var _a;
this.trustedIssuers = (_a = options === null || options === void 0 ? void 0 : options.trustedIssuers) !== null && _a !== void 0 ? _a : [
"did:web:nzcp.identity.health.nz",
];
}
isTrusted(iss) {
return this.trustedIssuers.includes(iss);
}
verify(message) {
return __awaiter(this, void 0, void 0, function* () {
const decodedPayload = (0, parseURI_1.parseURI)(message);
if (!decodedPayload) {
return undefined;
}
const coseSign1 = yield cbor.decodeFirst(decodedPayload);
if (!(coseSign1 instanceof cbor.Tagged) && coseSign1.tag !== 18) {
return undefined;
}
const header = yield cbor.decodeFirst(coseSign1.value[0]);
const cwt = yield cbor.decodeFirst(coseSign1.value[2]);
const jwt = (0, toJwt_1.toJwt)(cwt);
if (!this.isTrusted(jwt.iss) || !validJwt(jwt)) {
return undefined;
}
const key = yield (0, resolvePublicKey_1.resolvePublicKey)(`${jwt.iss}#${header.get(headers.kid)}`);
if (!key) {
return undefined;
}
if (!(yield (0, verifySignature_1.verifySignature)(decodedPayload, key))) {
return undefined;
}
return jwt;
});
}
}
exports.Verifier = Verifier;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsNkJBQThCO0FBRTlCLHlEQUFzRDtBQUN0RCx5Q0FBc0M7QUFFdEMsbUNBQWdDO0FBQ2hDLHVEQUFvRDtBQUVwRCxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ25ELE1BQU0sT0FBTyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFFbkMsU0FBUyxRQUFRLENBQUMsR0FBUTtJQUN0QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTlCLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDaEQsT0FBTyxLQUFLLENBQUM7S0FDaEI7SUFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUU7UUFDekMsT0FBTyxLQUFLLENBQUM7S0FDaEI7SUFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUU7UUFDekMsT0FBTyxLQUFLLENBQUM7S0FDaEI7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUQsTUFBYSxRQUFRO0lBR2pCLFlBQVksT0FBeUI7O1FBQ2pDLElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsY0FBYyxtQ0FBSTtZQUM3QyxpQ0FBaUM7U0FDcEMsQ0FBQztJQUNOLENBQUM7SUFFRCxTQUFTLENBQUMsR0FBVztRQUNqQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFWSxNQUFNLENBQUMsT0FBZTs7WUFDL0IsTUFBTSxjQUFjLEdBQUcsSUFBQSxtQkFBUSxFQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQ2pCLE9BQU8sU0FBUyxDQUFDO2FBQ3BCO1lBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxDQUFDLFNBQVMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksU0FBUyxDQUFDLEdBQUcsS0FBSyxFQUFFLEVBQUU7Z0JBQzdELE9BQU8sU0FBUyxDQUFDO2FBQ3BCO1lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sR0FBRyxHQUFHLElBQUEsYUFBSyxFQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXZCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDNUMsT0FBTyxTQUFTLENBQUM7YUFDcEI7WUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUEsbUNBQWdCLEVBQzlCLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUMxQyxDQUFDO1lBQ0YsSUFBSSxDQUFDLEdBQUcsRUFBRTtnQkFDTixPQUFPLFNBQVMsQ0FBQzthQUNwQjtZQUVELElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBQSxpQ0FBZSxFQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFO2dCQUMvQyxPQUFPLFNBQVMsQ0FBQzthQUNwQjtZQUVELE9BQU8sR0FBRyxDQUFDO1FBQ2YsQ0FBQztLQUFBO0NBQ0o7QUE3Q0QsNEJBNkNDIn0=