misc-bdauvergne/qrcode-certificate/v1/qrcode-reader/src/app.js

103 lines
3.3 KiB
JavaScript

let html5qrcode = require('html5-qrcode');
let b45 = require('base45-js');
let nacl = require('tweetnacl');
let cbor = require('cbor');
function init() {
let pre = document.getElementById('text');
let key_input = document.getElementById('verify-key');
let key = Buffer.from(key_input.value, 'hex');
function update_key() {
key = Buffer.from(key_input.value, 'hex');
console.log('new key', key)
}
key_input.change = update_key;
update_key();
function onScanSuccess(c, decodedResult) {
pre.textContent = 'Decoding...'
try {
let signed;
console.log("Decoding", decodedResult);
try {
signed = b45.decode(c);
} catch (error) {
pre.textContent = 'B45 decoding failed: ' + error
console.log("b45 decoding error", error);
return true;
}
console.log('signed', signed.toString("hex"));
// Check NaCl signature
let opened = nacl.sign.open(signed, key)
if (opened == null) {
pre.textContent = 'Signature validation failed'
return true;
}
console.log('opened', opened);
let decoder = new TextDecoder('utf-8');
const decoded = decoder.decode(opened);
console.log('decoded', decoded);
// MIME-like decoder
const chunks = decoded.split('\n');
let k = null;
let v = null;
let data = {};
for (let i = 0; i < chunks.length; i++) {
const line = chunks[i];
if (line.startsWith(' ')) {
if (k !== null) {
v += '\n' + line.slice(1);
}
} else {
if (k !== null) {
data[k] = v;
k = null;
v = null;
}
if (line.indexOf(': ') != -1) {
const parts = line.split(': ', 2);
k = parts[0];
v = parts[1];
}
}
}
if (k !== null) {
data[k] = v;
}
console.log('data', data);
pre.textContent = JSON.stringify(data, null, ' ');
return true;
} catch (error) {
pre.textContent = 'Unknown error: ' + error
console.log("unknown error", error);
return true;
}
}
let qrboxFunction = function(viewfinderWidth, viewfinderHeight) {
let minEdgePercentage = 0.7; // 70%
let minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight);
let qrboxSize = Math.floor(minEdgeSize * minEdgePercentage);
return {
width: qrboxSize,
height: qrboxSize
};
};
let scanner = new html5qrcode.Html5Qrcode("reader", {
formatsToSupport: [
html5qrcode.Html5QrcodeSupportedFormats.QR_CODE,
],
});
scanner.start(
{ facingMode: "environment" },
{ fps: 10, qrbox: qrboxFunction, aspectRation: 2, disableFlip: false},
onScanSuccess
);
}
document.addEventListener('DOMContentLoaded', function (event) {
console.log('cbor', cbor.encode({a: 1}));
init();
});