");
iframe.css("height", "100%");
iframe.css("width", "100%");
iframe.attr("src", "/api/message/"+selectedMessage.uuid+extension);
// Append iframe to the message contents view.
$("#message_contents").html("");
$("#message_contents").append(iframe);
} else {
// All other source types are handled here.
// Get the message source from the API.
$.ajax({
url: "/api/message/"+selectedMessage.uuid+extension
})
.done(function(data) {
// If an error was returned, we display it.
if (data.status!=undefined) {
displayError("Unable to pull message: "+data.error);
return;
}
// We display plain text message contents in a pre-formatted element.
var preFormated = $("").text(data);
// Append the pre-formatted element to the message contents.
$("#message_contents").html("");
$("#message_contents").append(preFormated);
})
.fail(function(jqXHR, textStatus) {
// Om error, display a message.
displayError("Unable to pull message: "+textStatus);
});
}
}
// This function is used to update the currently selected message view.
function updateSelectedMessage() {
// Update the header information.
$("#message_header .received").text(selectedMessage.formatted_date);
$("#message_header .size").text(bytesToHuman(selectedMessage.size));
$("#message_header .from").text(selectedMessage.from);
$("#message_header .to").text(selectedMessage.to);
$("#message_header .subject").text(selectedMessage.subject);
$("#message_header .spam_score").text(selectedMessage.spam_score);
$("#message_header .status").text(selectedMessage.status);
$("#message_header .source_ip").text(selectedMessage.source_ip);
// If no plain text, this must be a html email.
if (!selectedMessage.plain_text) {
// Disable plain text source selection tab.
$("#message_header .nav-tabs .plaintext").prop("disabled", true);
// Enable the html source selection tab.
$("#message_header .nav-tabs .html").prop("disabled", false);
// If the currently selected source tab is disabled, we need to select html.
if ($("#message_header .nav-tabs .active").prop("disabled")) {
$("#message_header .nav-tabs .html").click();
} else {
// Otherwise, select the active tab.
$("#message_header .nav-tabs .active").click();
}
} else {
// When plaintext is avaiable, we need to disable HTML source selection only if there is no HTML.
$("#message_header .nav-tabs .html").prop("disabled", !selectedMessage.html);
// We can enable the plain text source selection.
$("#message_header .nav-tabs .plaintext").prop("disabled", false);
// If the currently selected source tab is disabled, we need to select plain text.
if ($("#message_header .nav-tabs .active").prop("disabled")) {
$("#message_header .nav-tabs .plaintext").click();
} else {
// Otherwise, select the active tab.
$("#message_header .nav-tabs .active").click();
}
}
}
// When a message is selected in the message list, this function is called.
function handleMessageListSelection() {
// Get the selected message data.
var selection = $(this);
var message = JSON.parse(selection.attr("data"));
selectedMessage = message;
// Change the selelected message in the message list to this selection.
$("#message_list tr.active").removeClass("active");
selection.addClass("active");
// Update the location hash URI to this message.
window.location.hash = "uuid="+message.uuid;
// Update the selected message.
updateSelectedMessage();
}
// When the learn ham spam reporting button is clicked, this function is called.
function learnHam() {
// If no message is selected, we display a message and stop here.
if (selectedMessage==null) {
displayMessage("Select a message first.");
return;
}
// Confirm that this action is actually wanted to occur.
var r = confirm("Are you sure you want to report as ham?");
if (r != true) {
return
}
// Send request to the API.
$.ajax({
dataType: "json",
type: 'PUT',
url: "/api/message/"+selectedMessage.uuid+"/learn_ham"
})
.done(function(data) {
// If error, display message.
if (data.status=="error") {
displayError("Unable to report ham: "+data.error);
return;
}
// We Successfully submitted a report.
displaySuccess("Successfully reported as ham.");
})
.fail(function(jqXHR, textStatus) {
// On error, display message.
displayError("Unable to report ham: "+textStatus);
});
}
// When the learn spam spam reporting button is clicked, this function is called.
function learnSpam() {
// If no message is selected, we display a message and stop here.
if (selectedMessage==null) {
displayMessage("Select a message first.");
return;
}
// Confirm that this action is actually wanted to occur.
var r = confirm("Are you sure you want to report as spam?");
if (r != true) {
return
}
// Send request to the API.
$.ajax({
dataType: "json",
type: "PUT",
url: "/api/message/"+selectedMessage.uuid+"/learn_spam"
})
.done(function(data) {
// If error, display message.
if (data.status=="error") {
displayError("Unable to report spam: "+data.error);
return;
}
// We Successfully submitted a report.
displaySuccess("Successfully reported as spam.");
})
.fail(function(jqXHR, textStatus) {
// On error, display message.
displayError("Unable to report spam: "+textStatus);
});
}
// When the document has fully loaded, we get everything started.
$(document).ready(function() {
// Connect to websockets if available.
if (!window["WebSocket"]) {
displayError("Your browser does not support websockets, auto refresh will only occur once every minute.");
return;
} else {
connectToWS();
}
// Laod the configuration from API.
loadConfig();
// Make the message list resizer element work.
makeMessageListResizable();
// On window resize events, adjust view sizes.
$(window).resize(handleResize);
// Update the view sizes.
setTimeout(handleResize, 200);
// Load the message list.
loadMessageList();
// Every 5 seconds, we need to check if we need to refresh the message list.
setInterval(checkIfRefreshNeeded, 5000);
// Every minute, we force a refresh.
setInterval(function() {
shouldRefresh = true;
}, 60000);
// On input in the search field, handle it.
$("#searchInput").on("input", handleSearchInput);
// Handle clicking on items in the message list.
$("#message_list").on("click", "tr", handleMessageListSelection);
// Handle global document key down events.
$(document).keydown(handleKeydownEvent);
// Handle clicks on source selection tabs.
$("#message_header .nav-tabs .nav-link").click(handleSourceSelection);
// Handle a click on the email download button.
$("#mailDownloadButton").click(function() {
// If no message selected, stop here.
if (selectedMessage==null) {
return;
}
// Setup the download path.
var downloadPath = "/api/message/"+selectedMessage.uuid+".eml";
// Create an link with a download file name to allow downloading without navigating away.
// This is done to avoid disconnection from the websocket.
var a = document.createElement("a");
a.href = downloadPath;
a.download = downloadPath.substr(downloadPath.lastIndexOf('/') + 1);
// Append the link, click it and remove it.
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
// Setup handlers for spam reporting.
$("#mailLearnHamButton").click(learnHam);
$("#mailLearnSpamButton").click(learnSpam);
// Check if a message uuid was provided in the location hash.
var hashParams = new URLSearchParams(window.location.hash.slice(1));
if (hashParams.has("uuid")) {
// If it was, we should load that message.
var uuid = hashParams.get("uuid");
loadMessage(uuid);
}
// Register for when the hash location has changed.
$(window).bind('hashchange', function(e) {
// Check if the UUID is provided in the updated hash location.
var hashParams = new URLSearchParams(window.location.hash.slice(1));
if (hashParams.has("uuid")) {
// If it was, we can load the message.
var uuid = hashParams.get("uuid");
loadMessage(uuid);
}
});
});