From 32ea1edbae1176ec0e34c0999370686a692093b1 Mon Sep 17 00:00:00 2001 From: Billy Lo Date: Fri, 1 Oct 2021 03:23:02 -0400 Subject: [PATCH] pre-merge with main updates --- components/Form.tsx | 34 ++++++++++++--- src/decode.ts | 24 ++++++++--- src/pass.ts | 2 +- src/passphoto-common.ts | 96 +++++++++++++++++++++-------------------- src/photo.ts | 5 +-- 5 files changed, 96 insertions(+), 65 deletions(-) diff --git a/components/Form.tsx b/components/Form.tsx index 21b170a..fca7507 100644 --- a/components/Form.tsx +++ b/components/Form.tsx @@ -255,9 +255,18 @@ function Form(): JSX.Element { try { if (payloadBody) { - const passName = payloadBody.receipts[selectedDose].name.replace(' ', '-'); - const vaxName = payloadBody.receipts[selectedDose].vaccineName.replace(' ', '-'); - const passDose = payloadBody.receipts[selectedDose].numDoses; + + let selectedReceipt; + if (payloadBody.rawData.length > 0) { // shc stuff + const sortedKeys = Object.keys(payloadBody.receipts).sort(); // pickup the last key in the receipt table + const lastKey = sortedKeys[sortedKeys.length - 1]; + selectedReceipt = payloadBody.receipts[lastKey]; + } else { + selectedReceipt = payloadBody.receipts[selectedDose]; + } + const passName = selectedReceipt.name.replace(' ', '-'); + const vaxName = selectedReceipt.vaccineName.replace(' ', '-'); + const passDose = selectedReceipt.numDoses; const covidPassFilename = `grassroots-receipt-${passName}-${vaxName}-${passDose}.pkpass`; //console.log('> increment count'); @@ -310,13 +319,24 @@ function Form(): JSX.Element { } try { - const passName = payloadBody.receipts[selectedDose].name.replace(' ', '-'); - const vaxName = payloadBody.receipts[selectedDose].vaccineName.replace(' ', '-'); - const passDose = payloadBody.receipts[selectedDose].numDoses; + + let selectedReceipt; + if (payloadBody.rawData.length > 0) { // shc stuff + const sortedKeys = Object.keys(payloadBody.receipts).sort(); // pickup the last key in the receipt table + const lastKey = sortedKeys[sortedKeys.length - 1]; + selectedReceipt = payloadBody.receipts[lastKey]; + setSelectedDose(Number(lastKey)); + } else { + selectedReceipt = payloadBody.receipts[selectedDose]; + } + const passName = selectedReceipt.name.replace(' ', '-'); + const vaxName = selectedReceipt.vaccineName.replace(' ', '-'); + const passDose = selectedReceipt.numDoses; const covidPassFilename = `grassroots-receipt-${passName}-${vaxName}-${passDose}.png`; await incrementCount(); - let photoBlob = await Photo.generatePass(payloadBody, selectedDose); + + let photoBlob = await Photo.generatePass(payloadBody, passDose); saveAs(photoBlob, covidPassFilename); // need to clean up diff --git a/src/decode.ts b/src/decode.ts index e9cdb01..8d3db84 100644 --- a/src/decode.ts +++ b/src/decode.ts @@ -20,10 +20,17 @@ export function getQRFromImage(imageData) { export function decodedStringToReceipt(decoded: object) : HashTable { const codeToVaccineName = { - '28581000087106': 'Pfizer-BioNTech', - '28951000087107': 'Johnson & Johnson / Janssen', - '28761000087108': 'AstraZeneca', - '28571000087109': 'Moderna' + '28581000087106': 'PFIZER', + '28951000087107': 'JANSSEN', + '28761000087108': 'ASTRAZENECA', + '28571000087109': 'MODERNA' + } + + const cvxCodeToVaccineName = { // https://www2a.cdc.gov/vaccines/iis/iisstandards/vaccines.asp?rpt=cvx + '208': 'PFIZER', + '212': 'JANSSEN', + '210': 'ASTRAZENECA', + '207': 'MODERNA' } console.log(decoded); @@ -35,7 +42,7 @@ export function decodedStringToReceipt(decoded: object) : HashTable { if (decoded['iss'].includes('ontariohealth.ca')) { issuer = 'on'; } - if (decoded['iss'].includes('bchealth.ca')) { + if (decoded['iss'] == "https://smarthealthcard.phsa.ca/v1/issuer") { issuer = 'bc'; } @@ -62,12 +69,15 @@ export function decodedStringToReceipt(decoded: object) : HashTable { let vaccineName : string; let organizationName : string; let vaccinationDate : string; - for (const vaccineCodes of resource.vaccineCode.coding) { - if (vaccineCodes.system.includes("snomed.info")) { + if (vaccineCodes.system.includes("snomed.info")) { //bc vaccineName = codeToVaccineName[vaccineCodes.code]; if (vaccineName == undefined) vaccineName = 'Unknown - ' + vaccineCodes.code; + } else if (vaccineCodes.system == "http://hl7.org/fhir/sid/cvx") { //qc + vaccineName = cvxCodeToVaccineName[vaccineCodes.code]; + if (vaccineName == undefined) + vaccineName = 'Unknown - ' + vaccineCodes.code; } } diff --git a/src/pass.ts b/src/pass.ts index 4b48e46..5397e72 100644 --- a/src/pass.ts +++ b/src/pass.ts @@ -72,8 +72,8 @@ export class PassData { const results = await PassPhotoCommon.preparePayload(payloadBody, numDose); const payload = results.payload; - // Create pass data + const pass: PassData = new PassData(results.payload, results.qrCode); // Create new zip diff --git a/src/passphoto-common.ts b/src/passphoto-common.ts index b2fce1b..dd020dd 100644 --- a/src/passphoto-common.ts +++ b/src/passphoto-common.ts @@ -36,57 +36,61 @@ export class PassPhotoCommon { const payload: Payload = new Payload(payloadBody, numDose); payload.serialNumber = uuid4(); + let qrCodeMessage; - // register record + if (payloadBody.rawData.startsWith('shc:/')) { + + qrCodeMessage = payloadBody.rawData; - const clonedReceipt = Object.assign({}, payloadBody.receipts[numDose]); - delete clonedReceipt.name; - delete clonedReceipt.dateOfBirth; - clonedReceipt["serialNumber"] = payload.serialNumber; - clonedReceipt["type"] = 'applewallet'; + } else { + + // register record - let requestOptions = { - method: 'POST', // *GET, POST, PUT, DELETE, etc. - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(clonedReceipt) // body data type must match "Content-Type" header + const clonedReceipt = Object.assign({}, payloadBody.receipts[numDose]); + delete clonedReceipt.name; + delete clonedReceipt.dateOfBirth; + clonedReceipt["serialNumber"] = payload.serialNumber; + clonedReceipt["type"] = 'applewallet'; + + let requestOptions = { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(clonedReceipt) // body data type must match "Content-Type" header + } + + console.log('registering ' + JSON.stringify(clonedReceipt, null, 2)); + const configResponse = await fetch('/api/config'); + + const configResponseJson = await configResponse.json(); + + const verifierHost = configResponseJson.verifierHost; + const registrationHost = configResponseJson.registrationHost; + let functionSuffix = configResponseJson.functionSuffix; + + if (functionSuffix == undefined) + functionSuffix = ''; + + const registerUrl = `${registrationHost}/register${functionSuffix}`; + // console.log(registerUrl); + + const response = await fetch(registerUrl, requestOptions); + const responseJson = await response.json(); + + console.log(JSON.stringify(responseJson,null,2)); + + if (responseJson["result"] != 'OK') { + console.error(responseJson); + return Promise.reject(); + } + + const encodedUri = `serialNumber=${encodeURIComponent(payload.serialNumber)}&vaccineName=${encodeURIComponent(payloadBody.receipts[numDose].vaccineName)}&vaccinationDate=${encodeURIComponent(payloadBody.receipts[numDose].vaccinationDate)}&organization=${encodeURIComponent(payloadBody.receipts[numDose].organization)}&dose=${encodeURIComponent(payloadBody.receipts[numDose].numDoses)}`; + const qrCodeUrl = `${verifierHost}/verify?${encodedUri}`; + qrCodeMessage = qrCodeUrl; + // console.log(qrCodeUrl); } - console.log('registering ' + JSON.stringify(clonedReceipt, null, 2)); - const configResponse = await fetch('/api/config'); - - const configResponseJson = await configResponse.json(); - - const verifierHost = configResponseJson.verifierHost; - const registrationHost = configResponseJson.registrationHost; - let functionSuffix = configResponseJson.functionSuffix; - - if (functionSuffix == undefined) - functionSuffix = ''; - - const registerUrl = `${registrationHost}/register${functionSuffix}`; - // console.log(registerUrl); - - const response = await fetch(registerUrl, requestOptions); - const responseJson = await response.json(); - - console.log(JSON.stringify(responseJson,null,2)); - - if (responseJson["result"] != 'OK') { - console.error(responseJson); - return Promise.reject(); - } - - const encodedUri = `serialNumber=${encodeURIComponent(payload.serialNumber)}&vaccineName=${encodeURIComponent(payloadBody.receipts[numDose].vaccineName)}&vaccinationDate=${encodeURIComponent(payloadBody.receipts[numDose].vaccinationDate)}&organization=${encodeURIComponent(payloadBody.receipts[numDose].organization)}&dose=${encodeURIComponent(payloadBody.receipts[numDose].numDoses)}`; - const qrCodeUrl = `${verifierHost}/verify?${encodedUri}`; - - // console.log(qrCodeUrl); - - let qrCodeMessage = payloadBody.rawData.startsWith('shc:/') - ? payloadBody.rawData - : qrCodeUrl; - // Create QR Code Object const qrCode: QrCode = { message: qrCodeMessage, diff --git a/src/photo.ts b/src/photo.ts index 24fb66b..259eb1e 100644 --- a/src/photo.ts +++ b/src/photo.ts @@ -23,16 +23,13 @@ export class Photo { // Create Payload try { - console.log('generatePass'); - const results = await PassPhotoCommon.preparePayload(payloadBody, numDose); const payload = results.payload; const qrCode = results.qrCode; let receipt; - if (results.payload.rawData.length == 0) { receipt = results.payload.receipts[numDose]; } else { @@ -68,7 +65,7 @@ export class Photo { } const codeWriter = new BrowserQRCodeSvgWriter(); - const hints : Map = new Map().set(EncodeHintType.ERROR_CORRECTION,'M'); + const hints : Map = new Map().set(EncodeHintType.ERROR_CORRECTION,'L'); const svg = codeWriter.write(qrCode.message,200,200, hints); svg.setAttribute('style','background-color: white'); document.getElementById('qrcode').appendChild(svg);