blob: 8d7f222552fb1127cf951f093e62933a1648dc53 [file] [log] [blame]
Matthias Andreas Benkardd1f5b682023-11-18 13:18:30 +01001// Base64 functions
2var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,c,d="",C=0;for(r=Base64._utf8_encode(r);C<r.length;)a=(t=r.charCodeAt(C++))>>2,h=(3&t)<<4|(e=r.charCodeAt(C++))>>4,n=(15&e)<<2|(o=r.charCodeAt(C++))>>6,c=63&o,isNaN(e)?n=c=64:isNaN(o)&&(c=64),d=d+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(c);return d},decode:function(r){var t,e,o,a,h,n,c="",d=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");d<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(d++)))>>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(d++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(d++))),c+=String.fromCharCode(t),64!=h&&(c+=String.fromCharCode(e)),64!=n&&(c+=String.fromCharCode(o));return c=Base64._utf8_decode(c)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=c1=c2=0;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&o<224?(c2=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&c2),e+=2):(c2=r.charCodeAt(e+1),c3=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&c2)<<6|63&c3),e+=3);return t}};
3
4jQuery(function($){
5 acl_data = JSON.parse(acl);
6 // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
7 var entityMap={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};
8 function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})}
9 function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e<B.length-1);return i.toFixed(1)+" "+B[e]}
10 $(".refresh_table").on('click', function(e) {
11 e.preventDefault();
12 var table_name = $(this).data('table');
13 $('#' + table_name).DataTable().ajax.reload();
14 });
15 function draw_quarantine_table() {
16 var table = $('#quarantinetable').DataTable({
17 responsive: true,
18 processing: true,
19 serverSide: false,
20 stateSave: true,
21 pageLength: pagination_size,
22 order: [[2, 'desc']],
23 lengthMenu: [
24 [10, 25, 50, 100, -1],
25 [10, 25, 50, 100, 'all']
26 ],
27 pagingType: 'first_last_numbers',
28 aColumns: [
29 { sWidth: '8.25%' },
30 { sClass: 'classDataTable' }
31 ],
32 dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" +
33 "tr" +
34 "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
35 language: lang_datatables,
36 initComplete: function(){
37 hideTableExpandCollapseBtn('#quarantinetable');
38 },
39 ajax: {
40 type: "GET",
41 url: "/api/v1/get/quarantine/all",
42 dataSrc: function(data){
43 $.each(data, function (i, item) {
44 if (item.subject === null) {
45 item.subject = '';
46 } else {
47 item.subject = escapeHtml(item.subject);
48 }
49 if (item.score === null) {
50 item.score = '-';
51 }
52 if (item.virus_flag > 0) {
53 item.virus = '<span class="badge fs-6 bg-danger">' + lang.high_danger + '</span>';
54 } else {
55 item.virus = '<span class="badge fs-6 bg-secondary">' + lang.neutral_danger + '</span>';
56 }
57 if (item.action === "reject") {
58 item.rspamdaction = '<span class="badge fs-6 bg-danger">' + lang.rejected + '</span>';
59 } else if (item.action === "add header") {
60 item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.junk_folder + '</span>';
61 } else if (item.action === "rewrite subject") {
62 item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.rewrite_subject + '</span>';
63 }
64 if(item.notified > 0) {
65 item.notified = '&#10004;';
66 } else {
67 item.notified = '&#10006;';
68 }
69 if (acl_data.login_as === 1) {
70 item.action = '<div class="btn-group">' +
71 '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-info show_qid_info"><i class="bi bi-box-arrow-up-right"></i> ' + lang.show_item + '</a>' +
72 '<a href="#" data-action="delete_selected" data-id="del-single-qitem" data-api-url="delete/qitem" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
73 '</div>';
74 }
75 else {
76 item.action = '<div class="btn-group">' +
77 '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-info show_qid_info"><i class="bi bi-file-earmark-text"></i> ' + lang.show_item + '</a>' +
78 '</div>';
79 }
80 item.chkbox = '<input type="checkbox" class="form-check-input" data-id="qitems" name="multi_select" value="' + item.id + '" />';
81 });
82
83 return data;
84 }
85 },
86 columns: [
87 {
88 // placeholder, so checkbox will not block child row toggle
89 title: '',
90 data: null,
91 searchable: false,
92 orderable: false,
93 defaultContent: ''
94 },
95 {
96 title: '',
97 data: 'chkbox',
98 searchable: false,
99 orderable: false,
100 defaultContent: ''
101 },
102 {
103 title: 'ID',
104 data: 'id',
105 defaultContent: ''
106 },
107 {
108 title: lang.qid,
109 data: 'qid',
110 defaultContent: ''
111 },
112 {
113 title: lang.sender,
114 data: 'sender',
115 className: 'senders-mw220',
116 defaultContent: ''
117 },
118 {
119 title: lang.subj,
120 data: 'subject',
121 defaultContent: ''
122 },
123 {
124 title: lang.rspamd_result,
125 data: 'rspamdaction',
126 defaultContent: ''
127 },
128 {
129 title: lang.rcpt,
130 data: 'rcpt',
131 defaultContent: ''
132 },
133 {
134 title: lang.danger,
135 data: 'virus',
136 defaultContent: ''
137 },
138 {
139 title: lang.spam_score,
140 data: 'score',
141 defaultContent: ''
142 },
143 {
144 title: lang.notified,
145 data: 'notified',
146 defaultContent: ''
147 },
148 {
149 title: lang.received,
150 data: 'created',
151 defaultContent: '',
152 createdCell: function(td, cellData) {
153 $(td).attr({
154 "data-order": cellData,
155 "data-sort": cellData
156 });
157
158 var date = new Date(cellData ? cellData * 1000 : 0);
159 var dateString = date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
160 $(td).html(dateString);
161 }
162 },
163 {
164 title: lang.action,
165 data: 'action',
166 className: 'dt-text-right dt-sm-head-hidden',
167 defaultContent: ''
168 },
169 ]
170 });
171
172 table.on('responsive-resize', function (e, datatable, columns){
173 hideTableExpandCollapseBtn('#quarantinetable');
174 });
175 }
176
177 $('body').on('click', '.show_qid_info', function (e) {
178 e.preventDefault();
179 var qitem = $(this).attr('data-item');
180 var qError = $("#qid_error");
181
182 $('#qidDetailModal').modal('show');
183 qError.hide();
184
185 $.ajax({
186 url: '/inc/ajax/qitem_details.php',
187 data: { id: qitem },
188 dataType: 'json',
189 success: function(data){
190
191 $('[data-id="qitems_single"]').each(function(index) {
192 $(this).attr("data-item", qitem);
193 });
194
195 $("#quick_download_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&eml', '_blank')");
196 $("#quick_release_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_release', '_blank')");
197 $("#quick_delete_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_delete', '_blank')");
198
199 $('#qid_detail_subj').text(data.subject);
200 $('#qid_detail_hfrom').text(data.header_from);
201 $('#qid_detail_efrom').text(data.env_from);
202 $('#qid_detail_score').html('');
203 $('#qid_detail_recipients').html('');
204 $('#qid_detail_symbols').html('');
205 $('#qid_detail_fuzzy').html('');
206 if (typeof data.symbols !== 'undefined') {
207 data.symbols.sort(function (a, b) {
208 if (a.score === 0) return 1;
209 if (b.score === 0) return -1;
210 if (b.score < 0 && a.score < 0) {
211 return a.score - b.score;
212 }
213 if (b.score > 0 && a.score > 0) {
214 return b.score - a.score;
215 }
216 return b.score - a.score;
217 })
218 $.each(data.symbols, function (index, value) {
219 var highlightClass = '';
220 if (value.score > 0) highlightClass = 'negative';
221 else if (value.score < 0) highlightClass = 'positive';
222 else highlightClass = 'neutral';
223 $('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
224 });
225 $('[data-bs-toggle="tooltip"]').tooltip();
226 }
227 if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
228 $.each(data.fuzzy_hashes, function (index, value) {
229 $('#qid_detail_fuzzy').append('<p style="font-family:monospace">' + value + '</p>');
230 });
231 } else {
232 $('#qid_detail_fuzzy').append('-');
233 }
234 if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
235 if (data.action == "add header") {
236 $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
237 } else if (data.action == "reject") {
238 $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
239 } else if (data.action == "rewrite subject") {
240 $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
241 }
242 }
243 if (typeof data.recipients !== 'undefined') {
244 $.each(data.recipients, function(index, value) {
245 var elem = $('<span class="mail-address-item"></span>');
246 elem.text(value.address + ' (' + value.type.toUpperCase() + ')');
247 $('#qid_detail_recipients').append(elem);
248 });
249 }
250 $('#qid_detail_text').text(data.text_plain);
251 $('#qid_detail_text_from_html').text(data.text_html);
252 var qAtts = $("#qid_detail_atts");
253 if (typeof data.attachments !== 'undefined') {
254 qAtts.text('');
255 $.each(data.attachments, function(index, value) {
256 qAtts.append(
257 '<p><a href="/inc/ajax/qitem_details.php?id=' + qitem + '&att=' + index + '" target="_blank">' + value[0] + '</a> (' + value[1] + ')' +
258 ' - <small><a href="' + value[3] + '" target="_blank">' + lang.check_hash + '</a></small></p>'
259 );
260 });
261 }
262 else {
263 qAtts.text('-');
264 }
265 },
266 error: function(data){
267 if (typeof data.error !== 'undefined') {
268 $('#qid_detail_subj').text('-');
269 $('#qid_detail_hfrom').text('-');
270 $('#qid_detail_efrom').text('-');
271 $('#qid_detail_score').html('-');
272 $('#qid_detail_recipients').html('-');
273 $('#qid_detail_symbols').html('-');
274 $('#qid_detail_fuzzy').html('-');
275 $('#qid_detail_text').text('-');
276 $('#qid_detail_text_from_html').text('-');
277 qError.text("Error loading quarantine item");
278 qError.show();
279 }
280 }
281 });
282 });
283
284 $('body').on('click', 'span.footable-toggle', function () {
285 event.stopPropagation();
286 })
287
288 // Initial table drawings
289 draw_quarantine_table();
290
291 function hideTableExpandCollapseBtn(table){
292 if ($(table).hasClass('collapsed'))
293 $(".table_collapse_option").show();
294 else
295 $(".table_collapse_option").hide();
296 }
297});