"no-negated-condition": "off", | "no-negated-condition": "off", | ||||
"no-plusplus": "off", | "no-plusplus": "off", | ||||
"no-ternary": "off", | "no-ternary": "off", | ||||
"no-var": "off", | |||||
"object-curly-newline": ["error", { "consistent": true }], | "object-curly-newline": ["error", { "consistent": true }], | ||||
"object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], | "object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], | ||||
"object-shorthand": "off", | "object-shorthand": "off", |
define(["jquery", "app/rspamd"], | define(["jquery", "app/rspamd"], | ||||
function ($, rspamd) { | function ($, rspamd) { | ||||
"use strict"; | "use strict"; | ||||
var ui = {}; | |||||
const ui = {}; | |||||
ui.getActions = function getActions(checked_server) { | ui.getActions = function getActions(checked_server) { | ||||
rspamd.query("actions", { | rspamd.query("actions", { | ||||
success: function (data) { | success: function (data) { | ||||
$("#actionsFormField").empty(); | $("#actionsFormField").empty(); | ||||
var items = []; | |||||
const items = []; | |||||
$.each(data[0].data, function (i, item) { | $.each(data[0].data, function (i, item) { | ||||
var actionsOrder = ["greylist", "add header", "rewrite subject", "reject"]; | |||||
var idx = actionsOrder.indexOf(item.action); | |||||
const actionsOrder = ["greylist", "add header", "rewrite subject", "reject"]; | |||||
const idx = actionsOrder.indexOf(item.action); | |||||
if (idx >= 0) { | if (idx >= 0) { | ||||
items.push({ | items.push({ | ||||
idx: idx, | idx: idx, | ||||
ui.saveActions = function (server) { | ui.saveActions = function (server) { | ||||
function descending(arr) { | function descending(arr) { | ||||
var desc = true; | |||||
var filtered = arr.filter(function (el) { | |||||
let desc = true; | |||||
const filtered = arr.filter(function (el) { | |||||
return el !== null; | return el !== null; | ||||
}); | }); | ||||
for (var i = 0; i < filtered.length - 1; i++) { | |||||
for (let i = 0; i < filtered.length - 1; i++) { | |||||
if (filtered[i + 1] >= filtered[i]) { | if (filtered[i + 1] >= filtered[i]) { | ||||
desc = false; | desc = false; | ||||
break; | break; | ||||
return desc; | return desc; | ||||
} | } | ||||
var elts = (function () { | |||||
var values = []; | |||||
var inputs = $("#actionsForm :input[data-id=\"action\"]"); | |||||
const elts = (function () { | |||||
const values = []; | |||||
const inputs = $("#actionsForm :input[data-id=\"action\"]"); | |||||
// Rspamd order: [spam, rewrite_subject, probable_spam, greylist] | // Rspamd order: [spam, rewrite_subject, probable_spam, greylist] | ||||
values[0] = parseFloat(inputs[3].value); | values[0] = parseFloat(inputs[3].value); | ||||
values[1] = parseFloat(inputs[2].value); | values[1] = parseFloat(inputs[2].value); | ||||
return JSON.stringify(values); | return JSON.stringify(values); | ||||
}()); | }()); | ||||
// String to array for comparison | // String to array for comparison | ||||
var eltsArray = JSON.parse(elts); | |||||
const eltsArray = JSON.parse(elts); | |||||
if (eltsArray[0] < 0) { | if (eltsArray[0] < 0) { | ||||
rspamd.alertMessage("alert-modal alert-error", "Spam can not be negative"); | rspamd.alertMessage("alert-modal alert-error", "Spam can not be negative"); | ||||
} else if (eltsArray[1] < 0) { | } else if (eltsArray[1] < 0) { | ||||
}; | }; | ||||
ui.getMaps = function (checked_server) { | ui.getMaps = function (checked_server) { | ||||
var $listmaps = $("#listMaps"); | |||||
const $listmaps = $("#listMaps"); | |||||
$listmaps.closest(".card").hide(); | $listmaps.closest(".card").hide(); | ||||
rspamd.query("maps", { | rspamd.query("maps", { | ||||
success: function (json) { | success: function (json) { | ||||
var data = json[0].data; | |||||
const data = json[0].data; | |||||
$listmaps.empty(); | $listmaps.empty(); | ||||
$("#modalBody").empty(); | $("#modalBody").empty(); | ||||
var $tbody = $("<tbody>"); | |||||
const $tbody = $("<tbody>"); | |||||
$.each(data, function (i, item) { | $.each(data, function (i, item) { | ||||
var $td = '<td><span class="badge text-bg-secondary">Read</span></td>'; | |||||
let $td = '<td><span class="badge text-bg-secondary">Read</span></td>'; | |||||
if (!(item.editable === false || rspamd.read_only)) { | if (!(item.editable === false || rspamd.read_only)) { | ||||
$td = $($td).append(' <span class="badge text-bg-success">Write</span>'); | $td = $($td).append(' <span class="badge text-bg-success">Write</span>'); | ||||
} | } | ||||
var $tr = $("<tr>").append($td); | |||||
const $tr = $("<tr>").append($td); | |||||
var $span = $('<span class="map-link" data-bs-toggle="modal" data-bs-target="#modalDialog">' + item.uri + "</span>").data("item", item); | |||||
const $span = $('<span class="map-link" data-bs-toggle="modal" data-bs-target="#modalDialog">' + item.uri + "</span>").data("item", item); | |||||
$span.wrap("<td>").parent().appendTo($tr); | $span.wrap("<td>").parent().appendTo($tr); | ||||
$("<td>" + item.description + "</td>").appendTo($tr); | $("<td>" + item.description + "</td>").appendTo($tr); | ||||
$tr.appendTo($tbody); | $tr.appendTo($tbody); | ||||
}; | }; | ||||
var jar = {}; | |||||
let jar = {}; | |||||
const editor = { | const editor = { | ||||
advanced: { | advanced: { | ||||
codejar: true, | codejar: true, | ||||
// Modal form for maps | // Modal form for maps | ||||
$(document).on("click", "[data-bs-toggle=\"modal\"]", function () { | $(document).on("click", "[data-bs-toggle=\"modal\"]", function () { | ||||
var checked_server = rspamd.getSelector("selSrv"); | |||||
var item = $(this).data("item"); | |||||
const checked_server = rspamd.getSelector("selSrv"); | |||||
const item = $(this).data("item"); | |||||
rspamd.query("getmap", { | rspamd.query("getmap", { | ||||
headers: { | headers: { | ||||
Map: item.map | Map: item.map | ||||
document.querySelector("#editor").innerHTML = rspamd.escapeHTML(data[0].data); | document.querySelector("#editor").innerHTML = rspamd.escapeHTML(data[0].data); | ||||
} | } | ||||
var icon = "fa-edit"; | |||||
let icon = "fa-edit"; | |||||
if (item.editable === false || rspamd.read_only) { | if (item.editable === false || rspamd.read_only) { | ||||
$("#editor").attr(editor[mode].readonly_attr); | $("#editor").attr(editor[mode].readonly_attr); | ||||
icon = "fa-eye"; | icon = "fa-eye"; |
function ($, rspamd, D3Evolution, D3Pie, d3) { | function ($, rspamd, D3Evolution, D3Pie, d3) { | ||||
"use strict"; | "use strict"; | ||||
var rrd_pie_config = { | |||||
const rrd_pie_config = { | |||||
cornerRadius: 2, | cornerRadius: 2, | ||||
size: { | size: { | ||||
canvasWidth: 400, | canvasWidth: 400, | ||||
}, | }, | ||||
}; | }; | ||||
var ui = {}; | |||||
var prevUnit = "msg/s"; | |||||
const ui = {}; | |||||
let prevUnit = "msg/s"; | |||||
ui.draw = function (graphs, neighbours, checked_server, type) { | ui.draw = function (graphs, neighbours, checked_server, type) { | ||||
var graph_options = { | |||||
const graph_options = { | |||||
title: "Rspamd throughput", | title: "Rspamd throughput", | ||||
width: 1060, | width: 1060, | ||||
height: 370, | height: 370, | ||||
}; | }; | ||||
function initGraph() { | function initGraph() { | ||||
var graph = new D3Evolution("graph", $.extend({}, graph_options, { | |||||
const graph = new D3Evolution("graph", $.extend({}, graph_options, { | |||||
yScale: rspamd.getSelector("selYScale"), | yScale: rspamd.getSelector("selYScale"), | ||||
type: rspamd.getSelector("selType"), | type: rspamd.getSelector("selType"), | ||||
interpolate: rspamd.getSelector("selInterpolate"), | interpolate: rspamd.getSelector("selInterpolate"), | ||||
} | } | ||||
function getRrdSummary(json, scaleFactor) { | function getRrdSummary(json, scaleFactor) { | ||||
var xExtents = d3.extent(d3.merge(json), function (d) { return d.x; }); | |||||
var timeInterval = xExtents[1] - xExtents[0]; | |||||
const xExtents = d3.extent(d3.merge(json), function (d) { return d.x; }); | |||||
const timeInterval = xExtents[1] - xExtents[0]; | |||||
var total = 0; | |||||
var rows = json.map(function (curr, i) { | |||||
let total = 0; | |||||
const rows = json.map(function (curr, i) { | |||||
// Time intervals that don't have data are excluded from average calculation as d3.mean()ignores nulls | // Time intervals that don't have data are excluded from average calculation as d3.mean()ignores nulls | ||||
var avg = d3.mean(curr, function (d) { return d.y; }); | |||||
const avg = d3.mean(curr, function (d) { return d.y; }); | |||||
// To find an integral on the whole time interval we need to convert nulls to zeroes | // To find an integral on the whole time interval we need to convert nulls to zeroes | ||||
var value = d3.mean(curr, function (d) { return Number(d.y); }) * timeInterval / scaleFactor ^ 0; // eslint-disable-line no-bitwise | |||||
var yExtents = d3.extent(curr, function (d) { return d.y; }); | |||||
const value = d3.mean(curr, function (d) { return Number(d.y); }) * timeInterval / scaleFactor ^ 0; // eslint-disable-line no-bitwise | |||||
const yExtents = d3.extent(curr, function (d) { return d.y; }); | |||||
total += value; | total += value; | ||||
return { | return { | ||||
} | } | ||||
function updateWidgets(data) { | function updateWidgets(data) { | ||||
var rrd_summary = {rows:[]}; | |||||
var unit = "msg/s"; | |||||
let rrd_summary = {rows:[]}; | |||||
let unit = "msg/s"; | |||||
if (data) { | if (data) { | ||||
// Autoranging | // Autoranging | ||||
var scaleFactor = 1; | |||||
var yMax = d3.max(d3.merge(data), function (d) { return d.y; }); | |||||
let scaleFactor = 1; | |||||
const yMax = d3.max(d3.merge(data), function (d) { return d.y; }); | |||||
if (yMax < 1) { | if (yMax < 1) { | ||||
scaleFactor = 60; | scaleFactor = 60; | ||||
unit = "msg/min"; | unit = "msg/min"; | ||||
rspamd.query("graph", { | rspamd.query("graph", { | ||||
success: function (req_data) { | success: function (req_data) { | ||||
var data = null; | |||||
var neighbours_data = req_data | |||||
let data = null; | |||||
const neighbours_data = req_data | |||||
.filter(function (d) { return d.status; }) // filter out unavailable neighbours | .filter(function (d) { return d.status; }) // filter out unavailable neighbours | ||||
.map(function (d) { return d.data; }); | .map(function (d) { return d.data; }); | ||||
if (neighbours_data.length === 1) { | if (neighbours_data.length === 1) { | ||||
data = neighbours_data[0]; | data = neighbours_data[0]; | ||||
} else { | } else { | ||||
var time_match = true; | |||||
let time_match = true; | |||||
neighbours_data.reduce(function (res, curr, _, arr) { | neighbours_data.reduce(function (res, curr, _, arr) { | ||||
if ((curr[0][0].x !== res[0][0].x) || | if ((curr[0][0].x !== res[0][0].x) || | ||||
(curr[0][curr[0].length - 1].x !== res[0][res[0].length - 1].x)) { | (curr[0][curr[0].length - 1].x !== res[0][res[0].length - 1].x)) { |
define(["jquery", "app/rspamd", "d3", "footable"], | define(["jquery", "app/rspamd", "d3", "footable"], | ||||
function ($, rspamd, d3) { | function ($, rspamd, d3) { | ||||
"use strict"; | "use strict"; | ||||
var ui = {}; | |||||
var prevVersion = null; | |||||
const ui = {}; | |||||
let prevVersion = null; | |||||
function process_history_legacy(data) { | function process_history_legacy(data) { | ||||
var items = []; | |||||
const items = []; | |||||
var compare = function (e1, e2) { | |||||
const compare = function (e1, e2) { | |||||
return e1.name.localeCompare(e2.name); | return e1.name.localeCompare(e2.name); | ||||
}; | }; | ||||
}]; | }]; | ||||
} | } | ||||
var columns = { | |||||
const columns = { | |||||
2: columns_v2, | 2: columns_v2, | ||||
legacy: columns_legacy | legacy: columns_legacy | ||||
}; | }; | ||||
function process_history_data(data) { | function process_history_data(data) { | ||||
var process_functions = { | |||||
const process_functions = { | |||||
2: rspamd.process_history_v2, | 2: rspamd.process_history_v2, | ||||
legacy: process_history_legacy | legacy: process_history_legacy | ||||
}; | }; | ||||
var pf = process_functions.legacy; | |||||
let pf = process_functions.legacy; | |||||
if (data.version) { | if (data.version) { | ||||
var strkey = data.version.toString(); | |||||
const strkey = data.version.toString(); | |||||
if (process_functions[strkey]) { | if (process_functions[strkey]) { | ||||
pf = process_functions[strkey]; | pf = process_functions[strkey]; | ||||
} | } | ||||
} | } | ||||
function get_history_columns(data) { | function get_history_columns(data) { | ||||
var func = columns.legacy; | |||||
let func = columns.legacy; | |||||
if (data.version) { | if (data.version) { | ||||
var strkey = data.version.toString(); | |||||
const strkey = data.version.toString(); | |||||
if (columns[strkey]) { | if (columns[strkey]) { | ||||
func = columns[strkey]; | func = columns[strkey]; | ||||
} | } | ||||
rspamd.query("history", { | rspamd.query("history", { | ||||
success: function (req_data) { | success: function (req_data) { | ||||
function differentVersions(neighbours_data) { | function differentVersions(neighbours_data) { | ||||
var dv = neighbours_data.some(function (e) { | |||||
const dv = neighbours_data.some(function (e) { | |||||
return e.version !== neighbours_data[0].version; | return e.version !== neighbours_data[0].version; | ||||
}); | }); | ||||
if (dv) { | if (dv) { | ||||
return false; | return false; | ||||
} | } | ||||
var neighbours_data = req_data | |||||
const neighbours_data = req_data | |||||
.filter(function (d) { return d.status; }) // filter out unavailable neighbours | .filter(function (d) { return d.status; }) // filter out unavailable neighbours | ||||
.map(function (d) { return d.data; }); | .map(function (d) { return d.data; }); | ||||
if (neighbours_data.length && !differentVersions(neighbours_data)) { | if (neighbours_data.length && !differentVersions(neighbours_data)) { | ||||
var data = {}; | |||||
var version = neighbours_data[0].version; | |||||
let data = {}; | |||||
const version = neighbours_data[0].version; | |||||
if (version) { | if (version) { | ||||
data.rows = [].concat.apply([], neighbours_data | data.rows = [].concat.apply([], neighbours_data | ||||
.map(function (e) { | .map(function (e) { | ||||
data = [].concat.apply([], neighbours_data); | data = [].concat.apply([], neighbours_data); | ||||
$("#legacy-history-badge").show(); | $("#legacy-history-badge").show(); | ||||
} | } | ||||
var o = process_history_data(data); | |||||
var items = o.items; | |||||
const o = process_history_data(data); | |||||
const items = o.items; | |||||
rspamd.symbols.history = o.symbols; | rspamd.symbols.history = o.symbols; | ||||
if (Object.prototype.hasOwnProperty.call(rspamd.tables, "history") && | if (Object.prototype.hasOwnProperty.call(rspamd.tables, "history") && | ||||
rspamd.query("errors", { | rspamd.query("errors", { | ||||
success: function (data) { | success: function (data) { | ||||
var neighbours_data = data | |||||
const neighbours_data = data | |||||
.filter(function (d) { | .filter(function (d) { | ||||
return d.status; | return d.status; | ||||
}) // filter out unavailable neighbours | }) // filter out unavailable neighbours | ||||
.map(function (d) { | .map(function (d) { | ||||
return d.data; | return d.data; | ||||
}); | }); | ||||
var rows = [].concat.apply([], neighbours_data); | |||||
const rows = [].concat.apply([], neighbours_data); | |||||
$.each(rows, function (i, item) { | $.each(rows, function (i, item) { | ||||
item.ts = { | item.ts = { | ||||
value: rspamd.unix_time_format(item.ts), | value: rspamd.unix_time_format(item.ts), |
"bootstrap", "fontawesome"], | "bootstrap", "fontawesome"], | ||||
function ($, NProgress) { | function ($, NProgress) { | ||||
"use strict"; | "use strict"; | ||||
var ui = { | |||||
const ui = { | |||||
chartLegend: [ | chartLegend: [ | ||||
{label: "reject", color: "#FF0000"}, | {label: "reject", color: "#FF0000"}, | ||||
{label: "soft reject", color: "#BF8040"}, | {label: "soft reject", color: "#BF8040"}, | ||||
const defaultAjaxTimeout = 20000; | const defaultAjaxTimeout = 20000; | ||||
const ajaxTimeoutBox = ".popover #settings-popover #ajax-timeout"; | const ajaxTimeoutBox = ".popover #settings-popover #ajax-timeout"; | ||||
var graphs = {}; | |||||
var tables = {}; | |||||
var neighbours = []; // list of clusters | |||||
var checked_server = "All SERVERS"; | |||||
var timer_id = []; | |||||
const graphs = {}; | |||||
const tables = {}; | |||||
let neighbours = []; // list of clusters | |||||
let checked_server = "All SERVERS"; | |||||
const timer_id = []; | |||||
let pageSizeTimerId = null; | let pageSizeTimerId = null; | ||||
let pageSizeInvocationCounter = 0; | let pageSizeInvocationCounter = 0; | ||||
var locale = (localStorage.getItem("selected_locale") === "custom") ? localStorage.getItem("custom_locale") : null; | |||||
let locale = (localStorage.getItem("selected_locale") === "custom") ? localStorage.getItem("custom_locale") : null; | |||||
NProgress.configure({ | NProgress.configure({ | ||||
minimum: 0.01, | minimum: 0.01, | ||||
} | } | ||||
function stopTimers() { | function stopTimers() { | ||||
for (var key in timer_id) { | |||||
for (const key in timer_id) { | |||||
if (!{}.hasOwnProperty.call(timer_id, key)) continue; | if (!{}.hasOwnProperty.call(timer_id, key)) continue; | ||||
Visibility.stop(timer_id[key]); | Visibility.stop(timer_id[key]); | ||||
} | } | ||||
// Get selectors' current state | // Get selectors' current state | ||||
function getSelector(id) { | function getSelector(id) { | ||||
var e = document.getElementById(id); | |||||
const e = document.getElementById(id); | |||||
return e.options[e.selectedIndex].value; | return e.options[e.selectedIndex].value; | ||||
} | } | ||||
function tabClick(id) { | function tabClick(id) { | ||||
var tab_id = id; | |||||
let tab_id = id; | |||||
if ($(id).attr("disabled")) return; | if ($(id).attr("disabled")) return; | ||||
var navBarControls = $("#selSrv, #navBar li, #navBar a, #navBar button"); | |||||
let navBarControls = $("#selSrv, #navBar li, #navBar a, #navBar button"); | |||||
if (id !== "#autoRefresh") navBarControls.attr("disabled", true).addClass("disabled", true); | if (id !== "#autoRefresh") navBarControls.attr("disabled", true).addClass("disabled", true); | ||||
stopTimers(); | stopTimers(); | ||||
return; | return; | ||||
} | } | ||||
var timeLeft = interval; | |||||
let timeLeft = interval; | |||||
$("#countdown").text("00:00"); | $("#countdown").text("00:00"); | ||||
timer_id.countdown = Visibility.every(1000, 1000, function () { | timer_id.countdown = Visibility.every(1000, 1000, function () { | ||||
timeLeft -= 1000; | timeLeft -= 1000; | ||||
switch (tab_id) { | switch (tab_id) { | ||||
case "#status_nav": | case "#status_nav": | ||||
require(["app/stats"], (module) => { | require(["app/stats"], (module) => { | ||||
var refreshInterval = $(".dropdown-menu a.active.preset").data("value"); | |||||
const refreshInterval = $(".dropdown-menu a.active.preset").data("value"); | |||||
setAutoRefresh(refreshInterval, "status", | setAutoRefresh(refreshInterval, "status", | ||||
function () { return module.statWidgets(graphs, checked_server); }); | function () { return module.statWidgets(graphs, checked_server); }); | ||||
if (id !== "#autoRefresh") module.statWidgets(graphs, checked_server); | if (id !== "#autoRefresh") module.statWidgets(graphs, checked_server); | ||||
case "#throughput_nav": | case "#throughput_nav": | ||||
require(["app/graph"], (module) => { | require(["app/graph"], (module) => { | ||||
const selData = getSelector("selData"); // Graph's dataset selector state | const selData = getSelector("selData"); // Graph's dataset selector state | ||||
var step = { | |||||
const step = { | |||||
day: 60000, | day: 60000, | ||||
week: 300000 | week: 300000 | ||||
}; | }; | ||||
var refreshInterval = step[selData] || 3600000; | |||||
let refreshInterval = step[selData] || 3600000; | |||||
$("#dynamic-item").text((refreshInterval / 60000) + " min"); | $("#dynamic-item").text((refreshInterval / 60000) + " min"); | ||||
if (!$(".dropdown-menu a.active.dynamic").data("value")) { | if (!$(".dropdown-menu a.active.dynamic").data("value")) { | ||||
module.getHistory(); | module.getHistory(); | ||||
module.getErrors(); | module.getErrors(); | ||||
} | } | ||||
var refreshInterval = $(".dropdown-menu a.active.history").data("value"); | |||||
const refreshInterval = $(".dropdown-menu a.active.history").data("value"); | |||||
setAutoRefresh(refreshInterval, "history", | setAutoRefresh(refreshInterval, "history", | ||||
function () { return getHistoryAndErrors(); }); | function () { return getHistoryAndErrors(); }); | ||||
if (id !== "#autoRefresh") getHistoryAndErrors(); | if (id !== "#autoRefresh") getHistoryAndErrors(); | ||||
} | } | ||||
function get_compare_function(table) { | function get_compare_function(table) { | ||||
var compare_functions = { | |||||
const compare_functions = { | |||||
magnitude: function (e1, e2) { | magnitude: function (e1, e2) { | ||||
return Math.abs(e2.score) - Math.abs(e1.score); | return Math.abs(e2.score) - Math.abs(e1.score); | ||||
}, | }, | ||||
} | } | ||||
function set_page_size(table, page_size, changeTablePageSize) { | function set_page_size(table, page_size, changeTablePageSize) { | ||||
var n = parseInt(page_size, 10); // HTML Input elements return string representing a number | |||||
const n = parseInt(page_size, 10); // HTML Input elements return string representing a number | |||||
if (n > 0) { | if (n > 0) { | ||||
ui.page_size[table] = n; | ui.page_size[table] = n; | ||||
} | } | ||||
function unix_time_format(tm) { | function unix_time_format(tm) { | ||||
var date = new Date(tm ? tm * 1000 : 0); | |||||
const date = new Date(tm ? tm * 1000 : 0); | |||||
return (locale) | return (locale) | ||||
? date.toLocaleString(locale) | ? date.toLocaleString(locale) | ||||
: date.toLocaleString(); | : date.toLocaleString(); | ||||
} | } | ||||
function alertMessage(alertClass, alertText) { | function alertMessage(alertClass, alertText) { | ||||
var a = $("<div class=\"alert " + alertClass + " alert-dismissible fade in show\">" + | |||||
const a = $("<div class=\"alert " + alertClass + " alert-dismissible fade in show\">" + | |||||
"<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" title=\"Dismiss\"></button>" + | "<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" title=\"Dismiss\"></button>" + | ||||
"<strong>" + alertText + "</strong>"); | "<strong>" + alertText + "</strong>"); | ||||
$(".notification-area").append(a); | $(".notification-area").append(a); | ||||
neighbours_status[ind].checked = false; | neighbours_status[ind].checked = false; | ||||
neighbours_status[ind].data = {}; | neighbours_status[ind].data = {}; | ||||
neighbours_status[ind].status = false; | neighbours_status[ind].status = false; | ||||
var req_params = { | |||||
const req_params = { | |||||
jsonp: false, | jsonp: false, | ||||
data: o.data, | data: o.data, | ||||
headers: $.extend({Password:getPassword()}, o.headers), | headers: $.extend({Password:getPassword()}, o.headers), | ||||
url: neighbours_status[ind].url + req_url, | url: neighbours_status[ind].url + req_url, | ||||
xhr: function () { | xhr: function () { | ||||
var xhr = $.ajaxSettings.xhr(); | |||||
const xhr = $.ajaxSettings.xhr(); | |||||
// Download progress | // Download progress | ||||
if (req_url !== "neighbours") { | if (req_url !== "neighbours") { | ||||
xhr.addEventListener("progress", function (e) { | xhr.addEventListener("progress", function (e) { | ||||
if (e.lengthComputable) { | if (e.lengthComputable) { | ||||
neighbours_status[ind].percentComplete = e.loaded / e.total; | neighbours_status[ind].percentComplete = e.loaded / e.total; | ||||
var percentComplete = neighbours_status.reduce(function (prev, curr) { | |||||
const percentComplete = neighbours_status.reduce(function (prev, curr) { | |||||
return curr.percentComplete ? curr.percentComplete + prev : prev; | return curr.percentComplete ? curr.percentComplete + prev : prev; | ||||
}, 0); | }, 0); | ||||
NProgress.set(percentComplete / neighbours_status.length); | NProgress.set(percentComplete / neighbours_status.length); | ||||
o.error(neighbours_status[ind], | o.error(neighbours_status[ind], | ||||
jqXHR, textStatus, errorThrown); | jqXHR, textStatus, errorThrown); | ||||
} else if (o.errorOnceId) { | } else if (o.errorOnceId) { | ||||
var alert_status = o.errorOnceId + neighbours_status[ind].name; | |||||
const alert_status = o.errorOnceId + neighbours_status[ind].name; | |||||
if (!(alert_status in sessionStorage)) { | if (!(alert_status in sessionStorage)) { | ||||
sessionStorage.setItem(alert_status, true); | sessionStorage.setItem(alert_status, true); | ||||
errorMessage(); | errorMessage(); | ||||
$("#connectForm").off("submit").on("submit", function (e) { | $("#connectForm").off("submit").on("submit", function (e) { | ||||
e.preventDefault(); | e.preventDefault(); | ||||
var password = $("#connectPassword").val(); | |||||
const password = $("#connectPassword").val(); | |||||
function invalidFeedback(tooltip) { | function invalidFeedback(tooltip) { | ||||
$("#connectPassword") | $("#connectPassword") | ||||
Password: password | Password: password | ||||
}, | }, | ||||
success: function (json) { | success: function (json) { | ||||
var data = json[0].data; | |||||
const data = json[0].data; | |||||
$("#connectPassword").val(""); | $("#connectPassword").val(""); | ||||
if (data.auth === "ok") { | if (data.auth === "ok") { | ||||
sessionStorage.setItem("read_only", data.read_only); | sessionStorage.setItem("read_only", data.read_only); | ||||
*/ | */ | ||||
ui.query = function (url, options) { | ui.query = function (url, options) { | ||||
// Force options to be an object | // Force options to be an object | ||||
var o = options || {}; | |||||
const o = options || {}; | |||||
Object.keys(o).forEach(function (option) { | Object.keys(o).forEach(function (option) { | ||||
if (["complete", "data", "error", "errorMessage", "errorOnceId", "headers", "method", "params", "server", "statusCode", | if (["complete", "data", "error", "errorMessage", "errorOnceId", "headers", "method", "params", "server", "statusCode", | ||||
"success"] | "success"] | ||||
} | } | ||||
}); | }); | ||||
var neighbours_status = [{ | |||||
let neighbours_status = [{ | |||||
name: "local", | name: "local", | ||||
host: "local", | host: "local", | ||||
url: "", | url: "", | ||||
if (o.server === "All SERVERS") { | if (o.server === "All SERVERS") { | ||||
queryServer(neighbours_status, 0, "neighbours", { | queryServer(neighbours_status, 0, "neighbours", { | ||||
success: function (json) { | success: function (json) { | ||||
var data = json[0].data; | |||||
const data = json[0].data; | |||||
if (jQuery.isEmptyObject(data)) { | if (jQuery.isEmptyObject(data)) { | ||||
neighbours = { | neighbours = { | ||||
local: { | local: { | ||||
ui.bindHistoryTableEventHandlers = function (table, symbolsCol) { | ui.bindHistoryTableEventHandlers = function (table, symbolsCol) { | ||||
function change_symbols_order(order) { | function change_symbols_order(order) { | ||||
$(".btn-sym-" + table + "-" + order).addClass("active").siblings().removeClass("active"); | $(".btn-sym-" + table + "-" + order).addClass("active").siblings().removeClass("active"); | ||||
var compare_function = get_compare_function(table); | |||||
const compare_function = get_compare_function(table); | |||||
$.each(tables[table].rows.all, function (i, row) { | $.each(tables[table].rows.all, function (i, row) { | ||||
var cell_val = sort_symbols(ui.symbols[table][i], compare_function); | |||||
const cell_val = sort_symbols(ui.symbols[table][i], compare_function); | |||||
row.cells[symbolsCol].val(cell_val, false, true); | row.cells[symbolsCol].val(cell_val, false, true); | ||||
}); | }); | ||||
} | } | ||||
$("#selSymOrder_" + table).unbind().change(function () { | $("#selSymOrder_" + table).unbind().change(function () { | ||||
var order = this.value; | |||||
const order = this.value; | |||||
change_symbols_order(order); | change_symbols_order(order); | ||||
}); | }); | ||||
$("#" + table + "_page_size").change((e) => set_page_size(table, e.target.value, true)); | $("#" + table + "_page_size").change((e) => set_page_size(table, e.target.value, true)); | ||||
$(document).on("click", ".btn-sym-order-" + table + " input", function () { | $(document).on("click", ".btn-sym-order-" + table + " input", function () { | ||||
var order = this.value; | |||||
const order = this.value; | |||||
$("#selSymOrder_" + table).val(order); | $("#selSymOrder_" + table).val(order); | ||||
change_symbols_order(order); | change_symbols_order(order); | ||||
}); | }); | ||||
on: { | on: { | ||||
"expand.ft.row": function (e, ft, row) { | "expand.ft.row": function (e, ft, row) { | ||||
setTimeout(function () { | setTimeout(function () { | ||||
var detail_row = row.$el.next(); | |||||
var order = getSelector("selSymOrder_" + table); | |||||
const detail_row = row.$el.next(); | |||||
const order = getSelector("selSymOrder_" + table); | |||||
detail_row.find(".btn-sym-" + table + "-" + order) | detail_row.find(".btn-sym-" + table + "-" + order) | ||||
.addClass("active").siblings().removeClass("active"); | .addClass("active").siblings().removeClass("active"); | ||||
}, 5); | }, 5); | ||||
}; | }; | ||||
ui.escapeHTML = function (string) { | ui.escapeHTML = function (string) { | ||||
var htmlEscaper = /[&<>"'/`=]/g; | |||||
var htmlEscapes = { | |||||
const htmlEscaper = /[&<>"'/`=]/g; | |||||
const htmlEscapes = { | |||||
"&": "&", | "&": "&", | ||||
"<": "<", | "<": "<", | ||||
">": ">", | ">": ">", | ||||
arr.forEach(function (d, i) { arr[i] = ui.escapeHTML(d); }); | arr.forEach(function (d, i) { arr[i] = ui.escapeHTML(d); }); | ||||
} | } | ||||
for (var prop in item) { | |||||
for (const prop in item) { | |||||
if (!{}.hasOwnProperty.call(item, prop)) continue; | if (!{}.hasOwnProperty.call(item, prop)) continue; | ||||
switch (prop) { | switch (prop) { | ||||
case "rcpt_mime": | case "rcpt_mime": | ||||
break; | break; | ||||
case "symbols": | case "symbols": | ||||
Object.keys(item.symbols).forEach(function (key) { | Object.keys(item.symbols).forEach(function (key) { | ||||
var sym = item.symbols[key]; | |||||
const sym = item.symbols[key]; | |||||
if (!sym.name) { | if (!sym.name) { | ||||
sym.name = key; | sym.name = key; | ||||
} | } | ||||
item.action = "<div style='font-size:11px' class='badge text-bg-info'>" + item.action + "</div>"; | item.action = "<div style='font-size:11px' class='badge text-bg-info'>" + item.action + "</div>"; | ||||
} | } | ||||
var score_content = (item.score < item.required_score) | |||||
const score_content = (item.score < item.required_score) | |||||
? "<span class='text-success'>" + item.score.toFixed(2) + " / " + item.required_score + "</span>" | ? "<span class='text-success'>" + item.score.toFixed(2) + " / " + item.required_score + "</span>" | ||||
: "<span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span>"; | : "<span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span>"; | ||||
ui.process_history_v2 = function (data, table) { | ui.process_history_v2 = function (data, table) { | ||||
// Display no more than rcpt_lim recipients | // Display no more than rcpt_lim recipients | ||||
var rcpt_lim = 3; | |||||
var items = []; | |||||
var unsorted_symbols = []; | |||||
var compare_function = get_compare_function(table); | |||||
const rcpt_lim = 3; | |||||
const items = []; | |||||
const unsorted_symbols = []; | |||||
const compare_function = get_compare_function(table); | |||||
$("#selSymOrder_" + table + ", label[for='selSymOrder_" + table + "']").show(); | $("#selSymOrder_" + table + ", label[for='selSymOrder_" + table + "']").show(); | ||||
$.each(data.rows, | $.each(data.rows, | ||||
function (i, item) { | function (i, item) { | ||||
function more(p) { | function more(p) { | ||||
var l = item[p].length; | |||||
const l = item[p].length; | |||||
return (l > rcpt_lim) ? " … (" + l + ")" : ""; | return (l > rcpt_lim) ? " … (" + l + ")" : ""; | ||||
} | } | ||||
function format_rcpt(smtp, mime) { | function format_rcpt(smtp, mime) { | ||||
var full = ""; | |||||
var shrt = ""; | |||||
let full = ""; | |||||
let shrt = ""; | |||||
if (smtp) { | if (smtp) { | ||||
full = "[" + item.rcpt_smtp.join(", ") + "] "; | full = "[" + item.rcpt_smtp.join(", ") + "] "; | ||||
shrt = "[" + item.rcpt_smtp.slice(0, rcpt_lim).join(",​") + more("rcpt_smtp") + "]"; | shrt = "[" + item.rcpt_smtp.slice(0, rcpt_lim).join(",​") + more("rcpt_smtp") + "]"; | ||||
item.id = item["message-id"]; | item.id = item["message-id"]; | ||||
if (table === "history") { | if (table === "history") { | ||||
var rcpt = {}; | |||||
let rcpt = {}; | |||||
if (!item.rcpt_mime.length) { | if (!item.rcpt_mime.length) { | ||||
rcpt = format_rcpt(true, false); | rcpt = format_rcpt(true, false); | ||||
} else if ($(item.rcpt_mime).not(item.rcpt_smtp).length !== 0 || $(item.rcpt_smtp).not(item.rcpt_mime).length !== 0) { | } else if ($(item.rcpt_mime).not(item.rcpt_smtp).length !== 0 || $(item.rcpt_smtp).not(item.rcpt_mime).length !== 0) { | ||||
}; | }; | ||||
ui.waitForRowsDisplayed = function (table, rows_total, callback, iteration) { | ui.waitForRowsDisplayed = function (table, rows_total, callback, iteration) { | ||||
var i = (typeof iteration === "undefined") ? 10 : iteration; | |||||
var num_rows = $("#historyTable_" + table + " > tbody > tr:not(.footable-detail-row)").length; | |||||
let i = (typeof iteration === "undefined") ? 10 : iteration; | |||||
const num_rows = $("#historyTable_" + table + " > tbody > tr:not(.footable-detail-row)").length; | |||||
if (num_rows === ui.page_size[table] || | if (num_rows === ui.page_size[table] || | ||||
num_rows === rows_total) { | num_rows === rows_total) { | ||||
return callback(); | return callback(); | ||||
(function initSettings() { | (function initSettings() { | ||||
var selected_locale = null; | |||||
var custom_locale = null; | |||||
let selected_locale = null; | |||||
let custom_locale = null; | |||||
const localeTextbox = ".popover #settings-popover #locale"; | const localeTextbox = ".popover #settings-popover #locale"; | ||||
function validateLocale(saveToLocalStorage) { | function validateLocale(saveToLocalStorage) { | ||||
$(localeTextbox).removeClass("is-" + remove).addClass("is-" + add); | $(localeTextbox).removeClass("is-" + remove).addClass("is-" + add); | ||||
} | } | ||||
var now = new Date(); | |||||
const now = new Date(); | |||||
if (custom_locale.length) { | if (custom_locale.length) { | ||||
try { | try { | ||||
}); | }); | ||||
$(".dropdown-menu a").click(function (e) { | $(".dropdown-menu a").click(function (e) { | ||||
e.preventDefault(); | e.preventDefault(); | ||||
var classList = $(this).attr("class"); | |||||
var menuClass = (/\b(?:dynamic|history|preset)\b/).exec(classList)[0]; | |||||
const classList = $(this).attr("class"); | |||||
const menuClass = (/\b(?:dynamic|history|preset)\b/).exec(classList)[0]; | |||||
$(".dropdown-menu a.active." + menuClass).removeClass("active"); | $(".dropdown-menu a.active." + menuClass).removeClass("active"); | ||||
$(this).addClass("active"); | $(this).addClass("active"); | ||||
tabClick("#autoRefresh"); | tabClick("#autoRefresh"); |
define(["jquery", "app/rspamd"], | define(["jquery", "app/rspamd"], | ||||
function ($, rspamd) { | function ($, rspamd) { | ||||
"use strict"; | "use strict"; | ||||
var ui = {}; | |||||
const ui = {}; | |||||
function enable_disable_check_btn() { | function enable_disable_check_btn() { | ||||
$("#selectorsChkMsgBtn").prop("disabled", ( | $("#selectorsChkMsgBtn").prop("disabled", ( | ||||
} | } | ||||
function get_server() { | function get_server() { | ||||
var checked_server = rspamd.getSelector("selSrv"); | |||||
const checked_server = rspamd.getSelector("selSrv"); | |||||
return (checked_server === "All SERVERS") ? "local" : checked_server; | return (checked_server === "All SERVERS") ? "local" : checked_server; | ||||
} | } | ||||
function checkMsg(data) { | function checkMsg(data) { | ||||
var selector = $("#selectorsSelArea").val(); | |||||
const selector = $("#selectorsSelArea").val(); | |||||
rspamd.query("plugins/selectors/check_message?selector=" + encodeURIComponent(selector), { | rspamd.query("plugins/selectors/check_message?selector=" + encodeURIComponent(selector), { | ||||
data: data, | data: data, | ||||
method: "POST", | method: "POST", | ||||
success: function (neighbours_status) { | success: function (neighbours_status) { | ||||
var json = neighbours_status[0].data; | |||||
const json = neighbours_status[0].data; | |||||
if (json.success) { | if (json.success) { | ||||
rspamd.alertMessage("alert-success", "Message successfully processed"); | rspamd.alertMessage("alert-success", "Message successfully processed"); | ||||
$("#selectorsResArea") | $("#selectorsResArea") | ||||
$("#selectorsSelArea").removeClass("is-" + remove).addClass("is-" + add); | $("#selectorsSelArea").removeClass("is-" + remove).addClass("is-" + add); | ||||
enable_disable_check_btn(); | enable_disable_check_btn(); | ||||
} | } | ||||
var selector = $("#selectorsSelArea").val(); | |||||
const selector = $("#selectorsSelArea").val(); | |||||
if (selector.length && !rspamd.read_only ) { | if (selector.length && !rspamd.read_only ) { | ||||
rspamd.query("plugins/selectors/check_selector?selector=" + encodeURIComponent(selector), { | rspamd.query("plugins/selectors/check_selector?selector=" + encodeURIComponent(selector), { | ||||
method: "GET", | method: "GET", | ||||
function buildLists() { | function buildLists() { | ||||
function build_table_from_json(json, table_id) { | function build_table_from_json(json, table_id) { | ||||
Object.keys(json).forEach(function (key) { | Object.keys(json).forEach(function (key) { | ||||
var td = $("<td/>"); | |||||
var tr = $("<tr/>") | |||||
const td = $("<td/>"); | |||||
const tr = $("<tr/>") | |||||
.append(td.clone().html("<code>" + key + "</code>")) | .append(td.clone().html("<code>" + key + "</code>")) | ||||
.append(td.clone().html(json[key].description)); | .append(td.clone().html(json[key].description)); | ||||
$(table_id + " tbody").append(tr); | $(table_id + " tbody").append(tr); | ||||
rspamd.query("plugins/selectors/list_" + list, { | rspamd.query("plugins/selectors/list_" + list, { | ||||
method: "GET", | method: "GET", | ||||
success: function (neighbours_status) { | success: function (neighbours_status) { | ||||
var json = neighbours_status[0].data; | |||||
const json = neighbours_status[0].data; | |||||
build_table_from_json(json, "#selectorsTable-" + list); | build_table_from_json(json, "#selectorsTable-" + list); | ||||
}, | }, | ||||
server: get_server() | server: get_server() | ||||
function toggleSidebar(side) { | function toggleSidebar(side) { | ||||
$("#sidebar-" + side).toggleClass("collapsed"); | $("#sidebar-" + side).toggleClass("collapsed"); | ||||
var contentClass = "col-lg-6"; | |||||
var openSidebarsCount = $("#sidebar-left").hasClass("collapsed") + | |||||
let contentClass = "col-lg-6"; | |||||
const openSidebarsCount = $("#sidebar-left").hasClass("collapsed") + | |||||
$("#sidebar-right").hasClass("collapsed"); | $("#sidebar-right").hasClass("collapsed"); | ||||
switch (openSidebarsCount) { | switch (openSidebarsCount) { | ||||
case 1: | case 1: |
function msToTime(seconds) { | function msToTime(seconds) { | ||||
if (!Number.isFinite(seconds)) return "???"; | if (!Number.isFinite(seconds)) return "???"; | ||||
/* eslint-disable no-bitwise */ | /* eslint-disable no-bitwise */ | ||||
var years = seconds / 31536000 >> 0; // 3600*24*365 | |||||
var months = seconds % 31536000 / 2628000 >> 0; // 3600*24*365/12 | |||||
var days = seconds % 31536000 % 2628000 / 86400 >> 0; // 24*3600 | |||||
var hours = seconds % 31536000 % 2628000 % 86400 / 3600 >> 0; | |||||
var minutes = seconds % 31536000 % 2628000 % 86400 % 3600 / 60 >> 0; | |||||
const years = seconds / 31536000 >> 0; // 3600*24*365 | |||||
const months = seconds % 31536000 / 2628000 >> 0; // 3600*24*365/12 | |||||
const days = seconds % 31536000 % 2628000 / 86400 >> 0; // 24*3600 | |||||
const hours = seconds % 31536000 % 2628000 % 86400 / 3600 >> 0; | |||||
const minutes = seconds % 31536000 % 2628000 % 86400 % 3600 / 60 >> 0; | |||||
/* eslint-enable no-bitwise */ | /* eslint-enable no-bitwise */ | ||||
var out = null; | |||||
let out = null; | |||||
if (years > 0) { | if (years > 0) { | ||||
if (months > 0) { | if (months > 0) { | ||||
out = years + "yr " + months + "mth"; | out = years + "yr " + months + "mth"; | ||||
} | } | ||||
function displayStatWidgets(checked_server) { | function displayStatWidgets(checked_server) { | ||||
var servers = JSON.parse(sessionStorage.getItem("Credentials")); | |||||
var data = {}; | |||||
const servers = JSON.parse(sessionStorage.getItem("Credentials")); | |||||
let data = {}; | |||||
if (servers && servers[checked_server]) { | if (servers && servers[checked_server]) { | ||||
data = servers[checked_server].data; | data = servers[checked_server].data; | ||||
} | } | ||||
var stat_w = []; | |||||
const stat_w = []; | |||||
$("#statWidgets").empty().hide(); | $("#statWidgets").empty().hide(); | ||||
$.each(data, function (i, item) { | $.each(data, function (i, item) { | ||||
var widgetsOrder = ["scanned", "no action", "greylist", "add header", "rewrite subject", "reject", "learned"]; | |||||
const widgetsOrder = ["scanned", "no action", "greylist", "add header", "rewrite subject", "reject", "learned"]; | |||||
function widget(k, v, cls) { | function widget(k, v, cls) { | ||||
var c = (typeof cls === "undefined") ? "" : cls; | |||||
var titleAtt = d3.format(",")(v) + " " + k; | |||||
const c = (typeof cls === "undefined") ? "" : cls; | |||||
const titleAtt = d3.format(",")(v) + " " + k; | |||||
return '<div class="card stat-box d-inline-block text-center shadow-sm me-3 px-3">' + | return '<div class="card stat-box d-inline-block text-center shadow-sm me-3 px-3">' + | ||||
'<div class="widget overflow-hidden p-2' + c + '" title="' + titleAtt + | '<div class="widget overflow-hidden p-2' + c + '" title="' + titleAtt + | ||||
'"><strong class="d-block mt-2 mb-1 fw-bold">' + | '"><strong class="d-block mt-2 mb-1 fw-bold">' + | ||||
if (i === "auth" || i === "error") return; // Skip to the next iteration | if (i === "auth" || i === "error") return; // Skip to the next iteration | ||||
if (i === "uptime" || i === "version") { | if (i === "uptime" || i === "version") { | ||||
var cls = "border-end "; | |||||
var val = item; | |||||
let cls = "border-end "; | |||||
let val = item; | |||||
if (i === "uptime") { | if (i === "uptime") { | ||||
cls = ""; | cls = ""; | ||||
val = msToTime(item); | val = msToTime(item); | ||||
$("#clusterTable tbody").empty(); | $("#clusterTable tbody").empty(); | ||||
$("#selSrv").empty(); | $("#selSrv").empty(); | ||||
$.each(servers, function (key, val) { | $.each(servers, function (key, val) { | ||||
var row_class = "danger"; | |||||
var glyph_status = "fas fa-times"; | |||||
var version = "???"; | |||||
var uptime = "???"; | |||||
var short_id = "???"; | |||||
let row_class = "danger"; | |||||
let glyph_status = "fas fa-times"; | |||||
let version = "???"; | |||||
let uptime = "???"; | |||||
let short_id = "???"; | |||||
let scan_times = { | let scan_times = { | ||||
data: "???", | data: "???", | ||||
title: "" | title: "" | ||||
function addStatfiles(server, statfiles) { | function addStatfiles(server, statfiles) { | ||||
$.each(statfiles, function (i, statfile) { | $.each(statfiles, function (i, statfile) { | ||||
var cls = ""; | |||||
let cls = ""; | |||||
switch (statfile.symbol) { | switch (statfile.symbol) { | ||||
case "BAYES_SPAM": | case "BAYES_SPAM": | ||||
cls = "symbol-positive"; | cls = "symbol-positive"; | ||||
} | } | ||||
function addFuzzyStorage(server, storages) { | function addFuzzyStorage(server, storages) { | ||||
var i = 0; | |||||
let i = 0; | |||||
$.each(storages, function (storage, hashes) { | $.each(storages, function (storage, hashes) { | ||||
$("#fuzzyTable tbody").append("<tr>" + | $("#fuzzyTable tbody").append("<tr>" + | ||||
(i === 0 ? '<td rowspan="' + Object.keys(storages).length + '">' + server + "</td>" : "") + | (i === 0 ? '<td rowspan="' + Object.keys(storages).length + '">' + server + "</td>" : "") + | ||||
}); | }); | ||||
} | } | ||||
var data = []; | |||||
var creds = JSON.parse(sessionStorage.getItem("Credentials")); | |||||
const data = []; | |||||
const creds = JSON.parse(sessionStorage.getItem("Credentials")); | |||||
// Controller doesn't return the 'actions' object until at least one message is scanned | // Controller doesn't return the 'actions' object until at least one message is scanned | ||||
if (creds && creds[checked_server] && creds[checked_server].data.scanned) { | if (creds && creds[checked_server] && creds[checked_server].data.scanned) { | ||||
var actions = creds[checked_server].data.actions; | |||||
const actions = creds[checked_server].data.actions; | |||||
["no action", "soft reject", "add header", "rewrite subject", "greylist", "reject"] | ["no action", "soft reject", "add header", "rewrite subject", "greylist", "reject"] | ||||
.forEach(function (action) { | .forEach(function (action) { | ||||
} | } | ||||
// Public API | // Public API | ||||
var ui = { | |||||
const ui = { | |||||
statWidgets: function (graphs, checked_server) { | statWidgets: function (graphs, checked_server) { | ||||
rspamd.query("stat", { | rspamd.query("stat", { | ||||
success: function (neighbours_status) { | success: function (neighbours_status) { | ||||
var neighbours_sum = { | |||||
const neighbours_sum = { | |||||
version: neighbours_status[0].data.version, | version: neighbours_status[0].data.version, | ||||
uptime: 0, | uptime: 0, | ||||
scanned: 0, | scanned: 0, | ||||
"soft reject": 0, | "soft reject": 0, | ||||
} | } | ||||
}; | }; | ||||
var status_count = 0; | |||||
var promises = []; | |||||
var to_Credentials = { | |||||
let status_count = 0; | |||||
const promises = []; | |||||
const to_Credentials = { | |||||
"All SERVERS": { | "All SERVERS": { | ||||
name: "All SERVERS", | name: "All SERVERS", | ||||
url: "", | url: "", | ||||
}; | }; | ||||
function process_node_stat(e) { | function process_node_stat(e) { | ||||
var data = neighbours_status[e].data; | |||||
const data = neighbours_status[e].data; | |||||
// Controller doesn't return the 'actions' object until at least one message is scanned | // Controller doesn't return the 'actions' object until at least one message is scanned | ||||
if (data.scanned) { | if (data.scanned) { | ||||
for (var action in neighbours_sum.actions) { | |||||
for (const action in neighbours_sum.actions) { | |||||
if ({}.hasOwnProperty.call(neighbours_sum.actions, action)) { | if ({}.hasOwnProperty.call(neighbours_sum.actions, action)) { | ||||
neighbours_sum.actions[action] += data.actions[action]; | neighbours_sum.actions[action] += data.actions[action]; | ||||
} | } | ||||
// Get config_id, version and uptime using /auth query for Rspamd 2.5 and earlier | // Get config_id, version and uptime using /auth query for Rspamd 2.5 and earlier | ||||
function get_legacy_stat(e) { | function get_legacy_stat(e) { | ||||
var alerted = "alerted_stats_legacy_" + neighbours_status[e].name; | |||||
const alerted = "alerted_stats_legacy_" + neighbours_status[e].name; | |||||
promises.push($.ajax({ | promises.push($.ajax({ | ||||
url: neighbours_status[e].url + "auth", | url: neighbours_status[e].url + "auth", | ||||
headers: {Password:rspamd.getPassword()}, | headers: {Password:rspamd.getPassword()}, | ||||
})); | })); | ||||
} | } | ||||
for (var e in neighbours_status) { | |||||
for (const e in neighbours_status) { | |||||
if ({}.hasOwnProperty.call(neighbours_status, e)) { | if ({}.hasOwnProperty.call(neighbours_status, e)) { | ||||
to_Credentials[neighbours_status[e].name] = neighbours_status[e]; | to_Credentials[neighbours_status[e].name] = neighbours_status[e]; | ||||
if (neighbours_status[e].status === true) { | if (neighbours_status[e].status === true) { |
define(["jquery", "app/rspamd", "footable"], | define(["jquery", "app/rspamd", "footable"], | ||||
function ($, rspamd) { | function ($, rspamd) { | ||||
"use strict"; | "use strict"; | ||||
var ui = {}; | |||||
const ui = {}; | |||||
function saveSymbols(action, id, server) { | function saveSymbols(action, id, server) { | ||||
var inputs = $("#" + id + " :input[data-role=\"numerictextbox\"]"); | |||||
var url = action; | |||||
var values = []; | |||||
const inputs = $("#" + id + " :input[data-role=\"numerictextbox\"]"); | |||||
const url = action; | |||||
const values = []; | |||||
$(inputs).each(function () { | $(inputs).each(function () { | ||||
values.push({ | values.push({ | ||||
name: $(this).attr("id").substring(5), | name: $(this).attr("id").substring(5), | ||||
}); | }); | ||||
} | } | ||||
function decimalStep(number) { | function decimalStep(number) { | ||||
var digits = Number(number).toFixed(20).replace(/^-?\d*\.?|0+$/g, "").length; | |||||
const digits = Number(number).toFixed(20).replace(/^-?\d*\.?|0+$/g, "").length; | |||||
return (digits === 0 || digits > 4) ? 0.1 : 1.0 / Math.pow(10, digits); | return (digits === 0 || digits > 4) ? 0.1 : 1.0 / Math.pow(10, digits); | ||||
} | } | ||||
function process_symbols_data(data) { | function process_symbols_data(data) { | ||||
var items = []; | |||||
var lookup = {}; | |||||
var freqs = []; | |||||
var distinct_groups = []; | |||||
var selected_server = rspamd.getSelector("selSrv"); | |||||
const items = []; | |||||
const lookup = {}; | |||||
const freqs = []; | |||||
const distinct_groups = []; | |||||
const selected_server = rspamd.getSelector("selSrv"); | |||||
data.forEach(function (group) { | data.forEach(function (group) { | ||||
group.rules.forEach(function (item) { | group.rules.forEach(function (item) { | ||||
var max = 20; | |||||
var min = -20; | |||||
let max = 20; | |||||
let min = -20; | |||||
if (item.weight > max) { | if (item.weight > max) { | ||||
max = item.weight * 2; | max = item.weight * 2; | ||||
} | } | ||||
if (item.weight < min) { | if (item.weight < min) { | ||||
min = item.weight * 2; | min = item.weight * 2; | ||||
} | } | ||||
var label_class = ""; | |||||
let label_class = ""; | |||||
if (item.weight < 0) { | if (item.weight < 0) { | ||||
label_class = "scorebar-ham"; | label_class = "scorebar-ham"; | ||||
} else if (item.weight > 0) { | } else if (item.weight > 0) { | ||||
}); | }); | ||||
// For better mean calculations | // For better mean calculations | ||||
var avg_freq = freqs.sort(function (a, b) { | |||||
const avg_freq = freqs.sort(function (a, b) { | |||||
return Number(a) < Number(b); | return Number(a) < Number(b); | ||||
}).reduce(function (f1, acc) { | }).reduce(function (f1, acc) { | ||||
return f1 + acc; | return f1 + acc; | ||||
}) / (freqs.length !== 0 ? freqs.length : 1.0); | }) / (freqs.length !== 0 ? freqs.length : 1.0); | ||||
var mult = 1.0; | |||||
var exp = 0.0; | |||||
let mult = 1.0; | |||||
let exp = 0.0; | |||||
if (avg_freq > 0.0) { | if (avg_freq > 0.0) { | ||||
while (mult * avg_freq < 1.0) { | while (mult * avg_freq < 1.0) { | ||||
ui.getSymbols = function (checked_server) { | ui.getSymbols = function (checked_server) { | ||||
rspamd.query("symbols", { | rspamd.query("symbols", { | ||||
success: function (json) { | success: function (json) { | ||||
var data = json[0].data; | |||||
var items = process_symbols_data(data); | |||||
const data = json[0].data; | |||||
const items = process_symbols_data(data); | |||||
/* eslint-disable consistent-this, no-underscore-dangle, one-var-declaration-per-line */ | /* eslint-disable consistent-this, no-underscore-dangle, one-var-declaration-per-line */ | ||||
FooTable.groupFilter = FooTable.Filtering.extend({ | FooTable.groupFilter = FooTable.Filtering.extend({ | ||||
}, | }, | ||||
$create: function () { | $create: function () { | ||||
this._super(); | this._super(); | ||||
var self = this, $form_grp = $("<div/>", { | |||||
const self = this, $form_grp = $("<div/>", { | |||||
class: "form-group" | class: "form-group" | ||||
}).append($("<label/>", { | }).append($("<label/>", { | ||||
class: "sr-only", | class: "sr-only", | ||||
}); | }); | ||||
}, | }, | ||||
_onStatusDropdownChanged: function (e) { | _onStatusDropdownChanged: function (e) { | ||||
var self = e.data.self, selected = $(this).val(); | |||||
const self = e.data.self, selected = $(this).val(); | |||||
if (selected !== self.def) { | if (selected !== self.def) { | ||||
self.addFilter("group", selected, ["group"]); | self.addFilter("group", selected, ["group"]); | ||||
} else { | } else { | ||||
}, | }, | ||||
draw: function () { | draw: function () { | ||||
this._super(); | this._super(); | ||||
var group = this.find("group"); | |||||
const group = this.find("group"); | |||||
if (group instanceof FooTable.Filter) { | if (group instanceof FooTable.Filter) { | ||||
this.$group.val(group.query.val()); | this.$group.val(group.query.val()); | ||||
} else { | } else { | ||||
$("#symbolsTable") | $("#symbolsTable") | ||||
.off("click", ":button") | .off("click", ":button") | ||||
.on("click", ":button", function () { | .on("click", ":button", function () { | ||||
var value = $(this).data("save"); | |||||
const value = $(this).data("save"); | |||||
if (!value) return; | if (!value) return; | ||||
saveSymbols("./savesymbols", "symbolsTable", value); | saveSymbols("./savesymbols", "symbolsTable", value); | ||||
}); | }); | ||||
$("#updateSymbols").on("click", function (e) { | $("#updateSymbols").on("click", function (e) { | ||||
e.preventDefault(); | e.preventDefault(); | ||||
var checked_server = rspamd.getSelector("selSrv"); | |||||
const checked_server = rspamd.getSelector("selSrv"); | |||||
rspamd.query("symbols", { | rspamd.query("symbols", { | ||||
success: function (data) { | success: function (data) { | ||||
var items = process_symbols_data(data[0].data)[0]; | |||||
const items = process_symbols_data(data[0].data)[0]; | |||||
rspamd.tables.symbols.rows.load(items); | rspamd.tables.symbols.rows.load(items); | ||||
}, | }, | ||||
server: (checked_server === "All SERVERS") ? "local" : checked_server | server: (checked_server === "All SERVERS") ? "local" : checked_server |
define(["jquery", "app/rspamd"], | define(["jquery", "app/rspamd"], | ||||
function ($, rspamd) { | function ($, rspamd) { | ||||
"use strict"; | "use strict"; | ||||
var ui = {}; | |||||
const ui = {}; | |||||
function cleanTextUpload(source) { | function cleanTextUpload(source) { | ||||
$("#" + source + "TextSource").val(""); | $("#" + source + "TextSource").val(""); | ||||
// @upload text | // @upload text | ||||
function uploadText(data, source, headers) { | function uploadText(data, source, headers) { | ||||
var url = null; | |||||
let url = null; | |||||
if (source === "spam") { | if (source === "spam") { | ||||
url = "learnspam"; | url = "learnspam"; | ||||
} else if (source === "ham") { | } else if (source === "ham") { | ||||
} | } | ||||
function get_server() { | function get_server() { | ||||
var checked_server = rspamd.getSelector("selSrv"); | |||||
const checked_server = rspamd.getSelector("selSrv"); | |||||
return (checked_server === "All SERVERS") ? "local" : checked_server; | return (checked_server === "All SERVERS") ? "local" : checked_server; | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
var json = neighbours_status[0].data; | |||||
const json = neighbours_status[0].data; | |||||
if (json.action) { | if (json.action) { | ||||
rspamd.alertMessage("alert-success", "Data successfully scanned"); | rspamd.alertMessage("alert-success", "Data successfully scanned"); | ||||
var rows_total = $("#historyTable_scan > tbody > tr:not(.footable-detail-row)").length + 1; | |||||
var o = rspamd.process_history_v2({rows:[json]}, "scan"); | |||||
var items = o.items; | |||||
const rows_total = $("#historyTable_scan > tbody > tr:not(.footable-detail-row)").length + 1; | |||||
const o = rspamd.process_history_v2({rows:[json]}, "scan"); | |||||
const items = o.items; | |||||
rspamd.symbols.scan.push(o.symbols[0]); | rspamd.symbols.scan.push(o.symbols[0]); | ||||
if (Object.prototype.hasOwnProperty.call(rspamd.tables, "scan")) { | if (Object.prototype.hasOwnProperty.call(rspamd.tables, "scan")) { | ||||
}, | }, | ||||
method: "POST", | method: "POST", | ||||
success: function (neighbours_status) { | success: function (neighbours_status) { | ||||
var json = neighbours_status[0].data; | |||||
const json = neighbours_status[0].data; | |||||
if (json.success) { | if (json.success) { | ||||
rspamd.alertMessage("alert-success", "Message successfully processed"); | rspamd.alertMessage("alert-success", "Message successfully processed"); | ||||
fillHashTable(json.hashes); | fillHashTable(json.hashes); | ||||
}); | }); | ||||
$("[data-upload]").on("click", function () { | $("[data-upload]").on("click", function () { | ||||
var source = $(this).data("upload"); | |||||
var data = $("#scanMsgSource").val(); | |||||
var headers = {}; | |||||
const source = $(this).data("upload"); | |||||
const data = $("#scanMsgSource").val(); | |||||
let headers = {}; | |||||
if ($.trim(data).length > 0) { | if ($.trim(data).length > 0) { | ||||
if (source === "scan") { | if (source === "scan") { | ||||
headers = ["IP", "User", "From", "Rcpt", "Helo", "Hostname"].reduce(function (o, header) { | headers = ["IP", "User", "From", "Rcpt", "Helo", "Hostname"].reduce(function (o, header) { | ||||
var value = $("#scan-opt-" + header.toLowerCase()).val(); | |||||
const value = $("#scan-opt-" + header.toLowerCase()).val(); | |||||
if (value !== "") o[header] = value; | if (value !== "") o[header] = value; | ||||
return o; | return o; | ||||
}, {}); | }, {}); |