2017-12-30 13:57:48 +00:00
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const KEYWORDS = [
|
|
|
|
["Android", "android"],
|
|
|
|
["iPhone", "iphone"],
|
|
|
|
["iPad", "ipad"],
|
|
|
|
["Ubuntu", "ubuntu"],
|
|
|
|
["Fedora", "fedora"],
|
|
|
|
["Linux", "linux"],
|
|
|
|
["Macintosh", "mac"],
|
|
|
|
];
|
|
|
|
|
2017-01-30 22:59:43 +00:00
|
|
|
jQuery.timeago.settings.allowFuture = true;
|
2015-12-16 17:41:49 +00:00
|
|
|
|
2017-03-26 00:10:09 +00:00
|
|
|
function normalizeCommonName(j) {
|
|
|
|
return j.replace("@", "--").split(".").join("-"); // dafuq ?!
|
|
|
|
}
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
function onHashChanged() {
|
|
|
|
var query = {};
|
|
|
|
var a = location.hash.substring(1).split('&');
|
|
|
|
for (var i = 0; i < a.length; i++) {
|
|
|
|
var b = a[i].split('=');
|
|
|
|
query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
|
|
|
}
|
|
|
|
|
|
|
|
console.info("Hash is now:", query);
|
|
|
|
|
|
|
|
loadAuthority();
|
2017-03-26 00:10:09 +00:00
|
|
|
}
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
function onTagClicked(tag) {
|
|
|
|
var cn = $(tag).attr("data-cn");
|
|
|
|
var id = $(tag).attr("title");
|
|
|
|
var value = $(tag).html();
|
2015-12-16 17:41:49 +00:00
|
|
|
var updated = prompt("Enter new tag or clear to remove the tag", value);
|
|
|
|
if (updated == "") {
|
2017-12-30 13:57:48 +00:00
|
|
|
$(event.target).addClass("disabled");
|
2015-12-16 17:41:49 +00:00
|
|
|
$.ajax({
|
|
|
|
method: "DELETE",
|
2017-03-26 10:09:18 +00:00
|
|
|
url: "/api/signed/" + cn + "/tag/" + id + "/"
|
2015-12-16 17:41:49 +00:00
|
|
|
});
|
|
|
|
} else if (updated && updated != value) {
|
2017-12-30 13:57:48 +00:00
|
|
|
$(tag).addClass("disabled");
|
2017-03-26 10:09:18 +00:00
|
|
|
$.ajax({
|
|
|
|
method: "PUT",
|
|
|
|
url: "/api/signed/" + cn + "/tag/" + id + "/",
|
|
|
|
data: { value: updated },
|
|
|
|
dataType: "text",
|
|
|
|
complete: function(xhr, status) {
|
|
|
|
console.info("Tag added successfully", xhr.status, status);
|
|
|
|
},
|
|
|
|
success: function() {
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Submitting request failed with:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
});
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
function onNewTagClicked(menu) {
|
2017-03-26 00:10:09 +00:00
|
|
|
var cn = $(menu).attr("data-cn");
|
2017-12-30 13:57:48 +00:00
|
|
|
var key = $(menu).attr("data-key");
|
2015-12-16 17:41:49 +00:00
|
|
|
var value = prompt("Enter new " + key + " tag for " + cn);
|
|
|
|
if (!value) return;
|
|
|
|
if (value.length == 0) return;
|
2017-12-30 13:57:48 +00:00
|
|
|
var $container = $(".tags[data-cn='" + cn + "']");
|
|
|
|
$container.addClass("disabled");
|
|
|
|
$.ajax({
|
|
|
|
method: "POST",
|
|
|
|
url: "/api/signed/" + cn + "/tag/",
|
|
|
|
data: { value: value, key: key },
|
|
|
|
dataType: "text",
|
|
|
|
complete: function(xhr, status) {
|
|
|
|
console.info("Tag added successfully", xhr.status, status);
|
|
|
|
},
|
|
|
|
success: function() {
|
|
|
|
$container.removeClass("disabled");
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Submitting request failed with:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
});
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
|
2016-01-10 17:51:54 +00:00
|
|
|
function onTagFilterChanged() {
|
|
|
|
var key = $(event.target).val();
|
|
|
|
console.info("New key is:", key);
|
|
|
|
}
|
|
|
|
|
2015-12-16 17:41:49 +00:00
|
|
|
function onLogEntry (e) {
|
2017-12-30 13:57:48 +00:00
|
|
|
if (e.data) {
|
|
|
|
e = JSON.parse(e.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($("#log-level-" + e.severity).prop("checked")) {
|
|
|
|
$("#log-entries").prepend(env.render("views/logentry.html", {
|
2015-12-16 17:41:49 +00:00
|
|
|
entry: {
|
2017-12-30 13:57:48 +00:00
|
|
|
created: new Date(e.created).toLocaleString(),
|
|
|
|
message: e.message,
|
|
|
|
severity: e.severity
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function onRequestSubmitted(e) {
|
|
|
|
console.log("Request submitted:", e.data);
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
|
|
|
url: "/api/request/" + e.data + "/",
|
|
|
|
dataType: "json",
|
|
|
|
success: function(request, status, xhr) {
|
2017-03-26 00:10:09 +00:00
|
|
|
console.info("Going to prepend:", request);
|
2016-04-05 12:02:05 +00:00
|
|
|
onRequestDeleted(e); // Delete any existing ones just in case
|
2015-12-16 17:41:49 +00:00
|
|
|
$("#pending_requests").prepend(
|
2018-01-23 13:13:49 +00:00
|
|
|
env.render('views/request.html', { request: request, session: session }));
|
2017-03-26 00:10:09 +00:00
|
|
|
$("#pending_requests time").timeago();
|
|
|
|
},
|
|
|
|
error: function(response) {
|
|
|
|
console.info("Failed to retrieve certificate:", response);
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onRequestDeleted(e) {
|
2016-03-21 21:42:39 +00:00
|
|
|
console.log("Removing deleted request", e.data);
|
2017-03-26 00:10:09 +00:00
|
|
|
$("#request-" + normalizeCommonName(e.data)).remove();
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
|
2017-03-26 00:10:09 +00:00
|
|
|
function onLeaseUpdate(e) {
|
2017-12-30 13:57:48 +00:00
|
|
|
var slug = normalizeCommonName(e.data);
|
2017-03-26 00:10:09 +00:00
|
|
|
console.log("Lease updated:", e.data);
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
|
|
|
url: "/api/signed/" + e.data + "/lease/",
|
|
|
|
dataType: "json",
|
|
|
|
success: function(lease, status, xhr) {
|
|
|
|
console.info("Retrieved lease update details:", lease);
|
|
|
|
lease.age = (new Date() - new Date(lease.last_seen)) / 1000.0
|
2017-12-30 13:57:48 +00:00
|
|
|
var $lease = $("#certificate-" + slug + " .lease");
|
|
|
|
$lease.html(env.render('views/lease.html', {
|
2017-03-26 00:10:09 +00:00
|
|
|
certificate: {
|
|
|
|
lease: lease }}));
|
2017-12-30 13:57:48 +00:00
|
|
|
$("time", $lease).timeago();
|
2015-12-16 17:41:49 +00:00
|
|
|
|
2017-03-26 00:10:09 +00:00
|
|
|
},
|
|
|
|
error: function(response) {
|
|
|
|
console.info("Failed to retrieve certificate:", response);
|
|
|
|
}
|
|
|
|
});
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onRequestSigned(e) {
|
|
|
|
console.log("Request signed:", e.data);
|
2017-03-26 00:10:09 +00:00
|
|
|
var slug = normalizeCommonName(e.data);
|
2017-03-13 11:42:58 +00:00
|
|
|
console.log("Removing:", slug);
|
2016-03-21 21:42:39 +00:00
|
|
|
|
2017-03-13 11:42:58 +00:00
|
|
|
$("#request-" + slug).slideUp("normal", function() { $(this).remove(); });
|
|
|
|
$("#certificate-" + slug).slideUp("normal", function() { $(this).remove(); });
|
2015-12-16 17:41:49 +00:00
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
|
|
|
url: "/api/signed/" + e.data + "/",
|
|
|
|
dataType: "json",
|
|
|
|
success: function(certificate, status, xhr) {
|
2017-03-13 11:42:58 +00:00
|
|
|
console.info("Retrieved certificate:", certificate);
|
2015-12-16 17:41:49 +00:00
|
|
|
$("#signed_certificates").prepend(
|
2017-12-30 13:57:48 +00:00
|
|
|
env.render('views/signed.html', { certificate: certificate, session: session }));
|
2017-03-26 00:10:09 +00:00
|
|
|
$("#signed_certificates time").timeago(); // TODO: optimize?
|
2017-03-13 11:42:58 +00:00
|
|
|
},
|
|
|
|
error: function(response) {
|
|
|
|
console.info("Failed to retrieve certificate:", response);
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onCertificateRevoked(e) {
|
2016-03-21 21:42:39 +00:00
|
|
|
console.log("Removing revoked certificate", e.data);
|
2017-03-26 00:10:09 +00:00
|
|
|
$("#certificate-" + normalizeCommonName(e.data)).slideUp("normal", function() { $(this).remove(); });
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function onTagUpdated(e) {
|
2017-03-26 00:10:09 +00:00
|
|
|
var cn = e.data;
|
2017-12-30 13:57:48 +00:00
|
|
|
console.log("Tag updated event recevied", cn);
|
2015-12-16 17:41:49 +00:00
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
2017-03-26 00:10:09 +00:00
|
|
|
url: "/api/signed/" + cn + "/tag/",
|
2015-12-16 17:41:49 +00:00
|
|
|
dataType: "json",
|
2017-03-26 00:10:09 +00:00
|
|
|
success:function(tags, status, xhr) {
|
|
|
|
console.info("Updated", cn, "tags", tags);
|
2017-12-30 13:57:48 +00:00
|
|
|
$(".tags[data-cn='" + cn+"']").html(
|
|
|
|
env.render('views/tags.html', {
|
2017-03-26 00:10:09 +00:00
|
|
|
certificate: {
|
|
|
|
common_name: cn,
|
|
|
|
tags:tags }}));
|
2015-12-16 17:41:49 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-07-05 15:22:03 +00:00
|
|
|
function onAttributeUpdated(e) {
|
|
|
|
var cn = e.data;
|
|
|
|
console.log("Attributes updated", cn);
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
|
|
|
url: "/api/signed/" + cn + "/attr/",
|
|
|
|
dataType: "json",
|
|
|
|
success:function(attributes, status, xhr) {
|
|
|
|
console.info("Updated", cn, "attributes", attributes);
|
|
|
|
$(".attributes[data-cn='" + cn + "']").html(
|
2017-12-30 13:57:48 +00:00
|
|
|
env.render('views/attributes.html', {
|
2017-07-05 15:22:03 +00:00
|
|
|
certificate: {
|
|
|
|
common_name: cn,
|
|
|
|
attributes:attributes }}));
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-01-02 14:49:06 +00:00
|
|
|
function onSubmitRequest() {
|
|
|
|
$.ajax({
|
|
|
|
method: "POST",
|
|
|
|
url: "/api/request/",
|
|
|
|
headers: {
|
|
|
|
"Accept": "application/json; charset=utf-8",
|
|
|
|
"Content-Type": "application/pkcs10"
|
|
|
|
},
|
|
|
|
data: $("#request_body").val(),
|
|
|
|
|
|
|
|
success:function(attributes, status, xhr) {
|
|
|
|
// Close the modal
|
|
|
|
$("[data-dismiss=modal]").trigger({ type: "click" });
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Submitting request failed with:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-07-11 18:57:19 +00:00
|
|
|
function onServerStarted() {
|
|
|
|
console.info("Server started");
|
|
|
|
location.reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
function onServerStopped() {
|
2017-12-30 13:57:48 +00:00
|
|
|
$("view").html('<div class="loader"></div><p>Server under maintenance</p>');
|
2017-07-11 18:57:19 +00:00
|
|
|
console.info("Server stopped");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
function onSendToken() {
|
|
|
|
$.ajax({
|
|
|
|
method: "POST",
|
|
|
|
url: "/api/token/",
|
|
|
|
data: { username: $("#token_username").val(), mail: $("#token_mail").val() },
|
|
|
|
dataType: "text",
|
|
|
|
complete: function(xhr, status) {
|
|
|
|
console.info("Token sent successfully", xhr.status, status);
|
|
|
|
},
|
|
|
|
success: function(data) {
|
|
|
|
var url = JSON.parse(data).url;
|
|
|
|
console.info("DATA:", url);
|
|
|
|
var code = new QRCode({
|
|
|
|
content: url,
|
|
|
|
width: 512,
|
|
|
|
height: 512,
|
|
|
|
});
|
|
|
|
document.getElementById("token_qrcode").innerHTML = code.svg();
|
|
|
|
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Submitting request failed with:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadAuthority() {
|
2015-11-11 19:12:04 +00:00
|
|
|
console.info("Loading CA, to debug: curl " + window.location.href + " --negotiate -u : -H 'Accept: application/json'");
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
2015-12-12 22:34:08 +00:00
|
|
|
url: "/api/",
|
2015-11-11 19:12:04 +00:00
|
|
|
dataType: "json",
|
2015-11-15 14:55:26 +00:00
|
|
|
error: function(response) {
|
|
|
|
if (response.responseJSON) {
|
|
|
|
var msg = response.responseJSON
|
|
|
|
} else {
|
|
|
|
var msg = { title: "Error " + response.status, description: response.statusText }
|
|
|
|
}
|
2017-12-30 13:57:48 +00:00
|
|
|
$("#view").html(env.render('views/error.html', { message: msg }));
|
2015-11-15 14:55:26 +00:00
|
|
|
},
|
2015-11-11 19:12:04 +00:00
|
|
|
success: function(session, status, xhr) {
|
2017-12-30 13:57:48 +00:00
|
|
|
window.session = session;
|
|
|
|
|
|
|
|
console.info("Loaded:", session);
|
2016-03-21 21:42:39 +00:00
|
|
|
$("#login").hide();
|
2015-11-15 14:55:26 +00:00
|
|
|
|
2015-12-16 17:41:49 +00:00
|
|
|
/**
|
|
|
|
* Render authority views
|
|
|
|
**/
|
2017-12-30 13:57:48 +00:00
|
|
|
$("#view").html(env.render('views/authority.html', { session: session, window: window }));
|
2017-01-30 22:59:43 +00:00
|
|
|
$("time").timeago();
|
2016-03-21 21:42:39 +00:00
|
|
|
if (session.authority) {
|
|
|
|
$("#log input").each(function(i, e) {
|
|
|
|
console.info("e.checked:", e.checked , "and", e.id, "@localstorage is", localStorage[e.id], "setting to:", localStorage[e.id] || e.checked, "bool:", localStorage[e.id] || e.checked == "true");
|
|
|
|
e.checked = localStorage[e.id] ? localStorage[e.id] == "true" : e.checked;
|
|
|
|
});
|
|
|
|
|
|
|
|
$("#log input").change(function() {
|
|
|
|
localStorage[this.id] = this.checked;
|
|
|
|
});
|
|
|
|
|
|
|
|
console.info("Opening EventSource from:", session.authority.events);
|
|
|
|
|
|
|
|
var source = new EventSource(session.authority.events);
|
|
|
|
|
|
|
|
source.onmessage = function(event) {
|
|
|
|
console.log("Received server-sent event:", event);
|
|
|
|
}
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
|
2017-03-26 00:10:09 +00:00
|
|
|
source.addEventListener("lease-update", onLeaseUpdate);
|
2016-03-21 21:42:39 +00:00
|
|
|
source.addEventListener("request-deleted", onRequestDeleted);
|
|
|
|
source.addEventListener("request-submitted", onRequestSubmitted);
|
|
|
|
source.addEventListener("request-signed", onRequestSigned);
|
|
|
|
source.addEventListener("certificate-revoked", onCertificateRevoked);
|
2017-03-26 00:10:09 +00:00
|
|
|
source.addEventListener("tag-update", onTagUpdated);
|
2017-07-05 15:22:03 +00:00
|
|
|
source.addEventListener("attribute-update", onAttributeUpdated);
|
2017-07-11 18:57:19 +00:00
|
|
|
source.addEventListener("server-started", onServerStarted);
|
|
|
|
source.addEventListener("server-stopped", onServerStopped);
|
2016-03-21 21:42:39 +00:00
|
|
|
|
|
|
|
console.info("Swtiching to requests section");
|
|
|
|
$("section").hide();
|
|
|
|
$("section#requests").show();
|
|
|
|
$("#section-revoked").show();
|
|
|
|
$("#section-signed").show();
|
|
|
|
$("#section-requests").show();
|
2017-12-30 13:57:48 +00:00
|
|
|
$("#section-token").show();
|
|
|
|
|
|
|
|
|
2016-03-21 21:42:39 +00:00
|
|
|
}
|
2015-11-11 19:12:04 +00:00
|
|
|
|
2015-12-16 17:41:49 +00:00
|
|
|
$("nav#menu li").click(function(e) {
|
|
|
|
$("section").hide();
|
|
|
|
$("section#" + $(e.target).attr("data-section")).show();
|
|
|
|
});
|
2015-12-13 15:11:22 +00:00
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
$("#enroll").click(function() {
|
|
|
|
var keys = forge.pki.rsa.generateKeyPair(1024);
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
method: "POST",
|
|
|
|
url: "/api/token/",
|
|
|
|
data: "username=" + session.user.name,
|
|
|
|
complete: function(xhr, status) {
|
|
|
|
console.info("Token generated successfully:", xhr, status);
|
|
|
|
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Token generation failed:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var privateKeyBuffer = forge.pki.privateKeyToPem(keys.privateKey);
|
|
|
|
});
|
|
|
|
|
2015-12-16 17:41:49 +00:00
|
|
|
/**
|
|
|
|
* Set up search bar
|
|
|
|
*/
|
|
|
|
$(window).on("search", function() {
|
|
|
|
var q = $("#search").val();
|
|
|
|
$(".filterable").each(function(i, e) {
|
2017-03-13 11:42:58 +00:00
|
|
|
if ($(e).attr("data-cn").toLowerCase().indexOf(q) >= 0) {
|
2015-12-16 17:41:49 +00:00
|
|
|
$(e).show();
|
|
|
|
} else {
|
|
|
|
$(e).hide();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-12-30 13:57:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-16 17:41:49 +00:00
|
|
|
/**
|
|
|
|
* Bind key up event of search bar
|
|
|
|
*/
|
|
|
|
$("#search").on("keyup", function() {
|
|
|
|
if (window.searchTimeout) { clearTimeout(window.searchTimeout); }
|
|
|
|
window.searchTimeout = setTimeout(function() { $(window).trigger("search"); }, 500);
|
|
|
|
console.info("Setting timeout", window.searchTimeout);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2016-03-21 21:42:39 +00:00
|
|
|
console.log("Features enabled:", session.features);
|
2016-09-18 13:25:52 +00:00
|
|
|
|
|
|
|
if (session.request_submission_allowed) {
|
|
|
|
$("#request_submit").click(function() {
|
|
|
|
$(this).addClass("busy");
|
|
|
|
$.ajax({
|
|
|
|
method: "POST",
|
|
|
|
contentType: "application/pkcs10",
|
|
|
|
url: "/api/request/",
|
|
|
|
data: $("#request_body").val(),
|
|
|
|
dataType: "text",
|
|
|
|
complete: function(xhr, status) {
|
|
|
|
console.info("Request submitted successfully, server returned", xhr.status, status);
|
|
|
|
$("#request_submit").removeClass("busy");
|
|
|
|
},
|
|
|
|
success: function() {
|
|
|
|
// Clear textarea on success
|
|
|
|
$("#request_body").val("");
|
|
|
|
},
|
|
|
|
error: function(xhr, status, e) {
|
|
|
|
console.info("Submitting request failed with:", status, e);
|
|
|
|
alert(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-01-10 17:51:54 +00:00
|
|
|
/**
|
|
|
|
* Fetch log entries
|
|
|
|
*/
|
2016-03-21 21:42:39 +00:00
|
|
|
if (session.features.logging) {
|
2017-12-30 13:57:48 +00:00
|
|
|
$("nav .nav-link.log").removeClass("disabled").click(function() {
|
|
|
|
$("#view-dashboard").hide();
|
|
|
|
$("#view-log").show();
|
|
|
|
$.ajax({
|
|
|
|
method: "GET",
|
|
|
|
url: "/api/log/",
|
|
|
|
dataType: "json",
|
|
|
|
success: function(entries, status, xhr) {
|
|
|
|
console.info("Got", entries.length, "log entries");
|
|
|
|
console.info("j=", entries.length-1);
|
|
|
|
for (var j = entries.length-1; j--; ) {
|
|
|
|
onLogEntry(entries[j]);
|
|
|
|
};
|
|
|
|
source.addEventListener("log-entry", onLogEntry);
|
2016-01-10 17:51:54 +00:00
|
|
|
}
|
2017-12-30 13:57:48 +00:00
|
|
|
});
|
2016-03-21 21:42:39 +00:00
|
|
|
});
|
|
|
|
}
|
2015-11-11 19:12:04 +00:00
|
|
|
}
|
|
|
|
});
|
2017-12-30 13:57:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function datetimeFilter(s) {
|
|
|
|
return new Date(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
function serialFilter(s) {
|
|
|
|
return s.substring(0,8) + " " +
|
|
|
|
s.substring(8,12) + " " +
|
|
|
|
s.substring(12,16) + " " +
|
|
|
|
s.substring(16,28) + " " +
|
|
|
|
s.substring(28,32) + " " +
|
|
|
|
s.substring(32);
|
|
|
|
}
|
|
|
|
|
|
|
|
$(document).ready(function() {
|
|
|
|
window.env = new nunjucks.Environment();
|
|
|
|
env.addFilter("datetime", datetimeFilter);
|
|
|
|
env.addFilter("serial", serialFilter);
|
|
|
|
onHashChanged();
|
2015-10-28 10:46:36 +00:00
|
|
|
});
|