admin.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. var Base64 = {
  2. _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  3. encode: function(e) {
  4. var t = "";
  5. var n, r, i, s, o, u, a;
  6. var f = 0;
  7. e = Base64._utf8_encode(e);
  8. while (f < e.length) {
  9. n = e.charCodeAt(f++);
  10. r = e.charCodeAt(f++);
  11. i = e.charCodeAt(f++);
  12. s = n >> 2;
  13. o = (n & 3) << 4 | r >> 4;
  14. u = (r & 15) << 2 | i >> 6;
  15. a = i & 63;
  16. if (isNaN(r)) {
  17. u = a = 64
  18. } else if (isNaN(i)) {
  19. a = 64
  20. }
  21. t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) +
  22. this._keyStr.charAt(u) + this._keyStr.charAt(a)
  23. }
  24. return t
  25. },
  26. decode: function(e) {
  27. var t = "";
  28. var n, r, i;
  29. var s, o, u, a;
  30. var f = 0;
  31. e = e.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  32. while (f < e.length) {
  33. s = this._keyStr.indexOf(e.charAt(f++));
  34. o = this._keyStr.indexOf(e.charAt(f++));
  35. u = this._keyStr.indexOf(e.charAt(f++));
  36. a = this._keyStr.indexOf(e.charAt(f++));
  37. n = s << 2 | o >> 4;
  38. r = (o & 15) << 4 | u >> 2;
  39. i = (u & 3) << 6 | a;
  40. t = t + String.fromCharCode(n);
  41. if (u != 64) {
  42. t = t + String.fromCharCode(r)
  43. }
  44. if (a != 64) {
  45. t = t + String.fromCharCode(i)
  46. }
  47. }
  48. t = Base64._utf8_decode(t);
  49. return t
  50. },
  51. _utf8_encode: function(e) {
  52. e = e.replace(/\r\n/g, "\n");
  53. var t = "";
  54. for (var n = 0; n < e.length; n++) {
  55. var r = e.charCodeAt(n);
  56. if (r < 128) {
  57. t += String.fromCharCode(r)
  58. } else if (r > 127 && r < 2048) {
  59. t += String.fromCharCode(r >> 6 | 192);
  60. t += String.fromCharCode(r & 63 | 128)
  61. } else {
  62. t += String.fromCharCode(r >> 12 | 224);
  63. t += String.fromCharCode(r >> 6 & 63 | 128);
  64. t += String.fromCharCode(r & 63 | 128)
  65. }
  66. }
  67. return t
  68. },
  69. _utf8_decode: function(e) {
  70. var t = "";
  71. var n = 0;
  72. var r = c1 = c2 = 0;
  73. while (n < e.length) {
  74. r = e.charCodeAt(n);
  75. if (r < 128) {
  76. t += String.fromCharCode(r);
  77. n++
  78. } else if (r > 191 && r < 224) {
  79. c2 = e.charCodeAt(n + 1);
  80. t += String.fromCharCode((r & 31) << 6 | c2 & 63);
  81. n += 2
  82. } else {
  83. c2 = e.charCodeAt(n + 1);
  84. c3 = e.charCodeAt(n + 2);
  85. t += String.fromCharCode((r & 15) << 12 | (c2 & 63) <<
  86. 6 | c3 & 63);
  87. n += 3
  88. }
  89. }
  90. return t
  91. }
  92. }
  93. jQuery(function($){
  94. // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
  95. var entityMap = {
  96. '&': '&amp;',
  97. '<': '&lt;',
  98. '>': '&gt;',
  99. '"': '&quot;',
  100. "'": '&#39;',
  101. '/': '&#x2F;',
  102. '`': '&#x60;',
  103. '=': '&#x3D;'
  104. };
  105. function escapeHtml(string) {
  106. return String(string).replace(/[&<>"'`=\/]/g, function (s) {
  107. return entityMap[s];
  108. });
  109. }
  110. function humanFileSize(bytes) {
  111. if(Math.abs(bytes) < 1024) {
  112. return bytes + ' B';
  113. }
  114. var units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
  115. var u = -1;
  116. do {
  117. bytes /= 1024;
  118. ++u;
  119. } while(Math.abs(bytes) >= 1024 && u < units.length - 1);
  120. return bytes.toFixed(1)+' '+units[u];
  121. }
  122. $("#refresh_postfix_log").on('click', function(e) {
  123. e.preventDefault();
  124. draw_postfix_logs();
  125. });
  126. $("#refresh_autodiscover_log").on('click', function(e) {
  127. e.preventDefault();
  128. draw_autodiscover_logs();
  129. });
  130. $("#refresh_dovecot_log").on('click', function(e) {
  131. e.preventDefault();
  132. draw_dovecot_logs();
  133. });
  134. $("#refresh_sogo_log").on('click', function(e) {
  135. e.preventDefault();
  136. draw_sogo_logs();
  137. });
  138. $("#refresh_fail2ban_log").on('click', function(e) {
  139. e.preventDefault();
  140. draw_fail2ban_logs();
  141. });
  142. $("#refresh_rspamd_history").on('click', function(e) {
  143. e.preventDefault();
  144. draw_rspamd_history();
  145. });
  146. $("#import_dkim_legend").on('click', function(e) {
  147. e.preventDefault();
  148. $('#import_dkim_arrow').toggleClass("animation");
  149. });
  150. function draw_postfix_logs() {
  151. ft_postfix_logs = FooTable.init('#postfix_log', {
  152. "columns": [
  153. {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
  154. {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
  155. {"name":"message","title":lang.message},
  156. ],
  157. "rows": $.ajax({
  158. dataType: 'json',
  159. url: '/api/v1/get/logs/postfix/1000',
  160. jsonp: false,
  161. error: function () {
  162. console.log('Cannot draw postfix log table');
  163. },
  164. success: function (data) {
  165. $.each(data, function (i, item) {
  166. item.message = escapeHtml(item.message);
  167. var danger_class = ["emerg", "alert", "crit", "err"];
  168. var warning_class = ["warning", "warn"];
  169. var info_class = ["notice", "info", "debug"];
  170. if (jQuery.inArray(item.priority, danger_class) !== -1) {
  171. item.priority = '<span class="label label-danger">' + item.priority + '</span>';
  172. }
  173. else if (jQuery.inArray(item.priority, warning_class) !== -1) {
  174. item.priority = '<span class="label label-warning">' + item.priority + '</span>';
  175. }
  176. else if (jQuery.inArray(item.priority, info_class) !== -1) {
  177. item.priority = '<span class="label label-info">' + item.priority + '</span>';
  178. }
  179. });
  180. }
  181. }),
  182. "empty": lang.empty,
  183. "paging": {
  184. "enabled": true,
  185. "limit": 5,
  186. "size": log_pagination_size
  187. },
  188. "filtering": {
  189. "enabled": true,
  190. "position": "left",
  191. "placeholder": lang.filter_table
  192. },
  193. "sorting": {
  194. "enabled": true
  195. }
  196. });
  197. }
  198. function draw_autodiscover_logs() {
  199. ft_autodiscover_logs = FooTable.init('#autodiscover_log', {
  200. "columns": [
  201. {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
  202. {"name":"ua","title":"User-Agent","style":{"min-width":"200px"}},
  203. {"name":"user","title":"Username","style":{"min-width":"200px"}},
  204. {"name":"service","title":"Service"},
  205. ],
  206. "rows": $.ajax({
  207. dataType: 'json',
  208. url: '/api/v1/get/logs/autodiscover/100',
  209. jsonp: false,
  210. error: function () {
  211. console.log('Cannot draw autodiscover log table');
  212. },
  213. success: function (data) {
  214. $.each(data, function (i, item) {
  215. item.ua = '<span style="font-size:small">' + item.ua + '</span>';
  216. if (item.service == "activesync") {
  217. item.service = '<span class="label label-info">ActiveSync</span>';
  218. }
  219. else if (item.service == "imap") {
  220. item.service = '<span class="label label-success">IMAP, SMTP, Cal-/CardDAV</span>';
  221. }
  222. else {
  223. item.service = '<span class="label label-danger">' + item.service + '</span>';
  224. }
  225. });
  226. }
  227. }),
  228. "empty": lang.empty,
  229. "paging": {
  230. "enabled": true,
  231. "limit": 5,
  232. "size": log_pagination_size
  233. },
  234. "filtering": {
  235. "enabled": true,
  236. "position": "left",
  237. "placeholder": lang.filter_table
  238. },
  239. "sorting": {
  240. "enabled": true
  241. }
  242. });
  243. }
  244. function draw_fail2ban_logs() {
  245. ft_fail2ban_logs = FooTable.init('#fail2ban_log', {
  246. "columns": [
  247. {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
  248. {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
  249. {"name":"message","title":lang.message},
  250. ],
  251. "rows": $.ajax({
  252. dataType: 'json',
  253. url: '/api/v1/get/logs/fail2ban/1000',
  254. jsonp: false,
  255. error: function () {
  256. console.log('Cannot draw fail2ban log table');
  257. },
  258. success: function (data) {
  259. $.each(data, function (i, item) {
  260. var danger_class = ["emerg", "alert", "crit", "err"];
  261. var warning_class = ["warning", "warn"];
  262. var info_class = ["notice", "info", "debug"];
  263. item.message = escapeHtml(item.message);
  264. if (jQuery.inArray(item.priority, danger_class) !== -1) {
  265. item.priority = '<span class="label label-danger">' + item.priority + '</span>';
  266. }
  267. else if (jQuery.inArray(item.priority, warning_class) !== -1) {
  268. item.priority = '<span class="label label-warning">' + item.priority + '</span>';
  269. }
  270. else if (jQuery.inArray(item.priority, info_class) !== -1) {
  271. item.priority = '<span class="label label-info">' + item.priority + '</span>';
  272. }
  273. });
  274. }
  275. }),
  276. "empty": lang.empty,
  277. "paging": {
  278. "enabled": true,
  279. "limit": 5,
  280. "size": log_pagination_size
  281. },
  282. "filtering": {
  283. "enabled": true,
  284. "position": "left",
  285. "connectors": false,
  286. "placeholder": lang.filter_table
  287. },
  288. "sorting": {
  289. "enabled": true
  290. }
  291. });
  292. }
  293. function draw_sogo_logs() {
  294. ft_sogo_logs = FooTable.init('#sogo_log', {
  295. "columns": [
  296. {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
  297. {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
  298. {"name":"message","title":lang.message},
  299. ],
  300. "rows": $.ajax({
  301. dataType: 'json',
  302. url: '/api/v1/get/logs/sogo/1000',
  303. jsonp: false,
  304. error: function () {
  305. console.log('Cannot draw sogo log table');
  306. },
  307. success: function (data) {
  308. $.each(data, function (i, item) {
  309. var danger_class = ["emerg", "alert", "crit", "err"];
  310. var warning_class = ["warning", "warn"];
  311. var info_class = ["notice", "info", "debug"];
  312. item.message = escapeHtml(item.message);
  313. if (jQuery.inArray(item.priority, danger_class) !== -1) {
  314. item.priority = '<span class="label label-danger">' + item.priority + '</span>';
  315. }
  316. else if (jQuery.inArray(item.priority, warning_class) !== -1) {
  317. item.priority = '<span class="label label-warning">' + item.priority + '</span>';
  318. }
  319. else if (jQuery.inArray(item.priority, info_class) !== -1) {
  320. item.priority = '<span class="label label-info">' + item.priority + '</span>';
  321. }
  322. });
  323. }
  324. }),
  325. "empty": lang.empty,
  326. "paging": {
  327. "enabled": true,
  328. "limit": 5,
  329. "size": log_pagination_size
  330. },
  331. "filtering": {
  332. "enabled": true,
  333. "position": "left",
  334. "connectors": false,
  335. "placeholder": lang.filter_table
  336. },
  337. "sorting": {
  338. "enabled": true
  339. }
  340. });
  341. }
  342. function draw_dovecot_logs() {
  343. ft_postfix_logs = FooTable.init('#dovecot_log', {
  344. "columns": [
  345. {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
  346. {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
  347. {"name":"message","title":lang.message},
  348. ],
  349. "rows": $.ajax({
  350. dataType: 'json',
  351. url: '/api/v1/get/logs/dovecot/1000',
  352. jsonp: false,
  353. error: function () {
  354. console.log('Cannot draw dovecot log table');
  355. },
  356. success: function (data) {
  357. $.each(data, function (i, item) {
  358. var danger_class = ["emerg", "alert", "crit", "err"];
  359. var warning_class = ["warning", "warn"];
  360. var info_class = ["notice", "info", "debug"];
  361. item.message = escapeHtml(item.message);
  362. if (jQuery.inArray(item.priority, danger_class) !== -1) {
  363. item.priority = '<span class="label label-danger">' + item.priority + '</span>';
  364. }
  365. else if (jQuery.inArray(item.priority, warning_class) !== -1) {
  366. item.priority = '<span class="label label-warning">' + item.priority + '</span>';
  367. }
  368. else if (jQuery.inArray(item.priority, info_class) !== -1) {
  369. item.priority = '<span class="label label-info">' + item.priority + '</span>';
  370. }
  371. });
  372. }
  373. }),
  374. "empty": lang.empty,
  375. "paging": {
  376. "enabled": true,
  377. "limit": 5,
  378. "size": log_pagination_size
  379. },
  380. "filtering": {
  381. "enabled": true,
  382. "position": "left",
  383. "connectors": false,
  384. "placeholder": lang.filter_table
  385. },
  386. "sorting": {
  387. "enabled": true
  388. }
  389. });
  390. }
  391. function draw_domain_admins() {
  392. ft_domainadmins = FooTable.init('#domainadminstable', {
  393. "columns": [
  394. {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
  395. {"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
  396. {"name":"selected_domains","title":lang.admin_domains,"breakpoints":"xs sm"},
  397. {"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"}},
  398. {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
  399. {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
  400. ],
  401. "rows": $.ajax({
  402. dataType: 'json',
  403. url: '/api/v1/get/domain-admin/all',
  404. jsonp: false,
  405. error: function () {
  406. console.log('Cannot draw domain admin table');
  407. },
  408. success: function (data) {
  409. $.each(data, function (i, item) {
  410. item.chkbox = '<input type="checkbox" data-id="domain_admins" name="multi_select" value="' + item.username + '" />';
  411. item.action = '<div class="btn-group">' +
  412. '<a href="/edit.php?domainadmin=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
  413. '<a href="#" id="delete_selected" data-id="single-domain-admin" data-api-url="delete/domain-admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
  414. '</div>';
  415. });
  416. }
  417. }),
  418. "empty": lang.empty,
  419. "paging": {
  420. "enabled": true,
  421. "limit": 5,
  422. "size": log_pagination_size
  423. },
  424. "filtering": {
  425. "enabled": true,
  426. "position": "left",
  427. "connectors": false,
  428. "placeholder": lang.filter_table
  429. },
  430. "sorting": {
  431. "enabled": true
  432. }
  433. });
  434. }
  435. function draw_fwd_hosts() {
  436. ft_forwardinghoststable = FooTable.init('#forwardinghoststable', {
  437. "columns": [
  438. {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
  439. {"name":"host","type":"text","title":lang.host,"style":{"width":"250px"}},
  440. {"name":"source","title":lang.source,"breakpoints":"xs sm"},
  441. {"name":"keep_spam","title":lang.spamfilter, "type": "text","style":{"maxWidth":"80px","width":"80px"}},
  442. {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
  443. ],
  444. "rows": $.ajax({
  445. dataType: 'json',
  446. url: '/api/v1/get/fwdhost/all',
  447. jsonp: false,
  448. error: function () {
  449. console.log('Cannot draw forwarding hosts table');
  450. },
  451. success: function (data) {
  452. $.each(data, function (i, item) {
  453. item.action = '<div class="btn-group">' +
  454. '<a href="#" id="delete_selected" data-id="single-fwdhost" data-api-url="delete/fwdhost" data-item="' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
  455. '</div>';
  456. if (item.keep_spam == "yes") {
  457. item.keep_spam = lang.no;
  458. }
  459. else {
  460. item.keep_spam = lang.yes;
  461. }
  462. item.chkbox = '<input type="checkbox" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
  463. });
  464. }
  465. }),
  466. "empty": lang.empty,
  467. "paging": {
  468. "enabled": true,
  469. "limit": 5,
  470. "size": log_pagination_size
  471. },
  472. "sorting": {
  473. "enabled": true
  474. }
  475. });
  476. }
  477. function draw_relayhosts() {
  478. ft_forwardinghoststable = FooTable.init('#relayhoststable', {
  479. "columns": [
  480. {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
  481. {"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
  482. {"name":"hostname","type":"text","title":lang.host,"style":{"width":"250px"}},
  483. {"name":"username","title":lang.username,"breakpoints":"xs sm"},
  484. {"name":"used_by_domains","title":lang.in_use_by, "type": "text","breakpoints":"xs sm"},
  485. {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
  486. {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"280px","width":"280px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
  487. ],
  488. "rows": $.ajax({
  489. dataType: 'json',
  490. url: '/api/v1/get/relayhost/all',
  491. jsonp: false,
  492. error: function () {
  493. console.log('Cannot draw forwarding hosts table');
  494. },
  495. success: function (data) {
  496. $.each(data, function (i, item) {
  497. item.action = '<div class="btn-group">' +
  498. '<a href="#" data-toggle="modal" id="miau" data-target="#testRelayhostModal" data-relayhost-id="' + encodeURI(item.id) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-stats"></span> Test</a>' +
  499. '<a href="/edit.php?relayhost=' + encodeURI(item.id) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
  500. '<a href="#" id="delete_selected" data-id="single-rlshost" data-api-url="delete/relayhost" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
  501. '</div>';
  502. item.chkbox = '<input type="checkbox" data-id="rlyhosts" name="multi_select" value="' + item.id + '" />';
  503. });
  504. }
  505. }),
  506. "empty": lang.empty,
  507. "paging": {
  508. "enabled": true,
  509. "limit": 5,
  510. "size": log_pagination_size
  511. },
  512. "sorting": {
  513. "enabled": true
  514. }
  515. });
  516. }
  517. function draw_rspamd_history() {
  518. ft_postfix_logs = FooTable.init('#rspamd_history', {
  519. "columns": [{
  520. "name":"unix_time",
  521. "formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},
  522. "title":lang.time,
  523. "style":{
  524. "width":"170px"
  525. }
  526. }, {
  527. "name": "ip",
  528. "title": "IP address",
  529. "breakpoints": "all",
  530. "style": {
  531. "minWidth": 88
  532. }
  533. }, {
  534. "name": "sender_mime",
  535. "title": "From",
  536. "breakpoints": "xs sm md",
  537. "style": {
  538. "minWidth": 100
  539. }
  540. }, {
  541. "name": "rcpt_mime",
  542. "title": "To",
  543. "breakpoints": "xs sm md",
  544. "style": {
  545. "minWidth": 100
  546. }
  547. }, {
  548. "name": "subject",
  549. "title": "Subject",
  550. "breakpoints": "all",
  551. "style": {
  552. "word-break": "break-all",
  553. "minWidth": 150
  554. }
  555. }, {
  556. "name": "action",
  557. "title": "Action",
  558. "style": {
  559. "minwidth": 82
  560. }
  561. }, {
  562. "name": "score",
  563. "title": "Score",
  564. "style": {
  565. "maxWidth": 110
  566. },
  567. }, {
  568. "name": "symbols",
  569. "title": "Symbols",
  570. "breakpoints": "all",
  571. }, {
  572. "name": "size",
  573. "title": "Msg size",
  574. "breakpoints": "all",
  575. "style": {
  576. "minwidth": 50,
  577. },
  578. "formatter": function(value) { return humanFileSize(value); }
  579. }, {
  580. "name": "scan_time",
  581. "title": "Scan time",
  582. "breakpoints": "all",
  583. "style": {
  584. "maxWidth": 72
  585. },
  586. }, {
  587. "name": "message-id",
  588. "title": "ID",
  589. "breakpoints": "all",
  590. "style": {
  591. "minWidth": 130,
  592. "overflow": "hidden",
  593. "textOverflow": "ellipsis",
  594. "wordBreak": "break-all",
  595. "whiteSpace": "normal"
  596. }
  597. }, {
  598. "name": "user",
  599. "title": "Authenticated user",
  600. "breakpoints": "xs sm md",
  601. "style": {
  602. "minWidth": 100
  603. }
  604. }],
  605. "rows": $.ajax({
  606. dataType: 'json',
  607. url: '/api/v1/get/logs/rspamd-history',
  608. jsonp: false,
  609. error: function () {
  610. console.log('Cannot draw rspamd history table');
  611. },
  612. success: function (data) {
  613. $.each(data, function (i, item) {
  614. item.rcpt_mime = item.rcpt_mime.join(",&#8203;");
  615. Object.keys(item.symbols).map(function(key) {
  616. var sym = item.symbols[key];
  617. if (sym.score <= 0) {
  618. sym.score_formatted = '(<span class="text-success"><b>' + sym.score + '</b></span>)'
  619. }
  620. else {
  621. sym.score_formatted = '(<span class="text-danger"><b>' + sym.score + '</b></span>)'
  622. }
  623. var str = '<strong>' + key + '</strong> ' + sym.score_formatted;
  624. if (sym.options) {
  625. str += ' [' + sym.options.join(",") + "]";
  626. }
  627. item.symbols[key].str = str;
  628. });
  629. item.symbols = Object.keys(item.symbols).
  630. map(function(key) {
  631. return item.symbols[key];
  632. }).sort(function(e1, e2) {
  633. return Math.abs(e1.score) < Math.abs(e2.score);
  634. }).map(function(e) {
  635. return e.str;
  636. }).join("<br>\n");
  637. var scan_time = item.time_real.toFixed(3) + ' / ' + item.time_virtual.toFixed(3);
  638. item.scan_time = {
  639. "options": {
  640. "sortValue": item.time_real
  641. },
  642. "value": scan_time
  643. };
  644. if (item.action === 'clean' || item.action === 'no action') {
  645. item.action = "<div class='label label-success'>" + item.action + "</div>";
  646. } else if (item.action === 'rewrite subject' || item.action === 'add header' || item.action === 'probable spam') {
  647. item.action = "<div class='label label-warning'>" + item.action + "</div>";
  648. } else if (item.action === 'spam' || item.action === 'reject') {
  649. item.action = "<div class='label label-danger'>" + item.action + "</div>";
  650. } else {
  651. item.action = "<div class='label label-info'>" + item.action + "</div>";
  652. }
  653. var score_content;
  654. if (item.score < item.required_score) {
  655. score_content = "[ <span class='text-success'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]";
  656. } else {
  657. score_content = "[ <span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]";
  658. }
  659. item.score = {
  660. "options": {
  661. "sortValue": item.score
  662. },
  663. "value": score_content
  664. };
  665. if (item.user == null) {
  666. item.user = "none";
  667. }
  668. });
  669. }
  670. }),
  671. "empty": lang.empty,
  672. "paging": {
  673. "enabled": true,
  674. "limit": 5,
  675. "size": log_pagination_size
  676. },
  677. "filtering": {
  678. "enabled": true,
  679. "position": "left",
  680. "connectors": false,
  681. "placeholder": lang.filter_table
  682. },
  683. "sorting": {
  684. "enabled": true
  685. }
  686. });
  687. }
  688. draw_postfix_logs();
  689. draw_autodiscover_logs();
  690. draw_dovecot_logs();
  691. draw_sogo_logs();
  692. draw_fail2ban_logs();
  693. draw_domain_admins();
  694. draw_fwd_hosts();
  695. draw_relayhosts();
  696. draw_rspamd_history();
  697. $('#testRelayhostModal').on('show.bs.modal', function (e) {
  698. $('#test_relayhost_result').text("-");
  699. button = $(e.relatedTarget)
  700. if (button != null) {
  701. $('#relayhost_id').val(button.data('relayhost-id'));
  702. }
  703. })
  704. $('#showDKIMprivKey').on('show.bs.modal', function (e) {
  705. $('#priv_key_pre').text("-");
  706. p_related = $(e.relatedTarget)
  707. if (p_related != null) {
  708. var decoded_key = Base64.decode((p_related.data('priv-key')));
  709. $('#priv_key_pre').text(decoded_key);
  710. }
  711. })
  712. $('#test_relayhost').on('click', function (e) {
  713. e.preventDefault();
  714. prev = $('#test_relayhost').text();
  715. $(this).prop("disabled",true);
  716. $(this).html('<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> ');
  717. $.ajax({
  718. type: 'GET',
  719. url: 'inc/relay_check.php',
  720. dataType: 'text',
  721. data: $('#test_relayhost_form').serialize(),
  722. complete: function (data) {
  723. $('#test_relayhost_result').html(data.responseText);
  724. $('#test_relayhost').prop("disabled",false);
  725. $('#test_relayhost').text(prev);
  726. }
  727. });
  728. })
  729. function add_table_row(table_id) {
  730. var row = $('<tr />');
  731. cols = '<td><input class="input-sm form-control" data-id="app_links" type="text" name="app" required></td>';
  732. cols += '<td><input class="input-sm form-control" data-id="app_links" type="text" name="href" required></td>';
  733. cols += '<td><a href="#" role="button" class="btn btn-xs btn-default" type="button">Remove row</a></td>';
  734. row.append(cols);
  735. table_id.append(row);
  736. }
  737. $('#app_link_table').on('click', 'tr a', function (e) {
  738. e.preventDefault();
  739. $(this).parents('tr').remove();
  740. });
  741. $('#add_app_link_row').click(function() {
  742. add_table_row($('#app_link_table'));
  743. });
  744. });
  745. $(window).load(function(){
  746. initial_width = $("#sidebar-admin").width();
  747. $("#scrollbox").css("width", initial_width);
  748. $(window).bind('scroll', function() {
  749. if ($(window).scrollTop() > 70) {
  750. $('#scrollbox').addClass('scrollboxFixed');
  751. } else {
  752. $('#scrollbox').removeClass('scrollboxFixed');
  753. }
  754. });
  755. });
  756. function resizeScrollbox() {
  757. on_resize_width = $("#sidebar-admin").width();
  758. $("#scrollbox").removeAttr("style");
  759. $("#scrollbox").css("width", on_resize_width);
  760. }
  761. $(window).on('resize', resizeScrollbox);
  762. $('a[data-toggle="tab"]').on('shown.bs.tab', resizeScrollbox);