2020-03-18 17:15:06 +00:00
|
|
|
// polyfills for older browsers
|
|
|
|
if (typeof String.prototype.startsWith === 'undefined') {
|
|
|
|
String.prototype.startsWith = function (needle) {
|
|
|
|
return this.indexOf(needle) === 0;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-03-10 18:38:52 +00:00
|
|
|
// === Core functions ===
|
|
|
|
var api_base = "http://localhost:5000";
|
|
|
|
var app_token = null;
|
2020-03-18 17:15:06 +00:00
|
|
|
var app_key_id = null;
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
function do_request(method, url, data, onsuccess, onerror) {
|
|
|
|
var req = new XMLHttpRequest();
|
|
|
|
req.open(method, window.encodeURI(api_base + url), true);
|
|
|
|
req.onload = function() { onsuccess(this); }
|
|
|
|
req.setRequestHeader("X-Auth-Token", app_token);
|
|
|
|
req.onerror = function() { onerror(this); }
|
|
|
|
if (data === null) {
|
|
|
|
req.send();
|
|
|
|
} else {
|
|
|
|
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
|
|
|
req.send(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// == Events ===
|
|
|
|
function oninit() {
|
|
|
|
ui_keyholder_loading();
|
|
|
|
|
|
|
|
if (window.location.href.search("#tracker") < 0 &&
|
|
|
|
window.location.href.search("#keyholder") < 0)
|
|
|
|
window.location.href = "#tracker"
|
|
|
|
|
|
|
|
app_token = _get_token();
|
2020-03-18 17:15:06 +00:00
|
|
|
app_key_id = _get_key_id(app_token);
|
|
|
|
if (app_token === null || app_key_id === null) {
|
|
|
|
ui_tracker_error("Interner Fehler: kein/ungültiges Token. Bitte stelle sicher, dass du diese Seite durch Scannen des QR Codes erreicht hast");
|
|
|
|
return;
|
|
|
|
}
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
if (window.location.href.search("#keyholder") > 0)
|
|
|
|
keyholder_onload();
|
2020-03-18 17:15:06 +00:00
|
|
|
|
|
|
|
update_key_name();
|
2020-03-10 18:38:52 +00:00
|
|
|
update_key_status();
|
|
|
|
load_saved_tracker_data();
|
|
|
|
|
|
|
|
document.getElementById("input-contact").addEventListener("keyup", function(e) {
|
|
|
|
if (e.key === "Enter")
|
|
|
|
tracker_onsend();
|
|
|
|
});
|
|
|
|
document.getElementById("input-pass").addEventListener("keyup", function(e) {
|
|
|
|
if (e.key === "Enter")
|
|
|
|
password_submit();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function tracker_onsend(e) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_tracker_error(false);
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
var name = document.getElementById("input-name").value;
|
|
|
|
var contact = document.getElementById("input-contact").value;
|
|
|
|
var save_data = document.getElementById("input-tracker-save").checked;
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
if (name.length < 2 || contact.length < 2) {
|
2020-03-10 18:38:52 +00:00
|
|
|
ui_tracker_error("Name und Kontakt müssen mindestens 3 Zeichen lang sein")
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (app_token === null) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_tracker_error("Interner Fehler: kein Token. Bitte stelle sicher, dass du diese Seite durch Scannen des QR Codes erreicht hast");
|
2020-03-10 18:38:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_tracker_send_loading(true);
|
2020-03-10 18:38:52 +00:00
|
|
|
do_request(
|
|
|
|
"POST",
|
|
|
|
"/claim",
|
|
|
|
"name="+window.encodeURI(name)+"&contact="+window.encodeURI(contact),
|
|
|
|
function(r) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_tracker_send_loading(true);
|
2020-03-10 18:38:52 +00:00
|
|
|
if (r.status == 200) {
|
2020-03-18 17:15:06 +00:00
|
|
|
localStorage.setItem(app_key_id + "_last_cid", r.response);
|
2020-03-10 18:38:52 +00:00
|
|
|
if (save_data) {
|
|
|
|
localStorage.setItem("name", name);
|
|
|
|
localStorage.setItem("contact", contact);
|
|
|
|
} else {
|
|
|
|
localStorage.removeItem("name");
|
|
|
|
localStorage.removeItem("contact");
|
|
|
|
}
|
|
|
|
update_key_status();
|
|
|
|
} else {
|
|
|
|
ui_tracker_error("Fehlgeschlagen: Status code " + r.status);
|
|
|
|
console.log("Claim request failed (Status code)");
|
|
|
|
console.log(r);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function(r) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_tracker_send_loading(true);
|
2020-03-10 18:38:52 +00:00
|
|
|
ui_tracker_error("Fehlgeschlagen: Bitte überprüfe deine Internetverbindung");
|
|
|
|
console.log("Claim request failed");
|
|
|
|
console.log(r);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function keyholder_onload() {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_password_error(false);
|
|
|
|
ui_keyholder_error(false);
|
|
|
|
ui_keyholder_refresh_loading(true);
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
do_request(
|
|
|
|
"GET",
|
|
|
|
"/keyholder",
|
|
|
|
null,
|
|
|
|
function(r) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_keyholder_refresh_loading(false);
|
2020-03-10 18:38:52 +00:00
|
|
|
if (r.status == 200) {
|
|
|
|
ui_show_keyholder(JSON.parse(r.response));
|
|
|
|
} else if (r.status == 403) {
|
|
|
|
ui_request_password();
|
|
|
|
} else {
|
|
|
|
ui_keyholder_error("Fehlgeschlagen: Status code " + r.status);
|
|
|
|
console.log("Keyholder request failed (Status code)");
|
|
|
|
console.log(r);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function(r) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_keyholder_refresh_loading(false);
|
2020-03-10 18:38:52 +00:00
|
|
|
ui_keyholder_error("Fehlgeschlagen: Bitte überprüfe deine Internetverbindung");
|
|
|
|
console.log("Keyholder request failed");
|
|
|
|
console.log(r);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function password_submit() {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_password_error(false);
|
|
|
|
ui_keyholder_error(false);
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
var pass = document.getElementById("input-pass").value;
|
|
|
|
var save_token = document.getElementById("input-pass-save").checked;
|
|
|
|
|
|
|
|
document.getElementById("btn-send-pw").classList.add("loading");
|
|
|
|
do_request(
|
|
|
|
"POST",
|
|
|
|
"/auth",
|
|
|
|
"pass=" + window.encodeURI(pass),
|
|
|
|
function(r) {
|
|
|
|
document.getElementById("btn-send-pw").classList.remove("loading");
|
|
|
|
if (r.status == 200) {
|
2020-03-18 17:15:06 +00:00
|
|
|
// Delete previously used token
|
|
|
|
if (app_token !== null && localStorage.getItem("token") !== null) {
|
|
|
|
var tokenlist = localStorage.getItem("token").split(",");
|
|
|
|
if (tokenlist.indexOf(app_token) !== -1) {
|
|
|
|
tokenlist.splice(tokenlist.indexOf(app_token), 1);
|
|
|
|
localStorage.setItem("token", tokenlist.join(","));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-10 18:38:52 +00:00
|
|
|
app_token = r.response;
|
2020-03-18 17:15:06 +00:00
|
|
|
if (save_token) {
|
|
|
|
if (localStorage.getItem("token") !== null)
|
|
|
|
localStorage.setItem("token", localStorage.getItem("token") + "," + app_token);
|
|
|
|
else
|
|
|
|
localStorage.setItem("token", app_token)
|
|
|
|
}
|
2020-03-10 18:38:52 +00:00
|
|
|
|
|
|
|
ui_keyholder_loading();
|
|
|
|
keyholder_onload();
|
|
|
|
|
|
|
|
} else if (r.status == 401) {
|
2020-03-18 17:15:06 +00:00
|
|
|
ui_password_error(true);
|
2020-03-10 18:38:52 +00:00
|
|
|
} else {
|
|
|
|
ui_keyholder_error("Fehlgeschlagen: Status code " + r.status);
|
|
|
|
console.log("Auth request failed (Status code)");
|
|
|
|
console.log(r);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function(r) {
|
|
|
|
document.getElementById("btn-send-pw").classList.remove("loading");
|
|
|
|
ui_keyholder_error("Fehlgeschlagen: Bitte überprüfe deine Internetverbindung");
|
|
|
|
console.log("Auth request failed");
|
|
|
|
console.log(r);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// === Helper functions ===
|
|
|
|
function update_key_status() {
|
2020-03-18 17:15:06 +00:00
|
|
|
var last_cid = localStorage.getItem(app_key_id + "_last_cid");
|
|
|
|
if (last_cid !== null) {
|
2020-03-10 18:38:52 +00:00
|
|
|
do_request(
|
|
|
|
"GET",
|
2020-03-18 17:15:06 +00:00
|
|
|
"/status/" + last_cid,
|
2020-03-10 18:38:52 +00:00
|
|
|
null,
|
|
|
|
function(r) {
|
|
|
|
if (r.status == 200 && r.response == "latest")
|
|
|
|
ui_set_has_key();
|
|
|
|
else
|
|
|
|
ui_set_has_not_key();
|
|
|
|
},
|
|
|
|
function(r) { console.log("Status request failed"); console.log(r) }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function update_key_name() {
|
|
|
|
// For perception purposes, the last key name is cached but
|
|
|
|
// updated as soon as possible.
|
|
|
|
var last_key_name = localStorage.getItem(app_key_id + "_last_key_name");
|
|
|
|
if (last_key_name !== null)
|
|
|
|
ui_set_key_name(last_key_name);
|
|
|
|
do_request(
|
|
|
|
"GET",
|
|
|
|
"/keyname",
|
|
|
|
null,
|
|
|
|
function(r) {
|
|
|
|
if (r.status == 200) {
|
|
|
|
ui_set_key_name(r.response);
|
|
|
|
localStorage.setItem(app_key_id + "_last_key_name", r.response);
|
|
|
|
} else {
|
|
|
|
ui_set_key_name("?");
|
|
|
|
console.log("Keyname request failed (status code " + r.status + ")");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function(r) {
|
|
|
|
ui_set_key_name("?");
|
|
|
|
console.log("Keyname request failed"); console.log(r)
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-10 18:38:52 +00:00
|
|
|
function load_saved_tracker_data() {
|
|
|
|
if (localStorage.getItem("name") !== null)
|
|
|
|
document.getElementById("input-name").value = localStorage.getItem("name");
|
|
|
|
if (localStorage.getItem("contact") !== null)
|
|
|
|
document.getElementById("input-contact").value = localStorage.getItem("contact");
|
|
|
|
}
|
|
|
|
|
|
|
|
function _get_token() {
|
2020-03-18 17:15:06 +00:00
|
|
|
// A token in the URL is always required to know the key
|
|
|
|
var token = null;
|
|
|
|
// Very dirty parsing as of now
|
|
|
|
var params_str = window.location.search;
|
|
|
|
if (params_str.search("&") >= 0)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var parts = params_str.split("token=");
|
|
|
|
if (parts.length != 2)
|
|
|
|
return null
|
|
|
|
else
|
|
|
|
token = parts[1];
|
|
|
|
|
2020-03-10 18:38:52 +00:00
|
|
|
if (localStorage.getItem("token") === null) {
|
2020-03-18 17:15:06 +00:00
|
|
|
return token;
|
|
|
|
} else {
|
|
|
|
var key_id = token.split(":")[0];
|
|
|
|
|
|
|
|
var tokenlist = localStorage.getItem("token").split(",");
|
|
|
|
// This returns the last stored token for this key.
|
|
|
|
// Generally it should not happen (tm) that there is more than one token.
|
|
|
|
for (var i = tokenlist.length - 1; i >= 0; i--) {
|
|
|
|
if (tokenlist[i].indexOf(key_id + ":") === 0)
|
|
|
|
return tokenlist[i];
|
|
|
|
}
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
}
|
2020-03-10 18:38:52 +00:00
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function _get_key_id(token) {
|
|
|
|
if (token === null) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
var parts = token.split(":");
|
|
|
|
if (parts.length !== 2)
|
2020-03-10 18:38:52 +00:00
|
|
|
return null
|
|
|
|
else
|
2020-03-18 17:15:06 +00:00
|
|
|
return parts[0];
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// === Ugly UI manipulation code ===
|
|
|
|
function ui_set_has_key() {
|
|
|
|
document.getElementById("has-key").style.display = "inline"
|
|
|
|
document.getElementById("btn-tracker").disabled = true
|
|
|
|
document.getElementById("input-name").disabled = true
|
|
|
|
document.getElementById("input-contact").disabled = true
|
|
|
|
document.getElementById("input-tracker-save").disabled = true
|
|
|
|
document.getElementById("tracker-formgroup").style.opacity = 0.5
|
|
|
|
}
|
|
|
|
|
|
|
|
function ui_set_has_not_key() {
|
|
|
|
document.getElementById("has-key").style.display = "none"
|
|
|
|
document.getElementById("btn-tracker").disabled = false
|
|
|
|
document.getElementById("input-name").disabled = false
|
|
|
|
document.getElementById("input-contact").disabled = false
|
|
|
|
document.getElementById("input-tracker-save").disabled = false
|
|
|
|
document.getElementById("tracker-formgroup").style.opacity = 1
|
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_set_key_name(name) {
|
|
|
|
document.getElementById("tracker-key-name").textContent = name;
|
|
|
|
document.getElementById("keyholder-key-name").textContent = name;
|
|
|
|
}
|
|
|
|
|
2020-03-10 18:38:52 +00:00
|
|
|
function ui_keyholder_loading() {
|
|
|
|
document.getElementById("keyholder-loading").style.display = "block"
|
|
|
|
document.getElementById("btn-send-pw").style.display = "none"
|
|
|
|
document.getElementById("btn-update").style.display = "none"
|
|
|
|
document.getElementById("pass-formgroup").style.display = "none"
|
|
|
|
document.getElementById("keyholder-table-container").style.display = "none"
|
|
|
|
}
|
|
|
|
|
|
|
|
function ui_request_password() {
|
|
|
|
document.getElementById("keyholder-loading").style.display = "none"
|
|
|
|
document.getElementById("btn-send-pw").style.display = "block"
|
|
|
|
document.getElementById("btn-update").style.display = "none"
|
|
|
|
document.getElementById("pass-formgroup").style.display = "block"
|
|
|
|
document.getElementById("keyholder-table-container").style.display = "none"
|
|
|
|
}
|
|
|
|
|
|
|
|
function ui_show_keyholder(keyholder) {
|
|
|
|
document.getElementById("keyholder-tbody").innerHTML = "";
|
|
|
|
for (var i = 0; i < keyholder.length; i++) {
|
|
|
|
var date = new Date(keyholder[i]["timestamp"] * 1000);
|
|
|
|
|
|
|
|
var tr = document.createElement("tr");
|
|
|
|
if (i > 0)
|
|
|
|
tr.style.color = "#aaa";
|
|
|
|
var td_name = document.createElement("td");
|
|
|
|
var td_contact = document.createElement("td");
|
|
|
|
var td_timestamp = document.createElement("td");
|
|
|
|
td_name.appendChild(document.createTextNode(keyholder[i]["name"]));
|
|
|
|
td_contact.appendChild(document.createTextNode(keyholder[i]["contact"]));
|
|
|
|
td_timestamp.appendChild(document.createTextNode(date.toLocaleString()));
|
|
|
|
tr.appendChild(td_name);
|
|
|
|
tr.appendChild(td_contact);
|
|
|
|
tr.appendChild(td_timestamp);
|
|
|
|
document.getElementById("keyholder-tbody").appendChild(tr);
|
|
|
|
}
|
|
|
|
|
|
|
|
document.getElementById("keyholder-loading").style.display = "none"
|
|
|
|
document.getElementById("btn-send-pw").style.display = "none"
|
|
|
|
document.getElementById("btn-update").style.display = "block"
|
|
|
|
document.getElementById("pass-formgroup").style.display = "none"
|
|
|
|
document.getElementById("keyholder-table-container").style.display = "block"
|
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_keyholder_refresh_loading(is_loading) {
|
|
|
|
if (is_loading)
|
|
|
|
document.getElementById("btn-update").classList.add("loading");
|
|
|
|
else
|
|
|
|
document.getElementById("btn-update").classList.remove("loading");
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_tracker_send_loading(is_loading) {
|
|
|
|
if (is_loading)
|
|
|
|
document.getElementById("btn-tracker").classList.add("loading");
|
|
|
|
else
|
|
|
|
document.getElementById("btn-tracker").classList.remove("loading");
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_tracker_error(msg) {
|
|
|
|
if (msg === false) {
|
|
|
|
document.getElementById("tracker-error").style.display = "none";
|
|
|
|
} else {
|
|
|
|
document.getElementById("tracker-error").innerHTML = msg;
|
|
|
|
document.getElementById("tracker-error").style.display = "block";
|
|
|
|
}
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_keyholder_error(msg) {
|
|
|
|
if (msg === false) {
|
|
|
|
document.getElementById("keyholder-error").style.display = "none";
|
|
|
|
} else {
|
|
|
|
document.getElementById("keyholder-error").innerHTML = msg;
|
|
|
|
document.getElementById("keyholder-error").style.display = "block";
|
|
|
|
}
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 17:15:06 +00:00
|
|
|
function ui_password_error(is_error) {
|
|
|
|
if (is_error)
|
|
|
|
document.getElementById("input-pass").classList.add("is-error");
|
|
|
|
else
|
|
|
|
document.getElementById("input-pass").classList.remove("is-error");
|
2020-03-10 18:38:52 +00:00
|
|
|
}
|