diff --git a/frontend/example-html/script.js b/frontend/example-html/script.js
index aeba01d..9e8a190 100644
--- a/frontend/example-html/script.js
+++ b/frontend/example-html/script.js
@@ -1,85 +1,85 @@
async function decrypt(ciphertext, password) {
- const pwUtf8 = new TextEncoder().encode(password);
- const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
- const ctUtf8 = new Uint8Array(ciphertext);
- const iv = ctUtf8.slice(0, 12);
- const alg = { name: 'AES-GCM', iv: iv, additionalData: iv };
- const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
- try {
- const buf = await crypto.subtle.decrypt(alg, key, ctUtf8.slice(12));
- return new TextDecoder().decode(buf);
- } catch (e) {
- throw new Error('Decrypt failed')
- }
+ const pwUtf8 = new TextEncoder().encode(password);
+ const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
+ const ctUtf8 = new Uint8Array(ciphertext);
+ const iv = ctUtf8.slice(0, 12);
+ const alg = { name: 'AES-GCM', iv: iv, additionalData: iv };
+ const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
+ try {
+ const buf = await crypto.subtle.decrypt(alg, key, ctUtf8.slice(12));
+ return new TextDecoder().decode(buf);
+ } catch (e) {
+ throw new Error('Decrypt failed')
+ }
}
function setError(text) {
- document.getElementById('msg').innerText = text;
+ document.getElementById('msg').innerText = text;
}
function setFields(elem, fields) {
- for (const [k, v] of Object.entries(fields)) {
- for (const el of elem.querySelectorAll('#' + k)) {
- el.innerText = v;
- }
- }
+ for (const [k, v] of Object.entries(fields)) {
+ for (const el of elem.querySelectorAll('#' + k)) {
+ el.innerText = v;
+ }
+ }
}
async function apply(data, password) {
- const json = JSON.parse(await decrypt(data, password));
- const now = new Date().getTime();
- const vA = new Date(json['valid_since'] + 'T00:00:00');
- if (vA.getTime() > now) {
- return setError('Member card not valid yet');
- }
- const vZ = new Date(json['valid_until'] + 'T23:59:59');
- if (vZ.getTime() < now) {
- return setError('Member card expired');
- }
- const pass = document.getElementById('pass');
- const imgElem = pass.querySelector('#img');
- if (imgElem) {
- if (json['img']) {
- imgElem.src = 'data:image;base64,' + json['img'];
- } else {
- imgElem.src = 'img/no-img.svg';
- }
- }
- setFields(pass, {
- name: json['name'],
- member_id: json['id'],
- org_name: json['org'],
- valid: 'on ' + new Date().toLocaleDateString('en'),
- });
- setFields(pass, json['data']); // may overwrite previous fields
+ const json = JSON.parse(await decrypt(data, password));
+ const now = new Date().getTime();
+ const vA = new Date(json['valid_since'] + 'T00:00:00');
+ if (vA.getTime() > now) {
+ return setError('Member card not valid yet');
+ }
+ const vZ = new Date(json['valid_until'] + 'T23:59:59');
+ if (vZ.getTime() < now) {
+ return setError('Member card expired');
+ }
+ const pass = document.getElementById('pass');
+ const imgElem = pass.querySelector('#img');
+ if (imgElem) {
+ if (json['img']) {
+ imgElem.src = 'data:image;base64,' + json['img'];
+ } else {
+ imgElem.src = 'img/no-img.svg';
+ }
+ }
+ setFields(pass, {
+ name: json['name'],
+ member_id: json['id'],
+ org_name: json['org'],
+ valid: 'on ' + new Date().toLocaleDateString('en'),
+ });
+ setFields(pass, json['data']); // may overwrite previous fields
- const title = 'Member card for ' + json['name'] + ' – ' + json['org'];
- document.head.querySelector('title').innerText = title;
- document.getElementById('msg').classList.add('hidden');
- pass.classList.remove('hidden');
+ const title = 'Member card for ' + json['name'] + ' – ' + json['org'];
+ document.head.querySelector('title').innerText = title;
+ document.getElementById('msg').classList.add('hidden');
+ pass.classList.remove('hidden');
}
async function onLoad() {
- // reset previous download
- document.getElementById('pass').classList.add('hidden');
- const msg = document.getElementById('msg');
- msg.innerText = msg.dataset.load;
- msg.classList.remove('hidden');
- // download new data
- const [org, uuid, secret] = location.hash.slice(1).split('/');
- if (!org || !uuid || !secret) {
- return setError('Invalid URL');
- }
- const res = await fetch('./data/' + org + '/' + uuid);
- if (!res.ok) {
- return setError('Error loading\n\n' + res.status + ' ' + res.statusText);
- }
- try {
- const data = await res.arrayBuffer();
- await apply(data, secret);
- } catch (e) {
- setError(e);
- }
+ // reset previous download
+ document.getElementById('pass').classList.add('hidden');
+ const msg = document.getElementById('msg');
+ msg.innerText = msg.dataset.load;
+ msg.classList.remove('hidden');
+ // download new data
+ const [org, uuid, secret] = location.hash.slice(1).split('/');
+ if (!org || !uuid || !secret) {
+ return setError('Invalid URL');
+ }
+ const res = await fetch('./data/' + org + '/' + uuid);
+ if (!res.ok) {
+ return setError('Error loading\n\n' + res.status + ' ' + res.statusText);
+ }
+ try {
+ const data = await res.arrayBuffer();
+ await apply(data, secret);
+ } catch (e) {
+ setError(e);
+ }
}
// load and parse data
@@ -92,10 +92,10 @@ window.addEventListener('hashchange', onLoad, true);
// -------------
function onResize() {
- const card = document.getElementById('card');
- const sw = window.innerWidth / card.offsetWidth;
- const sh = window.innerHeight / card.offsetHeight;
- card.style.scale = Math.min(Math.min(sw, sh) * 0.97, 2);
+ const card = document.getElementById('card');
+ const sw = window.innerWidth / card.offsetWidth;
+ const sh = window.innerHeight / card.offsetHeight;
+ card.style.scale = Math.min(Math.min(sw, sh) * 0.97, 2);
}
window.addEventListener('resize', onResize, true);
@@ -109,16 +109,16 @@ screen?.orientation?.addEventListener('change', onResize, true);
lastUpdate = new Date().getTime();
function needsUpdate() {
- // reload page if older than 15min
- const now = new Date().getTime();
- if (now - lastUpdate > 900_000) {
- lastUpdate = now;
- onLoad();
- }
+ // reload page if older than 15min
+ const now = new Date().getTime();
+ if (now - lastUpdate > 900_000) {
+ lastUpdate = now;
+ onLoad();
+ }
}
// setInterval(needsUpdate, 1000);
window.addEventListener('focus', needsUpdate, true);
window.addEventListener('pageshow', needsUpdate, true);
window.addEventListener('visibilitychange', function () {
- !document.hidden && document.visibilityState !== 'hidden' && needsUpdate();
+ !document.hidden && document.visibilityState !== 'hidden' && needsUpdate();
}, true);