Merge pull request #28 from tvalenta1/shc-support
SHC - Smart Health Card support. Parse QR code from PNG image and par…
This commit is contained in:
commit
db5052aa9a
|
@ -330,7 +330,7 @@ function Form(): JSX.Element {
|
||||||
|
|
||||||
<input type='file'
|
<input type='file'
|
||||||
id='file'
|
id='file'
|
||||||
accept="application/pdf"
|
accept="application/pdf,image/png"
|
||||||
ref={inputFile}
|
ref={inputFile}
|
||||||
style={{display: 'none'}}
|
style={{display: 'none'}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/pako": "^1.0.1",
|
"@types/pako": "^1.0.1",
|
||||||
|
"@types/pngjs": "^6.0.1",
|
||||||
"@types/react": "^17.0.11",
|
"@types/react": "^17.0.11",
|
||||||
"autoprefixer": "^10.0.4",
|
"autoprefixer": "^10.0.4",
|
||||||
"postcss": "^8.1.10",
|
"postcss": "^8.1.10",
|
||||||
|
|
|
@ -118,9 +118,13 @@ export class PassData {
|
||||||
if (responseJson["result"] != 'OK')
|
if (responseJson["result"] != 'OK')
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
|
|
||||||
|
let qrCodeMessage = payloadBody.rawData.startsWith('shc:/')
|
||||||
|
? payloadBody.rawData
|
||||||
|
: `${verifierHost}/verify?serialNumber=${payload.serialNumber}&vaccineName=${payload.receipts[0].vaccineName}&vaccinationDate=${payload.receipts[0].vaccinationDate}&organization=${payload.receipts[0].organization}&dose=${payload.receipts[0].numDoses}`;
|
||||||
|
|
||||||
// Create QR Code Object
|
// Create QR Code Object
|
||||||
const qrCode: QrCode = {
|
const qrCode: QrCode = {
|
||||||
message: `${verifierHost}/verify?serialNumber=${payload.serialNumber}&vaccineName=${payload.receipts[0].vaccineName}&vaccinationDate=${payload.receipts[0].vaccinationDate}&organization=${payload.receipts[0].organization}&dose=${payload.receipts[0].numDoses}`,
|
message: qrCodeMessage,
|
||||||
format: QrFormat.PKBarcodeFormatQR,
|
format: QrFormat.PKBarcodeFormatQR,
|
||||||
messageEncoding: Encoding.iso88591,
|
messageEncoding: Encoding.iso88591,
|
||||||
// altText : payload.rawData
|
// altText : payload.rawData
|
||||||
|
|
|
@ -4,6 +4,7 @@ import jsQR, {QRCode} from "jsqr";
|
||||||
import { getCertificatesInfoFromPDF } from "@ninja-labs/verify-pdf"; // ES6
|
import { getCertificatesInfoFromPDF } from "@ninja-labs/verify-pdf"; // ES6
|
||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import * as Decode from './decode';
|
import * as Decode from './decode';
|
||||||
|
import { PNG } from 'pngjs/browser';
|
||||||
|
|
||||||
import { PDFPageProxy, TextContent, TextItem } from "pdfjs-dist/types/display/api";
|
import { PDFPageProxy, TextContent, TextItem } from "pdfjs-dist/types/display/api";
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ export async function getPayloadBodyFromFile(file: File): Promise<PayloadBody> {
|
||||||
switch (file.type) {
|
switch (file.type) {
|
||||||
case 'application/pdf':
|
case 'application/pdf':
|
||||||
return detectPDFTypeAndProcess(fileBuffer)
|
return detectPDFTypeAndProcess(fileBuffer)
|
||||||
|
case 'image/png':
|
||||||
|
return processBCPNG(fileBuffer);
|
||||||
default:
|
default:
|
||||||
throw Error('invalidFileType')
|
throw Error('invalidFileType')
|
||||||
}
|
}
|
||||||
|
@ -103,6 +106,34 @@ async function processBC(pdfPage: PDFPageProxy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function processBCPNG(fileBuffer : ArrayBuffer): Promise<any> {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
new PNG({ filterType: 4 }).parse(fileBuffer, async function (error, data) {
|
||||||
|
const scannedQR = jsQR(new Uint8ClampedArray(data.data.buffer), data.width, data.height)
|
||||||
|
if (scannedQR) {
|
||||||
|
//console.log(scannedQR.data);
|
||||||
|
let jws = Decode.getScannedJWS(scannedQR.data);
|
||||||
|
// const verified = Decode.verifyJWS(jws);
|
||||||
|
const verified = true;
|
||||||
|
|
||||||
|
if (verified) {
|
||||||
|
let decoded = await Decode.decodeJWS(jws);
|
||||||
|
//console.log(decoded);
|
||||||
|
let receipts = Decode.decodedStringToReceipt(decoded);
|
||||||
|
//console.log(receipts);
|
||||||
|
resolve({receipts: receipts, rawData: scannedQR.data});
|
||||||
|
} else {
|
||||||
|
reject('QR code not signed by BC or QC');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid QR code')
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function processON(signedPdfBuffer : ArrayBuffer, content: TextContent): Promise<any> {
|
async function processON(signedPdfBuffer : ArrayBuffer, content: TextContent): Promise<any> {
|
||||||
|
|
||||||
// check for certs first
|
// check for certs first
|
||||||
|
|
Loading…
Reference in New Issue