mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-30 16:09:32 +00:00
679 lines
26 KiB
JavaScript
679 lines
26 KiB
JavaScript
/**
|
|
(C) 2022 - ntop.org
|
|
*/
|
|
|
|
export const ntopng_sync = function () {
|
|
let components_ready = {};
|
|
let subscribers = [];
|
|
return {
|
|
ready: function (component_name) {
|
|
components_ready[component_name] = true;
|
|
subscribers.filter((s) => s.component_name == component_name).forEach((s) => s.resolve());
|
|
subscribers = subscribers.filter((s) => s.component_name != component_name);
|
|
},
|
|
on_ready: function (component_name) {
|
|
return new Promise((resolve, rejevt) => {
|
|
if (components_ready[component_name]) {
|
|
resolve();
|
|
return;
|
|
}
|
|
subscribers.push({ resolve, component_name, completed: false });
|
|
});
|
|
},
|
|
};
|
|
}();
|
|
|
|
/**
|
|
* Utility globals functions.
|
|
*/
|
|
export const ntopng_utility = function () {
|
|
let global_http_headers = {};
|
|
return {
|
|
is_array: function (e) {
|
|
return Array.isArray(e);
|
|
},
|
|
is_object: function (e) {
|
|
return typeof e === 'object'
|
|
&& !this.is_array(e)
|
|
&& e !== null;
|
|
},
|
|
/**
|
|
* Deep copy of a object.
|
|
* @param {object} obj.
|
|
* @returns {object}.
|
|
*/
|
|
clone: function (obj) {
|
|
if (obj == null) { return null; }
|
|
if (this.is_object(obj)) {
|
|
/* This does the deep copy using jquery for objects */
|
|
return $.extend(true, {}, obj);
|
|
} else if (Array.isArray(obj)) {
|
|
/* This does the deep copy using jquery for other types */
|
|
let res = [];
|
|
for (let i = 0; i < obj.length; i += 1) {
|
|
let el = this.clone(obj[i]);
|
|
res.push(el);
|
|
}
|
|
return res;
|
|
} else {
|
|
// return JSON.parse(JSON.stringify(obj))
|
|
return obj;
|
|
}
|
|
},
|
|
object_to_array: function (obj) {
|
|
if (obj == null) { return []; }
|
|
let array = [];
|
|
for (let key in obj) {
|
|
array.push(obj[key]);
|
|
}
|
|
return array;
|
|
},
|
|
get_utc_seconds: function (utc_ms) {
|
|
if (utc_ms == null) { utc_ms = Date.now(); }
|
|
return Number.parseInt(utc_ms / 1000);
|
|
},
|
|
get_timeframes_dict: function () {
|
|
const min = 60;
|
|
let t_day = new Date();
|
|
let t_week = new Date();
|
|
let t_month = new Date();
|
|
let t_year = new Date();
|
|
return {
|
|
"live": 0,
|
|
"min": min,
|
|
"5_min": min * 5,
|
|
"10_min": min * 10,
|
|
"30_min": min * 30,
|
|
hour: min * 60,
|
|
"2_hours": 2 * min * 60,
|
|
"6_hours": 6 * min * 60,
|
|
"12_hours": 12 * min * 60,
|
|
day: this.get_utc_seconds(Date.now() - t_day.setDate(t_day.getDate() - 1)),
|
|
week: this.get_utc_seconds(Date.now() - t_week.setDate(t_week.getDate() - 7)),
|
|
month: this.get_utc_seconds(Date.now() - t_month.setMonth(t_month.getMonth() - 1)),
|
|
year: this.get_utc_seconds(Date.now() - t_year.setMonth(t_year.getMonth() - 12)),
|
|
};
|
|
},
|
|
// given valid interval string get time in seconds
|
|
get_timeframe_from_timeframe_id: function (timeframe_id) {
|
|
let timeframes_dict = this.get_timeframes_dict();
|
|
// timeframes_dict[interval_string] == null => key is not present
|
|
if (timeframes_dict[timeframe_id] == null) {
|
|
throw `Wrong timeframe_id passed ${timeframe_id}, valid intervals are: ${Object.keys(timeframes_dict).join(", ")}`;
|
|
}
|
|
return timeframes_dict[timeframe_id];
|
|
},
|
|
round_time_by_timeframe_id: function (ts, timeframe_id) {
|
|
const timeframe = this.get_timeframe_from_timeframe_id(timeframe_id);
|
|
if (timeframe) {
|
|
return ts - (ts % timeframe);
|
|
}
|
|
return ts
|
|
},
|
|
// method to set default epoch begin to 30_min ago
|
|
set_default_time_interval: function (time_interval_id = "30_min", round_timeframe_id) {
|
|
let epoch = {
|
|
epoch_begin: ntopng_url_manager.get_url_entry("epoch_begin"),
|
|
epoch_end: ntopng_url_manager.get_url_entry("epoch_end"),
|
|
};
|
|
const now_s = this.get_utc_seconds(Date.now());
|
|
let seconds_in_interval = this.get_timeframe_from_timeframe_id(time_interval_id);
|
|
epoch.epoch_begin = now_s - seconds_in_interval;
|
|
epoch.epoch_end = now_s;
|
|
if (round_timeframe_id != null) {
|
|
epoch.epoch_begin = this.round_time_by_timeframe_id(epoch.epoch_begin, round_timeframe_id);
|
|
epoch.epoch_end = this.round_time_by_timeframe_id(epoch.epoch_end, round_timeframe_id);
|
|
}
|
|
ntopng_url_manager.set_key_to_url("epoch_begin", epoch.epoch_begin);
|
|
ntopng_url_manager.set_key_to_url("epoch_end", epoch.epoch_end);
|
|
|
|
return epoch;
|
|
},
|
|
//should take a string as parameter that represent time: min, 5_min, 30_min, hour, 2_hours, 6_hours, 12_hours, day, week, month, year. ID time_interval_id is null, default must be 30_min
|
|
// return epoch_interval only if epoch url is set
|
|
check_and_set_default_time_interval: function (time_interval_id = "30_min", f_condition, get_epoch = false, round_timeframe_id) {
|
|
let epoch = this.get_url_epoch_interval();
|
|
|
|
// if time_interval_id is 30 (default)
|
|
if (epoch.epoch_begin == null || epoch.epoch_end == null || (f_condition != null && f_condition(epoch) == true)) {
|
|
epoch = this.set_default_time_interval(time_interval_id, round_timeframe_id);
|
|
return epoch;
|
|
}
|
|
if (get_epoch == true) {
|
|
return epoch;
|
|
}
|
|
return null;
|
|
},
|
|
get_url_epoch_interval: function () {
|
|
let epoch = {
|
|
epoch_begin: ntopng_url_manager.get_url_entry("epoch_begin"),
|
|
epoch_end: ntopng_url_manager.get_url_entry("epoch_end"),
|
|
};
|
|
return epoch;
|
|
},
|
|
from_utc_s_to_server_date: function (utc_seconds) {
|
|
let utc = utc_seconds * 1000;
|
|
let d_local = new Date(utc);
|
|
let local_offset = d_local.getTimezoneOffset();
|
|
let server_offset = moment.tz(utc, ntop_zoneinfo)._offset;
|
|
let offset_minutes = server_offset + local_offset;
|
|
let offset_ms = offset_minutes * 1000 * 60;
|
|
var d_server = new Date(utc + offset_ms);
|
|
return d_server;
|
|
},
|
|
get_date_format: async function (is_range_picker, csrf, http_prefix) {
|
|
const rest_params = {
|
|
csrf: csrf
|
|
};
|
|
|
|
let date_format_url = `${http_prefix}/lua/rest/v2/get/timeseries/date_format.lua`;
|
|
const url = NtopUtils.buildURL(date_format_url, {
|
|
is_range_picker: is_range_picker
|
|
})
|
|
return await ntopng_utility.http_request(url, rest_params);
|
|
},
|
|
from_utc_to_server_date_format: function (utc_ms, format) {
|
|
if (format == null) { format = "DD/MMM/YYYY HH:mm:ss"; }
|
|
let m = moment.tz(utc_ms, ntop_zoneinfo);
|
|
let tz_server = m.format(format);
|
|
return tz_server;
|
|
},
|
|
copy_object_keys: function (source_obj, dest_obj, recursive_object = false) {
|
|
if (source_obj == null) {
|
|
return;
|
|
}
|
|
for (let key in source_obj) {
|
|
if (source_obj[key] == null) { continue; }
|
|
/* Security check for Prototype pollution vulnerability */
|
|
if (key === "__proto__" || key === "constructor") { continue; }
|
|
if (recursive_object == true && this.is_object(source_obj[key]) && this.is_object(dest_obj[key])) {
|
|
this.copy_object_keys(source_obj[key], dest_obj[key], recursive_object);
|
|
} else {
|
|
dest_obj[key] = source_obj[key];
|
|
}
|
|
}
|
|
},
|
|
get_cve_details_url(cve_id, scan_type) {
|
|
// IMPORTANT: The retrieved value must match the value in
|
|
// scripts/lua/modules/vulnerability_scan/cve_utils.lua for the 'cve_utils.getDocURL' function.
|
|
if (scan_type == "cve") {
|
|
return `https://nvd.nist.gov/vuln/detail/${cve_id}`;
|
|
} else if (scan_type == "openvas") {
|
|
return `https://vulners.com/openvas/OPENVAS:${cve_id}`;
|
|
}
|
|
},
|
|
set_http_globals_headers(headers) {
|
|
global_http_headers = headers;
|
|
},
|
|
http_post_request: async function (url, params, throw_exception, not_unwrap) {
|
|
let headers = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (params.csrf == null) {
|
|
throw `NULL csrf in ${url} POST request.`;
|
|
}
|
|
return this.http_request(url, { method: 'post', headers, body: JSON.stringify(params) }, throw_exception, not_unwrap);
|
|
},
|
|
http_request: async function (url, options, throw_exception, not_unwrap) {
|
|
try {
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
if (options.headers == null) {
|
|
options.headers = {};
|
|
}
|
|
if (options.headers != null && global_http_headers != null) {
|
|
options.headers = {
|
|
...options.headers,
|
|
...global_http_headers,
|
|
};
|
|
}
|
|
let res = await fetch(url, options);
|
|
if (res.ok === false) {
|
|
console.error(`http_request ${url}\n ok == false`);
|
|
console.error(res);
|
|
return null;
|
|
}
|
|
let json_res = await res.json();
|
|
if (not_unwrap === true) { return json_res; }
|
|
return json_res.rsp;
|
|
} catch (err) {
|
|
console.error(err);
|
|
console.error("URL: " + url);
|
|
if (throw_exception == true) { throw err; }
|
|
return null;
|
|
}
|
|
},
|
|
download_URI: function (uri, name) {
|
|
var link = document.createElement("a");
|
|
link.download = name;
|
|
link.href = uri;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
},
|
|
get_random_string: function () {
|
|
return Math.random().toString(16).substr(2, 8);
|
|
},
|
|
string_hash_code: function (s) {
|
|
let hash = 0, i, chr;
|
|
if (s.length === 0) return hash;
|
|
for (i = 0; i < s.length; i++) {
|
|
chr = s.charCodeAt(i);
|
|
hash = ((hash << 5) - hash) + chr;
|
|
hash |= 0; // Convert to 32bit integer
|
|
}
|
|
return hash;
|
|
},
|
|
mod: function (x, y) {
|
|
x = x % y;
|
|
if (x < 0) { x += y; }
|
|
return x;
|
|
}
|
|
}
|
|
}();
|
|
|
|
/**
|
|
* Allows to manage the application global status.
|
|
* The status is incapsulated into the url.
|
|
*/
|
|
export const ntopng_status_manager = function () {
|
|
let global_status = {};
|
|
/** @type {{ [id: string]: (status: object) => void}} */
|
|
let subscribers = {}; // dictionary of { [id: string]: f_on_ntopng_status_change() }
|
|
const clone = (e) => ntopng_utility.clone(e);
|
|
|
|
const replace_global_status = function (status) {
|
|
global_status = status;
|
|
}
|
|
|
|
/**
|
|
* Notifies the status to all subscribers with id different from skip_id.
|
|
* @param {object} status object that represent the application status.
|
|
* @param {string} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
const notify_subscribers = function (status, skip_id) {
|
|
for (let id in subscribers) {
|
|
if (id == skip_id) { continue; }
|
|
let f_on_change = subscribers[id];
|
|
f_on_change(clone(status));
|
|
}
|
|
};
|
|
|
|
return {
|
|
/**
|
|
* Gets the current global application status.
|
|
* @returns {object}
|
|
*/
|
|
get_status: function (not_clone) {
|
|
if (not_clone == true) {
|
|
return global_status;
|
|
}
|
|
return clone(global_status);
|
|
},
|
|
|
|
update_subscribers: function () {
|
|
const status = this.get_status();
|
|
notify_subscribers(status);
|
|
},
|
|
|
|
/**
|
|
* Allows to subscribers f_on_change callback on status change event.
|
|
* @param {string} id an identifier of the subscribtion.
|
|
* @param {(status:object) => void} f_on_change callback that take object status as param.
|
|
* @param {boolean} get_init_notify if true the callback it's immediately called with the last status available.
|
|
*/
|
|
on_status_change: function (id, f_on_change, get_init_notify) {
|
|
subscribers[id] = f_on_change;
|
|
if (get_init_notify == true) {
|
|
let status = this.get_status();
|
|
f_on_change(clone(status));
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Raplaces the application status and notifies the new status to all subscribers.
|
|
* Notifies the new status to all subscribers.
|
|
* @param {Object} status object that represent the application status.
|
|
* @param {string} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
replace_status: function (status, skip_id) {
|
|
replace_global_status(status);
|
|
notify_subscribers(status, skip_id);
|
|
},
|
|
|
|
/**
|
|
* Adds or replaces all obj param keys to the application status.
|
|
* Notifies the new status to all subscribers.
|
|
* @param {Object} obj object to add or edit to the application status.
|
|
* @param {string} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
add_obj_to_status: function (obj, skip_id) {
|
|
let new_status = this.get_status();
|
|
ntopng_utility.copy_object_keys(obj, new_status);
|
|
this.replace_status(new_status, skip_id);
|
|
},
|
|
|
|
/**
|
|
* Adds or replaces the value key to the application status.
|
|
* Notifies the new status to all subscribers.
|
|
* @param {string} key key to adds or replaces.
|
|
* @param {any} value value to adds or replaces.
|
|
* @param {*} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
add_value_to_status: function (key, value, skip_id) {
|
|
let new_status = this.get_status();
|
|
new_status[key] = value;
|
|
// /* This is needed to have muliple filters for the same key */
|
|
// (new_status[key] && new_status[key].search(value) === -1) ? new_status[key] += "," + value : new_status[key] = value
|
|
|
|
this.replace_status(new_status, skip_id);
|
|
},
|
|
}
|
|
}();
|
|
|
|
const ntopng_params_url_serializer = {
|
|
// filters: function(key, filters) {
|
|
// if (filters == null) { return ""; }
|
|
// let filters_groups = {};
|
|
// filters.forEach((f) => {
|
|
// let group = filters_groups[f.id];
|
|
// if (group == null) {
|
|
// group = [];
|
|
// filters_groups[f.id] = group;
|
|
// }
|
|
// group.push(f);
|
|
// });
|
|
// let url_params_array = [];
|
|
// for (let f_id in filters_groups) {
|
|
// let group = filters_groups[f_id];
|
|
// let url_values = group.filter((f) => f.value != null && f.operator != null && f.operator != "").map((f) => `${f.value};${f.operator}`).join(",");
|
|
// let url_params = ntopng_url_manager.serialize_param(f_id, url_values);
|
|
// url_params_array.push(url_params);
|
|
// }
|
|
// return url_params_array.join("&");
|
|
// },
|
|
};
|
|
|
|
export const ntopng_url_manager = function () {
|
|
/** @type {{ [key: string]: (obj: any) => string}} */
|
|
let custom_params_serializer = {};
|
|
ntopng_utility.copy_object_keys(ntopng_params_url_serializer, custom_params_serializer);
|
|
|
|
return {
|
|
|
|
get_url_params: function () {
|
|
return window.location.search.substring(1);
|
|
},
|
|
|
|
get_url_search_params: function (url) {
|
|
if (url == null) {
|
|
url = this.get_url_params();
|
|
}
|
|
// for(const [key, value] of entries) {
|
|
const url_params = new URLSearchParams(url);
|
|
return url_params;
|
|
},
|
|
|
|
get_url_entries: function (url) {
|
|
const url_params = this.get_url_search_params(url);
|
|
const entries = url_params.entries();
|
|
return entries;
|
|
},
|
|
|
|
get_url_entry: function (param_name, url) {
|
|
let entries = this.get_url_entries(url);
|
|
for (const [key, value] of entries) {
|
|
if (key == param_name) { return value; }
|
|
}
|
|
return null;
|
|
},
|
|
|
|
get_url_object: function (url) {
|
|
let entries = this.get_url_entries(url);
|
|
let obj = {};
|
|
for (const [key, value] of entries) {
|
|
obj[key] = value;
|
|
}
|
|
return obj;
|
|
},
|
|
|
|
open_new_window: function (url) {
|
|
if (url == null) {
|
|
url = window.location;
|
|
}
|
|
window.open(url);
|
|
},
|
|
|
|
reload_url: function () {
|
|
window.location.reload();
|
|
},
|
|
|
|
go_to_url: function (url) {
|
|
window.history.pushState({}, '', window.location);
|
|
window.location.replace(url);
|
|
},
|
|
|
|
replace_url: function (url_params) {
|
|
window.history.replaceState({}, null, `?${url_params}`);
|
|
},
|
|
|
|
replace_url_and_reload: function (url_params) {
|
|
this.replace_url(url_params);
|
|
this.reload_url();
|
|
},
|
|
|
|
serialize_param: function (key, value) {
|
|
if (value == null) {
|
|
value = "";
|
|
}
|
|
return `${key}=${encodeURIComponent(value)}`;
|
|
},
|
|
|
|
set_custom_key_serializer: function (key, f_get_url_param) {
|
|
custom_params_serializer[key] = f_get_url_param;
|
|
},
|
|
|
|
/**
|
|
* Convert js object into a string that represent url params.
|
|
* Uses custom serializer if set.
|
|
* @param {object} obj.
|
|
* @returns {string}.
|
|
*/
|
|
obj_to_url_params: function (obj) {
|
|
let params = [];
|
|
const default_serializer = this.serialize_param;
|
|
for (let key in obj) {
|
|
let serializer = custom_params_serializer[key];
|
|
if (serializer == null) {
|
|
serializer = default_serializer;
|
|
}
|
|
let param = serializer(key, obj[key]);
|
|
params.push(param);
|
|
}
|
|
let url_params = params.join("&");
|
|
return url_params;
|
|
},
|
|
|
|
delete_params: function (params_key) {
|
|
let search_params = this.get_url_search_params();
|
|
params_key.forEach((p) => {
|
|
search_params.delete(p);
|
|
});
|
|
this.replace_url(search_params.toString());
|
|
},
|
|
|
|
delete_key_from_url: function (key) {
|
|
let search_params = this.get_url_search_params();
|
|
search_params.delete(key);
|
|
this.replace_url(search_params.toString());
|
|
},
|
|
|
|
set_key_to_url: function (key, value) {
|
|
if (value == null) { value = ""; }
|
|
let search_params = this.get_url_search_params();
|
|
search_params.set(key, value);
|
|
this.replace_url(search_params.toString());
|
|
},
|
|
|
|
add_obj_to_url: function (url_params_obj, url) {
|
|
let new_url_params = this.obj_to_url_params(url_params_obj);
|
|
let search_params = this.get_url_search_params(url);
|
|
let new_entries = this.get_url_entries(new_url_params);
|
|
for (const [key, value] of new_entries) {
|
|
search_params.set(key, value);
|
|
}
|
|
let new_url = search_params.toString();
|
|
if (url != null) { return new_url; }
|
|
this.replace_url(new_url);
|
|
},
|
|
}
|
|
}();
|
|
|
|
// export const ntopng_params_manager = function() {
|
|
// const new = function(params_in_url) {
|
|
// }
|
|
// return {
|
|
// }
|
|
// }
|
|
|
|
/**
|
|
* Object that represents a list of prefedefined events that represent the status.
|
|
*/
|
|
export const ntopng_events = {
|
|
EPOCH_CHANGE: "epoch_change", // { epoch_begin: number, epoch_end: number }
|
|
FILTERS_CHANGE: "filters_change", // {filters: {id: string, operator: string, value: string}[] }
|
|
};
|
|
|
|
const ntopng_events_compare = {
|
|
EPOCH_CHANGE: function (new_status, old_status) {
|
|
return new_status.epoch_begin != old_status.epoch_begin
|
|
|| new_status.epoch_end != old_status.epoch_end;
|
|
},
|
|
FILTERS_CHANGE: function (new_status, old_status) {
|
|
return (new_status.filters == null && old_status.filters != null)
|
|
|| (new_status.filters != null && old_status.filters == null)
|
|
|| (new_status.filters != null && old_status.filters != null &&
|
|
(
|
|
(new_status.filters.length != old_status.filters.length)
|
|
|| (new_status.filters.some((f_new) => old_status.filters.find((f_old) => f_old.id == f_new.id) == null))
|
|
)
|
|
);
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Object that represents a list of prefedefined custom events.
|
|
*/
|
|
export const ntopng_custom_events = {
|
|
SHOW_MODAL_FILTERS: "show_modal_filters", // {id: string, operator: string, value: string}
|
|
MODAL_FILTERS_APPLY: "modal_filters_apply", // {id: string, label: string, operator: string, value: string, value_label: string}
|
|
SHOW_GLOBAL_ALERT_INFO: "show_global_alert_info", // html_text: string
|
|
VIS_DATA_LOADED: "vis_data_loaded",
|
|
CHANGE_PAGE_TITLE: "change_page_title",
|
|
DATATABLE_LOADED: "datatable_loaded",
|
|
GET_INTERFACE_FATA: "get_interface_data", // object returned by /lua/rest/v2/get/interface/data.lua
|
|
COMPONENT_EPOCH_INTERVAL_CHANGE: "component_epoch_interval_change", // { epoch_begin: number, epoch_end: number }
|
|
};
|
|
|
|
/**
|
|
* A global events service that allows to manage the application global status.
|
|
* The status is incapsulated into the url.
|
|
*/
|
|
export const ntopng_events_manager = function () {
|
|
const events_manager_id = "events_manager";
|
|
let status = {};
|
|
|
|
/** @type {{ [event_name: string]: { [id: string]: (status: object) => void}}} */
|
|
let events_subscribers = {}; // dictionary of { [event_name: string]: { [id: string]: f_on_event }
|
|
|
|
const clone = (e) => ntopng_utility.clone(e);
|
|
|
|
/**
|
|
* Notifies the status to all subscribers with id different from skip_id.
|
|
* @param {{ [id: string]: (status: object) => void}} subscribers dictionary of id => f_on_event().
|
|
* @param {object} status object that represent the application status.
|
|
* @param {string} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
const notify_subscribers = function (subscribers, status, skip_id) {
|
|
for (let id in subscribers) {
|
|
if (id == skip_id) { continue; }
|
|
let f_on_change = subscribers[id];
|
|
f_on_change(clone(status));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A callback that dispatches each event to all subscribers.
|
|
* @param {object} new_status
|
|
*/
|
|
const on_status_change = function (new_status) {
|
|
for (let event_name in ntopng_events) {
|
|
let f_compare = ntopng_events_compare[event_name];
|
|
if (f_compare(new_status, status) == true) {
|
|
let subscribers = events_subscribers[event_name];
|
|
notify_subscribers(subscribers, new_status);
|
|
}
|
|
}
|
|
|
|
status = new_status;
|
|
};
|
|
|
|
const get_event_for_single_dest = (event, dest_id) => {
|
|
return `${event}_${dest_id}`;
|
|
};
|
|
|
|
ntopng_status_manager.on_status_change(events_manager_id, on_status_change, true);
|
|
|
|
const emit = function (event, params, skip_id, dest_id) {
|
|
if (dest_id != null) {
|
|
event = get_event_for_single_dest(event, dest_id);
|
|
}
|
|
let subscribers = events_subscribers[event];
|
|
if (subscribers == null) { return; }
|
|
notify_subscribers(subscribers, params, skip_id);
|
|
};
|
|
|
|
const on_event = function (id, event, f_on_event, get_init_notify, is_single_dest_event) {
|
|
if (is_single_dest_event == true) {
|
|
event = get_event_for_single_dest(event, id);
|
|
}
|
|
if (events_subscribers[event] == null) {
|
|
events_subscribers[event] = {};
|
|
}
|
|
if (get_init_notify == true) {
|
|
let status = ntopng_status_manager.get_status();
|
|
f_on_event(clone(status));
|
|
}
|
|
events_subscribers[event][id] = f_on_event;
|
|
};
|
|
|
|
return {
|
|
emit_custom_event: function (event, params, dest_id) {
|
|
emit(event, params, null, dest_id);
|
|
},
|
|
on_custom_event: function (id, event, f_on_event, is_single_dest_event) {
|
|
on_event(id, event, f_on_event, null, is_single_dest_event);
|
|
},
|
|
/**
|
|
* Changes the application status and emits the new status to all subcribers registered to the event.
|
|
* @param {string} event event name.
|
|
* @param {object} new_status object to add or edit to the application status.
|
|
* @param {string} skip_id if != null doesn't notify the subscribers with skip_id identifier.
|
|
*/
|
|
emit_event: function (event, new_status, skip_id) {
|
|
emit(event, new_status, skip_id)
|
|
ntopng_status_manager.add_obj_to_status(new_status, events_manager_id);
|
|
},
|
|
/**
|
|
* Allows to subscribers f_on_event callback on status change on event event_name.
|
|
* @param {string} id an identifier of the subscribtion.
|
|
* @param {string} event event name.
|
|
* @param {(status:object) => void} f_on_event callback that take object status as param.
|
|
* @param {boolean} get_init_notify if true the callback it's immediately called with the last status available.
|
|
*/
|
|
on_event_change: function (id, event, f_on_event, get_init_notify) {
|
|
on_event(id, event, f_on_event, get_init_notify);
|
|
},
|
|
};
|
|
}();
|