This commit is contained in:
99
iris-web/source/app/static/assets/js/iris/activities.js
Normal file
99
iris-web/source/app/static/assets/js/iris/activities.js
Normal file
@ -0,0 +1,99 @@
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
|
||||
Table = $("#activities_table").DataTable({
|
||||
dom: 'Blfrtip',
|
||||
aaData: [],
|
||||
bSort: false,
|
||||
aoColumns: [
|
||||
{ "data": "activity_date",
|
||||
"render": $.fn.dataTable.render.text()
|
||||
},
|
||||
{
|
||||
"data": "user_name",
|
||||
"render": $.fn.dataTable.render.text()
|
||||
},
|
||||
{ "data": "case_name",
|
||||
"render": $.fn.dataTable.render.text()
|
||||
},
|
||||
{ "data": "user_input",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (data == true){
|
||||
data = "<i class='fas fa-check text-success text-center'></i>";
|
||||
} else {
|
||||
data = "<i class='fas fa-times text-muted'></i>";
|
||||
}
|
||||
}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "is_from_api",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (data == true){
|
||||
data = "<i class='fas fa-check text-success'></i>";
|
||||
} else {
|
||||
data = "<i class='fas fa-times text-muted'></i>";
|
||||
}
|
||||
|
||||
}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "activity_desc",
|
||||
"render": $.fn.dataTable.render.text()
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'activities_table');
|
||||
},
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
]
|
||||
});
|
||||
$("#activities_table").css("font-size", 12);
|
||||
|
||||
function refresh_activities() {
|
||||
get_activities ();
|
||||
notify_success('Refreshed');
|
||||
}
|
||||
|
||||
function get_activities () {
|
||||
show_loader();
|
||||
if ($('#non_case_related_act').is(':checked')) {
|
||||
url = '/activities/list-all';
|
||||
} else {
|
||||
url = '/activities/list';
|
||||
}
|
||||
|
||||
get_request_api(url)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
jsdata = data;
|
||||
if (jsdata.status == "success") {
|
||||
Table.clear();
|
||||
Table.rows.add(data.data);
|
||||
Table.columns.adjust().draw();
|
||||
Table.buttons().container().appendTo($('#activities_table_info'));
|
||||
hide_loader();
|
||||
}
|
||||
}
|
||||
}).fail((data) => {
|
||||
hide_loader();
|
||||
Table.clear();
|
||||
Table.columns.adjust().draw();
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
get_activities();
|
||||
$('#non_case_related_act').on('change', function() {
|
||||
get_activities();
|
||||
});
|
||||
});
|
2061
iris-web/source/app/static/assets/js/iris/alerts.js
Normal file
2061
iris-web/source/app/static/assets/js/iris/alerts.js
Normal file
File diff suppressed because it is too large
Load Diff
534
iris-web/source/app/static/assets/js/iris/case.asset.js
Normal file
534
iris-web/source/app/static/assets/js/iris/case.asset.js
Normal file
@ -0,0 +1,534 @@
|
||||
/* reload the asset table */
|
||||
g_asset_id = null;
|
||||
g_asset_desc_editor = null;
|
||||
|
||||
|
||||
function reload_assets() {
|
||||
get_case_assets();
|
||||
}
|
||||
|
||||
function edit_in_asset_desc() {
|
||||
|
||||
if($('#container_asset_desc_content').is(':visible')) {
|
||||
$('#container_asset_description').show(100);
|
||||
$('#container_asset_desc_content').hide(100);
|
||||
$('#asset_edition_btn').hide(100);
|
||||
$('#asset_preview_button').hide(100);
|
||||
} else {
|
||||
$('#asset_preview_button').show(100);
|
||||
$('#asset_edition_btn').show(100);
|
||||
$('#container_asset_desc_content').show(100);
|
||||
$('#container_asset_description').hide(100);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a modal that is compatible with the requested asset type */
|
||||
function add_assets() {
|
||||
url = 'assets/add/modal' + case_param();
|
||||
$('#modal_add_asset_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_asset_desc_editor = get_new_ace_editor('asset_description', 'asset_desc_content', 'target_asset_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null);
|
||||
g_asset_desc_editor.setOption("minLines", "10");
|
||||
edit_in_asset_desc();
|
||||
|
||||
let headers = get_editor_headers('g_asset_desc_editor', null, 'asset_edition_btn');
|
||||
$('#asset_edition_btn').append(headers);
|
||||
|
||||
$('#ioc_links').select2({});
|
||||
|
||||
$('#submit_new_assets').on("click", function () {
|
||||
|
||||
let assets = $('#assets_name').val();
|
||||
let assets_list = assets.split('\n');
|
||||
for (let index in assets_list) {
|
||||
|
||||
let data = $('#form_new_assets').serializeObject();
|
||||
data['asset_name'] = assets_list[index];
|
||||
delete data['assets_name'];
|
||||
|
||||
if (data['asset_name'] == "" || data['asset_name'] == null || data['asset_name'] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
if (typeof data["ioc_links"] == "string") {
|
||||
data["ioc_links"] = [data["ioc_links"]]
|
||||
}
|
||||
data['asset_tags'] = $('#asset_tags').val();
|
||||
data['asset_description'] = g_asset_desc_editor.getValue();
|
||||
let ret = get_custom_attributes_fields();
|
||||
let has_error = ret[0].length > 0;
|
||||
let attributes = ret[1];
|
||||
|
||||
if (has_error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('assets/add', JSON.stringify(data), true, function () {
|
||||
$('#submit_new_assets').text('Saving data..')
|
||||
.attr("disabled", true)
|
||||
.removeClass('bt-outline-success')
|
||||
.addClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_assets();
|
||||
if (index == (assets_list.length - 1)) {
|
||||
$('#modal_add_asset').modal('hide');
|
||||
notify_success("Assets created");
|
||||
}
|
||||
} else {
|
||||
$('#submit_new_assets').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
$('#submit_new_assets')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
})
|
||||
.fail(function (error) {
|
||||
$('#submit_new_assets').text('Save');
|
||||
propagate_form_api_errors(error.responseJSON.data);
|
||||
})
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
$('#modal_add_asset').modal({ show: true });
|
||||
$('#asset_name').focus();
|
||||
|
||||
});
|
||||
|
||||
$('.dtr-modal').hide();
|
||||
}
|
||||
|
||||
/* Retrieve the list of assets and build a datatable for each type of asset */
|
||||
function get_case_assets() {
|
||||
show_loader();
|
||||
|
||||
get_request_api('/case/assets/list')
|
||||
.done(function (response) {
|
||||
if (response.status == 'success') {
|
||||
if (response.data != null) {
|
||||
jsdata = response.data;
|
||||
if (jsdata.assets.length > 299) {
|
||||
set_page_warning("Backref disabled due to too many assets in the case");
|
||||
} else {
|
||||
set_page_warning("");
|
||||
}
|
||||
Table.clear();
|
||||
Table.rows.add(jsdata.assets);
|
||||
Table.columns.adjust().draw();
|
||||
load_menu_mod_options('asset', Table, delete_asset);
|
||||
|
||||
set_last_state(jsdata.state);
|
||||
hide_loader();
|
||||
Table.responsive.recalc();
|
||||
|
||||
$('[data-toggle="popover"]').popover({html: true, container: 'body'});
|
||||
|
||||
} else {
|
||||
Table.clear().draw();
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
} else {
|
||||
Table.clear().draw()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Delete an asset */
|
||||
function delete_asset(asset_id) {
|
||||
do_deletion_prompt("You are about to delete asset #" + asset_id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
post_request_api('assets/delete/' + asset_id)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_assets();
|
||||
$('#modal_add_asset').modal('hide');
|
||||
notify_success('Asset deleted');
|
||||
} else {
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Fetch the details of an asset and allow modification */
|
||||
function asset_details(asset_id) {
|
||||
|
||||
url = 'assets/' + asset_id + '/modal' + case_param();
|
||||
$('#modal_add_asset_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
g_asset_id = asset_id;
|
||||
g_asset_desc_editor = get_new_ace_editor('asset_description', 'asset_desc_content', 'target_asset_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null, false, false);
|
||||
|
||||
g_asset_desc_editor.setOption("minLines", "10");
|
||||
preview_asset_description(true);
|
||||
headers = get_editor_headers('g_asset_desc_editor', null, 'asset_edition_btn');
|
||||
|
||||
$('#asset_edition_btn').append(headers);
|
||||
|
||||
$('#ioc_links').select2({});
|
||||
|
||||
|
||||
$('#submit_new_asset').on("click", function () {
|
||||
update_asset(true);
|
||||
return false;
|
||||
})
|
||||
|
||||
load_menu_mod_options_modal(asset_id, 'asset', $("#asset_modal_quick_actions"));
|
||||
$('.dtr-modal').hide();
|
||||
|
||||
$('#modal_add_asset').modal({ show: true });
|
||||
edit_in_asset_desc();
|
||||
});
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function preview_asset_description(no_btn_update) {
|
||||
if(!$('#container_asset_description').is(':visible')) {
|
||||
asset_desc = g_asset_desc_editor.getValue();
|
||||
converter = get_showdown_convert();
|
||||
html = converter.makeHtml(do_md_filter_xss(asset_desc));
|
||||
asset_desc_html = do_md_filter_xss(html);
|
||||
$('#target_asset_desc').html(asset_desc_html);
|
||||
$('#container_asset_description').show();
|
||||
if (!no_btn_update) {
|
||||
$('#asset_preview_button').html('<i class="fa-solid fa-eye-slash"></i>');
|
||||
}
|
||||
$('#container_asset_desc_content').hide();
|
||||
}
|
||||
else {
|
||||
$('#container_asset_description').hide();
|
||||
if (!no_btn_update) {
|
||||
$('#asset_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
}
|
||||
|
||||
$('#asset_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
$('#container_asset_desc_content').show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function save_asset(){
|
||||
$('#submit_new_asset').click();
|
||||
}
|
||||
|
||||
function update_asset(do_close){
|
||||
if(!$('form#form_new_asset').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = $('#form_new_asset').serializeObject();
|
||||
if (typeof data["ioc_links"] === "string") {
|
||||
data["ioc_links"] = [data["ioc_links"]]
|
||||
} else if (typeof data["ioc_links"] === "object") {
|
||||
tmp_data = [];
|
||||
for (ioc_link in data["ioc_links"]) {
|
||||
if (typeof ioc_link === "string") {
|
||||
tmp_data.push(data["ioc_links"][ioc_link]);
|
||||
}
|
||||
}
|
||||
data["ioc_links"] = tmp_data;
|
||||
}
|
||||
else {
|
||||
data["ioc_links"] = [];
|
||||
}
|
||||
data['asset_tags'] = $('#asset_tags').val();
|
||||
data['asset_description'] = g_asset_desc_editor.getValue();
|
||||
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('assets/update/' + g_asset_id, JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_assets();
|
||||
$('#submit_new_asset').text("Saved").addClass('btn-outline-success').removeClass('btn-outline-danger').removeClass('btn-outline-warning');
|
||||
$('#last_saved').removeClass('btn-danger').addClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-check");
|
||||
if (do_close) {
|
||||
$('#modal_add_asset').modal('hide');
|
||||
}
|
||||
notify_success('Asset updated');
|
||||
} else {
|
||||
$('#submit_new_asset').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function fire_upload_assets() {
|
||||
$('#modal_upload_assets').modal('show');
|
||||
}
|
||||
|
||||
function upload_assets() {
|
||||
|
||||
var file = $("#input_upload_assets").get(0).files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
fileData = e.target.result
|
||||
var data = new Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
data['CSVData'] = fileData;
|
||||
|
||||
post_request_api('/case/assets/upload', JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
jsdata = data;
|
||||
if (jsdata.status == "success") {
|
||||
reload_assets();
|
||||
$('#modal_upload_assets').modal('hide');
|
||||
swal("Got news for you", data.message, "success");
|
||||
|
||||
} else {
|
||||
swal("Got bad news for you", data.message, "error");
|
||||
}
|
||||
})
|
||||
|
||||
};
|
||||
reader.readAsText(file)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function generate_sample_csv(){
|
||||
csv_data = "asset_name,asset_type_name,asset_description,asset_ip,asset_domain,asset_tags\n"
|
||||
csv_data += '"My computer","Mac - Computer","Computer of Mme Michu","192.168.15.5","iris.local","Compta|Mac"\n'
|
||||
csv_data += '"XCAS","Windows - Server","Xcas server","192.168.15.48","iris.local",""'
|
||||
download_file("sample_assets.csv", "text/csv", csv_data);
|
||||
}
|
||||
|
||||
/* Page is ready, fetch the assets of the case */
|
||||
$(document).ready(function(){
|
||||
|
||||
/* add filtering fields for each table of the page (must be done before datatable initialization) */
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
Table = $("#assets_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "asset_name",
|
||||
"className": "dt-nowrap",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' || type === 'filter' || type === 'sort' || type === 'export') {
|
||||
if (row['asset_domain']) {
|
||||
datak = sanitizeHTML(row['asset_domain'])+"\\"+ sanitizeHTML(data);
|
||||
} else {
|
||||
datak = sanitizeHTML(data);
|
||||
}
|
||||
|
||||
if (data.length > 60) {
|
||||
datak = data.slice(0, 60) + " (..)";
|
||||
}
|
||||
if (isWhiteSpace(data)) {
|
||||
datak = '#' + row['asset_id'];
|
||||
}
|
||||
share_link = buildShareLink(row['asset_id']);
|
||||
if (row['asset_compromise_status_id'] == 1) {
|
||||
src_icon = row['asset_icon_compromised'];
|
||||
} else {
|
||||
src_icon = row['asset_icon_not_compromised'];
|
||||
}
|
||||
ret = '<img class="mr-2" title="'+ sanitizeHTML(row['asset_type']) +'" style="width:1.5em;height:1.5em" src=\'/static/assets/img/graph/' + src_icon +
|
||||
'\'> <a href="' + share_link + '" data-selector="true" title="Asset ID #'+ row['asset_id'] +
|
||||
'" onclick="asset_details(\'' + row['asset_id'] + '\');return false;">' + datak +'</a>';
|
||||
|
||||
if (row.link.length > 0) {
|
||||
var has_compro = false;
|
||||
var datacontent = 'data-content="';
|
||||
for (idx in row.link) {
|
||||
if (row.link[idx]['asset_compromise_status_id'] == 1) {
|
||||
has_compro = true;
|
||||
datacontent += `<b><a target='_blank' rel='noopener' href='/case/assets?cid=${row.link[idx]['case_id']}&shared=${row.link[idx]['asset_id']}'>Observed <sup><i class='fa-solid fa-arrow-up-right-from-square ml-1 mr-1 text-muted'></i></sup></a></b> as <b class='text-danger'>compromised</b><br/> on <b><a href='/case?cid=${row.link[idx]['case_id']}'>case #${row.link[idx]['case_id']} <sup><i class='fa-solid fa-arrow-up-right-from-square ml-1 mr-1 text-muted'></i></sup></a></a></b> (${row.link[idx]['case_open_date'].replace('00:00:00 GMT', '')}) for the same customer.<br/><br/>`;
|
||||
} else {
|
||||
|
||||
datacontent += `<b><a target='_blank' rel='noopener' href='/case/assets?cid=${row.link[idx]['case_id']}&shared=${row.link[idx]['asset_id']}'>Observed <sup><i class='fa-solid fa-arrow-up-right-from-square ml-1 mr-1 text-muted'></i></sup></a></b> as <b class='text-success'>not compromised</b><br/> on <b><a href='/case?cid=${row.link[idx]['case_id']}'>case #${row.link[idx]['case_id']} <sup><i class='fa-solid fa-arrow-up-right-from-square ml-1 mr-1 text-muted'></i></sup></a></a></b> (${row.link[idx]['case_open_date'].replace('00:00:00 GMT', '')}) for the same customer.<br/><br/>`;
|
||||
}
|
||||
}
|
||||
if (has_compro) {
|
||||
ret += `<a tabindex="0" class="fas fa-meteor ml-2 text-danger" style="cursor: pointer;" data-html="true"
|
||||
data-toggle="popover" data-trigger="focus" title="Observed in previous case" `;
|
||||
} else {
|
||||
ret += `<a tabindex="0" class="fas fa-info-circle ml-2 text-success" style="cursor: pointer;" data-html="true"
|
||||
data-toggle="popover" data-trigger="focus" title="Observed in previous case" `;
|
||||
}
|
||||
|
||||
ret += datacontent;
|
||||
ret += '"></i>';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "asset_type",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "asset_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover-click-close" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "asset_ip",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "asset_compromise_status_id",
|
||||
"render": function(data, type, row) {
|
||||
if (data == 0) { ret = '<span class="badge badge-muted">TBD</span>';}
|
||||
else if (data == 1) { ret = '<span class="badge badge-danger">Yes</span>';}
|
||||
else if (data == 2) { ret = '<span class="badge badge-success">No</span>';}
|
||||
else { ret = '<span class="badge badge-warning">Unknown</span>';}
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "ioc_links",
|
||||
"render": function (data, type, row, meta) {
|
||||
if ((type === 'filter' || type === 'display') && data != null) {
|
||||
datas = "";
|
||||
for (ds in data) {
|
||||
datas += '<span class="badge badge-light">' + sanitizeHTML(data[ds]['ioc_value']) + '</span>';
|
||||
}
|
||||
return datas;
|
||||
} else if (type === 'export' && data != null) {
|
||||
let datas = data.map(ds => sanitizeHTML(ds['ioc_value'])).join(',');
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "asset_tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null ) {
|
||||
tags = "";
|
||||
de = data.split(',');
|
||||
for (tag in de) {
|
||||
tags += '<span class="badge badge-light ml-2">' + sanitizeHTML(de[tag]) + '</span>';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "analysis_status",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
if (data == 'To be done') {
|
||||
flag = 'danger';
|
||||
} else if (data == 'Started') {
|
||||
flag = 'warning';
|
||||
} else if (data == 'Done') {
|
||||
flag = 'success';
|
||||
} else {
|
||||
flag = 'muted';
|
||||
}
|
||||
data = '<span class="badge ml-2 badge-'+ flag +'">' + data + '</span>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
language: {
|
||||
"processing": '<i class="fa fa-spinner fa-spin" style="font-size:24px;color:rgb(75, 183, 245);"></i>'
|
||||
},
|
||||
retrieve: true,
|
||||
buttons: [],
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'assets_table');
|
||||
},
|
||||
select: true
|
||||
});
|
||||
$("#assets_table").css("font-size", 12);
|
||||
|
||||
Table.on( 'responsive-resize', function ( e, datatable, columns ) {
|
||||
hide_table_search_input( columns );
|
||||
});
|
||||
|
||||
var buttons = new $.fn.dataTable.Buttons(Table, {
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'<i class="fas fa-cloud-download-alt"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Download as CSV', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } } ,
|
||||
{ "extend": 'copyHtml5', "text":'<i class="fas fa-copy"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Copy', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } },
|
||||
{ "extend": 'colvis', "text":'<i class="fas fa-eye-slash"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Toggle columns' }
|
||||
]
|
||||
}).container().appendTo($('#tables_button'));
|
||||
|
||||
get_case_assets();
|
||||
setInterval(function() { check_update('assets/state'); }, 3000);
|
||||
|
||||
shared_id = getSharedLink();
|
||||
if (shared_id) {
|
||||
asset_details(shared_id);
|
||||
}
|
||||
});
|
72
iris-web/source/app/static/assets/js/iris/case.graph.js
Normal file
72
iris-web/source/app/static/assets/js/iris/case.graph.js
Normal file
@ -0,0 +1,72 @@
|
||||
|
||||
function get_case_graph() {
|
||||
get_request_api('graph/getdata')
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
redrawAll(data.data);
|
||||
hide_loader();
|
||||
} else {
|
||||
$('#submit_new_asset').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var network;
|
||||
|
||||
function redrawAll(data) {
|
||||
if (data.nodes.length == 0) {
|
||||
$('#card_main_load').show();
|
||||
$('#graph-container').text('No events in graph');
|
||||
hide_loader();
|
||||
return true;
|
||||
}
|
||||
var container = document.getElementById("graph-container");
|
||||
var options = {
|
||||
edges: {
|
||||
smooth: {
|
||||
enabled: true,
|
||||
type: 'continuous',
|
||||
roundness: 0.5
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
randomSeed: 2,
|
||||
improvedLayout: true
|
||||
},
|
||||
interaction: {
|
||||
hideEdgesOnDrag: false
|
||||
},
|
||||
width: (window.innerWidth - 400) + "px",
|
||||
height: (window.innerHeight- 250) + "px",
|
||||
"physics": {
|
||||
"forceAtlas2Based": {
|
||||
"gravitationalConstant": -167,
|
||||
"centralGravity": 0.04,
|
||||
"springLength": 0,
|
||||
"springConstant": 0.02,
|
||||
"damping": 0.9
|
||||
},
|
||||
"minVelocity": 0.41,
|
||||
"solver": "forceAtlas2Based",
|
||||
"timestep": 0.45
|
||||
}
|
||||
};
|
||||
|
||||
nodes = data.nodes;
|
||||
edges = data.edges;
|
||||
|
||||
network = new vis.Network(container, data, options);
|
||||
|
||||
network.on("stabilizationIterationsDone", function () {
|
||||
network.setOptions( { physics: false } );
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Page is ready, fetch the assets of the case */
|
||||
$(document).ready(function(){
|
||||
get_case_graph();
|
||||
});
|
||||
|
478
iris-web/source/app/static/assets/js/iris/case.ioc.js
Normal file
478
iris-web/source/app/static/assets/js/iris/case.ioc.js
Normal file
@ -0,0 +1,478 @@
|
||||
/* reload the ioc table */
|
||||
var g_ioc_id = null;
|
||||
var g_ioc_desc_editor = null;
|
||||
|
||||
|
||||
function reload_iocs() {
|
||||
get_case_ioc();
|
||||
}
|
||||
|
||||
function edit_in_ioc_desc() {
|
||||
if($('#container_ioc_desc_content').is(':visible')) {
|
||||
$('#container_ioc_description').show(100);
|
||||
$('#container_ioc_desc_content').hide(100);
|
||||
$('#ioc_edition_btn').hide(100);
|
||||
$('#ioc_preview_button').hide(100);
|
||||
} else {
|
||||
$('#ioc_preview_button').show(100);
|
||||
$('#ioc_edition_btn').show(100);
|
||||
$('#container_ioc_desc_content').show(100);
|
||||
$('#container_ioc_description').hide(100);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a modal that is compatible with the requested ioc type */
|
||||
function add_ioc() {
|
||||
url = 'ioc/add/modal' + case_param();
|
||||
|
||||
$('#modal_add_ioc_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_ioc_desc_editor = get_new_ace_editor('ioc_description', 'ioc_desc_content', 'target_ioc_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null);
|
||||
|
||||
g_ioc_desc_editor.setOption("minLines", "10");
|
||||
edit_in_ioc_desc();
|
||||
|
||||
headers = get_editor_headers('g_ioc_desc_editor', null, 'ioc_edition_btn');
|
||||
$('#ioc_edition_btn').append(headers);
|
||||
|
||||
|
||||
$('#submit_new_ioc').on("click", function () {
|
||||
if(!$('form#form_new_ioc').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = $('#form_new_ioc').serializeObject();
|
||||
data['ioc_tags'] = $('#ioc_tags').val();
|
||||
data['ioc_description'] = g_ioc_desc_editor.getValue();
|
||||
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data['custom_attributes'] = attributes;
|
||||
|
||||
id = $('#ioc_id').val();
|
||||
|
||||
if ($('#ioc_one_per_line').is(':checked')) {
|
||||
let iocs_values = $('#ioc_value').val();
|
||||
let iocs_list = iocs_values.split(/\r?\n/);
|
||||
for (let index in iocs_list) {
|
||||
if (iocs_list[index] === '' || iocs_list[index] === '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
data['ioc_value'] = iocs_list[index];
|
||||
post_request_api('ioc/add', JSON.stringify(data), true, function () {
|
||||
$('#submit_new_ioc').text('Saving data..')
|
||||
.attr("disabled", true)
|
||||
.removeClass('bt-outline-success')
|
||||
.addClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_iocs();
|
||||
notify_success(data.message);
|
||||
if (index == (iocs_list.length - 1)) {
|
||||
$('#modal_add_ioc').modal('hide');
|
||||
}
|
||||
} else {
|
||||
$('#submit_new_ioc').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
$('#submit_new_ioc')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
post_request_api('ioc/add', JSON.stringify(data), true, function () {
|
||||
$('#submit_new_ioc').text('Saving data..')
|
||||
.attr("disabled", true)
|
||||
.removeClass('bt-outline-success')
|
||||
.addClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_iocs();
|
||||
notify_success(data.message);
|
||||
$('#modal_add_ioc').modal('hide');
|
||||
|
||||
} else {
|
||||
$('#submit_new_ioc').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
$('#submit_new_ioc')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
})
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#modal_add_ioc').modal({ show: true });
|
||||
$('#ioc_value').focus();
|
||||
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function save_ioc() {
|
||||
$('#submit_new_ioc').click();
|
||||
}
|
||||
|
||||
/* Retrieve the list of iocs and build a datatable for each type of ioc */
|
||||
function get_case_ioc() {
|
||||
show_loader();
|
||||
|
||||
get_request_api("/case/ioc/list")
|
||||
.done(function (response) {
|
||||
if (response.status == 'success') {
|
||||
if (response.data != null) {
|
||||
jsdata = response.data;
|
||||
Table.clear();
|
||||
Table.rows.add(jsdata.ioc);
|
||||
|
||||
set_last_state(jsdata.state);
|
||||
$('#ioc_table_wrapper').on('click', function(e){
|
||||
if($('.popover').length>1)
|
||||
$('.popover').popover('hide');
|
||||
$(e.target).popover('toggle');
|
||||
});
|
||||
|
||||
$('#ioc_table_wrapper').show();
|
||||
$('[data-toggle="popover"]').popover();
|
||||
Table.columns.adjust().draw();
|
||||
load_menu_mod_options('ioc', Table, delete_ioc);
|
||||
hide_loader();
|
||||
Table.responsive.recalc();
|
||||
|
||||
} else {
|
||||
Table.clear().draw();
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
} else {
|
||||
Table.clear().draw()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/* Edit an ioc */
|
||||
function edit_ioc(ioc_id) {
|
||||
url = 'ioc/' + ioc_id + '/modal' + case_param();
|
||||
$('#modal_add_ioc_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_ioc_id = ioc_id;
|
||||
g_ioc_desc_editor = get_new_ace_editor('ioc_description', 'ioc_desc_content', 'target_ioc_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null, false, false);
|
||||
|
||||
g_ioc_desc_editor.setOption("minLines", "10");
|
||||
preview_ioc_description(true);
|
||||
headers = get_editor_headers('g_ioc_desc_editor', null, 'ioc_edition_btn');
|
||||
$('#ioc_edition_btn').append(headers);
|
||||
|
||||
load_menu_mod_options_modal(ioc_id, 'ioc', $("#ioc_modal_quick_actions"));
|
||||
$('.dtr-modal').hide();
|
||||
$('#modal_add_ioc').modal({ show: true });
|
||||
edit_in_ioc_desc();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function preview_ioc_description(no_btn_update) {
|
||||
if(!$('#container_ioc_description').is(':visible')) {
|
||||
ioc_desc = g_ioc_desc_editor.getValue();
|
||||
converter = get_showdown_convert();
|
||||
html = converter.makeHtml(do_md_filter_xss(ioc_desc));
|
||||
ioc_desc_html = do_md_filter_xss(html);
|
||||
$('#target_ioc_desc').html(ioc_desc_html);
|
||||
$('#container_ioc_description').show();
|
||||
if (!no_btn_update) {
|
||||
$('#ioc_preview_button').html('<i class="fa-solid fa-eye-slash"></i>');
|
||||
}
|
||||
$('#container_ioc_desc_content').hide();
|
||||
}
|
||||
else {
|
||||
$('#container_ioc_description').hide();
|
||||
if (!no_btn_update) {
|
||||
$('#ioc_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
}
|
||||
|
||||
$('#ioc_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
$('#container_ioc_desc_content').show();
|
||||
}
|
||||
}
|
||||
|
||||
function update_ioc(ioc_id) {
|
||||
update_ioc_ext(ioc_id, true);
|
||||
}
|
||||
|
||||
/* Update an ioc */
|
||||
function update_ioc_ext(ioc_id, do_close) {
|
||||
if(!$('form#form_new_ioc').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioc_id === undefined || ioc_id === null) {
|
||||
ioc_id = g_ioc_id;
|
||||
}
|
||||
|
||||
var data = $('#form_new_ioc').serializeObject();
|
||||
data['ioc_tags'] = $('#ioc_tags').val();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
data['ioc_description'] = g_ioc_desc_editor.getValue();
|
||||
data['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('ioc/update/' + ioc_id, JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_iocs();
|
||||
|
||||
$('#submit_new_ioc').text("Saved").addClass('btn-outline-success').removeClass('btn-outline-danger').removeClass('btn-outline-warning');
|
||||
$('#last_saved').removeClass('btn-danger').addClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-check");
|
||||
|
||||
if (do_close !== undefined && do_close === true) {
|
||||
$('#modal_add_ioc').modal('hide');
|
||||
}
|
||||
|
||||
notify_success(data.message);
|
||||
|
||||
} else {
|
||||
$('#submit_new_ioc').text('Save again');
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/* Delete an ioc */
|
||||
function delete_ioc(ioc_id) {
|
||||
do_deletion_prompt("You are about to delete IOC #" + ioc_id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
post_request_api('ioc/delete/' + ioc_id)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
reload_iocs();
|
||||
notify_success(data.message);
|
||||
$('#modal_add_ioc').modal('hide');
|
||||
|
||||
} else {
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fire_upload_iocs() {
|
||||
$('#modal_upload_ioc').modal('show');
|
||||
}
|
||||
|
||||
function upload_ioc() {
|
||||
|
||||
var file = $("#input_upload_ioc").get(0).files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
fileData = e.target.result
|
||||
var data = new Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
data['CSVData'] = fileData;
|
||||
|
||||
post_request_api('/case/ioc/upload', JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
jsdata = data;
|
||||
if (jsdata.status == "success") {
|
||||
reload_iocs();
|
||||
$('#modal_upload_ioc').modal('hide');
|
||||
swal("Got news for you", data.message, "success");
|
||||
|
||||
} else {
|
||||
swal("Got bad news for you", data.message, "error");
|
||||
}
|
||||
})
|
||||
};
|
||||
reader.readAsText(file)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function generate_sample_csv(){
|
||||
csv_data = "ioc_value,ioc_type,ioc_description,ioc_tags,ioc_tlp\n"
|
||||
csv_data += "1.1.1.1,ip-dst,Cloudflare DNS IP address,Cloudflare|DNS,green\n"
|
||||
csv_data += "wannacry.exe,filename,Wannacry sample found,Wannacry|Malware|PE,amber"
|
||||
download_file("sample_iocs.csv", "text/csv", csv_data);
|
||||
}
|
||||
|
||||
/* Page is ready, fetch the iocs of the case */
|
||||
$(document).ready(function(){
|
||||
|
||||
/* add filtering fields for each table of the page (must be done before datatable initialization) */
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
Table = $("#ioc_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
fixedHeader: true,
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "ioc_value",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
|
||||
let datak = '';
|
||||
|
||||
if (isWhiteSpace(data) || data === null) {
|
||||
datak = '#' + row['ioc_id'];
|
||||
} else {
|
||||
datak= ellipsis_field(data, 64);
|
||||
}
|
||||
|
||||
share_link = buildShareLink(row['ioc_id']);
|
||||
data = '<a href="' + share_link + '" data-selector="true" title="IOC ID #'+ row['ioc_id'] +'" onclick="edit_ioc(\'' + row['ioc_id'] + '\');return false;">' + datak +'</a>';
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "ioc_type",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "ioc_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "ioc_tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
tags = "";
|
||||
de = data.split(',');
|
||||
for (tag in de) {
|
||||
tags += '<span class="badge badge-light ml-2">' + sanitizeHTML(de[tag]) + '</span>';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "link",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
links = "";
|
||||
for (link in data) {
|
||||
links += '<span data-toggle="popover" style="cursor: pointer;" data-trigger="hover" class="text-primary mr-3" href="#" title="Case info" data-content="' + sanitizeHTML(data[link]['case_name']) +
|
||||
' (' + sanitizeHTML(data[link]['client_name']) + ')' + '">#' + data[link]['case_id'] + '</span>'
|
||||
}
|
||||
return links;
|
||||
} else if (type === 'export' && data != null) {
|
||||
return data.map(ds => sanitizeHTML(ds['case_name'])).join(',');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "tlp_name",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<span class="badge badge-'+ row['tlp_bscolor'] +' ml-2">tlp:' + data + '</span>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
buttons: [],
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'ioc_table');
|
||||
},
|
||||
select: true
|
||||
});
|
||||
$("#ioc_table").css("font-size", 12);
|
||||
|
||||
Table.on( 'responsive-resize', function ( e, datatable, columns ) {
|
||||
hide_table_search_input( columns );
|
||||
});
|
||||
|
||||
var buttons = new $.fn.dataTable.Buttons(Table, {
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'<i class="fas fa-cloud-download-alt"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Download as CSV', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } } ,
|
||||
{ "extend": 'copyHtml5', "text":'<i class="fas fa-copy"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Copy', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } },
|
||||
{ "extend": 'colvis', "text":'<i class="fas fa-eye-slash"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Toggle columns' }
|
||||
]
|
||||
}).container().appendTo($('#tables_button'));
|
||||
|
||||
get_case_ioc();
|
||||
setInterval(function() { check_update('ioc/state'); }, 3000);
|
||||
|
||||
shared_id = getSharedLink();
|
||||
if (shared_id) {
|
||||
edit_ioc(shared_id);
|
||||
}
|
||||
});
|
179
iris-web/source/app/static/assets/js/iris/case.js
Normal file
179
iris-web/source/app/static/assets/js/iris/case.js
Normal file
@ -0,0 +1,179 @@
|
||||
function buildShareLink(lookup_id) {
|
||||
current_path = location.protocol + '//' + location.host + location.pathname;
|
||||
current_path = current_path + case_param() + '&shared=' + lookup_id;
|
||||
|
||||
return current_path;
|
||||
}
|
||||
|
||||
function getSharedLink(){
|
||||
queryString = window.location.search;
|
||||
urlParams = new URLSearchParams(queryString);
|
||||
if (Number.isInteger(parseInt(urlParams.get('shared')))) {
|
||||
return urlParams.get('shared')
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function edit_case_info() {
|
||||
$('#case_gen_info_content').hide();
|
||||
$('#case_gen_info_edit').show();
|
||||
$('#cancel_case_info').show();
|
||||
$('#save_case_info').show();
|
||||
$('#case_info').hide();
|
||||
}
|
||||
|
||||
function cancel_case_edit() {
|
||||
$('#case_gen_info_content').show();
|
||||
$('#case_gen_info_edit').hide();
|
||||
$('#cancel_case_info').hide();
|
||||
$('#save_case_info').hide();
|
||||
$('#case_info').show();
|
||||
}
|
||||
|
||||
function save_case_edit(case_id) {
|
||||
|
||||
var data_sent = $('form#form_update_case').serializeObject();
|
||||
var map_protagonists = Object();
|
||||
|
||||
for (e in data_sent) {
|
||||
if (e.startsWith('protagonist_role_')) {
|
||||
map_protagonists[e.replace('protagonist_role_', '')] = {
|
||||
'role': data_sent[e]
|
||||
};
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_name_')) {
|
||||
map_protagonists[e.replace('protagonist_name_', '')]['name'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_contact_')) {
|
||||
map_protagonists[e.replace('protagonist_contact_', '')]['contact'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_id_')) {
|
||||
map_protagonists[e.replace('protagonist_id_', '')]['id'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
}
|
||||
data_sent['protagonists'] = [];
|
||||
for (e in map_protagonists) {
|
||||
data_sent['protagonists'].push(map_protagonists[e]);
|
||||
}
|
||||
|
||||
data_sent['case_tags'] = $('#case_tags').val();
|
||||
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/manage/cases/update/' + case_id, JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
case_detail(case_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Remove case function */
|
||||
function remove_case(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !\nAll associated data will be deleted",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/cases/delete/' + id)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
$('#modal_case_detail').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Reopen case function */
|
||||
function reopen_case(id) {
|
||||
post_request_api('/manage/cases/reopen/' + id)
|
||||
.done((data) => {
|
||||
window.location.reload();
|
||||
$('#modal_case_detail').modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
/* Close case function */
|
||||
function close_case(id) {
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "Case ID " + id + " will be closed",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, close it!'
|
||||
})
|
||||
.then((willClose) => {
|
||||
if (willClose) {
|
||||
post_request_api('/manage/cases/close/' + id)
|
||||
.done((data) => {
|
||||
window.location.reload();
|
||||
$('#modal_case_detail').modal('hide');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add_protagonist() {
|
||||
random_string = Math.random().toString(36).substring(7);
|
||||
prota_html = $('#protagonist_list_edit_template').html();
|
||||
prota_html = prota_html.replace(/__PROTAGONIST_ID__/g, random_string);
|
||||
$('#protagonist_list_edit').append(prota_html);
|
||||
}
|
||||
|
||||
function remove_protagonist(id) {
|
||||
$('#protagonist_' + id).remove();
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
$(function(){
|
||||
var current = location.pathname;
|
||||
$('#h_nav_tab li').each(function(){
|
||||
var $this = $(this);
|
||||
var child = $this.children();
|
||||
// if the current path is like this link, make it active
|
||||
if(child.attr('href') !== undefined && child.attr('href').split("?")[0] == current){
|
||||
$this.addClass('active');
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$('#case_quick_status').change(function(){
|
||||
post_request_api('/case/update-status', JSON.stringify({
|
||||
'status_id': $('#case_quick_status').val(),
|
||||
'csrf_token': $('#csrf_token').val()
|
||||
}))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
761
iris-web/source/app/static/assets/js/iris/case.notes.js
Normal file
761
iris-web/source/app/static/assets/js/iris/case.notes.js
Normal file
@ -0,0 +1,761 @@
|
||||
/* Defines the kanban board */
|
||||
let note_editor;
|
||||
let session_id = null ;
|
||||
let collaborator = null ;
|
||||
let collaborator_socket = null ;
|
||||
let buffer_dumped = false ;
|
||||
let last_applied_change = null ;
|
||||
let just_cleared_buffer = null ;
|
||||
let from_sync = null;
|
||||
let is_typing = "";
|
||||
let ppl_viewing = new Map();
|
||||
let timer_socket = 0;
|
||||
let note_id = null;
|
||||
let map_notes = Object();
|
||||
let last_ping = 0;
|
||||
let forceModalClose = false;
|
||||
let wasMiniNote = false;
|
||||
|
||||
const preventFormDefaultBehaviourOnSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
var boardNotes = {
|
||||
init: function init() {
|
||||
this.bindUIActions();
|
||||
},
|
||||
bindUIActions: function bindUIActions() {
|
||||
// event handlers
|
||||
this.handleBoardStyle();
|
||||
this.handleSortable();
|
||||
},
|
||||
byId: function byId(id) {
|
||||
return document.getElementById(id);
|
||||
},
|
||||
handleBoardStyle: function handleBoardStyle() {
|
||||
$(document).on('mouseenter mouseleave', '.kanban-board-header', function (e) {
|
||||
var isHover = e.type === 'mouseenter';
|
||||
$(this).parent().toggleClass('hover', isHover);
|
||||
});
|
||||
},
|
||||
handleSortable: function handleSortable() {
|
||||
var board = this.byId('myKanban');
|
||||
// Multi groups
|
||||
Sortable.create(board, {
|
||||
animation: 150,
|
||||
draggable: '.kanban-board',
|
||||
handle: '.kanban-board-header',
|
||||
filter: '.ignore-sort',
|
||||
forceFallback: true
|
||||
});
|
||||
[].forEach.call(board.querySelectorAll('.kanban-drag'), function (el) {
|
||||
Sortable.create(el, {
|
||||
group: 'tasks',
|
||||
animation: 150,
|
||||
filter: '.ignore-sort',
|
||||
forceFallback: true
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function Collaborator( session_id, note_id ) {
|
||||
this.collaboration_socket = collaborator_socket;
|
||||
|
||||
this.channel = "case-" + session_id + "-notes";
|
||||
|
||||
this.collaboration_socket.on( "change-note", function(data) {
|
||||
if ( data.note_id !== note_id ) return ;
|
||||
let delta = JSON.parse( data.delta ) ;
|
||||
last_applied_change = delta ;
|
||||
$("#content_typing").text(data.last_change + " is typing..");
|
||||
if ( delta !== null && delta !== undefined ) {
|
||||
note_editor.session.getDocument().applyDeltas([delta]);
|
||||
}
|
||||
}.bind()) ;
|
||||
|
||||
this.collaboration_socket.on( "clear_buffer-note", function() {
|
||||
if ( data.note_id !== note_id ) return ;
|
||||
just_cleared_buffer = true ;
|
||||
note_editor.setValue( "" ) ;
|
||||
}.bind() ) ;
|
||||
|
||||
this.collaboration_socket.on( "save-note", function(data) {
|
||||
if ( data.note_id !== note_id ) return ;
|
||||
sync_note(note_id)
|
||||
.then(function () {
|
||||
$("#content_last_saved_by").text("Last saved by " + data.last_saved);
|
||||
$('#btn_save_note').text("Saved").addClass('btn-success').removeClass('btn-danger').removeClass('btn-warning');
|
||||
$('#last_saved').removeClass('btn-danger').addClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-check");
|
||||
});
|
||||
|
||||
}.bind());
|
||||
|
||||
this.collaboration_socket.on('leave-note', function(data) {
|
||||
ppl_viewing.delete(data.user);
|
||||
refresh_ppl_list(session_id, note_id);
|
||||
});
|
||||
|
||||
this.collaboration_socket.on('join-note', function(data) {
|
||||
if ( data.note_id !== note_id ) return ;
|
||||
if ((data.user in ppl_viewing)) return;
|
||||
ppl_viewing.set(filterXSS(data.user), 1);
|
||||
refresh_ppl_list(session_id, note_id);
|
||||
collaborator.collaboration_socket.emit('ping-note', { 'channel': collaborator.channel, 'note_id': note_id });
|
||||
});
|
||||
|
||||
this.collaboration_socket.on('ping-note', function(data) {
|
||||
if ( data.note_id !== note_id ) return ;
|
||||
collaborator.collaboration_socket.emit('pong-note', { 'channel': collaborator.channel, 'note_id': note_id });
|
||||
});
|
||||
|
||||
this.collaboration_socket.on('disconnect', function(data) {
|
||||
ppl_viewing.delete(data.user);
|
||||
refresh_ppl_list(session_id, note_id);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function set_notes_follow(data) {
|
||||
|
||||
if (data.note_id !== null) {
|
||||
if (data.note_id in map_notes ) {
|
||||
map_notes[data.note_id][data.user] = 2;
|
||||
} else {
|
||||
map_notes[data.note_id] = Object();
|
||||
map_notes[data.note_id][data.user] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (let notid in map_notes) {
|
||||
for (let key in map_notes[notid]) {
|
||||
if (key !== data.user && data.note_id !== note_id || data.note_id === null) {
|
||||
map_notes[notid][key] -= 1;
|
||||
}
|
||||
if (map_notes[notid][key] < 0) {
|
||||
delete map_notes[notid][key];
|
||||
}
|
||||
}
|
||||
$(`#badge_${notid}`).empty();
|
||||
for (let key in map_notes[notid]) {
|
||||
$(`#badge_${notid}`).append(get_avatar_initials(filterXSS(key), false, undefined, true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Collaborator.prototype.change = function( delta, note_id ) {
|
||||
this.collaboration_socket.emit( "change-note", { 'delta': delta, 'channel': this.channel, 'note_id': note_id } ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.clear_buffer = function( note_id ) {
|
||||
this.collaboration_socket.emit( "clear_buffer-note", { 'channel': this.channel, 'note_id': note_id } ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.save = function( note_id ) {
|
||||
this.collaboration_socket.emit( "save-note", { 'channel': this.channel, 'note_id': note_id } ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.close = function( note_id ) {
|
||||
this.collaboration_socket.emit( "leave-note", { 'channel': this.channel, 'note_id': note_id } ) ;
|
||||
}
|
||||
|
||||
function auto_remove_typing() {
|
||||
if ($("#content_typing").text() == is_typing) {
|
||||
$("#content_typing").text("");
|
||||
} else {
|
||||
is_typing = $("#content_typing").text();
|
||||
}
|
||||
}
|
||||
|
||||
/* Generates a global sequence id for subnotes */
|
||||
let current_id = 0;
|
||||
|
||||
function nextSubNote(element, _item, title) {
|
||||
var newElement = element.clone();
|
||||
var id = current_id + 1;
|
||||
current_id = id;
|
||||
if (id < 10) id = "0" + id;
|
||||
newElement.attr("id", element.attr("id").split("_")[0] + "_" + id);
|
||||
var field = $(newElement).attr("id");
|
||||
$(newElement).attr("id", field.split("_")[0] + "_" + id);
|
||||
$(newElement).find('iris_note').attr('id', 'xqx' + id + 'qxq');
|
||||
$(newElement).find('iris_note').text("New note");
|
||||
var va = $(newElement).find('a');
|
||||
$(newElement).find(va[1]).attr("onclick", 'delete_note("_' + id + '")');
|
||||
newElement.appendTo($('#group-' + _item + "_main"));
|
||||
newElement.show();
|
||||
}
|
||||
|
||||
/* Generates a global sequence id for groups */
|
||||
var current_gid = 0;
|
||||
|
||||
async function get_remote_note(note_id) {
|
||||
return get_request_api("/case/notes/" + note_id);
|
||||
}
|
||||
|
||||
async function sync_note(node_id) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function nextGroupNote(title="", rid=0) {
|
||||
|
||||
if (rid == 0) {
|
||||
console.log("RID is needed to create group");
|
||||
return;
|
||||
}
|
||||
|
||||
var element = $('#group_');
|
||||
var newElement = element.clone();
|
||||
|
||||
if (title == "") {
|
||||
title = "Untitled group";
|
||||
}
|
||||
newElement.attr("id", "group-" + rid);
|
||||
newElement.attr("title", "New group note");
|
||||
|
||||
var fa = $(newElement).find('button')[0];
|
||||
var fb = $(newElement).find('button')[1];
|
||||
var va = $(newElement).find('a');
|
||||
|
||||
$(newElement).find('div.kanban-title-board').text(title);
|
||||
$(newElement).find('div.kanban-title-board').attr("onclick", 'edit_add_save(' + rid + ')');
|
||||
|
||||
$(newElement).find(fa).attr("onclick", 'edit_remote_groupnote(' + rid + ')');
|
||||
$(newElement).find(fb).attr("onclick", 'add_remote_note(' + rid + ')');
|
||||
|
||||
$(newElement).find(va[0]).attr("onclick", 'delete_remote_groupnote(' + rid + ')');
|
||||
|
||||
$(newElement).find('main').attr("id", "group-" + rid + "-main");
|
||||
newElement.appendTo($('#myKanban'));
|
||||
newElement.show();
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
/* Add a subnote to an item */
|
||||
function add_subnote(_item, tr=0, title='', last_up, user) {
|
||||
|
||||
if (tr != 0) {
|
||||
let element = $('#_subnote_');
|
||||
var newElement = element.clone();
|
||||
var id = tr;
|
||||
current_id = id;
|
||||
|
||||
let info = user + " on " + last_up.replace('GMT', '');
|
||||
|
||||
newElement.attr("id", element.attr("id").split("_")[0] + "_" + id);
|
||||
var field = $(newElement).attr("id");
|
||||
$(newElement).attr("id", field.split("_")[0] + "_" + id);
|
||||
$(newElement).attr("title", 'Note #' + id);
|
||||
$(newElement).find('iris_note').attr('id', tr);
|
||||
$(newElement).find('iris_note').text(title);
|
||||
$(newElement).find('a.kanban-title').text(title);
|
||||
$(newElement).find('small.kanban-info').text(info);
|
||||
$(newElement).find('div.kanban-badge').attr('id', 'badge_' + id);
|
||||
newElement.appendTo($('#group-' + _item + "-main"));
|
||||
newElement.show();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a group to the dashboard */
|
||||
function add_groupnote(title="", rid=0) {
|
||||
return nextGroupNote(title, rid=rid);
|
||||
}
|
||||
|
||||
/* Add a remote note to a group */
|
||||
function add_remote_note(group_id) {
|
||||
let data = Object();
|
||||
data['note_title'] = "Untitled note";
|
||||
data['note_content'] = "";
|
||||
|
||||
data['group_id'] = group_id;
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/case/notes/add', JSON.stringify(data), false)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
draw_kanban();
|
||||
} else {
|
||||
if (data.message != "No data to load for dashboard") {
|
||||
swal("Oh no !", data.message, "error");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/* Add a group note remotely */
|
||||
function add_remote_groupnote() {
|
||||
let data = Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/case/notes/groups/add', JSON.stringify(data), false)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
nextGroupNote(data.data.group_title, data.data.group_id);
|
||||
draw_kanban();
|
||||
} else {
|
||||
if (data.message != "No data to load for dashboard") {
|
||||
swal("Oh no !", data.message, "error");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Delete a group of the dashboard */
|
||||
function delete_remote_groupnote(group_id) {
|
||||
|
||||
swal({
|
||||
title: "Attention ",
|
||||
text: "All the notes in this group will be deleted !\nThis cannot be reverted, notes will not be recoverable",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
var data = Object();
|
||||
data['group_id'] = group_id;
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/case/notes/groups/delete/'+ group_id)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
swal("Done !", data.message, "success");
|
||||
draw_kanban();
|
||||
} else {
|
||||
if (data.message != "No data to load for dashboard") {
|
||||
swal("Oh no !", data.message, "error");
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* Add a button to save group name */
|
||||
function edit_add_save(group_id) {
|
||||
btn = $("#group-" + group_id).find('button')[0];
|
||||
$(btn).show();
|
||||
}
|
||||
|
||||
/* Delete a group of the dashboard */
|
||||
function edit_remote_groupnote(group_id) {
|
||||
|
||||
var data = Object();
|
||||
data['group_title'] = $("#group-" + group_id).find('div.kanban-title-board').text();
|
||||
data["csrf_token"] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/case/notes/groups/update/'+ group_id, JSON.stringify(data))
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
draw_kanban();
|
||||
})
|
||||
}
|
||||
|
||||
/* Delete a group of the dashboard */
|
||||
function delete_note(_item, cid) {
|
||||
|
||||
var n_id = $("#info_note_modal_content").find('iris_notein').text();
|
||||
|
||||
do_deletion_prompt("You are about to delete note #" + n_id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
post_request_api('/case/notes/delete/' + n_id, null, null, cid)
|
||||
.done((data) => {
|
||||
$('#modal_note_detail').modal('hide');
|
||||
notify_auto_api(data);
|
||||
})
|
||||
.fail(function (error) {
|
||||
draw_kanban();
|
||||
swal( 'Oh no :(', error.message, 'error');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* List all the notes on the dashboard */
|
||||
function list_notes() {
|
||||
output = {};
|
||||
$("#myKanban").children().each(function () {
|
||||
|
||||
gid = $(this).attr('id');
|
||||
|
||||
output[gid] = [];
|
||||
|
||||
$(this).find('iris_note').each(function () {
|
||||
output[gid].push(
|
||||
[$(this).attr('id'),
|
||||
$(this).text()
|
||||
]);
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
/* Edit one note */
|
||||
function edit_note(event) {
|
||||
|
||||
var nval = $(event).find('iris_note').attr('id');
|
||||
collaborator = null;
|
||||
note_detail(nval);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the edit modal with content from server */
|
||||
function note_detail(id, cid) {
|
||||
if (cid === undefined ) {
|
||||
cid = case_param()
|
||||
} else {
|
||||
cid = '?cid=' + cid;
|
||||
}
|
||||
|
||||
url = '/case/notes/' + id + "/modal" + cid;
|
||||
$('#info_note_modal_content').load(url, function (response, status, xhr) {
|
||||
$('#form_note').on("submit", preventFormDefaultBehaviourOnSubmit);
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
let timer;
|
||||
let timeout = 10000;
|
||||
$('#form_note').keyup(function(){
|
||||
if(timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
if (ppl_viewing.size <= 1) {
|
||||
timer = setTimeout(save_note, timeout);
|
||||
}
|
||||
});
|
||||
|
||||
note_id = id;
|
||||
|
||||
collaborator = new Collaborator( get_caseid(), id );
|
||||
|
||||
note_editor = get_new_ace_editor('editor_detail', 'note_content', 'targetDiv', function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
$('#btn_save_note').text("Save").removeClass('btn-success').addClass('btn-warning').removeClass('btn-danger');
|
||||
}, save_note);
|
||||
|
||||
note_editor.focus();
|
||||
|
||||
note_editor.on( "change", function( e ) {
|
||||
// TODO, we could make things more efficient and not likely to conflict by keeping track of change IDs
|
||||
if( last_applied_change != e && note_editor.curOp && note_editor.curOp.command.name) {
|
||||
collaborator.change( JSON.stringify(e), id ) ;
|
||||
}
|
||||
}, false
|
||||
);
|
||||
last_applied_change = null ;
|
||||
just_cleared_buffer = false ;
|
||||
|
||||
load_menu_mod_options_modal(id, 'note', $("#note_modal_quick_actions"));
|
||||
$('#modal_note_detail').modal({ show: true, backdrop: 'static'});
|
||||
|
||||
$('#modal_note_detail').off('hide.bs.modal').on("hide.bs.modal", function (e) {
|
||||
forceModalClose = false;
|
||||
return handle_note_close(id, e);
|
||||
});
|
||||
|
||||
collaborator_socket.emit('ping-note', { 'channel': 'case-' + get_caseid() + '-notes', 'note_id': note_id });
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function handle_note_close(id, e) {
|
||||
note_id = null;
|
||||
|
||||
if ($("#minimized_modal_box").is(":visible")) {
|
||||
forceModalClose = true;
|
||||
wasMiniNote = true;
|
||||
save_note(null, get_caseid());
|
||||
}
|
||||
|
||||
|
||||
if ($('#btn_save_note').text() === "Save" && !forceModalClose) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You have unsaved changes!",
|
||||
icon: "warning",
|
||||
buttons: {
|
||||
cancel: {
|
||||
text: "Cancel",
|
||||
value: null,
|
||||
visible: true,
|
||||
},
|
||||
confirm: {
|
||||
text: "Discard changes",
|
||||
value: true,
|
||||
}
|
||||
},
|
||||
dangerMode: true,
|
||||
closeOnEsc: false,
|
||||
allowOutsideClick: false,
|
||||
allowEnterKey: false
|
||||
})
|
||||
.then((willDiscard) => {
|
||||
if (willDiscard) {
|
||||
location.reload();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
forceModalClose = false;
|
||||
if (!wasMiniNote) {
|
||||
if (collaborator) {
|
||||
collaborator.close();
|
||||
}
|
||||
if (note_editor) {
|
||||
note_editor.destroy();
|
||||
}
|
||||
|
||||
if (ppl_viewing) {
|
||||
ppl_viewing.clear();
|
||||
}
|
||||
}
|
||||
collaborator_socket.off('save-note');
|
||||
collaborator_socket.off('leave-note');
|
||||
collaborator_socket.off('join-note');
|
||||
collaborator_socket.off('ping-note');
|
||||
collaborator_socket.off('disconnect');
|
||||
collaborator_socket.off('clear_buffer-note');
|
||||
collaborator_socket.off('change-note');
|
||||
collaborator_socket.emit('ping-note', {'channel': 'case-' + get_caseid() + '-notes', 'note_id': null});
|
||||
wasMiniNote = false;
|
||||
|
||||
await draw_kanban();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function refresh_ppl_list() {
|
||||
$('#ppl_list_viewing').empty();
|
||||
for (let [key, value] of ppl_viewing) {
|
||||
$('#ppl_list_viewing').append(get_avatar_initials(key, false, undefined, true));
|
||||
}
|
||||
}
|
||||
|
||||
function handle_ed_paste(event) {
|
||||
let filename = null;
|
||||
const { items } = event.originalEvent.clipboardData;
|
||||
for (let i = 0; i < items.length; i += 1) {
|
||||
const item = items[i];
|
||||
|
||||
if (item.kind === 'string') {
|
||||
item.getAsString(function (s){
|
||||
filename = $.trim(s.replace(/\t|\n|\r/g, '')).substring(0, 40);
|
||||
});
|
||||
}
|
||||
|
||||
if (item.kind === 'file') {
|
||||
console.log(item.type);
|
||||
const blob = item.getAsFile();
|
||||
|
||||
if (blob !== null) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
notify_success('The file is uploading in background. Don\'t leave the page');
|
||||
|
||||
if (filename === null) {
|
||||
filename = random_filename(25);
|
||||
}
|
||||
|
||||
upload_interactive_data(e.target.result, filename, function(data){
|
||||
url = data.data.file_url + case_param();
|
||||
event.preventDefault();
|
||||
note_editor.insertSnippet(`\n\n`);
|
||||
});
|
||||
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
} else {
|
||||
notify_error('Unsupported direct paste of this item. Use datastore to upload.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete a group of the dashboard */
|
||||
function search_notes() {
|
||||
var data = Object();
|
||||
data['search_term'] = $("#search_note_input").val();
|
||||
data['csrf_token'] = $("#csrf_token").val();
|
||||
|
||||
post_request_api('/case/notes/search', JSON.stringify(data))
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
$('#notes_search_list').empty();
|
||||
for (e in data.data) {
|
||||
li = `<li class="list-group-item list-group-item-action">
|
||||
<span class="name" style="cursor:pointer" title="Click to open note" onclick="note_detail(`+ data.data[e]['note_id'] +`);">`+ data.data[e]['note_title'] +`</span>
|
||||
</li>`
|
||||
$('#notes_search_list').append(li);
|
||||
}
|
||||
$('#notes_search_list').show();
|
||||
|
||||
} else {
|
||||
if (data.message != "No data to load for dashboard") {
|
||||
swal("Oh no !", data.message, "error");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function toggle_max_editor() {
|
||||
if ($('#container_note_content').hasClass('col-md-12')) {
|
||||
$('#container_note_content').removeClass('col-md-12').addClass('col-md-6');
|
||||
$('#ctrd_notesum').removeClass('d-none');
|
||||
$('#btn_max_editor').html('<i class="fa-solid fa-minimize"></i>');
|
||||
} else {
|
||||
$('#container_note_content').removeClass('col-md-6').addClass('col-md-12');
|
||||
$('#ctrd_notesum').addClass('d-none');
|
||||
$('#btn_max_editor').html('<i class="fa-solid fa-maximize"></i>');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Save a note into db */
|
||||
function save_note(this_item, cid) {
|
||||
clear_api_error();
|
||||
var n_id = $("#info_note_modal_content").find('iris_notein').text();
|
||||
|
||||
|
||||
var data_sent = $('#form_note').serializeObject();
|
||||
data_sent['note_content'] = $('#note_content').val();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('/case/notes/update/'+ n_id, JSON.stringify(data_sent), false, undefined, cid, function() {
|
||||
$('#btn_save_note').text("Error saving!").removeClass('btn-success').addClass('btn-danger').removeClass('btn-danger');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-xmark");
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
})
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
$('#btn_save_note').text("Saved").addClass('btn-success').removeClass('btn-danger').removeClass('btn-warning');
|
||||
$('#last_saved').removeClass('btn-danger').addClass('btn-success');
|
||||
$("#content_last_saved_by").text('Last saved by you');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-check");
|
||||
collaborator.save(n_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Span for note edition */
|
||||
function edit_innote() {
|
||||
return edit_inner_editor('notes_edition_btn', 'container_note_content', 'ctrd_notesum');
|
||||
}
|
||||
|
||||
/* Load the kanban case data and build the board from it */
|
||||
async function draw_kanban() {
|
||||
/* Empty board */
|
||||
$('#myKanban').empty();
|
||||
show_loader();
|
||||
|
||||
return get_request_api('/case/notes/groups/list')
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
gidl = [];
|
||||
if (data.data.groups.length > 0) {
|
||||
$('#empty-set-notes').hide();
|
||||
} else {
|
||||
$('#empty-set-notes').show();
|
||||
}
|
||||
for (idx in data.data.groups) {
|
||||
group = data.data.groups[idx];
|
||||
if (!gidl.includes(group.group_id)) {
|
||||
nextGroupNote(group.group_title, group.group_id);
|
||||
gidl.push(group.group_id);
|
||||
}
|
||||
for (ikd in group.notes) {
|
||||
note = group.notes[ikd];
|
||||
add_subnote(group.group_id,
|
||||
note.note_id,
|
||||
note.note_title,
|
||||
note.note_lastupdate,
|
||||
note.user
|
||||
);
|
||||
}
|
||||
}
|
||||
set_last_state(data.data.state);
|
||||
hide_loader();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function note_interval_pinger() {
|
||||
if (new Date() - last_ping > 2000) {
|
||||
collaborator_socket.emit('ping-note',
|
||||
{ 'channel': 'case-' + get_caseid() + '-notes', 'note_id': note_id });
|
||||
last_ping = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
shared_id = getSharedLink();
|
||||
if (shared_id) {
|
||||
note_detail(shared_id);
|
||||
}
|
||||
|
||||
let cid = get_caseid();
|
||||
collaborator_socket = io.connect();
|
||||
collaborator_socket.emit('join-notes-overview', { 'channel': 'case-' + cid + '-notes' });
|
||||
|
||||
collaborator_socket.on('ping-note', function(data) {
|
||||
last_ping = new Date();
|
||||
if ( data.note_id === null || data.note_id !== note_id) {
|
||||
set_notes_follow(data);
|
||||
return;
|
||||
}
|
||||
|
||||
ppl_viewing.set(data.user, 1);
|
||||
for (let [key, value] of ppl_viewing) {
|
||||
if (key !== data.user) {
|
||||
ppl_viewing.set(key, value-1);
|
||||
}
|
||||
if (value < 0) {
|
||||
ppl_viewing.delete(key);
|
||||
}
|
||||
}
|
||||
refresh_ppl_list(session_id, note_id);
|
||||
});
|
||||
|
||||
timer_socket = setInterval( function() {
|
||||
note_interval_pinger();
|
||||
}, 2000);
|
||||
|
||||
collaborator_socket.emit('ping-note', { 'channel': 'case-' + cid + '-notes', 'note_id': note_id });
|
||||
|
||||
setInterval(auto_remove_typing, 1500);
|
||||
|
||||
});
|
149
iris-web/source/app/static/assets/js/iris/case.pipelines.js
Normal file
149
iris-web/source/app/static/assets/js/iris/case.pipelines.js
Normal file
@ -0,0 +1,149 @@
|
||||
/*************************
|
||||
* Case update section
|
||||
*************************/
|
||||
/* Dropzone creation for update */
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
Dropzone.prototype.getErroredFiles = function () {
|
||||
var file, _i, _len, _ref, _results;
|
||||
_ref = this.files;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
file = _ref[_i];
|
||||
if (file.status === Dropzone.ERROR) {
|
||||
_results.push(file);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
var dropUpdate = new Dropzone("div#files_drop_1", {
|
||||
url: "/manage/cases/upload_files" + case_param(),
|
||||
addRemoveLinks: true,
|
||||
autoProcessQueue: false,
|
||||
parallelUploads: 40,
|
||||
maxFiles: 40,
|
||||
maxFilesize: 10000,
|
||||
timeout: 0,
|
||||
complete: function () {
|
||||
if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0 && this.getErroredFiles().length === 0) {
|
||||
$('#submit_update_case').text('Notifying for new import')
|
||||
send_update_case_data();
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, error) {
|
||||
if(error !== null || error !== undefined) {
|
||||
notify_error(error.message);
|
||||
} else {
|
||||
notify_error(jqXHR);
|
||||
ajax_notify_error(jqXHR, this.url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Add of field for file upload */
|
||||
dropUpdate.on('sending', function (file, xhr, formData) {
|
||||
formData.append('is_update', true);
|
||||
formData.append('pipeline', $('#update_pipeline_selector').val() );
|
||||
formData.append('csrf_token', $('#csrf_token').val());
|
||||
});
|
||||
|
||||
/* Update case function. start the update task */
|
||||
|
||||
function send_update_case_data() {
|
||||
|
||||
/* Get the pipeline args */
|
||||
var args = Object();
|
||||
$.each($(".update-" + $('#update_pipeline_selector').val()), function(el, k) {
|
||||
args['args_' + k.id] = k.value;
|
||||
});
|
||||
args['pipeline'] = $('#update_pipeline_selector').val();
|
||||
args['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/manage/cases/trigger-pipeline', JSON.stringify(args), true, function () {
|
||||
$('#submit_update_case').text('Starting pipeline');
|
||||
$('#submit_update_case')
|
||||
.attr("disabled", true)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
$('#submit_update_case').text('Saved');
|
||||
swal("That's done !",
|
||||
"Files are being processed in background.\nYou can follow the progress in DIM Tasks",
|
||||
"success",
|
||||
{
|
||||
buttons: {
|
||||
again: {
|
||||
text: "Import files again",
|
||||
value: "again"
|
||||
},
|
||||
dash: {
|
||||
text: "Go to dashboard",
|
||||
value: "dash",
|
||||
}
|
||||
}
|
||||
}
|
||||
).then((value) => {
|
||||
switch (value) {
|
||||
|
||||
case "dash":
|
||||
window.location.replace("/dashboard" + case_param());
|
||||
break;
|
||||
|
||||
case "again":
|
||||
window.location.replace("/case" + case_param());
|
||||
break;
|
||||
|
||||
default:
|
||||
window.location.replace("/case" + case_param());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#submit_update_case').text('Save');
|
||||
mdata = ""
|
||||
for (element in data.data) {
|
||||
mdata += data.data[element]
|
||||
}
|
||||
$.notify({
|
||||
icon: 'flaticon-error',
|
||||
title: data.message,
|
||||
message: mdata
|
||||
}, {
|
||||
type: 'danger',
|
||||
placement: {
|
||||
from: 'top',
|
||||
align: 'right'
|
||||
},
|
||||
time: 5000,
|
||||
});
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
})
|
||||
.fail(() => {
|
||||
$('#submit_new_case_btn').text('Save');
|
||||
})
|
||||
.always(() => {
|
||||
$('#submit_update_case')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
});
|
||||
}
|
||||
|
||||
/* Event listener to process update queue */
|
||||
function submit_update_casefn() {
|
||||
|
||||
var dse = $(".update-" + $('#update_pipeline_selector').val());
|
||||
for (var elm=0; elm < $(dse).length; elm++) {
|
||||
if($(dse[elm]).find('input').attr('required')) {
|
||||
if ( ! $(dse[elm]).find('input').val() ) {
|
||||
notify_error("Required fields are not set");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropUpdate.processQueue();
|
||||
}
|
367
iris-web/source/app/static/assets/js/iris/case.rfiles.js
Normal file
367
iris-web/source/app/static/assets/js/iris/case.rfiles.js
Normal file
@ -0,0 +1,367 @@
|
||||
/* reload the rfiles table */
|
||||
function reload_rfiles(notify) {
|
||||
get_case_rfiles();
|
||||
if (notify !== undefined) {
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
}
|
||||
|
||||
function edit_in_evidence_desc() {
|
||||
if($('#container_evidence_desc_content').is(':visible')) {
|
||||
$('#container_evidence_description').show(100);
|
||||
$('#container_evidence_desc_content').hide(100);
|
||||
$('#evidence_edition_btn').hide(100);
|
||||
$('#evidence_preview_button').hide(100);
|
||||
} else {
|
||||
$('#evidence_preview_button').show(100);
|
||||
$('#evidence_edition_btn').show(100);
|
||||
$('#container_evidence_desc_content').show(100);
|
||||
$('#container_evidence_description').hide(100);
|
||||
}
|
||||
}
|
||||
|
||||
function get_hash() {
|
||||
if (document.getElementById("input_autofill").files[0] === undefined) {
|
||||
$('#btn_rfile_proc').text("Please select a file");
|
||||
return;
|
||||
}
|
||||
getMD5(
|
||||
document.getElementById("input_autofill").files[0],
|
||||
prog => $('#btn_rfile_proc').text("Processing "+ (prog * 100).toFixed(2) + "%")
|
||||
).then(
|
||||
res => on_done_hash(res),
|
||||
err => console.error(err)
|
||||
);
|
||||
}
|
||||
|
||||
function on_done_hash(result) {
|
||||
$('#btn_rfile_proc').text('Done processing');
|
||||
$('form#form_edit_rfile #file_hash').val(result);
|
||||
$('form#form_edit_rfile #filename').val(document.getElementById("input_autofill").files[0].name);
|
||||
$('form#form_edit_rfile #file_size').val(document.getElementById("input_autofill").files[0].size);
|
||||
}
|
||||
|
||||
function add_modal_rfile() {
|
||||
url = 'evidences/add/modal' + case_param();
|
||||
$('#modal_add_rfiles_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_evidence_desc_editor = get_new_ace_editor('evidence_description', 'evidence_desc_content', 'target_evidence_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null);
|
||||
g_evidence_desc_editor.setOption("minLines", "10");
|
||||
edit_in_evidence_desc();
|
||||
|
||||
headers = get_editor_headers('g_evidence_desc_editor', null, 'evidence_edition_btn');
|
||||
$('#evidence_edition_btn').append(headers);
|
||||
|
||||
$('#modal_add_rfiles').modal({ show: true });
|
||||
$('#filename').focus();
|
||||
});
|
||||
}
|
||||
|
||||
function add_rfile() {
|
||||
var data_sent = $('form#form_edit_rfile').serializeObject();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
data_sent['file_description'] = g_evidence_desc_editor.getValue();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('/case/evidences/add', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
get_case_rfiles();
|
||||
$('#modal_add_rfiles').modal("hide");
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function readChunked(file, chunkCallback, endCallback) {
|
||||
var fileSize = file.size;
|
||||
var chunkSize = 4 * 1024 * 1024; // 4MB
|
||||
var offset = 0;
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
if (reader.error) {
|
||||
endCallback(reader.error || {});
|
||||
return;
|
||||
}
|
||||
offset += reader.result.length;
|
||||
// callback for handling read chunk
|
||||
// TODO: handle errors
|
||||
chunkCallback(reader.result, offset, fileSize);
|
||||
if (offset >= fileSize) {
|
||||
endCallback(null);
|
||||
return;
|
||||
}
|
||||
readNext();
|
||||
};
|
||||
|
||||
reader.onerror = function(err) {
|
||||
endCallback(err || {});
|
||||
};
|
||||
|
||||
function readNext() {
|
||||
var fileSlice = file.slice(offset, offset + chunkSize);
|
||||
reader.readAsBinaryString(fileSlice);
|
||||
}
|
||||
readNext();
|
||||
}
|
||||
|
||||
function getMD5(blob, cbProgress) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var md5 = CryptoJS.algo.MD5.create();
|
||||
readChunked(blob, (chunk, offs, total) => {
|
||||
md5.update(CryptoJS.enc.Latin1.parse(chunk));
|
||||
if (cbProgress) {
|
||||
cbProgress(offs / total);
|
||||
}
|
||||
}, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
// TODO: Handle errors
|
||||
var hash = md5.finalize();
|
||||
var hashHex = hash.toString(CryptoJS.enc.Hex);
|
||||
resolve(hashHex);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* Retrieve the list of rfiles and build a datatable for each type of rfiles */
|
||||
function get_case_rfiles() {
|
||||
|
||||
get_request_api("/case/evidences/list")
|
||||
.done(function (response) {
|
||||
if (response.status == 'success') {
|
||||
if (response.data != null) {
|
||||
jsdata = response.data;
|
||||
Table.clear();
|
||||
Table.rows.add(jsdata.evidences);
|
||||
Table.columns.adjust().draw();
|
||||
|
||||
load_menu_mod_options('evidence', Table, delete_rfile);
|
||||
|
||||
set_last_state(jsdata.state);
|
||||
hide_loader();
|
||||
|
||||
$('#rfiles_table_wrapper').show();
|
||||
Table.responsive.recalc();
|
||||
|
||||
} else {
|
||||
Table.clear().draw();
|
||||
swal("Oh no !", data.message, "error")
|
||||
}
|
||||
} else {
|
||||
Table.clear().draw()
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* Edit an rfiles */
|
||||
function edit_rfiles(rfiles_id) {
|
||||
url = 'evidences/' + rfiles_id + '/modal' + case_param();
|
||||
$('#modal_add_rfiles_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_evidence_id = rfiles_id;
|
||||
|
||||
g_evidence_desc_editor = get_new_ace_editor('evidence_description', 'evidence_desc_content', 'target_evidence_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
$('#submit_new_evidence').text("Unsaved").removeClass('btn-success').addClass('btn-outline-warning').removeClass('btn-outline-danger');
|
||||
}, null);
|
||||
|
||||
g_evidence_desc_editor.setOption("minLines", "6");
|
||||
preview_evidence_description(true);
|
||||
|
||||
headers = get_editor_headers('g_evidence_desc_editor', null, 'evidence_edition_btn');
|
||||
$('#evidence_edition_btn').append(headers);
|
||||
|
||||
load_menu_mod_options_modal(rfiles_id, 'evidence', $("#evidence_modal_quick_actions"));
|
||||
|
||||
$('#modal_add_rfiles').modal({ show: true });
|
||||
edit_in_evidence_desc();
|
||||
});
|
||||
}
|
||||
|
||||
function preview_evidence_description(no_btn_update) {
|
||||
if(!$('#container_evidence_description').is(':visible')) {
|
||||
evidence_desc = g_evidence_desc_editor.getValue();
|
||||
converter = get_showdown_convert();
|
||||
html = converter.makeHtml(do_md_filter_xss(evidence_desc));
|
||||
evidence_desc_html = do_md_filter_xss(html);
|
||||
$('#target_evidence_desc').html(evidence_desc_html);
|
||||
$('#container_evidence_description').show();
|
||||
if (!no_btn_update) {
|
||||
$('#evidence_preview_button').html('<i class="fa-solid fa-eye-slash"></i>');
|
||||
}
|
||||
$('#container_evidence_desc_content').hide();
|
||||
}
|
||||
else {
|
||||
$('#container_evidence_description').hide();
|
||||
if (!no_btn_update) {
|
||||
$('#evidence_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
}
|
||||
|
||||
$('#evidence_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
$('#container_evidence_desc_content').show();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update an rfiles */
|
||||
function update_rfile(rfiles_id) {
|
||||
var data_sent = $('form#form_edit_rfile').serializeObject();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
data_sent['file_description'] = g_evidence_desc_editor.getValue();
|
||||
|
||||
post_request_api('evidences/update/' + rfiles_id, JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
reload_rfiles();
|
||||
});
|
||||
}
|
||||
|
||||
/* Delete an rfiles */
|
||||
function delete_rfile(rfiles_id) {
|
||||
do_deletion_prompt("You are about to delete evidence #" + rfiles_id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
post_request_api('evidences/delete/' + rfiles_id)
|
||||
.done(function(data){
|
||||
reload_rfiles();
|
||||
$('#modal_add_rfiles').modal('hide');
|
||||
notify_auto_api(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Page is ready, fetch the rfiles of the case */
|
||||
$(document).ready(function(){
|
||||
|
||||
/* add filtering fields for each table of the page (must be done before datatable initialization) */
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
Table = $("#rfiles_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
fixedHeader: true,
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "filename",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
if (isWhiteSpace(data)) {
|
||||
data = '#' + row['id'];
|
||||
} else {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
share_link = buildShareLink(row['id']);
|
||||
data = '<a data-toggle="tooltip" data-selector="true" href="' + share_link + '" title="Evidence ID #' + row['id'] + '" onclick="edit_rfiles(\'' + row['id'] + '\');return false;">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "date_added" },
|
||||
{ "data": "file_hash",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "file_size",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}},
|
||||
{ "data": "file_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}},
|
||||
{ "data": "username",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
buttons: [
|
||||
],
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'rfiles_table');
|
||||
},
|
||||
select: true
|
||||
});
|
||||
$("#rfiles_table").css("font-size", 12);
|
||||
var buttons = new $.fn.dataTable.Buttons(Table, {
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'<i class="fas fa-cloud-download-alt"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Download as CSV', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } } ,
|
||||
{ "extend": 'copyHtml5', "text":'<i class="fas fa-copy"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Copy', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } },
|
||||
{ "extend": 'colvis', "text":'<i class="fas fa-eye-slash"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Toggle columns' }
|
||||
]
|
||||
}).container().appendTo($('#tables_button'));
|
||||
|
||||
Table.on( 'responsive-resize', function ( e, datatable, columns ) {
|
||||
hide_table_search_input( columns );
|
||||
});
|
||||
|
||||
get_case_rfiles();
|
||||
setInterval(function() { check_update('evidences/state'); }, 3000);
|
||||
|
||||
/* Modal to add rfiles is closed, clear its contents */
|
||||
$('.modal').on('hidden.bs.modal', function () {
|
||||
$(this).find('form').trigger('reset');
|
||||
$('#btn_rfile_proc').text('Process');
|
||||
})
|
||||
|
||||
shared_id = getSharedLink();
|
||||
if (shared_id) {
|
||||
edit_rfiles(shared_id);
|
||||
}
|
||||
|
||||
});
|
514
iris-web/source/app/static/assets/js/iris/case.summary.js
Normal file
514
iris-web/source/app/static/assets/js/iris/case.summary.js
Normal file
@ -0,0 +1,514 @@
|
||||
var session_id = null ;
|
||||
var collaborator = null ;
|
||||
var buffer_dumped = false ;
|
||||
var last_applied_change = null ;
|
||||
var just_cleared_buffer = null ;
|
||||
var from_sync = null;
|
||||
|
||||
var editor = ace.edit("editor_summary",
|
||||
{
|
||||
autoScrollEditorIntoView: true,
|
||||
minLines: 4
|
||||
});
|
||||
|
||||
var textarea = $('#case_summary');
|
||||
|
||||
function Collaborator( session_id ) {
|
||||
this.collaboration_socket = io.connect() ;
|
||||
|
||||
this.channel = "case-" + session_id;
|
||||
this.collaboration_socket.emit('join', { 'channel': this.channel });
|
||||
|
||||
this.collaboration_socket.on( "change", function(data) {
|
||||
delta = JSON.parse( data.delta ) ;
|
||||
console.log(delta);
|
||||
last_applied_change = delta ;
|
||||
$("#content_typing").text(data.last_change + " is typing..");
|
||||
editor.getSession().getDocument().applyDeltas( [delta] ) ;
|
||||
}.bind() ) ;
|
||||
|
||||
this.collaboration_socket.on( "clear_buffer", function() {
|
||||
just_cleared_buffer = true ;
|
||||
console.log( "setting editor empty" ) ;
|
||||
editor.setValue( "" ) ;
|
||||
}.bind() ) ;
|
||||
|
||||
this.collaboration_socket.on( "save", function(data) {
|
||||
$("#content_last_saved_by").text("Last saved by " + data.last_saved);
|
||||
sync_editor(true);
|
||||
}.bind() ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.change = function( delta ) {
|
||||
this.collaboration_socket.emit( "change", { 'delta': delta, 'channel': this.channel } ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.clear_buffer = function() {
|
||||
this.collaboration_socket.emit( "clear_buffer", { 'channel': this.channel } ) ;
|
||||
}
|
||||
|
||||
Collaborator.prototype.save = function() {
|
||||
this.collaboration_socket.emit( "save", { 'channel': this.channel } ) ;
|
||||
}
|
||||
|
||||
function body_loaded() {
|
||||
|
||||
collaborator = new Collaborator( get_caseid() ) ;
|
||||
|
||||
// registering change callback
|
||||
from_sync = true;
|
||||
editor.on( "change", function( e ) {
|
||||
// TODO, we could make things more efficient and not likely to conflict by keeping track of change IDs
|
||||
if( last_applied_change!=e && editor.curOp && editor.curOp.command.name) {
|
||||
collaborator.change( JSON.stringify(e) ) ;
|
||||
}
|
||||
}, false );
|
||||
|
||||
editor.$blockScrolling = Infinity ;
|
||||
|
||||
document.getElementsByTagName('textarea')[0].focus() ;
|
||||
last_applied_change = null ;
|
||||
just_cleared_buffer = false ;
|
||||
}
|
||||
|
||||
function handle_ed_paste(event) {
|
||||
filename = null;
|
||||
const { items } = event.originalEvent.clipboardData;
|
||||
for (let i = 0; i < items.length; i += 1) {
|
||||
const item = items[i];
|
||||
|
||||
if (item.kind === 'string') {
|
||||
item.getAsString(function (s){
|
||||
filename = $.trim(s.replace(/\t|\n|\r/g, '')).substring(0, 40);
|
||||
});
|
||||
}
|
||||
|
||||
if (item.kind === 'file') {
|
||||
const blob = item.getAsFile();
|
||||
|
||||
if (blob !== null) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
notify_success('The file is uploading in background. Don\'t leave the page');
|
||||
|
||||
if (filename === null) {
|
||||
filename = random_filename(25);
|
||||
}
|
||||
|
||||
upload_interactive_data(e.target.result, filename, function(data){
|
||||
url = data.data.file_url + case_param();
|
||||
event.preventDefault();
|
||||
editor.insertSnippet(`\n\n`);
|
||||
});
|
||||
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
} else {
|
||||
notify_error('Unsupported direct paste of this item. Use datastore to upload.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function report_template_selector() {
|
||||
$('#modal_select_report').modal({ show: true });
|
||||
}
|
||||
|
||||
function gen_report(safe) {
|
||||
url = '/case/report/generate-investigation/' + $("#select_report option:selected").val() + case_param();
|
||||
if (safe === true) {
|
||||
url += '&safe=true';
|
||||
}
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
function gen_act_report(safe) {
|
||||
url = '/case/report/generate-activities/' + $("#select_report_act option:selected").val() + case_param();
|
||||
if (safe === true) {
|
||||
url += '&safe=true';
|
||||
}
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
function act_report_template_selector() {
|
||||
$('#modal_select_report_act').modal({ show: true });
|
||||
}
|
||||
|
||||
function edit_case_summary() {
|
||||
$('#container_editor_summary').toggle();
|
||||
if ($('#container_editor_summary').is(':visible')) {
|
||||
$('#ctrd_casesum').removeClass('col-md-12').addClass('col-md-6');
|
||||
$('#summary_edition_btn').show(100);
|
||||
$("#sum_refresh_btn").html('Save');
|
||||
$("#sum_edit_btn").html('Close editor');
|
||||
} else {
|
||||
$('#ctrd_casesum').removeClass('col-md-6').addClass('col-md-12');
|
||||
$('#summary_edition_btn').hide();
|
||||
$("#sum_refresh_btn").html('Refresh');
|
||||
$("#sum_edit_btn").html('Edit');
|
||||
}
|
||||
}
|
||||
|
||||
/* sync_editor
|
||||
* Save the editor state.
|
||||
* Check if there are external changes first.
|
||||
* Copy local changes if conflict
|
||||
*/
|
||||
function sync_editor(no_check) {
|
||||
|
||||
$('#last_saved').text('Syncing..').addClass('badge-danger').removeClass('badge-success');
|
||||
|
||||
get_request_api('/case/summary/fetch')
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
if (no_check) {
|
||||
// Set the content from remote server
|
||||
from_sync = true;
|
||||
editor.getSession().setValue(data.data.case_description);
|
||||
|
||||
// Set the CRC in page
|
||||
$('#fetched_crc').val(data.data.crc32.toString());
|
||||
$('#last_saved').text('Changes saved').removeClass('badge-danger').addClass('badge-success');
|
||||
$('#content_last_sync').text("Last synced: " + new Date().toLocaleTimeString());
|
||||
}
|
||||
else {
|
||||
// Check if content is different
|
||||
st = editor.getSession().getValue();
|
||||
if (data.data.crc32 != $('#fetched_crc').val()) {
|
||||
// Content has changed remotely
|
||||
// Check if we have changes locally
|
||||
local_crc = crc32(st).toString();
|
||||
console.log('Content changed. Local CRC is ' + local_crc);
|
||||
console.log('Saved CRC is ' + $('#fetched_crc').val());
|
||||
console.log('Remote CRC is ' + data.data.crc32);
|
||||
if (local_crc == $('#fetched_crc').val()) {
|
||||
// No local change, we can sync and update local CRC
|
||||
editor.getSession().setValue(data.data.case_description);
|
||||
$('#fetched_crc').val(data.data.crc32);
|
||||
$('#last_saved').text('Changes saved').removeClass('badge-danger').addClass('badge-success');
|
||||
$('#content_last_sync').text("Last synced: " + new Date().toLocaleTimeString());
|
||||
} else {
|
||||
// We have a conflict
|
||||
$('#last_saved').text('Conflict !').addClass('badge-danger').removeClass('badge-success');
|
||||
swal ( "Oh no !" ,
|
||||
"We have a conflict with the remote content.\nSomeone may just have changed the description at the same time.\nThe local content will be copied into clipboard and content will be updated with remote." ,
|
||||
"error"
|
||||
).then((value) => {
|
||||
// Old fashion trick
|
||||
editor.selectAll();
|
||||
editor.focus();
|
||||
document.execCommand('copy');
|
||||
editor.getSession().setValue(data.data.desc);
|
||||
$('#fetched_crc').val(data.data.crc32);
|
||||
notify_success('Content updated with remote. Local changes copied to clipboard.');
|
||||
$('#content_last_sync').text("Last synced: " + new Date().toLocaleTimeString());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Content did not change remotely
|
||||
// Check local change
|
||||
local_crc = crc32(st).toString();
|
||||
if (local_crc != $('#fetched_crc').val()) {
|
||||
console.log('Local change. Old CRC is ' + local_crc);
|
||||
console.log('New CRC is ' + $('#fetched_crc').val());
|
||||
var data = Object();
|
||||
data['case_description'] = st;
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
// Local change detected. Update to remote
|
||||
$.ajax({
|
||||
url: '/case/summary/update' + case_param(),
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json;charset=UTF-8",
|
||||
data: JSON.stringify(data),
|
||||
success: function (data) {
|
||||
if (data.status == 'success') {
|
||||
collaborator.save();
|
||||
$('#content_last_sync').text("Last synced: " + new Date().toLocaleTimeString());
|
||||
$('#fetched_crc').val(data.data);
|
||||
$('#last_saved').text('Changes saved').removeClass('badge-danger').addClass('badge-success');
|
||||
} else {
|
||||
notify_error("Unable to save content to remote server");
|
||||
$('#last_saved').text('Error saving !').addClass('badge-danger').removeClass('badge-success');
|
||||
}
|
||||
},
|
||||
error: function(error) {
|
||||
notify_error(error.responseJSON.message);
|
||||
('#last_saved').text('Error saving !').addClass('badge-danger').removeClass('badge-success');
|
||||
}
|
||||
});
|
||||
}
|
||||
$('#content_last_sync').text("Last synced: " + new Date().toLocaleTimeString());
|
||||
$('#last_saved').text('Changes saved').removeClass('badge-danger').addClass('badge-success');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
is_typing = "";
|
||||
function auto_remove_typing() {
|
||||
if ($("#content_typing").text() == is_typing) {
|
||||
$("#content_typing").text("");
|
||||
} else {
|
||||
is_typing = $("#content_typing").text();
|
||||
}
|
||||
}
|
||||
|
||||
function case_pipeline_popup() {
|
||||
url = '/case/pipelines-modal' + case_param();
|
||||
$('#info_case_modal_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_case_detail').modal({ show: true });
|
||||
$("#update_pipeline_selector").selectpicker({
|
||||
liveSearch: true,
|
||||
style: "btn-outline-white"
|
||||
})
|
||||
$('#update_pipeline_selector').selectpicker("refresh");
|
||||
$(".control-update-pipeline-args ").hide();
|
||||
$('.control-update-pipeline-'+ $('#update_pipeline_selector').val() ).show();
|
||||
$('#update_pipeline_selector').on('change', function(e){
|
||||
$(".control-update-pipeline-args ").hide();
|
||||
$('.control-update-pipeline-'+this.value).show();
|
||||
});
|
||||
$('[data-toggle="popover"]').popover();
|
||||
});
|
||||
}
|
||||
|
||||
async function do_case_review(action, reviewer_id) {
|
||||
let data = Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
data['action'] = action;
|
||||
if (reviewer_id) {
|
||||
data['reviewer_id'] = reviewer_id;
|
||||
}
|
||||
|
||||
return post_request_api('/case/review/update', JSON.stringify(data));
|
||||
}
|
||||
|
||||
function case_detail(case_id, edit_mode=false) {
|
||||
url = '/case/details/' + case_id + case_param();
|
||||
$('#info_case_modal_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_case_detail').modal({ show: true });
|
||||
if (edit_mode) {
|
||||
edit_case_info();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function manage_case(case_id) {
|
||||
window.location = '/manage/cases?cid='+ case_id +'#view';
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
if ($("#editor_summary").attr("data-theme") !== "dark") {
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
} else {
|
||||
editor.setTheme("ace/theme/iris_night");
|
||||
}
|
||||
editor.session.setMode("ace/mode/markdown");
|
||||
editor.renderer.setShowGutter(true);
|
||||
editor.setOption("showLineNumbers", true);
|
||||
editor.setOption("showPrintMargin", false);
|
||||
editor.setOption("displayIndentGuides", true);
|
||||
editor.setOption("indentedSoftWrap", false);
|
||||
editor.session.setUseWrapMode(true);
|
||||
editor.setOption("maxLines", "Infinity")
|
||||
editor.renderer.setScrollMargin(8, 5)
|
||||
editor.setOption("enableBasicAutocompletion", true);
|
||||
editor.commands.addCommand({
|
||||
name: 'save',
|
||||
bindKey: {win: "Ctrl-S", "mac": "Cmd-S"},
|
||||
exec: function(editor) {
|
||||
sync_editor(false);
|
||||
}
|
||||
})
|
||||
editor.commands.addCommand({
|
||||
name: 'bold',
|
||||
bindKey: {win: "Ctrl-B", "mac": "Cmd-B"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('**${1:$SELECTION}**');
|
||||
}
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'italic',
|
||||
bindKey: {win: "Ctrl-I", "mac": "Cmd-I"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('*${1:$SELECTION}*');
|
||||
}
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'head_1',
|
||||
bindKey: {win: "Ctrl-Shift-1", "mac": "Cmd-Shift-1"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('# ${1:$SELECTION}');
|
||||
}
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'head_2',
|
||||
bindKey: {win: "Ctrl-Shift-2", "mac": "Cmd-Shift-2"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('## ${1:$SELECTION}');
|
||||
}
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'head_3',
|
||||
bindKey: {win: "Ctrl-Shift-3", "mac": "Cmd-Shift-3"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('### ${1:$SELECTION}');
|
||||
}
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'head_4',
|
||||
bindKey: {win: "Ctrl-Shift-4", "mac": "Cmd-Shift-4"},
|
||||
exec: function(editor) {
|
||||
editor.insertSnippet('#### ${1:$SELECTION}');
|
||||
}
|
||||
});
|
||||
$('#editor_summary').on('paste', (event) => {
|
||||
event.preventDefault();
|
||||
handle_ed_paste(event);
|
||||
});
|
||||
|
||||
var timer;
|
||||
var timeout = 10000;
|
||||
$('#editor_summary').keyup(function(){
|
||||
if(timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(sync_editor, timeout);
|
||||
});
|
||||
|
||||
|
||||
//var textarea = $('#case_summary');
|
||||
editor.getSession().on("change", function () {
|
||||
//textarea.val(do_md_filter_xss(editor.getSession().getValue()));
|
||||
$('#last_saved').text('Changes not saved').addClass('badge-danger').removeClass('badge-success');
|
||||
let target = document.getElementById('targetDiv');
|
||||
let converter = get_showdown_convert();
|
||||
let html = converter.makeHtml(do_md_filter_xss(editor.getSession().getValue()));
|
||||
|
||||
target.innerHTML = do_md_filter_xss(html);
|
||||
|
||||
});
|
||||
|
||||
edit_case_summary();
|
||||
body_loaded();
|
||||
sync_editor(true);
|
||||
setInterval(auto_remove_typing, 2000);
|
||||
|
||||
let review_state = $('#caseReviewState');
|
||||
if (review_state.length > 0) {
|
||||
let current_review_state = review_state.data('review-state');
|
||||
|
||||
if (current_review_state === 'Review in progress') {
|
||||
$(".btn-start-review").hide();
|
||||
$(".btn-confirm-review").show();
|
||||
$(".btn-cancel-review").show();
|
||||
$('#reviewSubtitle').text('You started this review. Press "Confirm review" when you are done.');
|
||||
} else if (current_review_state === 'Review completed') {
|
||||
$(".btn-start-review").hide();
|
||||
$(".btn-confirm-review").hide();
|
||||
$(".btn-cancel-review").hide();
|
||||
} else if (current_review_state === 'Pending review') {
|
||||
$(".btn-start-review").show();
|
||||
$(".btn-confirm-review").hide();
|
||||
$(".btn-cancel-review").hide();
|
||||
}
|
||||
$('.review-card').show();
|
||||
}
|
||||
|
||||
$('.btn-start-review').on('click', function(e){
|
||||
do_case_review('start').then(function(data) {
|
||||
if (notify_auto_api(data)) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.btn-confirm-review').on('click', function(e){
|
||||
do_case_review('done').then(function(data) {
|
||||
if (notify_auto_api(data)) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.btn-cancel-review').on('click', function(e){
|
||||
do_case_review('cancel').then(function(data) {
|
||||
if (notify_auto_api(data)) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#request_review').on('click', function(e){
|
||||
let reviewer_id = $('#caseReviewState').data('reviewer-id');
|
||||
let reviewer_name = $('#caseReviewState').data('reviewer-name');
|
||||
|
||||
|
||||
|
||||
if (reviewer_id !== "None") {
|
||||
swal({
|
||||
title: "Request review",
|
||||
text: "Request a case review from " + reviewer_name + "?",
|
||||
icon: "info",
|
||||
buttons: true,
|
||||
dangerMode: false,
|
||||
}).then((willRequest) => {
|
||||
if (willRequest) {
|
||||
do_case_review('request', reviewer_id).then(function (data) {
|
||||
if (notify_auto_api(data)) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#reviewer_id').selectpicker({
|
||||
liveSearch: true,
|
||||
size: 10,
|
||||
width: '100%'
|
||||
});
|
||||
get_request_api('/case/users/list')
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
let users = data.data;
|
||||
let options = '';
|
||||
for (let i = 0; i < users.length; i++) {
|
||||
if (users[i].user_access_level === 4) {
|
||||
options += '<option value="' + users[i].user_id + '">' + filterXSS(users[i].user_name) + '</option>';
|
||||
}
|
||||
}
|
||||
$('#reviewer_id').html(options);
|
||||
$('#reviewer_id').selectpicker('refresh');
|
||||
$('#modal_choose_reviewer').modal('show');
|
||||
|
||||
$('#submit_set_reviewer').off('click').on('click', function(e){
|
||||
let reviewer_id = $('#reviewer_id').val();
|
||||
do_case_review('request', reviewer_id).then(function (data) {
|
||||
if (notify_auto_api(data)) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
466
iris-web/source/app/static/assets/js/iris/case.tasks.js
Normal file
466
iris-web/source/app/static/assets/js/iris/case.tasks.js
Normal file
@ -0,0 +1,466 @@
|
||||
var current_users_list = [];
|
||||
var g_task_id = null;
|
||||
var g_task_desc_editor = null;
|
||||
|
||||
function edit_in_task_desc() {
|
||||
if($('#container_task_desc_content').is(':visible')) {
|
||||
$('#container_task_description').show(100);
|
||||
$('#container_task_desc_content').hide(100);
|
||||
$('#task_edition_btn').hide(100);
|
||||
$('#task_preview_button').hide(100);
|
||||
} else {
|
||||
$('#task_preview_button').show(100);
|
||||
$('#task_edition_btn').show(100);
|
||||
$('#container_task_desc_content').show(100);
|
||||
$('#container_task_description').hide(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Fetch a modal that allows to add an event */
|
||||
function add_task() {
|
||||
url = 'tasks/add/modal' + case_param();
|
||||
$('#modal_add_task_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_task_desc_editor = get_new_ace_editor('task_description', 'task_desc_content', 'target_task_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null);
|
||||
g_task_desc_editor.setOption("minLines", "10");
|
||||
edit_in_task_desc();
|
||||
|
||||
headers = get_editor_headers('g_task_desc_editor', null, 'task_edition_btn');
|
||||
$('#task_edition_btn').append(headers);
|
||||
|
||||
$('#submit_new_task').on("click", function () {
|
||||
|
||||
clear_api_error();
|
||||
if(!$('form#form_new_task').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var data_sent = $('#form_new_task').serializeObject();
|
||||
data_sent['task_tags'] = $('#task_tags').val();
|
||||
data_sent['task_assignees_id'] = $('#task_assignees_id').val();
|
||||
data_sent['task_status_id'] = $('#task_status_id').val();
|
||||
data_sent['task_description'] = g_task_desc_editor.getValue();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('tasks/add', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
get_tasks();
|
||||
$('#modal_add_task').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
$('#modal_add_task').modal({ show: true });
|
||||
$('#task_title').focus();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function save_task() {
|
||||
$('#submit_new_task').click();
|
||||
}
|
||||
|
||||
function update_task(task_id) {
|
||||
update_task_ext(task_id, true);
|
||||
}
|
||||
|
||||
function update_task_ext(task_id, do_close) {
|
||||
|
||||
clear_api_error();
|
||||
if(!$('form#form_new_task').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (task_id === undefined || task_id === null) {
|
||||
task_id = g_task_id;
|
||||
}
|
||||
|
||||
var data_sent = $('#form_new_task').serializeObject();
|
||||
data_sent['task_tags'] = $('#task_tags').val();
|
||||
|
||||
data_sent['task_assignees_id'] = $('#task_assignees_id').val();
|
||||
data_sent['task_status_id'] = $('#task_status_id').val();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
data_sent['task_description'] = g_task_desc_editor.getValue();
|
||||
|
||||
$('#update_task_btn').text('Updating..');
|
||||
|
||||
post_request_api('tasks/update/' + task_id, JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
get_tasks();
|
||||
$('#submit_new_task').text("Saved").addClass('btn-outline-success').removeClass('btn-outline-danger').removeClass('btn-outline-warning');
|
||||
$('#last_saved').removeClass('btn-danger').addClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-check");
|
||||
|
||||
if (do_close !== undefined && do_close === true) {
|
||||
$('#modal_add_task').modal('hide');
|
||||
}
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
$('#update_task_btn').text('Update');
|
||||
});
|
||||
}
|
||||
|
||||
/* Delete an event from the timeline thank to its id */
|
||||
function delete_task(id) {
|
||||
do_deletion_prompt("You are about to delete task #" + id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
post_request_api("tasks/delete/" + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
get_tasks();
|
||||
$('#modal_add_task').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Edit and event from the timeline thanks to its ID */
|
||||
function edit_task(id) {
|
||||
url = '/case/tasks/'+ id + '/modal' + case_param();
|
||||
$('#modal_add_task_content').load(url, function (response, status, xhr) {
|
||||
hide_minimized_modal_box();
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_task_id = id;
|
||||
|
||||
g_task_desc_editor = get_new_ace_editor('task_description', 'task_desc_content', 'target_task_desc',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null);
|
||||
|
||||
g_task_desc_editor.setOption("minLines", "6");
|
||||
preview_task_description(true);
|
||||
|
||||
headers = get_editor_headers('g_task_desc_editor', null, 'task_edition_btn');
|
||||
$('#task_edition_btn').append(headers);
|
||||
|
||||
load_menu_mod_options_modal(id, 'task', $("#task_modal_quick_actions"));
|
||||
$('#modal_add_task').modal({show:true});
|
||||
edit_in_task_desc();
|
||||
});
|
||||
}
|
||||
|
||||
function preview_task_description(no_btn_update) {
|
||||
if(!$('#container_task_description').is(':visible')) {
|
||||
task_desc = g_task_desc_editor.getValue();
|
||||
converter = get_showdown_convert();
|
||||
html = converter.makeHtml(do_md_filter_xss(task_desc));
|
||||
task_desc_html = do_md_filter_xss(html);
|
||||
$('#target_task_desc').html(task_desc_html);
|
||||
$('#container_task_description').show();
|
||||
if (!no_btn_update) {
|
||||
$('#task_preview_button').html('<i class="fa-solid fa-eye-slash"></i>');
|
||||
}
|
||||
$('#container_task_desc_content').hide();
|
||||
}
|
||||
else {
|
||||
$('#container_task_description').hide();
|
||||
if (!no_btn_update) {
|
||||
$('#task_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
}
|
||||
|
||||
$('#task_preview_button').html('<i class="fa-solid fa-eye"></i>');
|
||||
$('#container_task_desc_content').show();
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch and draw the tasks */
|
||||
function get_tasks() {
|
||||
$('#tasks_list').empty();
|
||||
show_loader();
|
||||
|
||||
get_request_api("tasks/list")
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
Table.MakeCellsEditable("destroy");
|
||||
tasks_list = data.data.tasks;
|
||||
|
||||
options_l = data.data.tasks_status;
|
||||
options = [];
|
||||
for (index in options_l) {
|
||||
option = options_l[index];
|
||||
options.push({ "value": option.id, "display": option.status_name })
|
||||
}
|
||||
Table.clear();
|
||||
Table.rows.add(tasks_list);
|
||||
Table.MakeCellsEditable({
|
||||
"onUpdate": callBackEditTaskStatus,
|
||||
"inputCss": 'form-control col-12',
|
||||
"columns": [2],
|
||||
"allowNulls": {
|
||||
"columns": [2],
|
||||
"errorClass": 'error'
|
||||
},
|
||||
"confirmationButton": {
|
||||
"confirmCss": 'my-confirm-class',
|
||||
"cancelCss": 'my-cancel-class'
|
||||
},
|
||||
"inputTypes": [
|
||||
{
|
||||
"column": 2,
|
||||
"type": "list",
|
||||
"options": options
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
Table.columns.adjust().draw();
|
||||
load_menu_mod_options('task', Table, delete_task);
|
||||
$('[data-toggle="popover"]').popover();
|
||||
Table.responsive.recalc();
|
||||
|
||||
set_last_state(data.data.state);
|
||||
hide_loader();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_users(on_finish, cur_assignees_id_list) {
|
||||
|
||||
get_request_api('/case/users/list')
|
||||
.done((data) => {
|
||||
|
||||
if(notify_auto_api(data, true)) {
|
||||
current_users_list = data.data;
|
||||
|
||||
if (on_finish !== undefined) {
|
||||
on_finish(current_users_list, cur_assignees_id_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function do_list_users(list_users, cur_assignees_id_list) {
|
||||
|
||||
$('#task_assignees_id').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select assignee(s)"
|
||||
});
|
||||
|
||||
for (let user in list_users) {
|
||||
if (list_users[user].user_access_level === 4) {
|
||||
$('#task_assignees_id').append(new Option(`${filterXSS(list_users[user].user_login)} (${filterXSS(list_users[user].user_name)})`,
|
||||
list_users[user].user_id));
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_assignees_id_list !== undefined) {
|
||||
$('#task_assignees_id').selectpicker('val', cur_assignees_id_list);
|
||||
}
|
||||
|
||||
$('#task_assignees_id').selectpicker('refresh');
|
||||
}
|
||||
|
||||
function callBackEditTaskStatus(updatedCell, updatedRow, oldValue) {
|
||||
data_send = updatedRow.data();
|
||||
data_send['csrf_token'] = $('#csrf_token').val();
|
||||
tid = data_send['task_id'];
|
||||
|
||||
post_request_api("tasks/status/update/" + tid, JSON.stringify(data_send))
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data)) {
|
||||
get_tasks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Page is ready, fetch the assets of the case */
|
||||
$(document).ready(function(){
|
||||
|
||||
/* add filtering fields for each table of the page (must be done before datatable initialization) */
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
Table = $("#tasks_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
aaData: [],
|
||||
fixedHeader: true,
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "task_title",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
|
||||
if (isWhiteSpace(data)) {
|
||||
data = '#' + row['task_id'];
|
||||
} else {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
share_link = buildShareLink(row['task_id']);
|
||||
data = '<a href="'+ share_link + '" data-selector="true" title="Task ID #'+ row['task_id'] +'" onclick="edit_task(\'' + row['task_id'] + '\');return false;">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "task_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_status_id",
|
||||
"render": function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<span class="badge ml-2 badge-'+ row['status_bscolor'] +'">' + row['status_name'] + '</span>';
|
||||
}
|
||||
else if (type === 'filter' || type === 'sort'){
|
||||
data = row['status_name']
|
||||
} else if (type === 'export') {
|
||||
data = row['status_name']
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_assignees",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (data != null) {
|
||||
names = "";
|
||||
|
||||
if (data.length > 0) {
|
||||
lst = [];
|
||||
data.forEach(function (item, index) { lst.push(item['name']); });
|
||||
if (type === 'display') {
|
||||
names = list_to_badges(lst, 'primary', 10, 'users');
|
||||
}
|
||||
else {
|
||||
lst.forEach(function (item, index) {
|
||||
names += `${sanitizeHTML(item)}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (type === 'display') {
|
||||
names = '<span class="badge badge-light ml-2">' + "Unassigned" + '</span>';
|
||||
}
|
||||
else {
|
||||
names = "Unassigned";
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_open_date",
|
||||
"render": function (data, type, row, meta) { return sanitizeHTML(data);}
|
||||
},
|
||||
{ "data": "task_tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
tags = "";
|
||||
de = data.split(',');
|
||||
for (tag in de) {
|
||||
tags += '<span class="badge badge-primary ml-2">' + sanitizeHTML(de[tag]) + '</span>';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
rowCallback: function (nRow, data) {
|
||||
nRow = '<span class="badge ml-2 badge-'+ sanitizeHTML(data['status_bscolor']) +'">' + sanitizeHTML(data['status_name']) + '</span>';
|
||||
},
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
pageLength: 50,
|
||||
order: [[ 2, "asc" ]],
|
||||
buttons: [
|
||||
],
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'tasks_table');
|
||||
},
|
||||
select: true
|
||||
});
|
||||
$("#tasks_table").css("font-size", 12);
|
||||
|
||||
Table.on( 'responsive-resize', function ( e, datatable, columns ) {
|
||||
hide_table_search_input( columns );
|
||||
});
|
||||
|
||||
var buttons = new $.fn.dataTable.Buttons(Table, {
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'<i class="fas fa-cloud-download-alt"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Download as CSV', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } } ,
|
||||
{ "extend": 'copyHtml5', "text":'<i class="fas fa-copy"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Copy', "exportOptions": { "columns": ':visible', 'orthogonal': 'export' } },
|
||||
{ "extend": 'colvis', "text":'<i class="fas fa-eye-slash"></i>',"className": 'btn btn-link text-white'
|
||||
, "titleAttr": 'Toggle columns' }
|
||||
]
|
||||
}).container().appendTo($('#tables_button'));
|
||||
|
||||
get_tasks();
|
||||
|
||||
setInterval(function() { check_update('tasks/state'); }, 3000);
|
||||
|
||||
shared_id = getSharedLink();
|
||||
if (shared_id) {
|
||||
edit_task(shared_id);
|
||||
}
|
||||
});
|
1088
iris-web/source/app/static/assets/js/iris/case.timeline.js
Normal file
1088
iris-web/source/app/static/assets/js/iris/case.timeline.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,73 @@
|
||||
function visualizeTimeline(group) {
|
||||
ggr = ['asset', 'category']
|
||||
if (group == 'asset') {
|
||||
src = '/case/timeline/visualize/data/by-asset';
|
||||
} else {
|
||||
src = '/case/timeline/visualize/data/by-category';
|
||||
}
|
||||
|
||||
get_request_api(src)
|
||||
.done((data) => {
|
||||
if (data.status == 'success') {
|
||||
var items = new vis.DataSet();
|
||||
|
||||
groups = new vis.DataSet();
|
||||
groups_l = []
|
||||
if (data.data.events.length == 0) {
|
||||
$('#card_main_load').show();
|
||||
$('#visualization').text('No events in summary');
|
||||
hide_loader();
|
||||
return true;
|
||||
}
|
||||
for (index in data.data.events) {
|
||||
event = data.data.events[index];
|
||||
if (!groups_l.includes(event.group)){
|
||||
groups.add({
|
||||
id: groups_l.length,
|
||||
content: event.group
|
||||
})
|
||||
groups_l.push(event.group);
|
||||
}
|
||||
items.add({
|
||||
id: index,
|
||||
group: groups_l.indexOf(event.group),
|
||||
start: event.date,
|
||||
content: event.content,
|
||||
style: event.style,
|
||||
title: event.title
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// specify options
|
||||
var options = {
|
||||
stack: true,
|
||||
minHeight: '400px',
|
||||
maxHeight: $(window).height() - 250,
|
||||
start: data.data.events[0].date,
|
||||
end: data.data.events[data.data.events.length - 1].date,
|
||||
};
|
||||
|
||||
// create a Timeline
|
||||
|
||||
var container = document.getElementById('visualization');
|
||||
container.innerHTML = '';
|
||||
$('#card_main_load').show();
|
||||
timeline = new vis.Timeline(container, null, options);
|
||||
if (ggr.includes(group)) {
|
||||
timeline.setGroups(groups);
|
||||
}
|
||||
timeline.setItems(items);
|
||||
hide_loader();
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_timeline_graph(){
|
||||
show_loader();
|
||||
queryString = window.location.search;
|
||||
urlParams = new URLSearchParams(queryString);
|
||||
group = urlParams.get('group-by');
|
||||
visualizeTimeline(group);
|
||||
}
|
261
iris-web/source/app/static/assets/js/iris/comments.js
Normal file
261
iris-web/source/app/static/assets/js/iris/comments.js
Normal file
@ -0,0 +1,261 @@
|
||||
var g_comment_desc_editor = null;
|
||||
function comment_element(element_id, element_type, is_alert=false) {
|
||||
|
||||
const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
|
||||
const url = `${prefix}/${element_id}/comments/modal`;
|
||||
$('#modal_comment_content').load(url + case_param(),
|
||||
function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#modal_comment_content').resizable({
|
||||
minHeight: 300,
|
||||
minWidth: 300,
|
||||
handles: "n, e, s, w, ne, se, sw, nw"
|
||||
});
|
||||
$('.modal-comment').draggable({
|
||||
cursor: 'move'
|
||||
});
|
||||
|
||||
$('#modal_comment').modal('show');
|
||||
|
||||
g_comment_desc_editor = get_new_ace_editor('comment_message', 'comment_content', 'target_comment_content',
|
||||
function() {
|
||||
$('#last_saved').addClass('btn-danger').removeClass('btn-success');
|
||||
$('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
|
||||
}, null, false, false);
|
||||
|
||||
headers = get_editor_headers('g_comment_desc_editor', null, 'comment_edition_btn');
|
||||
$('#comment_edition_btn').append(headers);
|
||||
|
||||
load_comments(element_id, element_type, undefined, undefined, is_alert);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function preview_comment() {
|
||||
if(!$('#container_comment_preview').is(':visible')) {
|
||||
let comment_text = g_comment_desc_editor.getValue();
|
||||
let converter = get_showdown_convert();
|
||||
let html = converter.makeHtml(comment_text);
|
||||
let comment_html = do_md_filter_xss(html);
|
||||
$('#target_comment_content').html(comment_html);
|
||||
$('#container_comment_preview').show();
|
||||
$('#comment_preview_button').html('<i class="fa-solid fa-eye-slash"></i> Edit');
|
||||
$('#container_comment_content').hide();
|
||||
}
|
||||
else {
|
||||
$('#container_comment_preview').hide();
|
||||
$('#comment_preview_button').html('<i class="fa-solid fa-eye"></i> Preview');
|
||||
$('#container_comment_content').show();
|
||||
}
|
||||
}
|
||||
|
||||
function save_comment(element_id, element_type) {
|
||||
save_comment_ext(element_id, element_type, false);
|
||||
}
|
||||
|
||||
function save_comment_ext(element_id, element_type, do_close){
|
||||
data = Object();
|
||||
data['comment_text'] = g_comment_desc_editor.getValue();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
const is_alert = element_type === 'alerts';
|
||||
const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
|
||||
|
||||
post_request_api(`${prefix}/${element_id}/comments/add`, JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
load_comments(element_id, element_type, undefined, undefined, is_alert);
|
||||
g_comment_desc_editor.setValue('');
|
||||
increase_modal_comments_count(element_type, element_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function decrease_modal_comments_count(element_type, element_id) {
|
||||
|
||||
let tid = '#object_comments_number';
|
||||
if (element_type === 'timeline/events' || element_type === 'alerts') {
|
||||
tid = '#object_comments_number_' + element_id;
|
||||
}
|
||||
|
||||
let curr_count = $(tid).text();
|
||||
|
||||
if (curr_count > 0) {
|
||||
$(tid).text(curr_count - 1);
|
||||
if (element_type === 'timeline/events' || element_type === 'alerts') {
|
||||
$('#object_comments_number').text(parseInt(curr_count) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function increase_modal_comments_count(element_type, element_id) {
|
||||
let tid = '#object_comments_number';
|
||||
if (element_type === 'timeline/events' || element_type === 'alerts') {
|
||||
tid = '#object_comments_number_' + element_id;
|
||||
}
|
||||
|
||||
let curr_count = $(tid).text();
|
||||
if (curr_count === '') {
|
||||
curr_count = 0;
|
||||
}
|
||||
|
||||
$(tid).text(parseInt(curr_count) + 1);
|
||||
if (element_type === 'timeline/events' || element_type === 'alerts') {
|
||||
$('#object_comments_number').text(parseInt(curr_count) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function delete_comment(comment_id, element_id, element_type) {
|
||||
do_deletion_prompt("You are about to delete comment #" + comment_id)
|
||||
.then((doDelete) => {
|
||||
if (doDelete) {
|
||||
data = Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
const is_alert = element_type === 'alerts';
|
||||
const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
|
||||
post_request_api(`${prefix}/${element_id}/comments/${comment_id}/delete`, JSON.stringify(data))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
load_comments(element_id, element_type, undefined, undefined, is_alert);
|
||||
decrease_modal_comments_count(element_type, element_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit_comment(comment_id, element_id, element_type) {
|
||||
const is_alert = element_type === 'alerts';
|
||||
const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
|
||||
get_request_api(`${prefix}/${element_id}/comments/${comment_id}`)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
|
||||
$('#comment_'+comment_id).addClass('comment_editing');
|
||||
$('#comment_'+comment_id).data('comment_id', comment_id);
|
||||
g_comment_desc_editor.setValue(data.data.comment_text);
|
||||
$('#comment_edition').show();
|
||||
$('#comment_submit').hide();
|
||||
$('#cancel_edition').show();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function save_edit_comment(element_id, element_type) {
|
||||
data = Object();
|
||||
data['comment_text'] = g_comment_desc_editor.getValue();
|
||||
comment_id = $('.comment_editing').data('comment_id');
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
const is_alert = element_type === 'alerts';
|
||||
const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
|
||||
post_request_api(`${prefix}/${element_id}/comments/${comment_id}/edit`, JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
cancel_edition(comment_id);
|
||||
load_comments(element_id, element_type, comment_id, undefined, is_alert);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancel_edition(comment_id) {
|
||||
$('.comment_editing').css('background-color', '');
|
||||
$('.comment_editing').css('border-radius', '');
|
||||
$('.comment_editing').removeClass('comment_editing');
|
||||
$('.comment_editing').data('comment_id', '');
|
||||
$('#comment_edition').hide();
|
||||
$('#cancel_edition').hide();
|
||||
$('#comment_submit').show();
|
||||
g_comment_desc_editor.setValue('');
|
||||
}
|
||||
|
||||
function load_comments(element_id, element_type, comment_id, do_notification, is_alert=false) {
|
||||
|
||||
if (do_notification !== undefined) {
|
||||
silent_success = !do_notification;
|
||||
} else {
|
||||
silent_success = true;
|
||||
}
|
||||
|
||||
const prefix = is_alert || element_type === 'alerts' ? '/alerts' : `/case/${element_type}`;
|
||||
|
||||
get_request_api(`${prefix}/${element_id}/comments/list`)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, silent_success)) {
|
||||
$('#comments_list').empty();
|
||||
var names = Object;
|
||||
for (var i = 0; i < data['data'].length; i++) {
|
||||
|
||||
comment_text = data['data'][i].comment_text;
|
||||
converter = get_showdown_convert();
|
||||
html = converter.makeHtml(do_md_filter_xss(comment_text));
|
||||
comment_html = do_md_filter_xss(html);
|
||||
const username = data['data'][i].user.user_name;
|
||||
if (names.hasOwnProperty(username)) {
|
||||
avatar = names[username];
|
||||
} else {
|
||||
avatar = get_avatar_initials(username);
|
||||
names[username] = avatar;
|
||||
}
|
||||
|
||||
can_edit = "";
|
||||
current_user = $('#current_username').text();
|
||||
|
||||
if (current_user === data['data'][i].user.user_login) {
|
||||
can_edit = '<a href="#" class="btn btn-sm comment-edition-hidden" title="Edit comment" onclick="edit_comment(\'' + data['data'][i].comment_id + '\', \'' + element_id + '\',\''+ element_type +'\'); return false;"><i class="fa-solid fa-edit text-dark"></i></a>';
|
||||
can_edit += '<a href="#" class="btn btn-sm comment-edition-hidden" title="Delete comment" onclick="delete_comment(\'' + data['data'][i].comment_id + '\', \'' + element_id + '\',\''+ element_type +'\'); return false;"><i class="fa-solid fa-trash text-dark"></i></a>';
|
||||
}
|
||||
|
||||
comment = `
|
||||
<div class="row mb-2 mr-1" >
|
||||
<div class="col-12" id="comment_${data['data'][i].comment_id}">
|
||||
<div class="row mt-2">
|
||||
<div class="col">
|
||||
<div class="row mr-2">
|
||||
<div class="col">
|
||||
<div class="ml-2 row">
|
||||
${avatar}
|
||||
<h6 class="text-uppercase fw-bold mb-1 ml-1 mt-2">${filterXSS(data['data'][i].name)}</h6>
|
||||
<div class="ml-auto">
|
||||
${can_edit} <small class="text-muted text-wrap">${data['data'][i].comment_date}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="border-left: 3px solid #eaeaea;margin-left:30px;">
|
||||
<span class="text-muted ml-2">${comment_html}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
$('#comments_list').append(comment);
|
||||
}
|
||||
$('#comments_list').append('<div id="last-comment"><div>');
|
||||
|
||||
if (data['data'].length === 0) {
|
||||
$('#comments_list').html('<div class="text-center">No comments yet</div>');
|
||||
} else if (comment_id === undefined || comment_id === null) {
|
||||
offset = document.getElementById("last-comment").offsetTop;
|
||||
if (offset > 20) {
|
||||
$('.comments-listing').animate({ scrollTop: offset});
|
||||
}
|
||||
} else {
|
||||
if (document.getElementById('#comment_'+comment_id) !== null) {
|
||||
offset = document.getElementById('#comment_'+comment_id).offsetTop;
|
||||
if (offset > 20) {
|
||||
$('.comments-listing').animate({ scrollTop: offset});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
1597
iris-web/source/app/static/assets/js/iris/common.js
Normal file
1597
iris-web/source/app/static/assets/js/iris/common.js
Normal file
File diff suppressed because it is too large
Load Diff
23
iris-web/source/app/static/assets/js/iris/crc32.js
Normal file
23
iris-web/source/app/static/assets/js/iris/crc32.js
Normal file
@ -0,0 +1,23 @@
|
||||
var makeCRCTable = function(){
|
||||
var c;
|
||||
var crcTable = [];
|
||||
for(var n =0; n < 256; n++){
|
||||
c = n;
|
||||
for(var k =0; k < 8; k++){
|
||||
c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
|
||||
}
|
||||
crcTable[n] = c;
|
||||
}
|
||||
return crcTable;
|
||||
}
|
||||
|
||||
var crc32 = function(str) {
|
||||
var crcTable = window.crcTable || (window.crcTable = makeCRCTable());
|
||||
var crc = 0 ^ (-1);
|
||||
|
||||
for (var i = 0; i < str.length; i++ ) {
|
||||
crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
|
||||
}
|
||||
|
||||
return (crc ^ (-1)) >>> 0;
|
||||
};
|
535
iris-web/source/app/static/assets/js/iris/dashboard.js
Normal file
535
iris-web/source/app/static/assets/js/iris/dashboard.js
Normal file
@ -0,0 +1,535 @@
|
||||
let UserReviewsTable;
|
||||
let UserCasesTable;
|
||||
let UserTaskTable;
|
||||
function check_page_update(){
|
||||
update_gtasks_list();
|
||||
update_utasks_list();
|
||||
}
|
||||
|
||||
function task_status(id) {
|
||||
url = 'tasks/status/human/'+id + case_param();
|
||||
$('#info_task_modal_body').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_task_detail').modal({show:true});
|
||||
});
|
||||
}
|
||||
|
||||
async function update_ucases_list(show_all=false) {
|
||||
$('#ucases_list').empty();
|
||||
get_raw_request_api("/user/cases/list" + case_param() + "&show_closed=" + show_all)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
UserCasesTable.clear();
|
||||
UserCasesTable.rows.add(data.data);
|
||||
UserCasesTable.columns.adjust().draw();
|
||||
UserCasesTable.buttons().container().appendTo($('#ucases_table_info'));
|
||||
$('[data-toggle="popover"]').popover();
|
||||
$('#ucases_last_updated').text("Last updated: " + new Date().toLocaleTimeString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function update_ureviews_list() {
|
||||
get_raw_request_api("/user/reviews/list" + case_param())
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
if (data.data.length == 0) {
|
||||
$('#rowPendingCasesReview').hide();
|
||||
return;
|
||||
}
|
||||
UserReviewsTable.clear();
|
||||
UserReviewsTable.rows.add(data.data);
|
||||
UserReviewsTable.columns.adjust().draw();
|
||||
$('[data-toggle="popover"]').popover();
|
||||
$('#ureviews_last_updated').text("Last updated: " + new Date().toLocaleTimeString());
|
||||
$('#rowPendingCasesReview').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function update_utasks_list() {
|
||||
$('#utasks_list').empty();
|
||||
return get_request_api("/user/tasks/list")
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
UserTaskTable.MakeCellsEditable("destroy");
|
||||
tasks_list = data.data.tasks;
|
||||
|
||||
$('#user_attr_count').text(tasks_list.length);
|
||||
if (tasks_list.length != 0){
|
||||
$('#icon_user_task').removeClass().addClass('flaticon-alarm text-danger');
|
||||
} else {
|
||||
$('#icon_user_task').removeClass().addClass('flaticon-success text-success');
|
||||
}
|
||||
options_l = data.data.tasks_status;
|
||||
options = [];
|
||||
for (index in options_l) {
|
||||
option = options_l[index];
|
||||
options.push({ "value": option.id, "display": option.status_name })
|
||||
}
|
||||
|
||||
UserTaskTable.clear();
|
||||
UserTaskTable.rows.add(tasks_list);
|
||||
UserTaskTable.MakeCellsEditable({
|
||||
"onUpdate": callBackEditUserTaskStatus,
|
||||
"inputCss": 'form-control col-12',
|
||||
"columns": [2],
|
||||
"allowNulls": {
|
||||
"columns": [2],
|
||||
"errorClass": 'error'
|
||||
},
|
||||
"confirmationButton": {
|
||||
"confirmCss": 'my-confirm-class',
|
||||
"cancelCss": 'my-cancel-class'
|
||||
},
|
||||
"inputTypes": [
|
||||
{
|
||||
"column": 2,
|
||||
"type": "list",
|
||||
"options": options
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
UserTaskTable.columns.adjust().draw();
|
||||
UserTaskTable.buttons().container().appendTo($('#utasks_table_info'));
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
$('#utasks_last_updated').text("Last updated: " + new Date().toLocaleTimeString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function callBackEditUserTaskStatus(updatedCell, updatedRow, oldValue) {
|
||||
data_send = updatedRow.data()
|
||||
data_send['csrf_token'] = $('#csrf_token').val();
|
||||
post_request_api("user/tasks/status/update", JSON.stringify(data_send))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
update_utasks_list();
|
||||
UserTaskTable.columns.adjust().draw();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**** GTASKS ****/
|
||||
|
||||
/* Fetch a modal that allows to add an event */
|
||||
function add_gtask() {
|
||||
url = '/global/tasks/add/modal' + case_param();
|
||||
$('#modal_add_gtask_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_gtask').on("click", function () {
|
||||
var data_sent = $('#form_new_gtask').serializeObject();
|
||||
data_sent['task_tags'] = $('#task_tags').val();
|
||||
data_sent['task_assignees_id'] = $('#task_assignees_id').val();
|
||||
data_sent['task_status_id'] = $('#task_status_id').val();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/global/tasks/add', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
update_gtasks_list();
|
||||
$('#modal_add_gtask').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
$('#modal_add_gtask').modal({ show: true });
|
||||
}
|
||||
|
||||
function update_gtask(id) {
|
||||
var data_sent = $('#form_new_gtask').serializeObject();
|
||||
data_sent['task_tags'] = $('#task_tags').val();
|
||||
data_sent['task_assignee_id'] = $('#task_assignee_id').val();
|
||||
data_sent['task_status_id'] = $('#task_status_id').val();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/global/tasks/update/' + id, JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
update_gtasks_list();
|
||||
$('#modal_add_gtask').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Delete an event from the timeline thank to its id */
|
||||
function delete_gtask(id) {
|
||||
post_request_api("/global/tasks/delete/" + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
update_gtasks_list();
|
||||
$('#modal_add_gtask').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Edit and event from the timeline thanks to its ID */
|
||||
function edit_gtask(id) {
|
||||
url = '/global/tasks/update/'+ id + "/modal" + case_param();
|
||||
$('#modal_add_gtask_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_add_gtask').modal({show:true});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* Fetch and draw the tasks */
|
||||
async function update_gtasks_list() {
|
||||
$('#gtasks_list').empty();
|
||||
|
||||
return get_request_api("/global/tasks/list")
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
Table.MakeCellsEditable("destroy");
|
||||
tasks_list = data.data.tasks;
|
||||
|
||||
options_l = data.data.tasks_status;
|
||||
options = [];
|
||||
for (index in options_l) {
|
||||
option = options_l[index];
|
||||
options.push({ "value": option.id, "display": option.status_name })
|
||||
}
|
||||
|
||||
Table.clear();
|
||||
Table.rows.add(tasks_list);
|
||||
|
||||
Table.columns.adjust().draw();
|
||||
Table.buttons().container().appendTo($('#gtasks_table_info'));
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
load_menu_mod_options('global_task', Table, delete_gtask);
|
||||
$('#tasks_last_updated').text("Last updated: " + new Date().toLocaleTimeString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
UserReviewsTable = $("#ureview_table").DataTable({
|
||||
dom: 'frtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = `<a href="/case?cid=${row['case_id']}">${sanitizeHTML(data)}</a>`;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "status_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = `<span class="badge badge-light">${sanitizeHTML(data)}</span>`;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
ordering: false,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: false,
|
||||
pageLength: 10,
|
||||
order: [[ 1, "asc" ]],
|
||||
select: true
|
||||
});
|
||||
|
||||
UserCasesTable = $("#ucases_table").DataTable({
|
||||
dom: 'Blfrtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = `<a rel="noopener" target="_blank" href="/case?cid=${row['case_id']}">${sanitizeHTML(data)}</a>`;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "client",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
//data = sanitizeHTML(data);
|
||||
data = sanitizeHTML(row['client']['customer_name']);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "open_date",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
datas = '';
|
||||
for (index in data) {
|
||||
datas += '<span class="badge badge-primary">' + sanitizeHTML(data[index]['tag_title']) + '</span> ';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: false,
|
||||
pageLength: 10,
|
||||
order: [[ 2, "asc" ]],
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
],
|
||||
select: true
|
||||
});
|
||||
|
||||
$("#ucases_table").css("font-size", 12);
|
||||
|
||||
UserTaskTable = $("#utasks_table").DataTable({
|
||||
dom: 'Blfrtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "task_title",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (isWhiteSpace(data)) {
|
||||
data = '#' + row['task_id'];
|
||||
} else {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
data = '<a target="_blank" rel="noopener" href="case/tasks?cid='+ row['case_id'] + '&shared=' + row['task_id'] + '">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "task_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_status_id",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<span class="badge ml-2 badge-'+ row['status_bscolor'] +'">' + row['status_name'] + '</span>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_case",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<a href="/case?cid='+ row['case_id'] +'">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_last_update",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data);
|
||||
data = data.replace(/GMT/g, "");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "task_tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
tags = "";
|
||||
de = data.split(',');
|
||||
for (tag in de) {
|
||||
tags += '<span class="badge badge-primary ml-2">' + sanitizeHTML(de[tag]) + '</span>';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
rowCallback: function (nRow, data) {
|
||||
data = sanitizeHTML(data);
|
||||
nRow = '<span class="badge ml-2 badge-'+ sanitizeHTML(data['status_bscolor']) +'">' + sanitizeHTML(data['status_name']) + '</span>';
|
||||
},
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: false,
|
||||
pageLength: 10,
|
||||
order: [[ 2, "asc" ]],
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
],
|
||||
select: true
|
||||
});
|
||||
$("#utasks_table").css("font-size", 12);
|
||||
|
||||
Table = $("#gtasks_table").DataTable({
|
||||
dom: 'Blfrtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "task_title",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (isWhiteSpace(data)) {
|
||||
data = '#' + row['task_id'];
|
||||
} else {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
data = '<a href="#" onclick="edit_gtask(\'' + row['task_id'] + '\');">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "task_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" title="Info" data-trigger="hover" href="#" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_status_id",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<span class="badge ml-2 badge-'+ row['status_bscolor'] +'">' + row['status_name'] + '</span>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "user_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "task_last_update",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data);
|
||||
data = data.replace(/GMT/g, "");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "task_tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
tags = "";
|
||||
de = data.split(',');
|
||||
for (tag in de) {
|
||||
tags += '<span class="badge badge-primary ml-2">' + sanitizeHTML(de[tag]) + '</span>';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
rowCallback: function (nRow, data) {
|
||||
nRow = '<span class="badge ml-2 badge-'+ sanitizeHTML(data['status_bscolor']) +'">' + sanitizeHTML(data['status_name']) + '</span>';
|
||||
},
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: false,
|
||||
pageLength: 10,
|
||||
order: [[ 2, "asc" ]],
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
],
|
||||
select: true
|
||||
});
|
||||
$("#gtasks_table").css("font-size", 12);
|
||||
|
||||
update_utasks_list();
|
||||
update_ucases_list();
|
||||
update_ureviews_list();
|
||||
setInterval(check_page_update,30000);
|
||||
});
|
639
iris-web/source/app/static/assets/js/iris/datastore.js
Normal file
639
iris-web/source/app/static/assets/js/iris/datastore.js
Normal file
@ -0,0 +1,639 @@
|
||||
var ds_filter;
|
||||
|
||||
function load_datastore() {
|
||||
|
||||
ds_filter = ace.edit("ds_file_search",
|
||||
{
|
||||
autoScrollEditorIntoView: true,
|
||||
minLines: 1,
|
||||
maxLines: 5
|
||||
});
|
||||
ds_filter.setTheme("ace/theme/tomorrow");
|
||||
ds_filter.session.setMode("ace/mode/json");
|
||||
ds_filter.renderer.setShowGutter(false);
|
||||
ds_filter.setShowPrintMargin(false);
|
||||
ds_filter.renderer.setScrollMargin(10, 10);
|
||||
ds_filter.setOption("displayIndentGuides", true);
|
||||
ds_filter.setOption("indentedSoftWrap", true);
|
||||
ds_filter.setOption("showLineNumbers", false);
|
||||
ds_filter.setOption("placeholder", "Search files");
|
||||
ds_filter.setOption("highlightActiveLine", false);
|
||||
ds_filter.commands.addCommand({
|
||||
name: "Do filter",
|
||||
bindKey: { win: "Enter", mac: "Enter" },
|
||||
exec: function (editor) {
|
||||
filter_ds_files();
|
||||
}
|
||||
});
|
||||
|
||||
get_request_api('/datastore/list/tree')
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data, true)){
|
||||
$('#ds-tree-root').empty();
|
||||
build_ds_tree(data.data, 'ds-tree-root');
|
||||
reparse_activate_tree();
|
||||
show_datastore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function build_ds_tree(data, tree_node) {
|
||||
|
||||
var standard_files_filters = [
|
||||
{value: 'name: ', score: 10, meta: 'Match filename'},
|
||||
{value: 'storage_name: ', score: 10, meta: 'Match local storage filename'},
|
||||
{value: 'tag: ', score: 10, meta: 'Match tag of file'},
|
||||
{value: 'description: ', score: 10, meta: 'Match description of file'},
|
||||
{value: 'is_ioc: ', score: 10, meta: "Match file is IOC"},
|
||||
{value: 'is_evidence: ', score: 10, meta: "Match file is evidence"},
|
||||
{value: 'has_password: ', score: 10, meta: "Match file is password protected"},
|
||||
{value: 'id: ', score: 10, meta: "Match ID of the file"},
|
||||
{value: 'uuid: ', score: 10, meta: "Match UUID of the file"},
|
||||
{value: 'sha256: ', score: 10, meta: "Match sha256 of the file"},
|
||||
{value: 'AND ', score: 10, meta: 'AND operator'}
|
||||
]
|
||||
|
||||
for (node in data) {
|
||||
|
||||
if (data[node] === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (data[node].type == 'directory') {
|
||||
data[node].name = sanitizeHTML(data[node].name);
|
||||
can_delete = '';
|
||||
if (!data[node].is_root) {
|
||||
can_delete = `<div class="dropdown-divider"></div><a href="#" class="dropdown-item text-danger" onclick="delete_ds_folder('${node}');"><small class="fa fa-trash mr-2"></small>Delete</a>`;
|
||||
}
|
||||
jnode = `<li>
|
||||
<span id='${node}' title='Folder ID ${node}' data-node-id="${node}"><i class="fa-regular fa-folder"></i> ${sanitizeHTML(data[node].name)}</span> <i class="fas fa-plus ds-folder-menu" role="menu" style="cursor:pointer;" data-toggle="dropdown" aria-expanded="false"></i>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a href="#" class="dropdown-item" onclick="add_ds_folder('${node}');return false;"><small class="fa-solid fa-folder mr-2"></small>Add subfolder</a>
|
||||
<a href="#" class="dropdown-item" onclick="add_ds_file('${node}');return false;"><small class="fa-solid fa-file mr-2"></small>Add file</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" class="dropdown-item" onclick="move_ds_folder('${node}');return false;"><small class="fa fa-arrow-right-arrow-left mr-2"></small>Move</a>
|
||||
<a href="#" class="dropdown-item" onclick="rename_ds_folder('${node}', '${sanitizeHTML(data[node].name)}');return false;"><small class="fa-solid fa-pencil mr-2"></small>Rename</a>
|
||||
${can_delete}
|
||||
</div>
|
||||
<ul id='tree-${node}'></ul>
|
||||
</li>`;
|
||||
$('#'+ tree_node).append(jnode);
|
||||
build_ds_tree(data[node].children, 'tree-' + node);
|
||||
} else {
|
||||
data[node].file_original_name = sanitizeHTML(data[node].file_original_name);
|
||||
data[node].file_password = sanitizeHTML(data[node].file_password);
|
||||
data[node].file_description = sanitizeHTML(data[node].file_description);
|
||||
standard_files_filters.push({
|
||||
value: data[node].file_original_name,
|
||||
score: 1,
|
||||
meta: data[node].file_description
|
||||
});
|
||||
icon = '';
|
||||
if (data[node].file_is_ioc) {
|
||||
icon += '<i class="fa-solid fa-virus-covid text-danger mr-1" title="File is an IOC"></i>';
|
||||
}
|
||||
if (data[node].file_is_evidence) {
|
||||
icon += '<i class="fa-solid fa-file-shield text-success mr-1" title="File is an evidence"></i>';
|
||||
}
|
||||
if (icon.length === 0) {
|
||||
icon = '<i class="fa-regular fa-file mr-1" title="Regular file"></i>';
|
||||
}
|
||||
icon_lock = '';
|
||||
has_password = data[node].file_password !== null && data[node].file_password.length > 0;
|
||||
if (has_password) {
|
||||
icon_lock = '<i title="Password protected" class="fa-solid fa-lock text-success mr-1"></i>'
|
||||
}
|
||||
icn_content = btoa(icon + icon_lock);
|
||||
jnode = `<li>
|
||||
<span id='${node}' data-file-id="${node}" title="ID : ${data[node].file_id}\nUUID : ${data[node].file_uuid}" class='tree-leaf'>
|
||||
<span role="menu" style="cursor:pointer;" data-toggle="dropdown" aria-expanded="false">${icon}${icon_lock} ${sanitizeHTML(data[node].file_original_name)}</span>
|
||||
<i class="fa-regular fa-circle ds-file-selector" style="cursor:pointer;display:none;" onclick="ds_file_select('${node}');"></i>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a href="#" class="dropdown-item" onclick="get_link_ds_file('${node}');return false;"><small class="fa fa-link mr-2"></small>Link</a>
|
||||
<a href="#" class="dropdown-item" onclick="get_mk_link_ds_file('${node}', '${toBinary64(data[node].file_original_name)}', '${icn_content}', '${has_password}');return false;"><small class="fa-brands fa-markdown mr-2"></small>Markdown link</a>
|
||||
<a href="#" class="dropdown-item" onclick="download_ds_file('${node}');return false;"><small class="fa-solid fa-download mr-2"></small>Download</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" class="dropdown-item" onclick="info_ds_file('${node}');return false;"><small class="fa fa-eye mr-2"></small>Info</a>
|
||||
<a href="#" class="dropdown-item" onclick="edit_ds_file('${node}');return false;"><small class="fa fa-pencil mr-2"></small>Edit</a>
|
||||
<a href="#" class="dropdown-item" onclick="move_ds_file('${node}');return false;"><small class="fa fa-arrow-right-arrow-left mr-2"></small>Move</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" class="dropdown-item text-danger" onclick="delete_ds_file('${node}');"><small class="fa fa-trash mr-2"></small>Delete</a>
|
||||
</div>
|
||||
</span>
|
||||
</li>`;
|
||||
$('#'+ tree_node).append(jnode);
|
||||
}
|
||||
}
|
||||
ds_filter.setOptions({
|
||||
enableBasicAutocompletion: [{
|
||||
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||
callback(null, standard_files_filters);
|
||||
},
|
||||
}],
|
||||
enableLiveAutocompletion: true,
|
||||
});
|
||||
}
|
||||
|
||||
function show_datastore() {
|
||||
$('html').addClass('ds_sidebar_open');
|
||||
$('.ds-sidebar-toggler').addClass('toggled');
|
||||
}
|
||||
|
||||
function hide_datastore() {
|
||||
$('html').removeClass('ds_sidebar_open');
|
||||
$('.ds-sidebar-toggler').removeClass('toggled');
|
||||
}
|
||||
|
||||
function reparse_activate_tree() {
|
||||
$('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch');
|
||||
$('.tree li.parent_li > span').on('click', function (e) {
|
||||
var children = $(this).parent('li.parent_li').find(' > ul > li');
|
||||
if (children.is(":visible")) {
|
||||
children.hide('fast');
|
||||
$(this).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign');
|
||||
} else {
|
||||
children.show('fast');
|
||||
$(this).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign');
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
function add_ds_folder(parent_node) {
|
||||
$('#ds_mod_folder_name').data('parent-node', parent_node);
|
||||
$('#ds_mod_folder_name').data('node-update', false);
|
||||
$('#ds_mod_folder_name').val('');
|
||||
$('#modal_ds_folder').modal("show");
|
||||
}
|
||||
|
||||
function rename_ds_folder(parent_node, name) {
|
||||
$('#ds_mod_folder_name').data('parent-node', parent_node);
|
||||
$('#ds_mod_folder_name').data('node-update', true);
|
||||
$('#ds_mod_folder_name').val(name);
|
||||
$('#modal_ds_folder').modal("show");
|
||||
}
|
||||
|
||||
function delete_ds_folder(node) {
|
||||
node = node.replace('d-', '');
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "This will delete all files included and sub-folders",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
var data_sent = {
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
}
|
||||
post_request_api('/datastore/folder/delete/' + node, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function save_ds_mod_folder() {
|
||||
var data = Object();
|
||||
|
||||
data['parent_node'] = $('#ds_mod_folder_name').data('parent-node').replace('d-', '');
|
||||
data['folder_name'] = $('#ds_mod_folder_name').val();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
if ($('#ds_mod_folder_name').data('node-update')) {
|
||||
uri = '/datastore/folder/rename/' + data['parent_node'];
|
||||
} else {
|
||||
uri = '/datastore/folder/add';
|
||||
}
|
||||
|
||||
post_request_api(uri, JSON.stringify(data))
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data)){
|
||||
$('#modal_ds_folder').modal("hide");
|
||||
load_datastore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add_ds_file(node) {
|
||||
node = node.replace('d-', '');
|
||||
url = '/datastore/file/add/'+ node +'/modal' + case_param();
|
||||
$('#modal_ds_file_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#modal_ds_file').modal("show");
|
||||
});
|
||||
}
|
||||
|
||||
function edit_ds_file(node) {
|
||||
node = node.replace('f-', '');
|
||||
url = '/datastore/file/update/'+ node +'/modal' + case_param();
|
||||
$('#modal_ds_file_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#modal_ds_file').modal("show");
|
||||
});
|
||||
}
|
||||
|
||||
function info_ds_file(node) {
|
||||
node = node.replace('f-', '');
|
||||
url = '/datastore/file/info/'+ node +'/modal' + case_param();
|
||||
$('#modal_ds_file_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#modal_ds_file').modal("show");
|
||||
});
|
||||
}
|
||||
|
||||
function save_ds_file(node, file_id) {
|
||||
var formData = new FormData($('#form_new_ds_file')[0]);
|
||||
formData.append('file_content', $('#input_upload_ds_file').prop('files')[0]);
|
||||
|
||||
if (file_id === undefined) {
|
||||
uri = '/datastore/file/add/' + node;
|
||||
} else {
|
||||
uri = '/datastore/file/update/' + file_id;
|
||||
}
|
||||
|
||||
post_request_data_api(uri, formData, true, function() {
|
||||
window.swal({
|
||||
title: "File is uploading",
|
||||
text: "Please wait. This window will close automatically when the file is uploaded.",
|
||||
icon: "/static/assets/img/loader.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
})
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data)){
|
||||
$('#modal_ds_file').modal("hide");
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
})
|
||||
.always((data) => {
|
||||
window.swal.close();
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_ds(){
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
notify_success('Datastore refreshed');
|
||||
}
|
||||
|
||||
function upload_interactive_data(data_blob, filename, completion_callback) {
|
||||
|
||||
var data_sent = Object()
|
||||
data_sent["csrf_token"] = $('#csrf_token').val();
|
||||
data_sent["file_content"] = data_blob.split(';base64,')[1];
|
||||
data_sent["file_original_name"] = filename;
|
||||
|
||||
post_request_api('/datastore/file/add-interactive', JSON.stringify(data_sent), true)
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data)) {
|
||||
if (completion_callback !== undefined) {
|
||||
completion_callback(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggle_select_file() {
|
||||
if ($('.btn-ds-bulk-selector').hasClass('active')) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
} else {
|
||||
$('.ds-file-selector').show(250);
|
||||
$('.btn-ds-bulk').show(250);
|
||||
$('.btn-ds-bulk-selector').addClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
function move_ds_file(file_id) {
|
||||
|
||||
reparse_activate_tree_selection();
|
||||
$('.ds-file-selector').show();
|
||||
$('#msg_mv_dst_folder').text('unselected destination');
|
||||
$('#msg_select_destination_folder').show();
|
||||
|
||||
ds_file_select(file_id);
|
||||
}
|
||||
|
||||
function reset_ds_file_view() {
|
||||
$(".node-selected").removeClass("node-selected");
|
||||
$(".file-selected").removeClass("file-selected");
|
||||
$('.ds-file-selector').hide();
|
||||
$('#msg_select_destination_folder').attr("data-file-id", '');
|
||||
$('#msg_select_destination_folder').hide();
|
||||
$('#msg_select_destination_folder_folder').hide();
|
||||
$('.ds-file-selector').hide();
|
||||
$('.btn-ds-bulk').hide();
|
||||
$('.btn-ds-bulk-selector').removeClass('active');
|
||||
}
|
||||
|
||||
function ds_file_select(file_id) {
|
||||
file_id = '#'+ file_id;
|
||||
if ($(file_id).hasClass('file-selected')) {
|
||||
$(file_id + '> i').removeClass('fa-circle-check');
|
||||
$(file_id + '> i').addClass('fa-circle');
|
||||
$(file_id).removeClass('file-selected');
|
||||
} else {
|
||||
$(file_id+ '> i').removeClass('fa-circle');
|
||||
$(file_id+ '> i').addClass('fa-circle-check');
|
||||
$(file_id).addClass('file-selected');
|
||||
}
|
||||
$('#msg_mv_files').text($('.file-selected').length);
|
||||
}
|
||||
|
||||
function validate_ds_file_move() {
|
||||
var data_sent = Object();
|
||||
if ($(".node-selected").length === 0) {
|
||||
notify_error('No destination folder selected');
|
||||
return false;
|
||||
}
|
||||
if ($(".file-selected").length === 0) {
|
||||
notify_error('No file to move selected');
|
||||
return false;
|
||||
}
|
||||
|
||||
data_sent['destination-node'] = $(".node-selected").data('node-id').replace('d-', '');
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
index = 0;
|
||||
selected_files = $(".file-selected");
|
||||
selected_files.each((index) => {
|
||||
file_id = $(selected_files[index]).data('file-id').replace('f-', '');
|
||||
post_request_api('/datastore/file/move/' + file_id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
if (index == $(".file-selected").length - 1) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
index +=1;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function move_ds_folder(node_id) {
|
||||
reset_ds_file_view();
|
||||
|
||||
$('#msg_mv_folder').text($('#' + node_id).text());
|
||||
$('#msg_mv_dst_folder_folder').text('unselected destination');
|
||||
$('#msg_select_destination_folder_folder').show();
|
||||
|
||||
reparse_activate_tree_selection();
|
||||
$('#' + node_id).addClass('node-source-selected');
|
||||
}
|
||||
|
||||
function validate_ds_folder_move() {
|
||||
var data_sent = Object();
|
||||
if ($(".node-selected").length === 0) {
|
||||
notify_error('No destination folder selected');
|
||||
return false;
|
||||
}
|
||||
if ($(".node-source-selected").length === 0) {
|
||||
notify_error('No initial folder to move');
|
||||
return false;
|
||||
}
|
||||
|
||||
data_sent['destination-node'] = $(".node-selected").data('node-id').replace('d-', '');
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
node_id = $(".node-source-selected").data('node-id').replace('d-', '');
|
||||
post_request_api('/datastore/folder/move/' + node_id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delete_ds_file(file_id) {
|
||||
file_id = file_id.replace('f-', '');
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "This will delete the file on the server and any manual reference will become invalid",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
var data_sent = {
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
}
|
||||
post_request_api('/datastore/file/delete/' + file_id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delete_bulk_ds_file() {
|
||||
|
||||
selected_files = $(".file-selected");
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: `Yu are about to delete ${selected_files.length} files\nThis will delete the files on the server and any manual reference will become invalid`,
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
selected_files.each((index) => {
|
||||
file_id = $(selected_files[index]).data('file-id').replace('f-', '');
|
||||
var data_sent = {
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
}
|
||||
post_request_api('/datastore/file/delete/' + file_id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
if (index == $(".file-selected").length - 1) {
|
||||
reset_ds_file_view();
|
||||
load_datastore();
|
||||
}
|
||||
index +=1;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function get_link_ds_file(file_id) {
|
||||
|
||||
file_id = file_id.replace('f-', '');
|
||||
|
||||
link = location.protocol + '//' + location.host + '/datastore/file/view/' + file_id;
|
||||
link = link + case_param();
|
||||
|
||||
navigator.clipboard.writeText(link).then(function() {
|
||||
notify_success('File link copied')
|
||||
}, function(err) {
|
||||
notify_error('Unable to copy link. Error ' + err);
|
||||
console.error('File link link', err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function build_dsfile_view_link(file_id) {
|
||||
file_id = file_id.replace('f-', '');
|
||||
|
||||
link = '/datastore/file/view/' + file_id;
|
||||
link = link + case_param();
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
function get_mk_link_ds_file(file_id, filename, file_icon, has_password) {
|
||||
|
||||
let link = build_dsfile_view_link(file_id);
|
||||
|
||||
filename = sanitizeHTML(fromBinary64(filename));
|
||||
|
||||
|
||||
if (has_password == 'false' && ['png', 'svg', 'jpeg', 'jpg', 'webp', 'bmp', 'gif'].includes(filename.split('.').pop())) {
|
||||
mk_link = ``;
|
||||
} else {
|
||||
file_icon = atob(file_icon);
|
||||
mk_link = `[${file_icon} [DS] ${filename}](${link})`;
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(mk_link).then(function() {
|
||||
notify_success('Markdown file link copied')
|
||||
}, function(err) {
|
||||
notify_error('Unable to copy link. Error ' + err);
|
||||
console.error(`Markdown file link ${md_link}`, err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function download_ds_file(file_id) {
|
||||
let link = build_dsfile_view_link(file_id);
|
||||
downloadURI(link, name);
|
||||
}
|
||||
|
||||
function reparse_activate_tree_selection() {
|
||||
$('.tree li.parent_li > span').on('click', function (e) {
|
||||
if ($(this).hasClass('node-selected')) {
|
||||
$(this).removeClass('node-selected');
|
||||
$('#msg_mv_dst_folder').text('unselected destination');
|
||||
$('#msg_mv_dst_folder_folder').text('unselected destination');
|
||||
} else {
|
||||
$(".node-selected").removeClass("node-selected");
|
||||
$(this).addClass('node-selected');
|
||||
$('#msg_mv_dst_folder').text($(".node-selected").text());
|
||||
$('#msg_mv_dst_folder_folder').text($(".node-selected").text());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var parsed_filter_ds = {};
|
||||
var ds_keywords = ['storage_name', 'name', 'tag', 'description', 'is_ioc', 'is_evidence', 'has_password', 'uuid', 'id', 'sha256'];
|
||||
|
||||
function parse_filter(str_filter, keywords) {
|
||||
for (var k = 0; k < keywords.length; k++) {
|
||||
keyword = keywords[k];
|
||||
items = str_filter.split(keyword + ':');
|
||||
|
||||
ita = items[1];
|
||||
|
||||
if (ita === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item = split_bool(ita);
|
||||
|
||||
if (item != null) {
|
||||
if (!(keyword in parsed_filter_ds)) {
|
||||
parsed_filter_ds[keyword] = [];
|
||||
}
|
||||
if (!parsed_filter_ds[keyword].includes(item)) {
|
||||
parsed_filter_ds[keyword].push(item.trim());
|
||||
}
|
||||
|
||||
if (items[1] != undefined) {
|
||||
str_filter = str_filter.replace(keyword + ':' + item, '');
|
||||
if (parse_filter(str_filter, keywords)) {
|
||||
keywords.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function filter_ds_files() {
|
||||
|
||||
ds_keywords = ['storage_name', 'name', 'tag', 'description', 'is_ioc', 'is_evidence', 'has_password', 'uuid', 'id', 'sha256'];
|
||||
parsed_filter_ds = {};
|
||||
parse_filter(ds_filter.getValue(), ds_keywords);
|
||||
filter_query = encodeURIComponent(JSON.stringify(parsed_filter_ds));
|
||||
|
||||
$('#btn_filter_ds_files').text('Searching..');
|
||||
get_request_data_api("/datastore/list/filter",{ 'q': filter_query })
|
||||
.done(function (data){
|
||||
if(notify_auto_api(data, true)){
|
||||
$('#ds-tree-root').empty();
|
||||
build_ds_tree(data.data, 'ds-tree-root');
|
||||
reparse_activate_tree();
|
||||
show_datastore();
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
$('#btn_filter_ds_files').text('Search');
|
||||
});
|
||||
}
|
||||
|
||||
function reset_ds_files_filter() {
|
||||
ds_filter.setValue("");
|
||||
load_datastore();
|
||||
}
|
||||
|
||||
function show_ds_filter_help() {
|
||||
$('#modal_help').load('/datastore/filter-help/modal' + case_param(), function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, '/datastore/filter-help/modal');
|
||||
return false;
|
||||
}
|
||||
$('#modal_help').modal('show');
|
||||
});
|
||||
}
|
||||
|
66
iris-web/source/app/static/assets/js/iris/datatablesUtils.js
Normal file
66
iris-web/source/app/static/assets/js/iris/datatablesUtils.js
Normal file
@ -0,0 +1,66 @@
|
||||
/* remove user provided filter */
|
||||
function removeFilter(clickedObject) {
|
||||
console.log("removeFilter")
|
||||
let inputObject = $(clickedObject)
|
||||
.parents("table")
|
||||
.find("input")[$(clickedObject).parents("th").index()]
|
||||
inputObject.value=""; // Clear input
|
||||
$(inputObject).trigger("change"); // trigger change event
|
||||
}
|
||||
|
||||
/* add a text input to each column of a given datatable to allow filtering */
|
||||
function addFilterFields(tableId){
|
||||
$('#' + tableId + ' thead tr')
|
||||
.clone(true)
|
||||
.addClass('filters')
|
||||
.appendTo('#' + tableId + ' thead');
|
||||
}
|
||||
|
||||
/* callback function to activate filtering on a datatable */
|
||||
function tableFiltering(api, table_anchor, exclude_columns=[]) {
|
||||
// For each column
|
||||
api
|
||||
.columns()
|
||||
.eq(0)
|
||||
.each(function (colIdx) {
|
||||
// Set the header cell to contain the input element
|
||||
var cell = $('#'+table_anchor+' .filters th').eq(
|
||||
$(api.column(colIdx).header()).index()
|
||||
);
|
||||
|
||||
if (exclude_columns.includes(colIdx)) {
|
||||
$(cell).html('<div class="form-group has-feedback" style="display: none;"><input type="text" class="form-control" placeholder="Filter"><i class="fas fa-times-circle form-control-feedback" onclick="removeFilter(this);"></i></div>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$(cell).html('<div class="form-group has-feedback"><input type="text" class="form-control" placeholder="Filter"><i class="fas fa-times-circle form-control-feedback" onclick="removeFilter(this);"></i></div>');
|
||||
// On every keypress in this input
|
||||
$(
|
||||
'input',
|
||||
$('#'+table_anchor+' .filters th').eq($(api.column(colIdx).header()).index())
|
||||
)
|
||||
.off('keyup change')
|
||||
.on('keyup change', function (e) {
|
||||
e.stopPropagation();
|
||||
// Get the search value
|
||||
$(this).attr('title', $(this).val());
|
||||
var regexr = '({search})';
|
||||
var cursorPosition = this.selectionStart;
|
||||
// Search the column for that value
|
||||
api
|
||||
.column(colIdx)
|
||||
.search(
|
||||
this.value != ''
|
||||
? regexr.replace('{search}', '(((' + this.value + ')))')
|
||||
: '',
|
||||
this.value != '',
|
||||
this.value == ''
|
||||
)
|
||||
.draw();
|
||||
$(this)
|
||||
.focus()[0]
|
||||
.setSelectionRange(cursorPosition, cursorPosition);
|
||||
});
|
||||
});
|
||||
}
|
86
iris-web/source/app/static/assets/js/iris/dim_tasks.js
Normal file
86
iris-web/source/app/static/assets/js/iris/dim_tasks.js
Normal file
@ -0,0 +1,86 @@
|
||||
function get_activities () {
|
||||
|
||||
get_request_api('/dim/tasks/list/1000')
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
content = data.data;
|
||||
Table.clear();
|
||||
Table.rows.add(content);
|
||||
Table.columns.adjust().draw();
|
||||
$('#feed_last_updated').text("Last updated: " + new Date().toLocaleTimeString());
|
||||
hide_loader();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
|
||||
Table = $("#activities_table").DataTable({
|
||||
dom: 'Blfrtip',
|
||||
aaData: [],
|
||||
bSort: false,
|
||||
aoColumns: [
|
||||
|
||||
{ "data": "task_id",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = "<a href='#' onclick=\"dim_task_status('"+ data +"');return false;\">"+ data +"</a>"
|
||||
}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "state",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (data == 'success'){
|
||||
data = "<i class='fas fa-check text-success' title='success'></i>";
|
||||
} else {
|
||||
data = "<i class='fas fa-times text-danger' title='failure'></i>";
|
||||
}
|
||||
}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "date_done",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "case",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "module",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "user",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} }
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'activities_table');
|
||||
},
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
]
|
||||
});
|
||||
$("#activities_table").css("font-size", 12);
|
||||
|
||||
|
||||
get_activities();
|
||||
});
|
188
iris-web/source/app/static/assets/js/iris/manage.attributes.js
Normal file
188
iris-web/source/app/static/assets/js/iris/manage.attributes.js
Normal file
@ -0,0 +1,188 @@
|
||||
function add_object_attribute() {
|
||||
url = '/manage/attributes/add/modal' + case_param();
|
||||
$('#modal_add_attribute_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_attribute').on("click", function () {
|
||||
var form = $('#form_new_attribute').serializeObject();
|
||||
|
||||
post_request_api('/manage/attributes/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
refresh_attribute_table();
|
||||
$('#modal_add_attribute').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#attributes_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "/manage/attributes/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "desc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "attribute_id",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="attribute_detail(\'' + row['attribute_id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "attribute_display_name",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="attribute_detail(\'' + row['attribute_id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "attribute_description"
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_attribute_table() {
|
||||
$('#attributes_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
function attribute_detail(attr_id) {
|
||||
url = '/manage/attributes/' + attr_id + '/modal' + case_param();
|
||||
$('#modal_add_attribute_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
var editor = ace.edit("editor_detail",
|
||||
{
|
||||
autoScrollEditorIntoView: true,
|
||||
minLines: 30,
|
||||
});
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
editor.session.setMode("ace/mode/json");
|
||||
editor.renderer.setShowGutter(true);
|
||||
editor.setOption("showLineNumbers", true);
|
||||
editor.setOption("showPrintMargin", false);
|
||||
editor.setOption("displayIndentGuides", true);
|
||||
editor.setOption("maxLines", "Infinity");
|
||||
editor.session.setUseWrapMode(true);
|
||||
editor.setOption("indentedSoftWrap", true);
|
||||
editor.renderer.setScrollMargin(8, 5)
|
||||
|
||||
editor.setOptions({
|
||||
enableBasicAutocompletion: [{
|
||||
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||
callback(null, [
|
||||
{value: 'mandatory', score: 1, meta: 'mandatory tag'},
|
||||
{value: 'type', score: 1, meta: 'type tag'},
|
||||
{value: 'input_string', score: 1, meta: 'An input string field type'},
|
||||
{value: 'input_checkbox', score: 1, meta: 'An input checkbox field type'},
|
||||
{value: 'input_textfield', score: 1, meta: 'An input textfield field type'},
|
||||
{value: 'input_date', score: 1, meta: 'An input date field type'},
|
||||
{value: 'input_datetime', score: 1, meta: 'An input datetime field type'},
|
||||
{value: 'input_select', score: 1, meta: 'An input select field type'},
|
||||
{value: 'raw', score: 1, meta: 'A raw field type'},
|
||||
{value: 'html', score: 1, meta: 'An html field type'},
|
||||
{value: 'value', score: 1, meta: 'default value'},
|
||||
]);
|
||||
},
|
||||
}],
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true
|
||||
});
|
||||
|
||||
$('#preview_attribute').on("click", function () {
|
||||
var data_sent = Object();
|
||||
data_sent['attribute_content'] = editor.getSession().getValue();
|
||||
data_sent['csrf_token'] = $("#csrf_token").val();
|
||||
|
||||
post_request_api('/manage/attributes/preview', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
$('#modal_preview_attribute_content').html(data.data);
|
||||
|
||||
$('#modal_preview_attribute').modal({ show: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#submit_new_attribute').on("click", function () {
|
||||
update_attribute(attr_id, editor, false, false);
|
||||
})
|
||||
$('#submit_partial_overwrite').on("click", function () {
|
||||
update_attribute(attr_id, editor, true, false);
|
||||
})
|
||||
$('#submit_complete_overwrite').on("click", function () {
|
||||
update_attribute(attr_id, editor, false, true);
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_attribute').modal({ show: true });
|
||||
}
|
||||
|
||||
function update_attribute(attr_id, editor, partial, complete){
|
||||
event.preventDefault();
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['attribute_content'] = editor.getSession().getValue();
|
||||
data_sent['csrf_token'] = $("#csrf_token").val();
|
||||
data_sent['partial_overwrite'] = partial;
|
||||
data_sent['complete_overwrite'] = complete;
|
||||
|
||||
$('#alert_attributes_edit').empty();
|
||||
$('#alert_attributes_details').hide();
|
||||
$('#attributes_err_details_list').empty();
|
||||
|
||||
post_request_api('/manage/attributes/update/' + attr_id, JSON.stringify(data_sent), false, function() {
|
||||
window.swal({
|
||||
title: "Updating and migrating...",
|
||||
text: "Please wait",
|
||||
icon: "/static/assets/img/loader.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
})
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
})
|
||||
.fail((error) => {
|
||||
data = error.responseJSON;
|
||||
$('#submit_new_attribute').text('Save');
|
||||
$('#alert_attributes_edit').text(data.message);
|
||||
if (data.data && data.data.length > 0) {
|
||||
for(var i in data.data)
|
||||
{
|
||||
var output='<li>'+ sanitizeHTML(data.data[i]) +'</li>';
|
||||
$('#attributes_err_details_list').append(output);
|
||||
}
|
||||
|
||||
$('#alert_attributes_details').show();
|
||||
}
|
||||
$('#alert_attributes_edit').show();
|
||||
$('#submit_new_module').text("Retry");
|
||||
})
|
||||
.always((data) => {
|
||||
window.swal.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
|
||||
|
||||
|
||||
function get_case_audit_page() {
|
||||
us_val = $('#cases_audit_select').val();
|
||||
if (!us_val) {
|
||||
notify_error('I really wanna help you but I still can\'t read your mind');
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#get_case_audit_btn').text('Auditing case..');
|
||||
url = '/manage/access-control/audit/cases/'+ us_val +'/modal' + case_param();
|
||||
$('#case_audit_content').load(url, function (response, status, xhr) {
|
||||
$('#get_case_audit_btn').text('Audit');
|
||||
if (status !== "success") {
|
||||
$('#get_case_audit_btn').text('Audit');
|
||||
ajax_notify_error(xhr, url);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
$('#case_audit_access_table').dataTable({
|
||||
order: [[ 1, "asc" ]],
|
||||
info: true,
|
||||
filter: true,
|
||||
processing: true,
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'case_audit_access_table');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_cases_list_audit() {
|
||||
get_request_api('/manage/cases/list')
|
||||
.done((data) => {
|
||||
|
||||
if(notify_auto_api(data, true)) {
|
||||
|
||||
$('#cases_audit_select').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select case to audit",
|
||||
style: "btn-outline-white",
|
||||
size: 10
|
||||
});
|
||||
data_select = [];
|
||||
for (caseid in data.data) {
|
||||
label = `${sanitizeHTML(data.data[caseid].case_name)}`;
|
||||
$("#cases_audit_select").append('<option value="'+data.data[caseid].case_id+'">'+label+'</option>');
|
||||
}
|
||||
$("#cases_audit_select").selectpicker("refresh");
|
||||
$("#cases_audit_select").show();
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
refresh_cases_list_audit();
|
||||
});
|
||||
|
@ -0,0 +1,78 @@
|
||||
|
||||
|
||||
|
||||
function get_user_audit_page() {
|
||||
|
||||
us_val = $('#users_audit_select').val();
|
||||
if (!us_val) {
|
||||
notify_error('I really wanna help you but I still can\'t read your mind');
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#get_user_audit_btn').text('Auditing user..');
|
||||
url = '/manage/access-control/audit/users/'+ us_val +'/modal' + case_param();
|
||||
$('#user_audit_content').load(url, function (response, status, xhr) {
|
||||
$('#get_user_audit_btn').text('Audit');
|
||||
if (status !== "success") {
|
||||
$('#get_user_audit_btn').text('Audit');
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
|
||||
$('#user_audit_access_table').dataTable({
|
||||
order: [[ 1, "asc" ]],
|
||||
info: true,
|
||||
filter: true,
|
||||
processing: true,
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'user_audit_access_table');
|
||||
}
|
||||
});
|
||||
|
||||
$('#user_audit_permissions_table').dataTable({
|
||||
order: [[ 1, "asc" ]],
|
||||
info: true,
|
||||
filter: true,
|
||||
processing: true,
|
||||
orderCellsTop: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'user_audit_permissions_table');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_users_list_audit() {
|
||||
get_request_api('/manage/users/list')
|
||||
.done((data) => {
|
||||
|
||||
if(notify_auto_api(data, true)) {
|
||||
|
||||
$('#users_audit_select').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select user to audit",
|
||||
style: "btn-outline-white",
|
||||
size: 10
|
||||
});
|
||||
data_select = [];
|
||||
for (user in data.data) {
|
||||
label = `${sanitizeHTML(data.data[user].user_login)} (${sanitizeHTML(data.data[user].user_name)} - ${sanitizeHTML(data.data[user].user_email)})`;
|
||||
$("#users_audit_select").append('<option value="'+data.data[user].user_id+'">'+label+'</option>');
|
||||
}
|
||||
$("#users_audit_select").selectpicker("refresh");
|
||||
$("#users_audit_select").show();
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
refresh_users_list_audit();
|
||||
});
|
||||
|
@ -0,0 +1,336 @@
|
||||
function add_case_template() {
|
||||
let url = '/manage/case-templates/add/modal' + case_param();
|
||||
$('#modal_case_template_json').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
let editor = ace.edit("editor_detail",
|
||||
{
|
||||
autoScrollEditorIntoView: true,
|
||||
minLines: 30,
|
||||
});
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
editor.session.setMode("ace/mode/json");
|
||||
editor.renderer.setShowGutter(true);
|
||||
editor.setOption("showLineNumbers", true);
|
||||
editor.setOption("showPrintMargin", false);
|
||||
editor.setOption("displayIndentGuides", true);
|
||||
editor.setOption("maxLines", "Infinity");
|
||||
editor.session.setUseWrapMode(true);
|
||||
editor.setOption("indentedSoftWrap", true);
|
||||
editor.renderer.setScrollMargin(8, 5)
|
||||
|
||||
editor.setOptions({
|
||||
enableBasicAutocompletion: [{
|
||||
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||
callback(null, [
|
||||
{value: 'name', score: 1, meta: 'name of the template'},
|
||||
{value: 'display', score: 1, meta: 'display name of the template'},
|
||||
{value: 'description', score: 1, meta: 'description of the template'},
|
||||
{value: 'author', score: 1, meta: 'author of the template'},
|
||||
{value: 'title_prefix', score: 1, meta: 'prefix of instantiated cases'},
|
||||
{value: 'summary', score: 1, meta: 'summary of the case'},
|
||||
{value: 'tags', score: 1, meta: 'tags of the case or the tasks'},
|
||||
{value: 'tasks', score: 1, meta: 'tasks of the case'},
|
||||
{value: 'note_groups', score: 1, meta: 'groups of notes'},
|
||||
{value: 'title', score: 1, meta: 'title of the task or the note group or the note'},
|
||||
{value: 'content', score: 1, meta: 'content of the note'},
|
||||
]);
|
||||
},
|
||||
}],
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true
|
||||
});
|
||||
|
||||
$('#submit_new_case_template').on("click", function () {
|
||||
let data_sent = Object();
|
||||
data_sent['case_template_json'] = editor.getSession().getValue();
|
||||
data_sent['csrf_token'] = $("#csrf_token").val();
|
||||
|
||||
post_request_api('/manage/case-templates/add', JSON.stringify(data_sent), false, function() {
|
||||
window.swal({
|
||||
title: "Adding...",
|
||||
text: "Please wait",
|
||||
icon: "/static/assets/img/loader.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
})
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
refresh_case_template_table();
|
||||
$('#modal_case_template').modal('hide');
|
||||
}
|
||||
})
|
||||
.fail((error) => {
|
||||
let data = error.responseJSON;
|
||||
$('#submit_new_case_template').text('Save');
|
||||
$('#alert_case_template_edit').text(data.message);
|
||||
if (data.data && data.data.length > 0) {
|
||||
|
||||
let output='<li>'+ sanitizeHTML(data.data) +'</li>';
|
||||
$('#case_template_err_details_list').append(output);
|
||||
|
||||
$('#alert_case_template_details').show();
|
||||
}
|
||||
$('#alert_case_template_edit').show();
|
||||
})
|
||||
.always((data) => {
|
||||
window.swal.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_case_template').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#case_templates_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "/manage/case-templates/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "desc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "id",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="case_template_detail(\'' + row['id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "display_name",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="case_template_detail(\'' + row['id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "description"
|
||||
},
|
||||
{
|
||||
"data": "added_by"
|
||||
},
|
||||
{
|
||||
"data": "created_at"
|
||||
},
|
||||
{
|
||||
"data": "updated_at"
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_case_template_table() {
|
||||
$('#case_templates_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
function delete_case_template(id) {
|
||||
swal({
|
||||
title: "Are you sure ?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/case-templates/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.href = '/manage/case-templates' + case_param();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function case_template_detail(ctempl_id) {
|
||||
let url = '/manage/case-templates/' + ctempl_id + '/modal' + case_param();
|
||||
$('#modal_case_template_json').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
let editor = ace.edit("editor_detail",
|
||||
{
|
||||
autoScrollEditorIntoView: true,
|
||||
minLines: 30,
|
||||
});
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
editor.session.setMode("ace/mode/json");
|
||||
editor.renderer.setShowGutter(true);
|
||||
editor.setOption("showLineNumbers", true);
|
||||
editor.setOption("showPrintMargin", false);
|
||||
editor.setOption("displayIndentGuides", true);
|
||||
editor.setOption("maxLines", "Infinity");
|
||||
editor.session.setUseWrapMode(true);
|
||||
editor.setOption("indentedSoftWrap", true);
|
||||
editor.renderer.setScrollMargin(8, 5)
|
||||
|
||||
editor.setOptions({
|
||||
enableBasicAutocompletion: [{
|
||||
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||
callback(null, [
|
||||
{value: 'name', score: 1, meta: 'name of the template'},
|
||||
{value: 'display_name', score: 1, meta: 'display name of the template'},
|
||||
{value: 'description', score: 1, meta: 'description of the template'},
|
||||
{value: 'author', score: 1, meta: 'author of the template'},
|
||||
{value: 'title_prefix', score: 1, meta: 'prefix of instantiated cases'},
|
||||
{value: 'summary', score: 1, meta: 'summary of the case'},
|
||||
{value: 'tags', score: 1, meta: 'tags of the case or the tasks'},
|
||||
{value: 'tasks', score: 1, meta: 'tasks of the case'},
|
||||
{value: 'note_groups', score: 1, meta: 'groups of notes'},
|
||||
{value: 'title', score: 1, meta: 'title of the task or the note group or the note'},
|
||||
{value: 'content', score: 1, meta: 'content of the note'},
|
||||
]);
|
||||
},
|
||||
}],
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true
|
||||
});
|
||||
|
||||
$('#submit_new_case_template').on("click", function () {
|
||||
update_case_template(ctempl_id, editor, false, false);
|
||||
});
|
||||
|
||||
$('#submit_delete_case_template').on("click", function () {
|
||||
delete_case_template(ctempl_id);
|
||||
});
|
||||
});
|
||||
$('#modal_case_template').modal({ show: true });
|
||||
}
|
||||
|
||||
function update_case_template(ctempl_id, editor, partial, complete){
|
||||
event.preventDefault();
|
||||
|
||||
let data_sent = Object();
|
||||
data_sent['case_template_json'] = editor.getSession().getValue();
|
||||
data_sent['csrf_token'] = $("#csrf_token").val();
|
||||
|
||||
$('#alert_case_template_edit').empty();
|
||||
$('#alert_case_template_details').hide();
|
||||
$('#case_template_err_details_list').empty();
|
||||
|
||||
post_request_api('/manage/case-templates/update/' + ctempl_id, JSON.stringify(data_sent), false, function() {
|
||||
window.swal({
|
||||
title: "Updating...",
|
||||
text: "Please wait",
|
||||
icon: "/static/assets/img/loader.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
})
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
})
|
||||
.fail((error) => {
|
||||
let data = error.responseJSON;
|
||||
$('#submit_new_case_template').text('Update');
|
||||
$('#alert_case_template_edit').text(data.message);
|
||||
if (data.data && data.data.length > 0) {
|
||||
let output='<li>'+ sanitizeHTML(data.data) +'</li>';
|
||||
$('#case_template_err_details_list').append(output);
|
||||
|
||||
$('#alert_case_template_details').show();
|
||||
}
|
||||
$('#alert_case_template_edit').show();
|
||||
})
|
||||
.always((data) => {
|
||||
window.swal.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function fire_upload_case_template() {
|
||||
let url = '/manage/case-templates/upload/modal' + case_param();
|
||||
$('#modal_upload_case_template_json').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('#modal_upload_case_template').modal({ show: true });
|
||||
}
|
||||
|
||||
function upload_case_template() {
|
||||
|
||||
if ($("#input_upload_case_template").val() !== "")
|
||||
{
|
||||
var file = $("#input_upload_case_template").get(0).files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
fileData = e.target.result
|
||||
var data = new Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
data['case_template_json'] = fileData;
|
||||
|
||||
post_request_api('/manage/case-templates/add', JSON.stringify(data), false, function() {
|
||||
window.swal({
|
||||
title: "Adding...",
|
||||
text: "Please wait",
|
||||
icon: "/static/assets/img/loader.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
})
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
jsdata = data;
|
||||
if (jsdata.status == "success") {
|
||||
refresh_case_template_table();
|
||||
$('#modal_upload_case_template').modal('hide');
|
||||
}
|
||||
})
|
||||
.fail((error) => {
|
||||
let data = error.responseJSON;
|
||||
$('#alert_upload_case_template').text(data.message);
|
||||
if (data.data && data.data.length > 0) {
|
||||
|
||||
let output='<li>'+ sanitizeHTML(data.data) +'</li>';
|
||||
$('#upload_case_template_err_details_list').append(output);
|
||||
|
||||
$('#alert_upload_case_template_details').show();
|
||||
}
|
||||
$('#alert_upload_case_template').show();
|
||||
})
|
||||
.always((data) => {
|
||||
$("#input_upload_case_template").val("");
|
||||
window.swal.close();
|
||||
});
|
||||
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function downloadCaseTemplateDefinition() {
|
||||
event.preventDefault();
|
||||
let editor = ace.edit("editor_detail");
|
||||
let data = editor.getSession().getValue();
|
||||
|
||||
let filename = "case_template.json";
|
||||
download_file(filename, 'text/json' , data);
|
||||
}
|
404
iris-web/source/app/static/assets/js/iris/manage.cases.common.js
Normal file
404
iris-web/source/app/static/assets/js/iris/manage.cases.common.js
Normal file
@ -0,0 +1,404 @@
|
||||
|
||||
function add_protagonist() {
|
||||
prota_html = $('#protagonist_list_edit_template').html();
|
||||
$('#protagonist_list_edit').append(prota_html);
|
||||
}
|
||||
|
||||
function refresh_case_table() {
|
||||
if ($('#cases_table').length === 0) {
|
||||
return false;
|
||||
}
|
||||
$('#cases_table').DataTable().ajax.reload();
|
||||
$('#cases_table').DataTable().columns.adjust().draw();
|
||||
notify_success('Cases list refreshed');
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create detail modal function */
|
||||
function case_detail(id) {
|
||||
url = 'cases/details/' + id + case_param();
|
||||
$('#info_case_modal_content').load(url, function (response, status, xhr) {
|
||||
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#modal_case_detail').modal({ show: true });
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/* Remove case function */
|
||||
function remove_case(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You are about to delete this case forever. This cannot be reverted.\nAll associated data will be deleted",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/cases/delete/' + id)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
if (!refresh_case_table()) {
|
||||
swal({
|
||||
title: "Done!",
|
||||
text: "You will be redirected in 5 seconds",
|
||||
icon: "success",
|
||||
buttons: false,
|
||||
dangerMode: false
|
||||
})
|
||||
setTimeout(function () {
|
||||
window.location.href = '/dashboard?cid=1';
|
||||
}, 4500);
|
||||
} else {
|
||||
refresh_case_table();
|
||||
$('#modal_case_detail').modal('hide');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Reopen case function */
|
||||
function reopen_case(id) {
|
||||
post_request_api('/manage/cases/reopen/' + id)
|
||||
.done((data) => {
|
||||
if (!refresh_case_table()) {
|
||||
window.location.reload();
|
||||
}
|
||||
$('#modal_case_detail').modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
/* Close case function */
|
||||
function close_case(id) {
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "Case ID " + id + " will be closed and will not appear in contexts anymore",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, close it!'
|
||||
})
|
||||
.then((willClose) => {
|
||||
if (willClose) {
|
||||
post_request_api('/manage/cases/close/' + id)
|
||||
.done((data) => {
|
||||
if (!refresh_case_table()) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit_case_info() {
|
||||
$('#case_gen_info_content').hide();
|
||||
$('#case_gen_info_edit').show();
|
||||
$('#cancel_case_info').show();
|
||||
$('#save_case_info').show();
|
||||
$('#case_info').hide();
|
||||
}
|
||||
|
||||
function cancel_case_edit() {
|
||||
$('#case_gen_info_content').show();
|
||||
$('#case_gen_info_edit').hide();
|
||||
$('#cancel_case_info').hide();
|
||||
$('#case_info').show();
|
||||
$('#save_case_info').hide();
|
||||
}
|
||||
|
||||
function save_case_edit(case_id) {
|
||||
|
||||
var data_sent = $('form#form_update_case').serializeObject();
|
||||
var map_protagonists = Object();
|
||||
|
||||
for (e in data_sent) {
|
||||
if (e.startsWith('protagonist_role_')) {
|
||||
map_protagonists[e.replace('protagonist_role_', '')] = {
|
||||
'role': data_sent[e]
|
||||
};
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_name_')) {
|
||||
map_protagonists[e.replace('protagonist_name_', '')]['name'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_contact_')) {
|
||||
map_protagonists[e.replace('protagonist_contact_', '')]['contact'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
if (e.startsWith('protagonist_id_')) {
|
||||
map_protagonists[e.replace('protagonist_id_', '')]['id'] = data_sent[e];
|
||||
delete data_sent[e];
|
||||
}
|
||||
}
|
||||
data_sent['protagonists'] = [];
|
||||
for (e in map_protagonists) {
|
||||
data_sent['protagonists'].push(map_protagonists[e]);
|
||||
}
|
||||
|
||||
data_sent['case_tags'] = $('#case_tags').val();
|
||||
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/manage/cases/update/' + case_id, JSON.stringify(data_sent), true, undefined, case_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
case_detail(case_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function remove_case_access_from_user(user_id, case_id, on_finish) {
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "This user might not be able access this case anymore",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, remove it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
url = '/manage/users/' + user_id + '/case-access/delete';
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['case'] = case_id;
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
|
||||
post_request_api(url, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
|
||||
if (on_finish !== undefined) {
|
||||
on_finish();
|
||||
}
|
||||
|
||||
}
|
||||
}).always(() => {
|
||||
window.swal.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var access_levels = [
|
||||
{ "id": 1, "name": "Deny all" },
|
||||
{ "id": 2, "name": "Read only" },
|
||||
{ "id": 4, "name": "Full access" }
|
||||
]
|
||||
|
||||
function get_access_level_options(data) {
|
||||
var options = "";
|
||||
|
||||
for (var i = 0; i < access_levels.length; i++) {
|
||||
options += `<option value="${access_levels[i].id}" ${data == access_levels[i].id ? 'selected' : ''}>${access_levels[i].name}</option>`;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function update_user_case_access_level(user_id, case_id, access_level) {
|
||||
var data = {
|
||||
"case_id": parseInt(case_id),
|
||||
"user_id": parseInt(user_id),
|
||||
"access_level": parseInt(access_level),
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
};
|
||||
|
||||
post_request_api('/case/access/set-user', JSON.stringify(data), false, null, case_id)
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function view_case_access_via_group(case_id) {
|
||||
url = '/case/groups/access/modal' + case_param();
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
function set_case_access_via_group(case_id) {
|
||||
var data = {
|
||||
"case_id": parseInt(case_id),
|
||||
"access_level": parseInt($('#group_case_ac_select').val()),
|
||||
"group_id": parseInt($('#group_case_access_select').val()),
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
};
|
||||
|
||||
post_request_api('/case/access/set-group', JSON.stringify(data))
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
access_case_info_reload(case_id);
|
||||
$('#modal_ac_additional').modal('hide');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function access_case_info_reload(case_id, owner_id, reviewer_id) {
|
||||
var req_users = [];
|
||||
|
||||
get_request_api('/case/users/list')
|
||||
.done((data) => {
|
||||
has_table = $.fn.dataTable.isDataTable( '#case_access_users_list_table' );
|
||||
if (!notify_auto_api(data, !has_table)) {
|
||||
return;
|
||||
}
|
||||
|
||||
req_users = data.data;
|
||||
if ( has_table ) {
|
||||
table = $('#case_access_users_list_table').DataTable();
|
||||
table.clear();
|
||||
table.rows.add(req_users);
|
||||
table.draw();
|
||||
} else {
|
||||
addFilterFields($('#case_access_users_list_table').attr("id"));
|
||||
$("#case_access_users_list_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
aaData: req_users,
|
||||
aoColumns: [
|
||||
{
|
||||
"data": "user_id",
|
||||
"className": "dt-center"
|
||||
},
|
||||
{
|
||||
"data": "user_name",
|
||||
"className": "dt-center",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "user_login",
|
||||
"className": "dt-center",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "user_access_level",
|
||||
"className": "dt-center",
|
||||
"render": function ( data, type, row ) {
|
||||
return `<select class="form-control" onchange="update_user_case_access_level('${row.user_id}',${case_id},this.value)">${get_access_level_options(data)}</select>`;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'case_access_users_list_table');
|
||||
}
|
||||
});
|
||||
}
|
||||
let quick_owner = $('#case_quick_owner');
|
||||
let quick_reviewer = $('#case_quick_reviewer');
|
||||
quick_reviewer.append($('<option>'));
|
||||
|
||||
|
||||
for (let i = 0; i < req_users.length; i++) {
|
||||
$('#username-list').append($('<option>', {
|
||||
value: req_users[i].user_name
|
||||
}));
|
||||
$('#emails-list').append($('<option>', {
|
||||
value: req_users[i].user_email
|
||||
}));
|
||||
|
||||
quick_owner.append($('<option>', {
|
||||
value: req_users[i].user_id,
|
||||
text: req_users[i].user_name
|
||||
}));
|
||||
if (req_users[i].user_id == owner_id) {
|
||||
quick_owner.val(req_users[i].user_id);
|
||||
}
|
||||
quick_owner.selectpicker('refresh');
|
||||
quick_reviewer.append($('<option>', {
|
||||
value: req_users[i].user_id,
|
||||
text: req_users[i].user_name
|
||||
}));
|
||||
if (req_users[i].user_id == reviewer_id) {
|
||||
quick_reviewer.val(req_users[i].user_id);
|
||||
}
|
||||
quick_reviewer.selectpicker('refresh');
|
||||
}
|
||||
});
|
||||
|
||||
$('#case_tags').amsifySuggestags({
|
||||
printValues: false,
|
||||
suggestions: []
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function remove_cases_access_user(user_id, cases, on_finish) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "This user might not be able access these cases anymore",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, remove it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
url = '/manage/users/' + user_id + '/cases-access/delete';
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['cases'] = cases;
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
|
||||
post_request_api(url, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_user_cac(user_id);
|
||||
|
||||
if (on_finish !== undefined) {
|
||||
on_finish();
|
||||
}
|
||||
|
||||
}
|
||||
}).always(() => {
|
||||
window.swal.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
239
iris-web/source/app/static/assets/js/iris/manage.cases.js
Normal file
239
iris-web/source/app/static/assets/js/iris/manage.cases.js
Normal file
@ -0,0 +1,239 @@
|
||||
/*************************
|
||||
* Case creation section
|
||||
*************************/
|
||||
|
||||
/* create the select picker for customer */
|
||||
$('#case_customer').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select customer *",
|
||||
style: "btn-outline-white",
|
||||
size: 8
|
||||
});
|
||||
$('#case_template_id').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select case template",
|
||||
style: "btn-outline-white",
|
||||
size: 8
|
||||
});
|
||||
$('#case_template_id').prepend(new Option('', ''));
|
||||
$('#classification_id').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Select classification",
|
||||
style: "btn-outline-white",
|
||||
size: 8
|
||||
});
|
||||
$('#classification_id').prepend(new Option('', ''));
|
||||
|
||||
|
||||
/* Submit event handler for new case */
|
||||
function submit_new_case() {
|
||||
|
||||
if(!$('form#form_new_case').valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var data_sent = $('form#form_new_case').serializeObject();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
data_sent['custom_attributes'] = attributes;
|
||||
|
||||
send_add_case(data_sent);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
function send_add_case(data_sent) {
|
||||
|
||||
post_request_api('/manage/cases/add', JSON.stringify(data_sent), true, function () {
|
||||
$('#submit_new_case_btn').text('Checking data..')
|
||||
.attr("disabled", true)
|
||||
.removeClass('bt-outline-success')
|
||||
.addClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
case_id = data.data.case_id;
|
||||
swal("That's done !",
|
||||
"Case has been successfully created",
|
||||
"success",
|
||||
{
|
||||
buttons: {
|
||||
again: {
|
||||
text: "Create a case again",
|
||||
value: "again",
|
||||
dangerMode: true,
|
||||
color: '#d33'
|
||||
},
|
||||
dash: {
|
||||
text: "Go to dashboard",
|
||||
value: "dash",
|
||||
color: '#d33'
|
||||
},
|
||||
go_case: {
|
||||
text: "Switch to newly created case",
|
||||
value: "go_case"
|
||||
}
|
||||
}
|
||||
}
|
||||
).then((value) => {
|
||||
switch (value) {
|
||||
|
||||
case "dash":
|
||||
window.location.replace("/dashboard" + case_param());
|
||||
break;
|
||||
|
||||
case "again":
|
||||
window.location.replace("/manage/cases" + case_param());
|
||||
break;
|
||||
|
||||
case 'go_case':
|
||||
window.location.replace("/case?cid=" + case_id);
|
||||
|
||||
default:
|
||||
window.location.replace("/case?cid=" + case_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
$('#submit_new_case_btn')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
})
|
||||
.fail(() => {
|
||||
$('#submit_new_case_btn').text('Save');
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Case list section
|
||||
*************************/
|
||||
/* case table creation */
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
$('#cases_table').dataTable({
|
||||
"ajax": {
|
||||
"url": "cases/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function (d) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify(d.data);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
data = sanitizeHTML(data);
|
||||
return '<a href="#" onclick="case_detail(\'' + row['case_id'] + '\');">' + data + '</a>';
|
||||
},
|
||||
"data": "case_name"
|
||||
},
|
||||
{
|
||||
"data": "case_description",
|
||||
"render": function (data, type, row) {
|
||||
if (type === 'display' && data != null) {
|
||||
if (row["case_description"].length > 50){
|
||||
return sanitizeHTML(row["case_description"].slice(0,50)) + " ... " ;
|
||||
}
|
||||
else {
|
||||
return sanitizeHTML(row["case_description"]);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
},
|
||||
{
|
||||
"data": "client_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "state_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "case_open_date",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
},
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"data": "case_close_date",
|
||||
"type": "date",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "case_soc_id",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "opened_by",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: true,
|
||||
pageLength: 25,
|
||||
select: true,
|
||||
sort: true,
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'cases_table');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
if ($('.nav-tabs').length > 0) { // if .nav-tabs exists
|
||||
var hashtag = window.location.hash;
|
||||
if (hashtag!='') {
|
||||
$('.nav-item > a').removeClass('active').removeClass('show');
|
||||
$('.nav-item > a[href="'+hashtag+'"]').addClass('active');
|
||||
$('.nav-item > a[href="'+hashtag+'"]').addClass('show');
|
||||
$('.tab-content > div').removeClass('active');
|
||||
$(hashtag).addClass('active'); $(hashtag).addClass('show');
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
148
iris-web/source/app/static/assets/js/iris/manage.customers.js
Normal file
148
iris-web/source/app/static/assets/js/iris/manage.customers.js
Normal file
@ -0,0 +1,148 @@
|
||||
const preventFormDefaultBehaviourOnSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
function add_customer() {
|
||||
const url = 'customers/add/modal' + case_param();
|
||||
$('#modal_add_customer_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#form_new_customer').on("submit", preventFormDefaultBehaviourOnSubmit);
|
||||
$('#submit_new_customer').on("click", function () {
|
||||
const form = $('#form_new_customer').serializeObject();
|
||||
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
form['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('customers/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_customer_table();
|
||||
$('#modal_add_customer').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_customer').modal({show: true});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
cid = case_param();
|
||||
$('#customers_table').dataTable({
|
||||
"ajax": {
|
||||
"url": "customers/list" + cid,
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function (d) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify(d.data);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[0, "desc"]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "customer_name",
|
||||
"render": function (data, type, row) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
return '<a href="/manage/customers/' + row['customer_id'] + '/view'+ cid +'">' + data + '</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "customer_description",
|
||||
"render": function (data, type, row) {
|
||||
if (type === 'display') {
|
||||
return sanitizeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function refresh_customer_table(do_notify) {
|
||||
$('#customers_table').DataTable().ajax.reload();
|
||||
if (do_notify !== undefined) {
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the details of an asset and allow modification */
|
||||
function customer_detail(customer_id) {
|
||||
url = '/manage/customers/update/' + customer_id + '/modal' + case_param();
|
||||
$('#modal_add_customer_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#form_new_customer').on("submit", preventFormDefaultBehaviourOnSubmit);
|
||||
$('#submit_new_customer').on("click", function () {
|
||||
|
||||
const form = $('#form_new_customer').serializeObject();
|
||||
ret = get_custom_attributes_fields();
|
||||
has_error = ret[0].length > 0;
|
||||
attributes = ret[1];
|
||||
|
||||
if (has_error){return false;}
|
||||
|
||||
form['custom_attributes'] = attributes;
|
||||
|
||||
post_request_api('/manage/customers/update/' + customer_id, JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_customer').modal({show: true});
|
||||
}
|
||||
|
||||
function delete_customer(id) {
|
||||
swal({
|
||||
title: "Are you sure ?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/customers/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.href = '/manage/customers' + case_param();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
349
iris-web/source/app/static/assets/js/iris/manage.groups.js
Normal file
349
iris-web/source/app/static/assets/js/iris/manage.groups.js
Normal file
@ -0,0 +1,349 @@
|
||||
var modal_group_table;
|
||||
var current_groups_list;
|
||||
manage_groups_table = $('#groups_table').dataTable( {
|
||||
"order": [[ 1, "asc" ]],
|
||||
"autoWidth": true,
|
||||
"columns": [
|
||||
{
|
||||
"data": "group_id",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data)
|
||||
return '<a href="#" onclick="group_detail(\'' + row["group_id"] + '\');">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "group_name",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data)
|
||||
return '<a href="#" onclick="group_detail(\'' + row["group_id"] + '\');">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "group_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "group_permissions_list",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
tags = "";
|
||||
for (perm in data) {
|
||||
permstr = sanitizeHTML(data[perm].name);
|
||||
tags += '<span class="badge badge-pill badge-light" title="Value 0x'+ data[perm].value.toString(16) +'">'+ permstr + '</span> ';
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "group_members",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
return data.length;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_groups(do_notify) {
|
||||
|
||||
get_request_api('groups/list')
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
current_groups_list = data.data;
|
||||
manage_groups_table.api().clear().rows.add(data.data).draw();
|
||||
|
||||
if (do_notify !== undefined) {
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the details of an user and allow modification */
|
||||
function group_detail(group_id) {
|
||||
url = 'groups/' + group_id + '/modal' + case_param();
|
||||
$('#modal_access_control').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_group').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = $('#form_new_group').serializeObject();
|
||||
post_request_api('/manage/groups/update/' + group_id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_access_control').modal({ show: true });
|
||||
}
|
||||
|
||||
function add_group() {
|
||||
url = '/manage/groups/add/modal' + case_param();
|
||||
$('#modal_access_control').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_group').on("click", function () {
|
||||
clear_api_error();
|
||||
var data_sent = $('#form_new_group').serializeObject();
|
||||
post_request_api('/manage/groups/add', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#modal_access_control').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
function delete_group(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this!\nPlease make sure a group remains with enough rights to avoid a lockdown!",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
var data_sent = {
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
}
|
||||
post_request_api('/manage/groups/delete/' + id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function remove_members_from_group(group_id, user_id, on_finish) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "This will remove the user from the group",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, remove it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
url = '/manage/groups/' + group_id + '/members/delete/' + user_id;
|
||||
var data_sent = {
|
||||
"csrf_token": $('#csrf_token').val()
|
||||
}
|
||||
post_request_api(url, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
refresh_group_members(group_id);
|
||||
|
||||
if (on_finish !== undefined) {
|
||||
on_finish();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function add_members_to_group(group_id) {
|
||||
url = 'groups/' + group_id + '/members/modal' + case_param();
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#save_group_members').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['group_members'] = $('#group_members').val();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('groups/' + group_id + '/members/update', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
refresh_group_members(group_id);
|
||||
$('#modal_ac_additional').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_group_members(group_id) {
|
||||
if (modal_group_table !== undefined) {
|
||||
get_request_api('/manage/groups/' + group_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
modal_group_table.clear();
|
||||
modal_group_table.rows.add(data.data.group_members).draw();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function refresh_group_cac(group_id) {
|
||||
if (modal_group_cac_table !== undefined) {
|
||||
get_request_api('/manage/groups/' + group_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
current_group_cases_access_list = data.data.group_cases_access;
|
||||
modal_group_cac_table.clear();
|
||||
modal_group_cac_table.rows.add(current_group_cases_access_list).draw();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function manage_group_cac(group_id) {
|
||||
url = 'groups/' + group_id + '/cases-access/modal' + case_param();
|
||||
|
||||
$('#manage_group_cac_button').text('Loading manager...');
|
||||
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
$('#manage_group_cac_button').text('Set case access');
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#grant_case_access_to_group').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['access_level'] = parseInt($('#group_case_ac_select').val());
|
||||
data_sent['cases_list'] = $('#group_case_access_select').val();
|
||||
data_sent['auto_follow_cases'] = $('#enable_auto_follow_cases').is(':checked');
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
window.swal({
|
||||
title: "Updating access",
|
||||
text: "Please wait. We are updating users access.",
|
||||
icon: "/static/assets/img/loader_cubes.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
|
||||
post_request_api('groups/' + group_id + '/cases-access/update', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_group_cac(group_id);
|
||||
$('#modal_ac_additional').modal('hide');
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
window.swal.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
function remove_case_access_from_group(group_id, case_id, on_finish) {
|
||||
remove_cases_access_group(group_id, [case_id], on_finish);
|
||||
}
|
||||
|
||||
function remove_group_cases_from_group_table(group_id, rows) {
|
||||
cases = [];
|
||||
for (cid in rows) {
|
||||
cases.push(rows[cid].case_id);
|
||||
}
|
||||
remove_cases_access_group(group_id, cases);
|
||||
}
|
||||
|
||||
function remove_cases_access_group(group_id, cases, on_finish) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "Members of this group won't be able to access these cases anymore",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, remove them!'
|
||||
}).then((willDelete) => {
|
||||
if (willDelete) {
|
||||
url = '/manage/groups/' + group_id + '/cases-access/delete';
|
||||
|
||||
window.swal({
|
||||
title: "Updating access",
|
||||
text: "Please wait. We are updating users access.",
|
||||
icon: "/static/assets/img/loader_cubes.gif",
|
||||
button: false,
|
||||
allowOutsideClick: false
|
||||
});
|
||||
var data_sent = Object();
|
||||
data_sent['cases'] = cases;
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api(url, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_group_cac(group_id);
|
||||
if (on_finish !== undefined) {
|
||||
on_finish();
|
||||
}
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
window.swal.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
refresh_groups();
|
||||
});
|
371
iris-web/source/app/static/assets/js/iris/manage.modules.js
Normal file
371
iris-web/source/app/static/assets/js/iris/manage.modules.js
Normal file
@ -0,0 +1,371 @@
|
||||
$('#form_new_module').submit(function () {
|
||||
|
||||
post_request_api('/manage/modules/add', $('form#form_new_module').serializeArray(), function() {
|
||||
$('#submit_new_module').text('Saving..')
|
||||
.attr("disabled", true)
|
||||
.removeClass('bt-outline-success')
|
||||
.addClass('btn-success', 'text-dark');
|
||||
})
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
})
|
||||
.always(() => {
|
||||
$('#submit_new_module')
|
||||
.attr("disabled", false)
|
||||
.addClass('bt-outline-success')
|
||||
.removeClass('btn-success', 'text-dark');
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
function add_module() {
|
||||
url = 'modules/add/modal' + case_param();
|
||||
$('#modal_add_module_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_module').on("click", function () {
|
||||
|
||||
post_request_api('modules/add', JSON.stringify($('#form_new_module').serializeObject()), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_modules(true);
|
||||
refresh_modules_hooks(true);
|
||||
$('#modal_add_module').modal('hide');
|
||||
} else {
|
||||
$('#alert_mod_add').text(data.message);
|
||||
if (data.data) {
|
||||
$('#details_list').empty();
|
||||
for(var i in data.data)
|
||||
{
|
||||
var output='<li>'+data.data[i]+'</li>';
|
||||
$('#details_list').append(output);
|
||||
}
|
||||
|
||||
$('#alert_mod_details').show();
|
||||
}
|
||||
$('#alert_mod_add').show();
|
||||
$('#submit_new_module').text("Retry");
|
||||
}
|
||||
})
|
||||
.fail((error) => {
|
||||
data = error.responseJSON;
|
||||
$('#submit_new_module').text('Save');
|
||||
$('#alert_mod_add').text(data.message);
|
||||
if (data.data && data.data.length > 0) {
|
||||
$('#details_list').empty();
|
||||
for(var i in data.data)
|
||||
{
|
||||
var output='<li>'+data.data[i]+'</li>';
|
||||
$('#details_list').append(output);
|
||||
}
|
||||
|
||||
$('#alert_mod_details').show();
|
||||
}
|
||||
$('#alert_mod_add').show();
|
||||
$('#submit_new_module').text("Retry");
|
||||
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_module').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#modules_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "modules/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 1, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{ 'data': 'id'},
|
||||
{ 'data': 'module_human_name'},
|
||||
{ 'data': 'has_pipeline',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'module_version',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'interface_version',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'date_added',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'name',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'is_active'},
|
||||
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function ( data, type, row ) {
|
||||
data = sanitizeHTML(data);
|
||||
return '<a href="#" onclick="module_detail(\'' + row['id'] + '\');">' + data +'</a>';
|
||||
},
|
||||
"targets": [0, 1]
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {
|
||||
if (data == true) {
|
||||
data = '<i class="fas fa-check text-success"></i>';
|
||||
} else {
|
||||
data = '<i class="fas fa-times text-warning"></i>';
|
||||
}
|
||||
if (row['configured'] == false) {
|
||||
return data + ' <i class="fas fa-exclamation-triangle text-warning" data-toggle="tooltip" data-placement="top" title="Module was disabled because mandatory settings are not set. Please configure to activate."></i>'
|
||||
} else { return data; }
|
||||
},
|
||||
"targets": [7]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_modules(silent) {
|
||||
$('#modules_table').DataTable().ajax.reload();
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
if (silent === undefined || silent !== true) {
|
||||
notify_success("Modules refreshed");
|
||||
}
|
||||
}
|
||||
|
||||
$('#hooks_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "modules/hooks/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 1, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{ 'data': 'id'},
|
||||
{ 'data': 'module_name',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'hook_name',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'hook_description',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ 'data': 'is_manual_hook',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (data == false) {
|
||||
data = "<i class='fas fa-check text-success'></i>";
|
||||
} else {
|
||||
data = "<i class='fas fa-times text-muted'></i>";
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ 'data': 'is_active',
|
||||
"render": function (data, type, row, meta) {
|
||||
if (data == true) {
|
||||
data = "<i class='fas fa-check text-success'></i>";
|
||||
} else {
|
||||
data = "<i class='fas fa-times text-muted'></i>";
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_modules_hooks(silent) {
|
||||
$('#hooks_table').DataTable().ajax.reload();
|
||||
if (silent === undefined || silent !== true) {
|
||||
notify_success("Hooks refreshed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function export_mod_config(module_id) {
|
||||
get_request_api('/manage/modules/export-config/' + module_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
download_file(data.data.module_name + "_configuration_export.json", "text/json",
|
||||
JSON.stringify(data.data.module_configuration, null, 4));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function import_mod_config(module_id){
|
||||
|
||||
var file = $("#input_configuration_file").get(0).files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
fileData = e.target.result
|
||||
var data = new Object();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
data['module_configuration'] = fileData;
|
||||
|
||||
post_request_api('/manage/modules/import-config/'+ module_id, JSON.stringify(data), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
module_detail(module_id);
|
||||
$('#modal_input_config').modal('hide');
|
||||
swal("Got news for you", data.message, "success");
|
||||
} else {
|
||||
swal("Got bad news for you", data.data, "error");
|
||||
}
|
||||
});
|
||||
};
|
||||
reader.readAsText(file)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Update the param of a module */
|
||||
function update_param(module_id, param_name) {
|
||||
url = 'modules/get-parameter/' + decodeURIComponent(escape(window.btoa(param_name))) + case_param();
|
||||
$('#modal_update_param_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#submit_save_parameter').on("click", function () {
|
||||
var data = Object();
|
||||
if ($('#editor_detail').length != 0) {
|
||||
editor = ace.edit("editor_detail");
|
||||
data['parameter_value'] = editor.getSession().getValue();
|
||||
data['csrf_token'] = $('#csrf_token').val();
|
||||
} else {
|
||||
data = $('#form_update_param').serializeObject();
|
||||
if ($('#parameter_value').attr('type') == "checkbox") {
|
||||
data['parameter_value'] = $('#parameter_value').prop('checked');
|
||||
}
|
||||
}
|
||||
|
||||
post_request_api('modules/set-parameter/' + decodeURIComponent(escape(window.btoa(param_name))), JSON.stringify(data))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
module_detail(module_id);
|
||||
refresh_modules(true);
|
||||
$('#modal_update_param').modal('hide');
|
||||
}
|
||||
})
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_update_param').modal({ show: true });
|
||||
}
|
||||
|
||||
/* Fetch the details of an module and allow modification */
|
||||
function module_detail(module_id) {
|
||||
url = 'modules/update/' + module_id + '/modal' + case_param();
|
||||
$('#modal_add_module_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_module').on("click", function () {
|
||||
post_request_api('modules/update/' + module_id, $('#form_new_module').serializeArray())
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
module_detail(module_id);
|
||||
$('#modal_update_param').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
});
|
||||
$('#modal_add_module').modal({ show: true });
|
||||
}
|
||||
|
||||
function remove_module(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "Please note this will only remove the reference of the module in Iris. The module will stay installed on the server.",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, remove it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/modules/remove/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_modules(true);
|
||||
refresh_modules_hooks(true);
|
||||
$('#modal_add_module').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function enable_module(module_id) {
|
||||
post_request_api('modules/enable/' + module_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_modules(true);
|
||||
refresh_modules_hooks(true);
|
||||
module_detail(module_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function disable_module(module_id) {
|
||||
post_request_api('modules/disable/' + module_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_modules(true);
|
||||
refresh_modules_hooks(true);
|
||||
module_detail(module_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
538
iris-web/source/app/static/assets/js/iris/manage.objects.js
Normal file
538
iris-web/source/app/static/assets/js/iris/manage.objects.js
Normal file
@ -0,0 +1,538 @@
|
||||
function add_asset_type() {
|
||||
url = '/manage/asset-type/add/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#form_new_asset_type').submit("click", function (event) {
|
||||
|
||||
|
||||
event.preventDefault();
|
||||
var formData = new FormData(this);
|
||||
|
||||
url = '/manage/asset-type/add' + case_param();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: formData,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (data) {
|
||||
if(notify_auto_api(data, true)) {
|
||||
refresh_asset_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
},
|
||||
error: function (error) {
|
||||
$('#modal_add_type').text('Save');
|
||||
propagate_form_api_errors(error.responseJSON.data);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
})};
|
||||
|
||||
$('#assets_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "/manage/asset-type/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "desc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "asset_name",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="assettype_detail(\'' + row['asset_id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "asset_description",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "asset_icon_not_compromised_path",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return '<img style="width:2em;height:2em" src=\'' + data + '\'>';
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "asset_icon_compromised_path",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return '<img style="width:2em;height:2em" src=\'' + data + '\'>';
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_asset_table() {
|
||||
$('#assets_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the details of an asset and allow modification */
|
||||
function assettype_detail(asset_id) {
|
||||
url = '/manage/asset-type/update/' + asset_id + '/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#form_new_asset_type').submit("click", function (event) {
|
||||
event.preventDefault();
|
||||
var formData = new FormData(this);
|
||||
|
||||
url = '/manage/asset-type/update/' + asset_id + case_param();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: formData,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (data) {
|
||||
if(notify_auto_api(data, true)) {
|
||||
refresh_asset_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
},
|
||||
error: function (jqXHR) {
|
||||
if(jqXHR.responseJSON && jqXHR.status == 400) {
|
||||
propagate_form_api_errors(jqXHR.responseJSON.data);
|
||||
} else {
|
||||
ajax_notify_error(jqXHR, this.url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
function delete_asset_type(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/asset-type/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_asset_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*** IOC Type ***/
|
||||
|
||||
function add_ioc_type() {
|
||||
let url = '/manage/ioc-types/add/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_ioc_type').on("click", function () {
|
||||
var form = $('form#form_new_ioc_type').serializeObject();
|
||||
|
||||
post_request_api('/manage/ioc-types/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_ioc_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$('#ioc_table').dataTable({
|
||||
"ajax": {
|
||||
"url": "/manage/ioc-types/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "type_name",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="ioc_type_detail(\'' + row['type_id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "type_description",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "type_taxonomy",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "type_validation_regex",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function refresh_ioc_table() {
|
||||
$('#ioc_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the details of an asset and allow modification */
|
||||
function ioc_type_detail(ioc_id) {
|
||||
url = '/manage/ioc-types/update/' + ioc_id + '/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_ioc_type').on("click", function () {
|
||||
var form = $('form#form_new_ioc_type').serializeObject();
|
||||
|
||||
post_request_api('/manage/ioc-types/update/' + ioc_id, JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_ioc_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
function delete_ioc_type(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/ioc-types/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_ioc_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*** Classification ***/
|
||||
|
||||
function add_classification() {
|
||||
url = '/manage/case-classifications/add/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function () {
|
||||
|
||||
$('#submit_new_case_classification').on("click", function () {
|
||||
var form = $('form#form_new_case_classification').serializeObject();
|
||||
|
||||
post_request_api('/manage/case-classifications/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_classification_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#classification_table').dataTable({
|
||||
"ajax": {
|
||||
"url": "/manage/case-classifications/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "name",
|
||||
"render": function ( data, type, row ) {
|
||||
return '<a href="#" onclick="classification_detail(\'' + row['id'] + '\');">' + sanitizeHTML(data) +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "name_expanded",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "description",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function refresh_classification_table() {
|
||||
$('#classification_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
/* Fetch the details of an classification and allow modification */
|
||||
function classification_detail(ioc_id) {
|
||||
url = '/manage/case-classifications/update/' + ioc_id + '/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_case_classification').on("click", function () {
|
||||
var form = $('form#form_new_case_classification').serializeObject();
|
||||
|
||||
post_request_api('/manage/case-classifications/update/' + ioc_id, JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_classification_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
function delete_case_classification(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/case-classifications/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_classification_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*** State ***/
|
||||
|
||||
function add_state() {
|
||||
url = '/manage/case-states/add/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function () {
|
||||
|
||||
$('#submit_new_case_state').on("click", function () {
|
||||
var form = $('form#form_new_case_state').serializeObject();
|
||||
|
||||
post_request_api('/manage/case-states/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_state_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#state_table').dataTable({
|
||||
"ajax": {
|
||||
"url": "/manage/case-states/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"order": [[ 0, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "state_name",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
if (row['protected'] === true) {
|
||||
return '<span href="#" "><i class="fa fa-lock mr-2" title="Protected state"></i>' + sanitizeHTML(data) + '</span>';
|
||||
}
|
||||
return '<a href="#" onclick="state_detail(\'' + row['state_id'] + '\');">' + sanitizeHTML(data) + '</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "state_description",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function refresh_state_table() {
|
||||
$('#state_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
/* Fetch the details of an state and allow modification */
|
||||
function state_detail(ioc_id) {
|
||||
url = '/manage/case-states/update/' + ioc_id + '/modal' + case_param();
|
||||
$('#modal_add_type_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_case_state').on("click", function () {
|
||||
var form = $('form#form_new_case_state').serializeObject();
|
||||
|
||||
post_request_api('/manage/case-states/update/' + ioc_id, JSON.stringify(form))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_state_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_type').modal({ show: true });
|
||||
}
|
||||
function delete_case_state(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/case-states/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_state_table();
|
||||
$('#modal_add_type').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
function update_settings() {
|
||||
var data_sent = $('form#form_srv_settings').serializeObject();
|
||||
data_sent['prevent_post_mod_repush'] = $('#prevent_post_mod_repush').is(":checked");
|
||||
data_sent['prevent_post_objects_repush'] = $('#prevent_post_objects_repush').is(":checked");
|
||||
data_sent['password_policy_upper_case'] = $('#password_policy_upper_case').is(":checked");
|
||||
data_sent['password_policy_lower_case'] = $('#password_policy_lower_case').is(":checked");
|
||||
data_sent['password_policy_digit'] = $('#password_policy_digit').is(":checked");
|
||||
|
||||
post_request_api('/manage/settings/update', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function init_db_backup() {
|
||||
|
||||
get_request_api('/manage/server/backups/make-db')
|
||||
.done((data) => {
|
||||
msg = ""
|
||||
for (idx in data.data) {
|
||||
msg += data.data[idx] + '\n';
|
||||
}
|
||||
swal("Done",
|
||||
msg,
|
||||
{
|
||||
icon: "success"
|
||||
});
|
||||
})
|
||||
.fail((error) => {
|
||||
for (idx in error.responseJSON.data) {
|
||||
msg += data.data[idx] + '\n';
|
||||
}
|
||||
|
||||
swal("Error",
|
||||
msg,
|
||||
{
|
||||
icon: "error"
|
||||
});
|
||||
});
|
||||
}
|
179
iris-web/source/app/static/assets/js/iris/manage.templates.js
Normal file
179
iris-web/source/app/static/assets/js/iris/manage.templates.js
Normal file
@ -0,0 +1,179 @@
|
||||
function add_report_template() {
|
||||
url = 'templates/add/modal' + case_param();
|
||||
$('#modal_report_template_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create the select picker for language */
|
||||
$('#report_language').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Language",
|
||||
style: "Bootstrap 4: 'btn-outline-primary'"
|
||||
});
|
||||
$('#report_type').selectpicker({
|
||||
liveSearch: true,
|
||||
title: "Report type",
|
||||
style: "Bootstrap 4: 'btn-outline-primary'"
|
||||
});
|
||||
$('#form_new_report_template').submit("click", function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
var formData = new FormData(this);
|
||||
|
||||
$.ajax({
|
||||
url: 'templates/add' + case_param(),
|
||||
type: "POST",
|
||||
data: formData,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (data) {
|
||||
if (notify_auto_api(data)) {
|
||||
refresh_template_table();
|
||||
$('#modal_add_report_template').modal('hide');
|
||||
}
|
||||
},
|
||||
error: function (error) {
|
||||
if(error.responseJSON) {
|
||||
notify_error(error.responseJSON.message);
|
||||
} else {
|
||||
ajax_notify_error(error, this.url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_add_report_template').modal({ show: true });
|
||||
}
|
||||
|
||||
$('#reports_table').dataTable( {
|
||||
"ajax": {
|
||||
"url": "templates/list" + case_param(),
|
||||
"contentType": "application/json",
|
||||
"type": "GET",
|
||||
"data": function ( d ) {
|
||||
if (d.status == 'success') {
|
||||
return JSON.stringify( d.data );
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoWidth": false,
|
||||
"columns": [
|
||||
{
|
||||
"data": "name",
|
||||
"render": function ( data, type, row ) {
|
||||
data = sanitizeHTML(data);
|
||||
return '<a href="#" onclick="delete_report(\'' + row['id'] + '\');">' + data +'</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "description",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "naming_format",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "date_created",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "created_by",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "code",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {return sanitizeHTML(data);},
|
||||
"data": "type_name",
|
||||
},
|
||||
{
|
||||
"render": function ( data, type, row ) {
|
||||
data = sanitizeHTML(data);
|
||||
return '<a href="templates/download/' + row["id"] + case_param() + '"><i class="fas fa-download"></i></a>';
|
||||
},
|
||||
"data": "id",
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_template_table() {
|
||||
$('#reports_table').DataTable().ajax.reload();
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the details of an asset and allow modification */
|
||||
function report_detail(report_id) {
|
||||
url = 'templates/update/' + report_id + case_param();
|
||||
$('#modal_report_template_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_report_template').on("click", function () {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: $('#form_new_report_template').serializeArray(),
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (notify_auto_api(data)) {
|
||||
refresh_template_table();
|
||||
$('#modal_add_report_template').modal('hide');
|
||||
}
|
||||
},
|
||||
error: function (error) {
|
||||
if(error.responseJSON) {
|
||||
notify_error(error.responseJSON.message);
|
||||
} else {
|
||||
ajax_notify_error(error, this.url);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_report_template').modal({ show: true });
|
||||
}
|
||||
|
||||
function delete_report(id) {
|
||||
|
||||
swal({
|
||||
title: "This will delete the report template\nAre you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
post_request_api('/manage/templates/delete/' + id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_template_table();
|
||||
$('#modal_add_report_template').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
337
iris-web/source/app/static/assets/js/iris/manage.users.js
Normal file
337
iris-web/source/app/static/assets/js/iris/manage.users.js
Normal file
@ -0,0 +1,337 @@
|
||||
var current_users_list = [];
|
||||
function add_user() {
|
||||
url = 'users/add/modal' + case_param();
|
||||
$('#modal_access_control').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_user').on("click", function () {
|
||||
|
||||
var data_sent = $('#form_new_user').serializeObject()
|
||||
clear_api_error();
|
||||
|
||||
post_request_api('users/add', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_users();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
});
|
||||
$('#modal_access_control').modal({ show: true });
|
||||
}
|
||||
|
||||
manage_users_table = $('#users_table').dataTable( {
|
||||
"order": [[ 1, "asc" ]],
|
||||
"autoWidth": false,
|
||||
"language": {
|
||||
"emptyTable": "Loading users..."
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"data": "user_id",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data)
|
||||
return '<a href="#" onclick="user_detail(\'' + row["user_id"] + '\');">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "user_name",
|
||||
"render": function ( data, type, row ) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data)
|
||||
return '<a href="#" onclick="user_detail(\'' + row["user_id"] + '\');">' + data +'</a>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "user_login",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "user_email",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "user_active",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (data == true) {
|
||||
data = '<span class="badge ml-2 badge-success">Active</span>';
|
||||
} else {
|
||||
data = '<span class="badge ml-2 badge-warning">Disabled</span>';
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "user_is_service_account",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (data == true) {
|
||||
data = '<i class="fa fa-check text-success"></i>';
|
||||
} else {
|
||||
data = '<i class="fa fa-xmark text-danger"></i>';
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
function refresh_users(do_notify) {
|
||||
|
||||
get_request_api('users/list')
|
||||
.done((data) => {
|
||||
|
||||
if(notify_auto_api(data, true)) {
|
||||
current_users_list = data.data;
|
||||
manage_users_table.api().clear().rows.add(data.data).draw();
|
||||
|
||||
if (do_notify !== undefined) {
|
||||
notify_success("Refreshed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Fetch the details of an user and allow modification */
|
||||
function user_detail(user_id, goto_tab) {
|
||||
url = 'users/' + user_id + '/modal' + case_param();
|
||||
$('#modal_access_control').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#submit_new_user').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = $('#form_new_user').serializeObject();
|
||||
post_request_api('/manage/users/update/' + user_id, JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_users();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
if (goto_tab !== undefined) {
|
||||
$('.nav-pills a[href="#'+ goto_tab +'"]').tab('show');
|
||||
}
|
||||
$('#modal_access_control').modal({ show: true });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function refresh_user_ac(user_id) {
|
||||
var ori_txt = $('#users_refresh_ac_btn').text();
|
||||
$('#users_refresh_ac_btn').text('Refreshing..');
|
||||
get_request_api('/manage/access-control/recompute-effective-user-ac/' + user_id)
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
}).always(() => {
|
||||
$('#users_refresh_ac_btn').text(ori_txt);
|
||||
});
|
||||
}
|
||||
|
||||
function delete_user(id) {
|
||||
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this !",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Yes, delete it!'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
var data_sent = {
|
||||
'csrf_token': $('#csrf_token').val()
|
||||
}
|
||||
post_request_api('/manage/users/delete/' + id, JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_users();
|
||||
$('#modal_access_control').modal('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function activate_user(user_id) {
|
||||
get_request_api('/manage/users/activate/' + user_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
user_detail(user_id);
|
||||
refresh_users();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deactivate_user(user_id) {
|
||||
get_request_api('/manage/users/deactivate/' + user_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
user_detail(user_id);
|
||||
refresh_users();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function remove_member_from_org_wrap(org_id, user_id) {
|
||||
remove_members_from_org(org_id, user_id, function() {
|
||||
user_detail(user_id, 'user_orgs_tab');
|
||||
});
|
||||
}
|
||||
|
||||
function remove_member_from_group_wrap(group_id, user_id) {
|
||||
remove_members_from_group(group_id, user_id, function() {
|
||||
user_detail(user_id, 'user_groups_tab');
|
||||
});
|
||||
}
|
||||
|
||||
function manage_user_groups(user_id) {
|
||||
url = 'users/' + user_id + '/groups/modal' + case_param();
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
|
||||
$('#save_user_groups_membership').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['groups_membership'] = $('#user_groups_membership').val();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/manage/users/' + user_id + '/groups/update', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_groups();
|
||||
user_detail(user_id, 'user_groups_tab');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function manage_user_organisations(user_id) {
|
||||
url = 'users/' + user_id + '/organisations/modal' + case_param();
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
|
||||
$('#save_user_orgs_membership').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = Object();
|
||||
data_sent['orgs_membership'] = $('#user_orgs_membership').val();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('/manage/users/' + user_id + '/organisations/update', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
user_detail(user_id, 'user_orgs_tab');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refresh_user_cac(user_id) {
|
||||
if (modal_user_cac_table !== undefined) {
|
||||
get_request_api('/manage/users/' + user_id)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
current_user_cases_access_list = data.data.user_cases_access;
|
||||
modal_user_cac_table.clear();
|
||||
modal_user_cac_table.rows.add(current_user_cases_access_list).draw();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function manage_user_cac(user_id) {
|
||||
url = 'users/' + user_id + '/cases-access/modal' + case_param();
|
||||
|
||||
$('#manage_user_cac_button').text('Loading manager...');
|
||||
|
||||
$('#modal_ac_additional').load(url, function (response, status, xhr) {
|
||||
$('#manage_user_cac_button').text('Set case access');
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#grant_case_access_to_user').on("click", function () {
|
||||
clear_api_error();
|
||||
|
||||
var data_sent = Object();
|
||||
|
||||
data_sent['cases_list'] = $('#user_case_access_select').val();
|
||||
data_sent['access_level'] = parseInt($('#user_case_ac_select').val());
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
|
||||
post_request_api('users/' + user_id + '/cases-access/update', JSON.stringify(data_sent))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
refresh_user_cac(user_id);
|
||||
$('#modal_ac_additional').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
$('#modal_ac_additional').modal({ show: true });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function remove_cases_access_from_user_table(org_id, rows) {
|
||||
cases = [];
|
||||
for (cid in rows) {
|
||||
cases.push(rows[cid].case_id);
|
||||
}
|
||||
remove_cases_access_user(org_id, cases);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
refresh_users();
|
||||
});
|
363
iris-web/source/app/static/assets/js/iris/overview.js
Normal file
363
iris-web/source/app/static/assets/js/iris/overview.js
Normal file
@ -0,0 +1,363 @@
|
||||
$.each($.find("table"), function(index, element){
|
||||
addFilterFields($(element).attr("id"));
|
||||
});
|
||||
var OverviewTable = $("#overview_table").DataTable({
|
||||
dom: '<"container-fluid"<"row"<"col"l><"col"f>>>rt<"container-fluid"<"row"<"col"i><"col"p>>>',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{
|
||||
data: "case_id",
|
||||
render: function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = `<span title="Quick look" class="bg-transparent btn-quick-view" style="cursor: pointer;" data-index="${meta.row}" ><i class="fa-solid fa-eye"></i></span>`;
|
||||
} else if (type === 'sort' || type === 'filter') {
|
||||
data = parseInt(row['case_id']);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
if (isWhiteSpace(data)) {
|
||||
data = '#' + row['case_id'];
|
||||
} else {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
data = '<a rel="noopener" title="Open case in new tab" target="_blank" href="case?cid='+ row['case_id'] + '">' + data +'</a>';
|
||||
} else if (type === 'sort' || type === 'filter') {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "client",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data.customer_name);
|
||||
} else if (type === 'sort' || type === 'filter') {
|
||||
data = sanitizeHTML(data.customer_name);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "classification",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data.name);
|
||||
} else if (data != null && (type === 'sort' || type === 'filter')) {
|
||||
data = data.name;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "state",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
let datar = sanitizeHTML(data.state_name);
|
||||
let review_status = row['review_status'] ? row['review_status'].status_name : 'Not reviewed';
|
||||
datar = `${datar} ${review_status === "Not reviewed"? '' : ' - ' + review_status}`;
|
||||
if (data.state_name === 'Closed') {
|
||||
datar = `<span class="badge badge-light"> Closed - ${review_status}</span>`;
|
||||
}
|
||||
return datar;
|
||||
} else if (data != null && (type === 'sort' || type === 'filter')) {
|
||||
let datar = sanitizeHTML(data.state_name);
|
||||
let review_status = row['review_status'] ? row['review_status'].status_name : 'Not reviewed';
|
||||
datar = `${datar} ${review_status === "Not reviewed"? '' : ' - ' + review_status}`;
|
||||
if (data.state_name === 'Closed') {
|
||||
datar = `Closed - ${review_status}`;
|
||||
}
|
||||
return datar;
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "tags",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
let output = '';
|
||||
for (let index in data) {
|
||||
let tag = sanitizeHTML(data[index].tag_title);
|
||||
output += `<span class="badge badge-pill badge-light">${tag}</span> `;
|
||||
}
|
||||
return output;
|
||||
} else if (type === 'sort' || type === 'filter') {
|
||||
let output = [];
|
||||
for (let index in data) {
|
||||
let tag = sanitizeHTML(data[index].tag_title);
|
||||
output.push(tag);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"data": "case_open_since_days",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
title = "You\'re not forgetting me, are you?";
|
||||
if (data <= 1) {
|
||||
data = `<i title="Sounds good" class="text-success fw-bold fa-solid fa-stopwatch mr-1"></i>${data} day`;
|
||||
}
|
||||
else if (data <= 7) {
|
||||
data = `<i title="Sounds good" class="text-success fw-bold fa-solid fa-stopwatch mr-1"></i>${data} days`;
|
||||
} else if (7 < data && data < 14) {
|
||||
data = `<i title="${title}" class="text-warning fw-bold fa-solid fa-stopwatch mr-1"></i>${data} days</div>`;
|
||||
} else {
|
||||
data = `<i title="${title}" class="text-danger fw-bold fa-solid fa-stopwatch mr-1"></i>${data} days</div>`;
|
||||
}
|
||||
} else if (type === 'sort' || type === 'filter') {
|
||||
data = parseInt(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "open_date",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
data = sanitizeHTML(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "tasks_status",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
now = (data.closed_tasks / (data.closed_tasks + data.open_tasks))*100;
|
||||
if (data.closed_tasks + data.open_tasks > 1) {
|
||||
tasks_text = `tasks`;
|
||||
} else {
|
||||
tasks_text = `task`;
|
||||
}
|
||||
data = `<div class="progress progress-sm">
|
||||
<div class="progress-bar bg-success" style="width:${now}%" role="progressbar" aria-valuenow="${now}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div><small class="float-right">${data.closed_tasks} / ${data.closed_tasks + data.open_tasks} ${tasks_text} done</small>`;
|
||||
} else if (data != null && (type === 'sort' || type === 'filter')) {
|
||||
data = data.closed_tasks / (data.closed_tasks + data.open_tasks);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "owner",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display' && data != null) {
|
||||
sdata = sanitizeHTML(data.user_name);
|
||||
data = `<div class="row">${get_avatar_initials(sdata, false, null, true)} <span class="ml-1">${sdata}</span></div>`;
|
||||
} else if (type === 'filter' || type === 'sort') {
|
||||
data = data.user_name;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
lengthChange: true,
|
||||
pageLength: 25,
|
||||
searchBuilder: {
|
||||
},
|
||||
language: {
|
||||
searchBuilder: {
|
||||
add: "Add filter",
|
||||
title: {
|
||||
_: 'Filters (%d)',
|
||||
0: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
order: [[ 1, "asc" ]],
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
],
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.childRow,
|
||||
renderer: $.fn.dataTable.Responsive.renderer.tableAll()
|
||||
}
|
||||
},
|
||||
select: true,
|
||||
initComplete: function () {
|
||||
tableFiltering(this.api(), 'overview_table', [0]);
|
||||
},
|
||||
drawCallback: function () {
|
||||
$('.btn-quick-view').off('click').on('click', function() {
|
||||
show_case_view($(this).data('index'));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
OverviewTable.searchBuilder.container().appendTo($('#table_buttons'));
|
||||
|
||||
function get_cases_overview(silent, show_full=false) {
|
||||
show_full = show_full || $('#overviewLoadClosedCase').prop('checked');
|
||||
|
||||
$('#overviewTableTitle').text(show_full ? 'All cases' : 'Open cases');
|
||||
|
||||
get_raw_request_api('/overview/filter?cid=' + get_caseid() + (show_full ? '&show_closed=true' : ''))
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, silent)) {
|
||||
overview_list = data.data;
|
||||
OverviewTable.clear();
|
||||
OverviewTable.rows.add(overview_list);
|
||||
OverviewTable.columns.adjust().draw();
|
||||
$(".truncate").on("click", function() {
|
||||
var index = $(this).index() + 1;
|
||||
$('table tr td:nth-child(' + index + ')').toggleClass("truncate");
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function show_case_view(row_index) {
|
||||
let case_data = OverviewTable.row(row_index).data();
|
||||
$('#caseViewModal').find('.modal-title').text(case_data.name);
|
||||
$('#caseViewModal').find('.modal-subtitle').text(case_data.case_uuid);
|
||||
|
||||
let body = $('#caseViewModal').find('.modal-body .container');
|
||||
body.empty();
|
||||
|
||||
// Owner Card
|
||||
let owner_card = $('<div/>').addClass('card mb-3');
|
||||
let owner_body = $('<div/>').addClass('card-body');
|
||||
owner_body.append($('<h2/>').addClass('card-title mb-2').text('Metadata'));
|
||||
|
||||
let owner_row = $('<div/>').addClass('row');
|
||||
let owner_col1 = $('<div/>').addClass('col-md-6');
|
||||
let owner_col2 = $('<div/>').addClass('col-md-6');
|
||||
let timeSinceLastUpdateStr = '';
|
||||
let modifications = case_data.modification_history;
|
||||
if (modifications != null) {
|
||||
let timestamps = Object.keys(modifications).map(parseFloat);
|
||||
let lastUpdatedTimestamp = Math.max(...timestamps);
|
||||
|
||||
let currentTime = Date.now() / 1000; // convert to seconds
|
||||
let timeSinceLastUpdate = currentTime - lastUpdatedTimestamp;
|
||||
let timeSinceLastUpdateInSeconds = currentTime - lastUpdatedTimestamp;
|
||||
|
||||
let timeSinceLastUpdateInMinutes = timeSinceLastUpdate / 60;
|
||||
let timeSinceLastUpdateInHours = timeSinceLastUpdateInMinutes / 60;
|
||||
let timeSinceLastUpdateInDays = timeSinceLastUpdateInHours / 24;
|
||||
|
||||
|
||||
if (timeSinceLastUpdateInSeconds < 60) {
|
||||
timeSinceLastUpdateStr = `${Math.round(timeSinceLastUpdateInSeconds)} second(s) ago`;
|
||||
} else if (timeSinceLastUpdateInMinutes < 60) {
|
||||
timeSinceLastUpdateStr = `${Math.round(timeSinceLastUpdateInMinutes)} minute(s) ago`;
|
||||
} else if (timeSinceLastUpdateInHours < 24) {
|
||||
timeSinceLastUpdateStr = `${Math.round(timeSinceLastUpdateInHours)} hour(s) ago`;
|
||||
} else {
|
||||
timeSinceLastUpdateStr = `${Math.round(timeSinceLastUpdateInDays)} day(s) ago`;
|
||||
}
|
||||
} else {
|
||||
timeSinceLastUpdateStr = 'Never';
|
||||
}
|
||||
|
||||
let tagsStr = '';
|
||||
for (let index in case_data.tags) {
|
||||
let tag = sanitizeHTML(case_data.tags[index].tag_title);
|
||||
tagsStr += `<span class="badge badge-pill badge-light">${tag}</span> `;
|
||||
}
|
||||
|
||||
let owner_dl1 = $('<dl class="row"/>');
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Owner:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(case_data.owner.user_name));
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Opening User:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(case_data.user.user_name));
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Open Date:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(case_data.open_date));
|
||||
|
||||
if (case_data.close_date != null) {
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Close Date:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(case_data.close_date))
|
||||
}
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Tags:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').html(tagsStr !== ''? tagsStr : 'No tags'));
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('State:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(case_data.state ? case_data.state.state_description: 'None'));
|
||||
owner_dl1.append($('<dt class="col-sm-3"/>').text('Last update:'));
|
||||
owner_dl1.append($('<dd class="col-sm-8"/>').text(timeSinceLastUpdateStr));
|
||||
|
||||
|
||||
owner_col1.append(owner_dl1);
|
||||
|
||||
|
||||
|
||||
let owner_dl2 = $('<dl class="row"/>');
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Customer Name:'));
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text(case_data.client.customer_name));
|
||||
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Classification:'));
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text(case_data.classification ? case_data.classification.name: 'None'));
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('SOC ID:'));
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text(case_data.soc_id !== '' ? case_data.soc_id : 'None'));
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Related alerts:'));
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').html(`<a target="_blank" rel="noopener" href='/alerts?case_id=${case_data.case_id}'>${case_data.alerts.length} related alert(s) <i class="fa-solid fa-up-right-from-square ml-2"></i></a>`));
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Tasks:'));
|
||||
if (case_data.tasks_status != null) {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').html(`<a target="_blank" rel="noopener" href='/case/tasks?cid=${case_data.case_id}'>${case_data.tasks_status.closed_tasks}/${case_data.tasks_status.open_tasks + case_data.tasks_status.closed_tasks} task(s) <i class="fa-solid fa-up-right-from-square ml-2"></i></a>`));
|
||||
} else {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text('No tasks'));
|
||||
}
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Review:'));
|
||||
if (case_data.review_status != null) {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text(case_data.review_status.status_name));
|
||||
} else {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text('No review'));
|
||||
}
|
||||
owner_dl2.append($('<dt class="col-sm-3"/>').text('Reviewer:'));
|
||||
if (case_data.reviewer != null) {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text(case_data.reviewer.user_name));
|
||||
} else {
|
||||
owner_dl2.append($('<dd class="col-sm-8"/>').text('No reviewer'));
|
||||
}
|
||||
owner_col2.append(owner_dl2);
|
||||
|
||||
owner_row.append(owner_col1);
|
||||
owner_row.append(owner_col2);
|
||||
owner_body.append(owner_row);
|
||||
owner_body.append(`<a type="button" class="btn btn-sm btn-dark float-right" target="_blank" rel="noopener" href='/case?cid=${case_data.case_id}'><i class="fa-solid fa-up-right-from-square mr-2"></i> View case</a>`);
|
||||
|
||||
owner_card.append(owner_body);
|
||||
body.append(owner_card);
|
||||
|
||||
// Description Card
|
||||
let desc_card = $('<div/>').addClass('card mb-3');
|
||||
let desc_body = $('<div/>').addClass('card-body');
|
||||
desc_body.append($('<h2/>').addClass('card-title mb-3').text('Summary'));
|
||||
let converter = get_showdown_convert();
|
||||
let html = converter.makeHtml(case_data.description);
|
||||
desc_body.append($('<div/>').addClass('card-text').html(html));
|
||||
|
||||
desc_card.append(desc_body);
|
||||
body.append(desc_card);
|
||||
|
||||
|
||||
$('#caseViewModal').modal('show');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
get_cases_overview(true);
|
||||
|
||||
|
||||
$('#overviewLoadClosedCase').change(function() {
|
||||
get_cases_overview(true, this.checked);
|
||||
});
|
||||
|
||||
});
|
209
iris-web/source/app/static/assets/js/iris/search.js
Normal file
209
iris-web/source/app/static/assets/js/iris/search.js
Normal file
@ -0,0 +1,209 @@
|
||||
$('#search_value').keypress(function(event){
|
||||
var keycode = (event.keyCode ? event.keyCode : event.which);
|
||||
if(keycode == '13'){
|
||||
jQuery(this).blur();
|
||||
jQuery('#submit_search').focus().click();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Table_1 = $("#file_search_table_1").DataTable({
|
||||
dom: 'Bfrtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{ "data": "ioc_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
if (row['ioc_misp'] != null) {
|
||||
jse = JSON.parse(row['ioc_misp']);
|
||||
data += `<i class="fas fa-exclamation-triangle ml-2 text-warning" style="cursor: pointer;" data-html="true"
|
||||
data-toggle="popover" data-trigger="hover" title="Seen on MISP" data-content="Has been seen on <a href='` + row['misp_link'] + `/events/view/` + jse.misp_id +`'>this event</a><br/><br/><b>Description: </b>`+ jse.misp_desc +`"></i>`;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "ioc_description",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" data-trigger="hover" title="Description" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "type_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}},
|
||||
{ "data": "case_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<a target="_blank" href="case?cid='+ row["case_id"] +'">' + data + '</a>';
|
||||
}
|
||||
return data;
|
||||
}},
|
||||
{ "data": "customer_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
} },
|
||||
{ "data": "tlp_name",
|
||||
"render": function(data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<span class="badge badge-'+ row['tlp_bscolor'] +' ml-2">tlp:' + data + '</span>';
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
]
|
||||
});
|
||||
$("#file_search_table_1").css("font-size", 12);
|
||||
|
||||
Table_comments = $("#comments_search_table").DataTable({
|
||||
dom: 'Bfrtip',
|
||||
aaData: [],
|
||||
aoColumns: [
|
||||
{ "data": "comment_id",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
if (row['ioc_misp'] != null) {
|
||||
jse = JSON.parse(row['ioc_misp']);
|
||||
data += `<i class="fas fa-exclamation-triangle ml-2 text-warning" style="cursor: pointer;" data-html="true"
|
||||
data-toggle="popover" data-trigger="hover" title="Seen on MISP" data-content="Has been seen on <a href='` + row['misp_link'] + `/events/view/` + jse.misp_id +`'>this event</a><br/><br/><b>Description: </b>`+ jse.misp_desc +`"></i>`;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "comment_text",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
datas = '<span data-toggle="popover" style="cursor: pointer;" data-trigger="hover" title="Description" data-content="' + data + '">' + data.slice(0, 70);
|
||||
|
||||
if (data.length > 70) {
|
||||
datas += ' (..)</span>';
|
||||
} else {
|
||||
datas += '</span>';
|
||||
}
|
||||
return datas;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "case_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') {
|
||||
data = sanitizeHTML(data);
|
||||
data = '<a target="_blank" href="case?cid='+ row["case_id"] +'">' + data + '</a>';
|
||||
}
|
||||
return data;
|
||||
}},
|
||||
{ "data": "customer_name",
|
||||
"render": function (data, type, row, meta) {
|
||||
if (type === 'display') { data = sanitizeHTML(data);}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
],
|
||||
filter: true,
|
||||
info: true,
|
||||
ordering: true,
|
||||
processing: true,
|
||||
retrieve: true,
|
||||
buttons: [
|
||||
{ "extend": 'csvHtml5', "text":'Export',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
{ "extend": 'copyHtml5', "text":'Copy',"className": 'btn btn-primary btn-border btn-round btn-sm float-left mr-4 mt-2' },
|
||||
]
|
||||
});
|
||||
$("#comments_search_table").css("font-size", 12);
|
||||
|
||||
$('#submit_search').click(function () {
|
||||
search();
|
||||
});
|
||||
|
||||
|
||||
function search() {
|
||||
var data_sent = $('form#form_search').serializeObject();
|
||||
data_sent['csrf_token'] = $('#csrf_token').val();
|
||||
post_request_api('/search', JSON.stringify(data_sent), true, function (data) {
|
||||
$('#submit_search').text("Searching...");
|
||||
})
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
$('#notes_msearch_list').empty();
|
||||
Table_1.clear();
|
||||
Table_comments.clear();
|
||||
$('#search_table_wrapper_1').hide();
|
||||
$('#search_table_wrapper_2').hide();
|
||||
$('#search_table_wrapper_3').hide();
|
||||
val = $("input[type='radio']:checked").val();
|
||||
if (val == "ioc") {
|
||||
Table_1.rows.add(data.data);
|
||||
Table_1.columns.adjust().draw();
|
||||
$('#search_table_wrapper_1').show();
|
||||
|
||||
$('#search_table_wrapper_1').on('click', function(e){
|
||||
if($('.popover').length>1)
|
||||
$('.popover').popover('hide');
|
||||
$(e.target).popover('toggle');
|
||||
});
|
||||
}
|
||||
else if (val == "notes") {
|
||||
for (e in data.data) {
|
||||
li = `<li class="list-group-item">
|
||||
<span class="name" style="cursor:pointer" title="Click to open note" onclick="note_in_details(${data.data[e]['note_id']}, ${data.data[e]['case_id']});">`+ sanitizeHTML(data.data[e]['note_title']) + ` - ` + sanitizeHTML(data.data[e]['case_name']) + ` - ` + sanitizeHTML(data.data[e]['client_name']) +`</span>
|
||||
</li>`
|
||||
$('#notes_msearch_list').append(li);
|
||||
}
|
||||
$('#search_table_wrapper_2').show();
|
||||
} else if (val == "comments") {
|
||||
Table_comments.rows.add(data.data);
|
||||
Table_comments.columns.adjust().draw();
|
||||
$('#search_table_wrapper_3').show();
|
||||
|
||||
$('#search_table_wrapper_3').on('click', function(e){
|
||||
if($('.popover').length>1)
|
||||
$('.popover').popover('hide');
|
||||
$(e.target).popover('toggle');
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
$('#submit_search').text("Search");
|
||||
});
|
||||
}
|
||||
|
||||
function note_in_details(note_id, case_id) {
|
||||
window.open("/case/notes?cid=" + case_id + "&shared=" + note_id);
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#search_value').focus();
|
||||
});
|
174
iris-web/source/app/static/assets/js/iris/updates.handler.js
Normal file
174
iris-web/source/app/static/assets/js/iris/updates.handler.js
Normal file
@ -0,0 +1,174 @@
|
||||
channel = 'iris_update_status';
|
||||
|
||||
function log_error(message) {
|
||||
add_update_log(message, true);
|
||||
}
|
||||
|
||||
function log_msg(message) {
|
||||
add_update_log(message, false)
|
||||
}
|
||||
|
||||
function add_update_log(message, is_error) {
|
||||
html_wrap = `<h4><i class="mt-2 fas fa-check text-success"></i> `
|
||||
if (is_error) {
|
||||
html_wrap = `<h4><i class="mt-2 fas fa-times text-danger"></i> `
|
||||
}
|
||||
$("#updates_log").append(html_wrap + message + '</h4><br/>')
|
||||
$('html, body').animate({
|
||||
scrollTop: $("#updates_log_end").offset().top
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function get_caseid() {
|
||||
queryString = window.location.search;
|
||||
urlParams = new URLSearchParams(queryString);
|
||||
|
||||
return urlParams.get('cid')
|
||||
}
|
||||
|
||||
function case_param() {
|
||||
var params = {
|
||||
cid: get_caseid
|
||||
}
|
||||
return '?'+ $.param(params);
|
||||
}
|
||||
|
||||
function initiate_update() {
|
||||
$.ajax({
|
||||
url: '/manage/server/start-update' + case_param(),
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
beforeSend : function () {
|
||||
log_msg('Update order sent. Expecting feedback anytime soon');
|
||||
},
|
||||
success: function (data) {},
|
||||
error: function (data) {
|
||||
log_error('Unexpected error starting update');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var intervalId = null;
|
||||
var ios = io('/server-updates');
|
||||
var update_socket = null;
|
||||
var current_version = null;
|
||||
var updated_version = null;
|
||||
var steps = 0;
|
||||
var no_resp_time = 0;
|
||||
|
||||
function check_server_version() {
|
||||
$.ajax({
|
||||
url: '/api/versions' + case_param(),
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
timeout: 1000,
|
||||
success: function (data) {
|
||||
server_version = data.data.iris_current;
|
||||
if (server_version == current_version) {
|
||||
add_update_log('Something was wrong - server is still in the same version', true);
|
||||
add_update_log('Please check server logs', true);
|
||||
clearInterval(intervalId);
|
||||
$('#tag_bottom').hide();
|
||||
$('#update_return_button').show();
|
||||
} else {
|
||||
add_update_log('Successfully updated from ' + current_version + ' to ' + server_version, false);
|
||||
add_update_log('You can now leave this page', false);
|
||||
clearInterval(intervalId);
|
||||
$('#tag_bottom').hide();
|
||||
$('#update_return_button').show();
|
||||
}
|
||||
},
|
||||
error: function (error) {
|
||||
log_error('Something\'s wrong, server is not answering');
|
||||
log_error('Please check server logs')
|
||||
clearInterval(intervalId);
|
||||
$('#tag_bottom').hide();
|
||||
$('#update_return_button').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ping_check_server_online() {
|
||||
|
||||
$.ajax({
|
||||
url: '/api/ping' + case_param(),
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
timeout: 1000,
|
||||
success: function (data) {
|
||||
$("#offline_time").hide();
|
||||
log_msg('Server is back online');
|
||||
clearInterval(intervalId);
|
||||
check_server_version();
|
||||
},
|
||||
error: function (error) {
|
||||
no_resp_time += 1;
|
||||
if (no_resp_time > 29) {
|
||||
log_error('Something\'s wrong, server is not answering');
|
||||
log_error('Please check server logs')
|
||||
clearInterval(intervalId);
|
||||
$('#tag_bottom').hide();
|
||||
$('#update_return_button').show();
|
||||
}
|
||||
$("#offline_time").html('<h4 id="offline_time"><i class="fas fa-clock"></i> Attempt '+ no_resp_time +' / 30</h4><br/>');
|
||||
$("#offline_time").show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function start_updates(){
|
||||
$('#update_start_btn').hide();
|
||||
$('.update_start_txt').hide();
|
||||
$('#container-updates').show();
|
||||
update_socket.emit('update_get_current_version', { 'channel': channel });
|
||||
update_socket.emit('update_ping', { 'channel': channel });
|
||||
// index = 0;
|
||||
// while(index < 20) {
|
||||
// add_update_log('ping');
|
||||
// index += 1;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
update_socket = ios.connect();
|
||||
|
||||
update_socket.on( "update_status", function(data) {
|
||||
add_update_log(data.message, data.is_error)
|
||||
}.bind() );
|
||||
|
||||
update_socket.on( "update_ping", function(data) {
|
||||
log_msg('Server connection verified');
|
||||
log_msg('Starting update');
|
||||
initiate_update();
|
||||
}.bind() );
|
||||
|
||||
update_socket.on( "server_has_updated", function(data) {
|
||||
log_msg('Server reported updates applied. Checking . . .');
|
||||
check_server_version();
|
||||
}.bind() );
|
||||
|
||||
update_socket.on('disconnect', function () {
|
||||
add_update_log('Server is offline, waiting for connection', false);
|
||||
intervalId = window.setInterval(function(){
|
||||
ping_check_server_online();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
update_socket.on('update_current_version', function (data) {
|
||||
add_update_log('Server reported version ' + data.version , false);
|
||||
if (current_version == null) {
|
||||
current_version = data.version;
|
||||
}
|
||||
});
|
||||
|
||||
update_socket.on('update_has_fail', function () {
|
||||
$('#tag_bottom').hide();
|
||||
$('#update_return_button').show();
|
||||
});
|
||||
|
||||
update_socket.emit('join-update', { 'channel': channel });
|
||||
|
||||
|
||||
});
|
104
iris-web/source/app/static/assets/js/iris/user.js
Normal file
104
iris-web/source/app/static/assets/js/iris/user.js
Normal file
@ -0,0 +1,104 @@
|
||||
function renew_api() {
|
||||
swal({
|
||||
title: "Are you sure?",
|
||||
text: "The current key will be revoked and cannot be used anymore",
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Go for it'
|
||||
})
|
||||
.then((willDelete) => {
|
||||
if (willDelete) {
|
||||
get_request_api('/user/token/renew')
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
location.reload(true);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
swal("Pfew, that was close");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function save_user_password() {
|
||||
clear_api_error();
|
||||
|
||||
if ( $('#user_password').val() != $('#user_password_v').val()) {
|
||||
$('#user_password').addClass('is-invalid');
|
||||
$('#user_password').after("<div class='invalid-feedback' id='user_password-invalid-msg'>Password and verification are not the same</div>");
|
||||
$('#user_password').show();
|
||||
return False;
|
||||
}
|
||||
|
||||
var data_sent = $('#form_update_pwd').serializeObject();
|
||||
data_sent['user_password'] = $('#user_password').val();
|
||||
|
||||
post_request_api('update', JSON.stringify(data_sent), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
$('#modal_pwd_user').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Fetch the details of an user and allow modification */
|
||||
function update_password(user_id) {
|
||||
url = 'update/modal' + case_param();
|
||||
$('#modal_pwd_user_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('#modal_pwd_user').modal({ show: true });
|
||||
}
|
||||
|
||||
function refresh_user_permissions() {
|
||||
var ori_txt = $('#user_refresh_perms_btn').text();
|
||||
$('#user_refresh_perms_btn').text('Refreshing..');
|
||||
get_request_api('refresh-permissions')
|
||||
.done((data) => {
|
||||
notify_auto_api(data);
|
||||
}).always(() => {
|
||||
$('#user_refresh_perms_btn').text(ori_txt);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
$('input[type=radio][name=iris-theme]').change(function() {
|
||||
if (this.value == 'false') {
|
||||
theme = 'light'
|
||||
}
|
||||
else if (this.value == 'true') {
|
||||
theme = 'dark';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
get_request_api('theme/set/'+ theme)
|
||||
.done((data) => {
|
||||
if (notify_auto_api(data, true)) {
|
||||
location.reload(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('input[type=radio][name=user-has-deletion-prompt]').change(function() {
|
||||
if (this.value == 'false') {
|
||||
do_prompt = false;
|
||||
}
|
||||
else if (this.value == 'true') {
|
||||
do_prompt = true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
get_request_api('deletion-prompt/set/'+ do_prompt)
|
||||
.then((data) => {
|
||||
if (notify_auto_api(data)) {
|
||||
userWhoamiRequest(true);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
117
iris-web/source/app/static/assets/js/iris/view.customers.js
Normal file
117
iris-web/source/app/static/assets/js/iris/view.customers.js
Normal file
@ -0,0 +1,117 @@
|
||||
|
||||
function delete_contact(contact_id, customer_id) {
|
||||
post_request_api('/manage/customers/' + customer_id + '/contacts/' + contact_id + '/delete', null, true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function edit_contact(contact_id, customer_id) {
|
||||
url = '/manage/customers/' + customer_id + '/contacts/' + contact_id + '/modal' + case_param();
|
||||
$('#modal_add_contact_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#form_new_contact').on("submit", preventFormDefaultBehaviourOnSubmit);
|
||||
$('#submit_new_contact').on("click", function () {
|
||||
|
||||
const form = $('#form_new_contact').serializeObject();
|
||||
|
||||
post_request_api('/manage/customers/' + customer_id + '/contacts/' + contact_id + '/update', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
$('#submit_delete_contact').on("click", function () {
|
||||
post_request_api('/manage/customers/' + customer_id + '/contacts/' + contact_id + '/delete')
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
$('#modal_add_contact').modal({show: true});
|
||||
}
|
||||
|
||||
function add_new_contact(customer_id) {
|
||||
url = '/manage/customers/' + customer_id + '/contacts/add/modal' + case_param();
|
||||
$('#modal_add_contact_content').load(url, function (response, status, xhr) {
|
||||
if (status !== "success") {
|
||||
ajax_notify_error(xhr, url);
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#form_new_contact').on("submit", preventFormDefaultBehaviourOnSubmit);
|
||||
$('#submit_new_contact').on("click", function () {
|
||||
|
||||
const form = $('#form_new_contact').serializeObject();
|
||||
|
||||
post_request_api('/manage/customers/' + customer_id + '/contacts/add', JSON.stringify(form), true)
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data)) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
$('#modal_add_contact').modal({show: true});
|
||||
}
|
||||
|
||||
function load_customer_stats(customer_id) {
|
||||
get_request_api('/manage/customers/' + customer_id + '/cases')
|
||||
.done((data) => {
|
||||
if(notify_auto_api(data, true)) {
|
||||
$('#last_month_cases').text(data.data.stats.cases_last_month);
|
||||
$('#last_year_cases').text(data.data.stats.cases_last_year);
|
||||
$('#cases_last_month').text(data.data.stats.cases_last_month);
|
||||
$('#cases_current_month').text(data.data.stats.cases_current_month);
|
||||
$('#cases_current_year').text(data.data.stats.cases_current_year);
|
||||
$('#current_open_cases').text(data.data.stats.open_cases);
|
||||
$('#cases_total').text(data.data.stats.cases_total);
|
||||
$('#ratio_year').text(data.data.stats.ratio_year);
|
||||
$('#average_case_duration').text(data.data.stats.average_case_duration);
|
||||
|
||||
if (data.data.stats.ratio_year > 0) {
|
||||
$('#ratio_year').addClass('text-warning');
|
||||
$('#ratio_year').html(`+${data.data.stats.ratio_year}% <i class="ml-1 fa fa-chevron-up"></i>`);
|
||||
} else if (data.data.stats.ratio_year < 0) {
|
||||
$('#ratio_year').addClass('text-success');
|
||||
$('#ratio_year').html(`${data.data.stats.ratio_year}% <i class="ml-1 fa fa-chevron-down"></i>`);
|
||||
}
|
||||
|
||||
if (data.data.stats.ratio_month > 0) {
|
||||
$('#ratio_month').addClass('text-warning');
|
||||
$('#ratio_month').html(`+${data.data.stats.ratio_month}% <i class="ml-1 fa fa-chevron-up"></i>`);
|
||||
} else if (data.data.stats.ratio_month < 0) {
|
||||
$('#ratio_month').addClass('text-success');
|
||||
$('#ratio_month').html(`${data.data.stats.ratio_month}% <i class="ml-1 fa fa-chevron-down"></i>`);
|
||||
}
|
||||
|
||||
$('#last_year').text(data.data.stats.last_year);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
customer_id = $('#customer_id').val();
|
||||
load_customer_stats(customer_id);
|
||||
|
||||
});
|
Reference in New Issue
Block a user