Last active
January 31, 2021 01:57
-
-
Save AdamJLemmon/1db9316c9b9f04c4b9aa669de96ecaac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dependencies | |
const axios = require('axios') | |
const jp = require('jsonpath') | |
// Environment Variables | |
const API_URL = process.env.API_URL || 'http://localhost:3002' | |
const VCX_API_KEY = process.env.VCX_API_KEY || '42d34daf-29fc-4703-b52c-82c69f4e1a58' | |
const ORG_ID = process.env.ORG_ID || '60160d896915b96d1f50c9c2' | |
// API authZ | |
const orgId = ORG_ID | |
const headers = { | |
'vcx-api-key': VCX_API_KEY | |
} | |
// Credential data | |
// Patient - "required": ["resourceType", "extension", "identifier", "name", "gender", "birthDate"], | |
const Patient = { | |
resourceType: "Patient", | |
extension: [{ | |
url: "http://hl7.org/fhir/StructureDefinition/patient-nationality", | |
code: { "text": "SG" } | |
}], | |
identifier: [{ | |
type: { "text": "NRIC" }, | |
value: "S9098989Z" | |
},{ | |
type: "PPN", | |
value: "HN1234" | |
}], | |
name: [{ | |
text: "Tan Chen Chen" | |
}], | |
gender: "female", | |
birthDate: "1990-01-15" | |
} | |
// Specimen - "required": ["resourceType", "type", "collection"], | |
const Specimen = { | |
resourceType: "Specimen", | |
type: { | |
coding: [{ | |
system: "http://snomed.info/sct", | |
code: "258500001", | |
display: "Nasopharyngeal swab" | |
}] | |
}, | |
collection: { | |
collectedDateTime: "2020-09-27T06:15:00Z" | |
} | |
} | |
// Observation - "required": [ "resourceType", "identifier", "code", "valueCodeableConcept", "effectiveDateTime", "qualification", "status" ], | |
const Observation = { | |
"resourceType": "Observation", | |
"identifier": [{ | |
"value": "123456789", | |
"type": "ACSN" | |
}], | |
"code": { | |
"coding": [{ | |
"system": "http://loinc.org", | |
"code": "94531-1", | |
"display": "Reverse transcription polymerase chain reaction (rRT-PCR) test" | |
}] | |
}, | |
"valueCodeableConcept": { | |
"coding": [{ | |
"system": "http://snomed.info/sct", | |
"code": "260385009", | |
"display": "Negative" | |
}] | |
}, | |
"effectiveDateTime": "2020-09-28T06:15:00Z", | |
"status": "final", | |
"performer": { | |
"name": [{ | |
"text": "Dr Michael Lim" | |
}] | |
}, | |
"qualification": [{ | |
"identifier": "MCR 123214", | |
"issuer": "MOH" | |
}] | |
} | |
// Organization - "required": ["resourceType", "name", "type", "contact"], | |
// Organization: Healtcare Provider | |
const Organization1 = { | |
"resourceType": "Organization", | |
"name": "MacRitchie Medical Clinic", | |
"type": "Licensed Healthcare Provider", | |
"contact": { | |
"telecom": [{ | |
"system": "phone", | |
"value": "+6563113111" | |
}], | |
"address": { | |
"type": "physical", | |
"use": "work", | |
"text": "MacRitchie Hospital Thomson Road Singapore 123000" | |
} | |
} | |
} | |
// Organization: Quest | |
const Organization2 = { | |
"resourceType": "Organization", | |
"name": "Quest Laboratories", | |
"type": "Accredited Laboratory", | |
"id": "quest-labs-0163", | |
"contact": { | |
"telecom": [{ | |
"system": "phone", | |
"value": "+6563113111" | |
}], | |
"address": { | |
"type": "physical", | |
"use": "work", | |
"text": "Quest Laboratories Address" | |
}, | |
} | |
} | |
// Package it all up into the credential | |
const credential = { | |
"type": [ "VerifiableCredential", "HealthPassportBundleCredentialV1" ], | |
credentialSubject: { | |
data: { | |
// "required": ["id", "name", "validFrom", "fhirVersion", "fhirBundle"] | |
'@type': 'BundleContainer', | |
id: 'Unique test ID', | |
name: 'HealthCert', | |
validFrom: new Date().toISOString(), | |
fhirVersion: '4.0.1', | |
fhirBundle: { | |
'@type': 'Bundle', | |
resourceType: 'Bundle', | |
type: 'collection', | |
entry: [ Patient, Specimen, Observation, Organization1, Organization2 ], | |
}, | |
}, | |
}, | |
} | |
/** | |
* Complete flow to issue a HealthCerts Verifiable Credential | |
*/ | |
const issueCredential = async ({ orgId, credential, options }) => { | |
const body = { credential, options, orgId } | |
const url = `${API_URL}/provider/issueCustomCredential` | |
const response = await axios.post(url, body, { headers }) | |
return response.data; | |
} | |
const getIssuedCredentials = async ({ orgId, query }) => { | |
const searchParams = new URLSearchParams({ orgId, ...query }) | |
const url = `${API_URL}/provider/getIssuedCredentials?${searchParams.toString()}` | |
const response = await axios.get(url, { headers }) | |
return response.data; | |
} | |
const run = async () => { | |
/** | |
* Will return: | |
* 1. Credential download URL, also sent in SMS (protected by pasport number) | |
* 2. QR Code access URL, also sent in SMS (protected by pasport number) | |
* 3. QR Code base64 raw data (to be included on PDF) | |
*/ | |
const options = { | |
responseType: [ | |
'walletInstallAndCredentialDownloadUrl', | |
'encryptedCredentialPresentationProtectedQrCodeUrl', | |
'encryptedCredentialPresentationQrCode' | |
], | |
indexes: [{ | |
property: 'labNumber', | |
path: '$.credentialSubject.data.fhirBundle.entry[4].id' | |
}, { | |
property: 'ppn', | |
path: '$.credentialSubject.data.fhirBundle.entry[0].identifier[1].value' | |
}], | |
requiredUserAuthentication: [{ | |
property: 'ppn', | |
name: 'Passport Number', | |
description: 'Passport Number.', | |
acceptedValues: ['1234'], | |
reason: 'authentication' | |
}], | |
holderContactDetails: { | |
firstName: 'Adam', | |
type: 'sms', | |
to: '+16472399319' | |
}, | |
} | |
const response = await issueCredential({ orgId, credential, options }) | |
console.log({ response }) | |
// Now confirm you can get the response later with the indexes | |
const labNumber = jp.query(credential, options.indexes[0].path, 1)[0] | |
const ppn = jp.query(credential, options.indexes[1].path, 1)[0] | |
const query = { labNumber, ppn } | |
const { savedCredentials } = await getIssuedCredentials({ orgId, query }) | |
console.log({ response: savedCredentials[0].response }) | |
} | |
run() | |
// VCX_API_KEY=663b4151-2b80-4d46-80c2-c9ae3728a134 ORG_ID=5fc7d717da620b611af5de4f node apiProviderHealthCert.js |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment