UNPKG

eudgc

Version:

EuDGC (European Digital Green Certificate) handling in Javascript and Typescript

139 lines (115 loc) 4.48 kB
<html lang="en"> <head> <title>EuDGC Parser Sample</title> <meta charset="utf-8" /> <style> h1 { margin: 2px; } body { display: flex; flex-direction: column; margin: 2px; font-family: Helvetica, sans-serif; } #info { font-family: 'Courier New', Courier, monospace; background-color: #eeeeee; padding: 0.5rem; margin-top: 1rem; font-size: 11px; overflow: auto; } </style> </head> <body> <h1>EuDGC Parser Demo</h1> <p>Scan your EuDGC Covid Vaccination QR-Code <br>Demo for <a href="https://github.com/Scopevisio/eudgc">https://github.com/Scopevisio/eudgc</a> / Apache 2.0 licensed free javascript library by Scopevisio AG </p> <div> <canvas id="canvas" style="width: 480px; height: 360px;"></canvas> </div> <pre id="info"> </div> <script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script> <script src="eudgc.js"></script> <script> const canvas = document.getElementById("canvas") const ctx = canvas.getContext("2d") const video = document.createElement("video") video.setAttribute("width", 400) video.setAttribute("height", 300) navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then((stream) => { video.srcObject = stream video.setAttribute("playsinline", true) // for safari video.play() requestAnimationFrame(frame) }) let payload = "" // the qrcode will end up here const frame = async () => { requestAnimationFrame(frame) if (video.readyState != video.HAVE_ENOUGH_DATA) { return } canvas.height = video.videoHeight canvas.width = video.videoWidth ctx.drawImage(video, 0, 0, canvas.width, canvas.height) const size = Math.min(canvas.width, canvas.height) / 1.6 const x = .5 * (canvas.width - size) const y = .5 * (canvas.height - size) const imageData = ctx.getImageData(x, y, size, size) let code = jsQR( imageData.data, imageData.width, imageData.height, { inversionAttempts: "dontInvert", }) const DEBUG_MANUALLY = false if (DEBUG_MANUALLY && !code) { code = { // the italian test-certficate in textual form data: "HC1:6BFOXN%TS3DHPVO13J /G-/2YRVA.Q/R82JD2FCJG96V75DOW%IY17EIHY P8L6IWM$S4U45P84HW6U/4:84LC6 YM::QQHIZC4.OI1RM8ZA.A5:S9MKN4NN3F85QNCY0O%0VZ001HOC9JU0D0HT0HB2PL/IB*09B9LW4T*8+DCMH0LDK2%KI*V AQ2%KYZPQV6YP8722XOE7:8IPC2L4U/6H1D31BLOETI0K/4VMA/.6LOE:/8IL882B+SGK*R3T3+7A.N88J4R$F/MAITHW$P7S3-G9++9-G9+E93ZM$96TV6QRR 1JI7JSTNCA7G6MXYQYYQQKRM64YVQB95326FW4AJOMKMV35U:7-Z7QT499RLHPQ15O+4/Z6E 6U963X7$8Q$HMCP63HU$*GT*Q3-Q4+O7F6E%CN4D74DWZJ$7K+ CZEDB2M$9C1QD7+2K3475J%6VAYCSP0VSUY8WU9SG43A-RALVMO8+-VD2PRPTB7S015SSFW/BE1S1EV*2Q396Q*4TVNAZHJ7N471FPL-CA+2KG-6YPPB7C%40F18N4" } } if (code && code.data && payload != code.data) { payload = code.data // now the qrcode is inside the payload variable and we can show // the contents of the eudgc certificate and also of the validation // make a result structure let result = {} result.qrcode = payload // try to parse the EuDGC Vaccination Qr-Code try { const certificate = await EuDgc_parse(payload?.trim()) result.eudgc = certificate } catch (error) { console.error("no eudgc certificate found: " + error) result.eudgc = "No Vaccination Datastructure" } // "hacky" filter to only use DE certs const exampleCertFilter = (certInfo) => { return certInfo.subject && certInfo.subject.match(/O.?=.?Robert Koch-Institut/) } // try to validate the EuDGC Vaccination Qr-Code try { const certificate = await EuDgc_validate(payload?.trim()) /* const certifcate = await EuDgc_validate(payload?.trim(), { certFilter: (certInfo) => { return true; }, explicitCerts: explicitCerts, }); */ result.validationCertificate = certificate } catch (error) { console.error("no eudgc signed certificate found: " + error) result.validation = "Invalid Signature" } // format into a buffer and print out the buffer let buffer = JSON.stringify(result, null, 4) document.getElementById("info").textContent = buffer } } </script> </html>