9ba92d9495
was changed to dt-processing in datatables 2.0 Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
1023 lines
No EOL
41 KiB
HTML
1023 lines
No EOL
41 KiB
HTML
<!--
|
|
Copyright (C) 2024 Nicola Murino
|
|
|
|
This WebUI uses the KeenThemes Mega Bundle, a proprietary theme:
|
|
|
|
https://keenthemes.com/products/templates-mega-bundle
|
|
|
|
KeenThemes HTML/CSS/JS components are allowed for use only within the
|
|
SFTPGo product and restricted to be used in a resealable HTML template
|
|
that can compete with KeenThemes products anyhow.
|
|
|
|
This WebUI is allowed for use only within the SFTPGo product and
|
|
therefore cannot be used in derivative works/products without an
|
|
explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|
-->
|
|
{{template "base" .}}
|
|
|
|
{{- define "extra_css"}}
|
|
<link href="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.css" rel="stylesheet" type="text/css"/>
|
|
{{- end}}
|
|
|
|
{{- define "page_body"}}
|
|
{{- template "errmsg" ""}}
|
|
<div class="card shadow-sm">
|
|
<div class="card-header bg-light">
|
|
<h3 data-i18n="events.search" class="card-title section-title">Search logs</h3>
|
|
</div>
|
|
<div id="card_body" class="card-body">
|
|
<div class="form-group row">
|
|
<div class="col-md-3 mt-5">
|
|
<select class="form-select" id="idEventType" name="events_type" data-control="i18n-select2" data-hide-search="true">
|
|
<option value="1" data-i18n="events.fs_events">Fs events</option>
|
|
<option value="2" data-i18n="events.provider_events">Provider events</option>
|
|
<option value="3" data-i18n="events.other_events">Other events</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4 mt-5">
|
|
<select class="form-select" id="idActions" name="actions" data-control="i18n-select2" data-hide-search="true"
|
|
data-close-on-select="false" data-i18n="[data-placeholder]general.actions" multiple>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3 mt-5">
|
|
<input type="text" class="form-control" id="idUsername" name="username" data-i18n="[placeholder]login.username" spellcheck="false">
|
|
</div>
|
|
<div class="col-md-2 mt-5">
|
|
<input type="text" class="form-control" id="idIp" name="ip" data-i18n="[placeholder]defender.ip">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-md-3 mt-5">
|
|
<select class="form-select fs-events" id="idStatuses" name="statuses" data-control="i18n-select2" data-hide-search="true"
|
|
data-close-on-select="false" data-i18n="[data-placeholder]general.status" multiple>
|
|
<option value="1" data-i18n="general.ok">OK</option>
|
|
<option value="2" data-i18n="general.failed">KO</option>
|
|
<option value="3" data-i18n="events.quota_exceeded">Quota exceeded</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4 mt-5">
|
|
<select class="form-select fs-events log-events" id="idProtocols" name="protocols" data-control="i18n-select2" data-hide-search="true"
|
|
data-close-on-select="false" data-i18n="[data-placeholder]ip_list.protocols" multiple>
|
|
<option value="SFTP">SFTP</option>
|
|
<option value="SCP">SCP</option>
|
|
<option value="SSH">SSH</option>
|
|
<option value="FTP">FTP</option>
|
|
<option value="DAV">DAV</option>
|
|
<option value="HTTP">HTTP</option>
|
|
<option value="OIDC">OIDC</option>
|
|
<option value="HTTPShare">HTTPShare</option>
|
|
<option value="DataRetention">DataRetention</option>
|
|
<option value="EventAction">EventAction</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-5 mt-5">
|
|
<input id="dateTimeRange" class="form-control" data-i18n="[placeholder]events.date_range" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-end mt-10 mb-10">
|
|
<button id="export_button" class="btn btn-secondary px-10 me-10">
|
|
<span data-i18n="general.export" class="indicator-label">
|
|
Export
|
|
</span>
|
|
<span data-i18n="general.wait" class="indicator-progress">
|
|
Please wait...
|
|
<span class="spinner-border spinner-border-sm align-middle ms-2"></span>
|
|
</span>
|
|
</button>
|
|
<button id="search_button" class="btn btn-primary px-10">
|
|
<span data-i18n="general.search" class="indicator-label">
|
|
Search
|
|
</span>
|
|
<span data-i18n="general.wait" class="indicator-progress">
|
|
Please wait...
|
|
<span class="spinner-border spinner-border-sm align-middle ms-2"></span>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
|
|
<table id="dataTableFs" class="table align-middle table-row-dashed fs-6 gy-5 fs-events">
|
|
<thead>
|
|
<tr class="text-start text-muted fw-bold fs-6 gs-0">
|
|
<th data-i18n="events.datetime">Date and time</th>
|
|
<th data-i18n="events.action">Action</th>
|
|
<th data-i18n="events.path">Path</th>
|
|
<th data-i18n="login.username">Username</th>
|
|
<th data-i18n="general.protocol">Protocol</th>
|
|
<th data-i18n="defender.ip">IP</th>
|
|
<th data-i18n="general.info">Info</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table_body" class="text-gray-800 fw-semibold"></tbody>
|
|
</table>
|
|
|
|
<table id="dataTableProvider" class="table align-middle table-row-dashed fs-6 gy-5 provider-events">
|
|
<thead>
|
|
<tr class="text-start text-muted fw-bold fs-6 gs-0">
|
|
<th data-i18n="events.datetime">Date and time</th>
|
|
<th data-i18n="events.action">Action</th>
|
|
<th data-i18n="events.object">Object</th>
|
|
<th data-i18n="login.username">Username</th>
|
|
<th data-i18n="defender.ip">IP</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table_body" class="text-gray-800 fw-semibold"></tbody>
|
|
</table>
|
|
|
|
<table id="dataTableLog" class="table align-middle table-row-dashed fs-6 gy-5 log-events">
|
|
<thead>
|
|
<tr class="text-start text-muted fw-bold fs-6 gs-0">
|
|
<th data-i18n="events.datetime">Date and time</th>
|
|
<th data-i18n="events.event">Event</th>
|
|
<th data-i18n="login.username">Username</th>
|
|
<th data-i18n="general.protocol">Protocol</th>
|
|
<th data-i18n="defender.ip">IP</th>
|
|
<th data-i18n="general.info">Info</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table_body" class="text-gray-800 fw-semibold"></tbody>
|
|
</table>
|
|
|
|
<div id="paginationContainer" class="d-flex mt-4 mb-4 justify-content-end d-none">
|
|
<div class="btn-group" role="group" aria-label="Pagination">
|
|
<button id="pagePrevious" data-i18n="general.previous" type="button" class="btn btn-outline btn-active-primary disabled">Previous</button>
|
|
<button id="pageNext" data-i18n="general.next" type="button" class="btn btn-outline btn-active-primary disabled">Next</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
{{- end}}
|
|
|
|
{{- define "extra_js"}}
|
|
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
|
|
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/flatpickr/l10n/it.js"></script>
|
|
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/vendor/humanize-duration/humanize-duration.min.js"></script>
|
|
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
|
const pageSize = 20;
|
|
const paginationData = new Map();
|
|
|
|
function resetPagination() {
|
|
$('#pagePrevious').addClass("disabled");
|
|
$('#pageNext').addClass("disabled");
|
|
$('#paginationContainer').addClass("d-none");
|
|
paginationData.delete("firstId");
|
|
paginationData.delete("firstTs");
|
|
paginationData.delete("lastId");
|
|
paginationData.delete("lastTs");
|
|
paginationData.set("prevClicked",false);
|
|
paginationData.set("nextClicked",false);
|
|
}
|
|
|
|
function prevClicked(){
|
|
paginationData.set("prevClicked",true);
|
|
paginationData.set("nextClicked",false);
|
|
doSearch();
|
|
}
|
|
|
|
function nextClicked(){
|
|
paginationData.set("prevClicked",false);
|
|
paginationData.set("nextClicked",true);
|
|
doSearch();
|
|
}
|
|
|
|
function handleResponseData(data) {
|
|
let length = data.length;
|
|
let isNext = paginationData.get("nextClicked");
|
|
let isPrev = paginationData.get("prevClicked");
|
|
|
|
if (length > pageSize) {
|
|
data.pop();
|
|
length--;
|
|
if (isPrev || isNext){
|
|
$('#pagePrevious').removeClass("disabled");
|
|
}
|
|
$('#pageNext').removeClass("disabled");
|
|
} else {
|
|
if (isPrev){
|
|
$('#pagePrevious').addClass("disabled");
|
|
$('#pageNext').removeClass("disabled");
|
|
} else if (isNext){
|
|
$('#pagePrevious').removeClass("disabled");
|
|
$('#pageNext').addClass("disabled");
|
|
} else {
|
|
$('#pageNext').addClass("disabled");
|
|
}
|
|
}
|
|
if (isPrev){
|
|
data = data.reverse();
|
|
}
|
|
if (length > 0){
|
|
paginationData.set("lastId",data[0].id);
|
|
paginationData.set("lastTs",data[0].timestamp);
|
|
paginationData.set("firstId",data[length-1].id);
|
|
paginationData.set("firstTs",data[length-1].timestamp);
|
|
$('#paginationContainer').removeClass("d-none");
|
|
} else {
|
|
resetPagination();
|
|
}
|
|
return data;
|
|
}
|
|
|
|
function humanizeMilliseconds(val) {
|
|
let units = ["d", "h", "m", "s", "ms"];
|
|
let decimalPoints = 1;
|
|
if (val > 1000){
|
|
units = ["d", "h", "m", "s"]
|
|
}
|
|
if (val > 60000){
|
|
decimalPoints = 0;
|
|
}
|
|
return humanizeDuration(val, {
|
|
language: i18next.resolvedLanguage,
|
|
fallbacks: ["en"],
|
|
maxDecimalPoints: decimalPoints,
|
|
units: units
|
|
})
|
|
}
|
|
|
|
function getSearchURL(csvExport) {
|
|
let url = "";
|
|
let eventType = $('#idEventType').val();
|
|
let order = "DESC";
|
|
let limit = pageSize + 1;
|
|
if (csvExport){
|
|
order = "ASC";
|
|
}
|
|
if (eventType == 1){
|
|
url = "{{.FsEventsSearchURL}}?limit="+limit;
|
|
let protocols = [];
|
|
$('#idProtocols').find('option:selected').each(function(){
|
|
protocols.push($(this).val());
|
|
});
|
|
if (protocols.length > 0){
|
|
url+="&protocols="+encodeURIComponent(String(protocols));
|
|
}
|
|
let statuses = [];
|
|
$('#idStatuses').find('option:selected').each(function(){
|
|
statuses.push($(this).val());
|
|
});
|
|
if (statuses.length > 0){
|
|
url+="&statuses="+encodeURIComponent(String(statuses));
|
|
}
|
|
} else if (eventType == 2) {
|
|
url = "{{.ProviderEventsSearchURL}}?omit_object_data=true&limit="+limit;
|
|
} else {
|
|
url = "{{.LogEventsSearchURL}}?limit="+limit;
|
|
let protocols = [];
|
|
$('#idProtocols').find('option:selected').each(function(){
|
|
protocols.push($(this).val());
|
|
});
|
|
if (protocols.length > 0){
|
|
url+="&protocols="+encodeURIComponent(String(protocols));
|
|
}
|
|
}
|
|
let actions = [];
|
|
$('#idActions').find('option:selected').each(function(){
|
|
actions.push($(this).val());
|
|
});
|
|
if (actions.length > 0){
|
|
if (eventType == 3){
|
|
url+="&events="+encodeURIComponent(String(actions));
|
|
} else {
|
|
url+="&actions="+encodeURIComponent(String(actions));
|
|
}
|
|
}
|
|
let username = $('#idUsername').val();
|
|
if (username){
|
|
url+="&username="+encodeURIComponent(username);
|
|
}
|
|
let ip = $('#idIp').val();
|
|
if (ip){
|
|
url+="&ip="+encodeURIComponent(ip);
|
|
}
|
|
const dateRangePicker = document.querySelector("#dateTimeRange")._flatpickr;
|
|
let drp = dateRangePicker.selectedDates;
|
|
let fromID = "";
|
|
let start_ts = 0;
|
|
if (!csvExport && paginationData.get("prevClicked") && paginationData.has("lastId") && paginationData.has("lastTs")){
|
|
order = "ASC";
|
|
start_ts = paginationData.get("lastTs");
|
|
fromID = paginationData.get("lastId");
|
|
} else {
|
|
if (drp.length > 0){
|
|
let d = drp[0];
|
|
if (d) {
|
|
start_ts = d.getTime()*1000000;
|
|
}
|
|
}
|
|
}
|
|
let end_ts = 0;
|
|
if (!csvExport && paginationData.get("nextClicked") && paginationData.has("firstId") && paginationData.has("firstTs")){
|
|
end_ts = paginationData.get("firstTs");
|
|
fromID = paginationData.get("firstId");
|
|
} else {
|
|
if (drp.length > 1){
|
|
let d = drp[1];
|
|
if (d) {
|
|
end_ts = d.getTime()*1000000;
|
|
}
|
|
}
|
|
}
|
|
url+="&start_timestamp="+encodeURIComponent(start_ts);
|
|
url+="&end_timestamp="+encodeURIComponent(end_ts);
|
|
if (fromID){
|
|
url+="&from_id="+encodeURIComponent(fromID);
|
|
}
|
|
url+="&order="+order;
|
|
if (csvExport){
|
|
url+="&csv_export=true";
|
|
}
|
|
return url;
|
|
}
|
|
|
|
function onExportClicked() {
|
|
paginationData.set("prevClicked",false);
|
|
paginationData.set("nextClicked",false);
|
|
let exportURL = getSearchURL(true);
|
|
let ts = new Date().getTime().toString();
|
|
window.open(`${exportURL}&_=${ts}`);
|
|
}
|
|
|
|
function onSearchClicked() {
|
|
resetPagination();
|
|
doSearch();
|
|
}
|
|
|
|
function doSearch() {
|
|
let eventType = $('#idEventType').val();
|
|
switch (eventType){
|
|
case "1":
|
|
datatableFsEvents.init();
|
|
return;
|
|
case "2":
|
|
datatableProviderEvents.init();
|
|
return;
|
|
case "3":
|
|
datatableLogEvents.init();
|
|
return;
|
|
default:
|
|
console.log(`unsupported event type "${eventType}"`);
|
|
}
|
|
}
|
|
|
|
function selectFsEvents(){
|
|
let idActions = $('#idActions');
|
|
idActions.empty();
|
|
idActions.append(new Option($.t('events.upload'),"upload",false,false));
|
|
idActions.append(new Option($.t('events.download'),"download",false,false));
|
|
idActions.append(new Option($.t('events.mkdir'),"mkdir",false,false));
|
|
idActions.append(new Option($.t('events.rmdir'),"rmdir",false,false));
|
|
idActions.append(new Option($.t('events.rename'),"rename",false,false));
|
|
idActions.append(new Option($.t('events.delete'),"delete",false,false));
|
|
idActions.append(new Option($.t('events.first_upload'),"first-upload",false,false));
|
|
idActions.append(new Option($.t('events.first_download'),"first-download",false,false));
|
|
idActions.append(new Option($.t('events.ssh_cmd'),"ssh_cmd",false,false));
|
|
idActions.trigger('change');
|
|
$('#idUsername').val("");
|
|
$('#idIp').val("");
|
|
$('.provider-events').hide();
|
|
$('.log-events').hide();
|
|
$('.fs-events').show();
|
|
onSearchClicked();
|
|
}
|
|
|
|
function selectLogEvents(){
|
|
let idActions = $('#idActions');
|
|
idActions.empty();
|
|
idActions.append(new Option($.t('events.login_ok'),"5",false,false));
|
|
idActions.append(new Option($.t('events.login_failed'),"1",false,false));
|
|
idActions.append(new Option($.t('events.login_missing_user'),"2",false,false));
|
|
idActions.append(new Option($.t('events.no_login_tried'),"3",false,false));
|
|
idActions.append(new Option($.t('events.algo_negotiation_failed'),"4",false,false));
|
|
idActions.trigger('change');
|
|
$('#idUsername').val("");
|
|
$('#idIp').val("");
|
|
$('.provider-events').hide();
|
|
$('.fs-events').hide();
|
|
$('.log-events').show();
|
|
onSearchClicked();
|
|
}
|
|
|
|
function selectProviderEvents(){
|
|
let idActions = $('#idActions');
|
|
idActions.empty();
|
|
idActions.append(new Option($.t('events.add'),"add",false,false));
|
|
idActions.append(new Option($.t('events.update'),"update",false,false));
|
|
idActions.append(new Option($.t('events.delete'),"delete",false,false));
|
|
idActions.trigger('change');
|
|
$('#idUsername').val("");
|
|
$('#idIp').val("");
|
|
$('.fs-events').hide();
|
|
$('.log-events').hide();
|
|
$('.provider-events').show();
|
|
onSearchClicked();
|
|
}
|
|
|
|
function onEventChanged(val){
|
|
switch (val){
|
|
case '1':
|
|
selectFsEvents();
|
|
break;
|
|
case '2':
|
|
selectProviderEvents();
|
|
break;
|
|
case '3':
|
|
selectLogEvents();
|
|
break;
|
|
default:
|
|
console.log(`unsupported event type: ${val}`);
|
|
}
|
|
}
|
|
|
|
var datatableFsEvents = function(){
|
|
var dt;
|
|
|
|
var initDatatable = function () {
|
|
if (dt){
|
|
dt.clear().draw();
|
|
dt.ajax.url(getSearchURL(false)).load();
|
|
return;
|
|
}
|
|
$('#errorMsg').addClass("d-none");
|
|
dt = $('#dataTableFs').DataTable({
|
|
ajax: {
|
|
url: getSearchURL(false),
|
|
dataSrc: handleResponseData,
|
|
error: function ($xhr, textStatus, errorThrown) {
|
|
$(".dt-processing").hide();
|
|
let txt = "";
|
|
if ($xhr) {
|
|
let json = $xhr.responseJSON;
|
|
if (json) {
|
|
if (json.message){
|
|
txt = json.message;
|
|
}
|
|
}
|
|
}
|
|
if (!txt){
|
|
txt = "general.error500";
|
|
}
|
|
setI18NData($('#errorTxt'), txt);
|
|
$('#errorMsg').removeClass("d-none");
|
|
}
|
|
},
|
|
columns: [
|
|
{
|
|
data: "timestamp",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (data){
|
|
let ts = data/1000000;
|
|
if (ts){
|
|
return $.t('general.datetime', {
|
|
val: new Date(ts),
|
|
formatParams: {
|
|
val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "action",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
switch (data){
|
|
case "upload":
|
|
return $.t('events.upload');
|
|
case "download":
|
|
return $.t('events.download');
|
|
case "mkdir":
|
|
return $.t('events.mkdir');
|
|
case "rmdir":
|
|
return $.t('events.rmdir');
|
|
case "rename":
|
|
return $.t('events.rename');
|
|
case "delete":
|
|
return $.t('events.delete');
|
|
case "first-upload":
|
|
return $.t('events.first_upload');
|
|
case "first-download":
|
|
return $.t('events.first_download');
|
|
case "ssh_cmd":
|
|
return $.t('events.ssh_cmd');
|
|
default:
|
|
console.log(`unknown fs action "${data}"`);
|
|
return "";
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "virtual_path",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (!data){
|
|
return "";
|
|
}
|
|
if (row.virtual_target_path){
|
|
return escapeHTML(`${data} => ${row.virtual_target_path}`);
|
|
}
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "username",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "protocol",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "ip",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "status",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
let info = "";
|
|
switch (data){
|
|
case 1:
|
|
info = $.t('general.ok');
|
|
break;
|
|
case 2:
|
|
info = $.t('general.failed');
|
|
break;
|
|
case 3:
|
|
info = $.t('events.quota_exceeded');
|
|
break;
|
|
default:
|
|
console.log(`unknow status ${data}`);
|
|
}
|
|
if (row.file_size || row.file_size == 0){
|
|
let humanSize = fileSizeIEC(row["file_size"]);
|
|
info+=`. ${humanSize}`;
|
|
}
|
|
if (row.elapsed){
|
|
let elapsed = humanizeMilliseconds(row.elapsed);
|
|
info+=`. ${elapsed}`;
|
|
}
|
|
if (row.ssh_cmd){
|
|
info+=". "+$.t('events.ssh_cmd')+` "${row.ssh_cmd}"`;
|
|
}
|
|
return info;
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
],
|
|
deferRender: true,
|
|
processing: true,
|
|
lengthChange: false,
|
|
searching: false,
|
|
paging: false,
|
|
info: false,
|
|
ordering: false,
|
|
language: {
|
|
info: $.t('datatable.info'),
|
|
infoEmpty: $.t('datatable.info_empty'),
|
|
infoFiltered: $.t('datatable.info_filtered'),
|
|
loadingRecords: "",
|
|
processing: $.t('datatable.processing'),
|
|
zeroRecords: "",
|
|
emptyTable: $.t('datatable.no_records')
|
|
},
|
|
});
|
|
|
|
dt.on('draw', drawAction);
|
|
}
|
|
|
|
function drawAction() {
|
|
$('#table_body').localize();
|
|
}
|
|
|
|
return {
|
|
init: function () {
|
|
initDatatable();
|
|
}
|
|
}
|
|
}();
|
|
|
|
var datatableProviderEvents = function(){
|
|
var dt;
|
|
|
|
var initDatatable = function () {
|
|
if (dt){
|
|
dt.clear().draw();
|
|
dt.ajax.url(getSearchURL(false)).load();
|
|
return;
|
|
}
|
|
$('#errorMsg').addClass("d-none");
|
|
dt = $('#dataTableProvider').DataTable({
|
|
ajax: {
|
|
url: getSearchURL(false),
|
|
dataSrc: handleResponseData,
|
|
error: function ($xhr, textStatus, errorThrown) {
|
|
$(".dt-processing").hide();
|
|
let txt = "";
|
|
if ($xhr) {
|
|
let json = $xhr.responseJSON;
|
|
if (json) {
|
|
if (json.message){
|
|
txt = json.message;
|
|
}
|
|
}
|
|
}
|
|
if (!txt){
|
|
txt = "general.error500";
|
|
}
|
|
setI18NData($('#errorTxt'), txt);
|
|
$('#errorMsg').removeClass("d-none");
|
|
}
|
|
},
|
|
columns: [
|
|
{
|
|
data: "timestamp",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (data){
|
|
let ts = data/1000000;
|
|
if (ts){
|
|
return $.t('general.datetime', {
|
|
val: new Date(ts),
|
|
formatParams: {
|
|
val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "action",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
switch (data){
|
|
case "add":
|
|
return $.t('events.add');
|
|
case "update":
|
|
return $.t('events.update');
|
|
case "delete":
|
|
return $.t('events.delete');
|
|
console.log(`unknown provider action "${data}"`);
|
|
return "";
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "object_type",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (!data){
|
|
return "";
|
|
}
|
|
let message;
|
|
switch (data){
|
|
case "user":
|
|
message = $.t('provider_objects.user');
|
|
break;
|
|
case "folder":
|
|
message = $.t('provider_objects.folder');
|
|
break;
|
|
case "group":
|
|
message = $.t('provider_objects.group');
|
|
break;
|
|
case "admin":
|
|
message = $.t('provider_objects.admin');
|
|
break;
|
|
case "api_key":
|
|
message = $.t('provider_objects.api_key');
|
|
break;
|
|
case "share":
|
|
message = $.t('provider_objects.share');
|
|
break;
|
|
case "event_action":
|
|
message = $.t('provider_objects.event_action');
|
|
break;
|
|
case "event_rule":
|
|
message = $.t('provider_objects.event_rule');
|
|
break;
|
|
case "role":
|
|
message = $.t('provider_objects.role');
|
|
break;
|
|
case "ip_list_entry":
|
|
message = $.t('provider_objects.ip_list_entry');
|
|
break;
|
|
case "configs":
|
|
message = $.t('provider_objects.configs');
|
|
break;
|
|
default:
|
|
console.log("uknown object type: "+data);
|
|
return ""
|
|
}
|
|
if (row.object_name && data != "configs"){
|
|
return message+= escapeHTML(` "${row.object_name}"`);
|
|
}
|
|
return message;
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "username",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "ip",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
],
|
|
deferRender: true,
|
|
processing: true,
|
|
lengthChange: false,
|
|
searching: false,
|
|
paging: false,
|
|
info: false,
|
|
ordering: false,
|
|
language: {
|
|
info: $.t('datatable.info'),
|
|
infoEmpty: $.t('datatable.info_empty'),
|
|
infoFiltered: $.t('datatable.info_filtered'),
|
|
loadingRecords: "",
|
|
processing: $.t('datatable.processing'),
|
|
zeroRecords: "",
|
|
emptyTable: $.t('datatable.no_records')
|
|
},
|
|
});
|
|
|
|
dt.on('draw', drawAction);
|
|
}
|
|
|
|
function drawAction() {
|
|
$('#table_body').localize();
|
|
}
|
|
|
|
return {
|
|
init: function () {
|
|
initDatatable();
|
|
}
|
|
}
|
|
}();
|
|
|
|
var datatableLogEvents = function(){
|
|
var dt;
|
|
|
|
var initDatatable = function () {
|
|
if (dt){
|
|
dt.clear().draw();
|
|
dt.ajax.url(getSearchURL(false)).load();
|
|
return;
|
|
}
|
|
$('#errorMsg').addClass("d-none");
|
|
dt = $('#dataTableLog').DataTable({
|
|
ajax: {
|
|
url: getSearchURL(false),
|
|
dataSrc: handleResponseData,
|
|
error: function ($xhr, textStatus, errorThrown) {
|
|
$(".dt-processing").hide();
|
|
let txt = "";
|
|
if ($xhr) {
|
|
let json = $xhr.responseJSON;
|
|
if (json) {
|
|
if (json.message){
|
|
txt = json.message;
|
|
}
|
|
}
|
|
}
|
|
if (!txt){
|
|
txt = "general.error500";
|
|
}
|
|
setI18NData($('#errorTxt'), txt);
|
|
$('#errorMsg').removeClass("d-none");
|
|
}
|
|
},
|
|
columns: [
|
|
{
|
|
data: "timestamp",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (data){
|
|
let ts = data/1000000;
|
|
if (ts){
|
|
return $.t('general.datetime', {
|
|
val: new Date(ts),
|
|
formatParams: {
|
|
val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "event",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
switch (data){
|
|
case 1:
|
|
return $.t('events.login_failed');
|
|
case 2:
|
|
return $.t('events.login_missing_user');
|
|
case 3:
|
|
return $.t('events.no_login_tried');
|
|
case 4:
|
|
return $.t('events.algo_negotiation_failed');
|
|
case 5:
|
|
return $.t('events.login_ok');
|
|
default:
|
|
console.log(`unknown log action "${data}"`);
|
|
return "";
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "username",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (!data){
|
|
return "";
|
|
}
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "protocol",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (!data){
|
|
return "";
|
|
}
|
|
return escapeHTML(data);
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "ip",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (data){
|
|
return escapeHTML(data);
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
},
|
|
{
|
|
data: "message",
|
|
defaultContent: "",
|
|
render: function(data, type, row) {
|
|
if (type === 'display') {
|
|
if (data){
|
|
return escapeHTML(data);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
},
|
|
],
|
|
deferRender: true,
|
|
processing: true,
|
|
lengthChange: false,
|
|
searching: false,
|
|
paging: false,
|
|
info: false,
|
|
ordering: false,
|
|
language: {
|
|
info: $.t('datatable.info'),
|
|
infoEmpty: $.t('datatable.info_empty'),
|
|
infoFiltered: $.t('datatable.info_filtered'),
|
|
loadingRecords: "",
|
|
processing: $.t('datatable.processing'),
|
|
zeroRecords: "",
|
|
emptyTable: $.t('datatable.no_records')
|
|
},
|
|
});
|
|
|
|
dt.on('draw', drawAction);
|
|
}
|
|
|
|
function drawAction() {
|
|
$('#table_body').localize();
|
|
}
|
|
|
|
return {
|
|
init: function () {
|
|
initDatatable();
|
|
}
|
|
}
|
|
}();
|
|
|
|
$(document).on("i18nload", function(){
|
|
$('#dateTimeRange').flatpickr({
|
|
enableTime: true,
|
|
time_24hr: true,
|
|
formatDate: (date, format, locale) => {
|
|
return $.t('general.datetime', {
|
|
val: new Date(date),
|
|
formatParams: {
|
|
val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
|
|
}
|
|
});
|
|
},
|
|
mode: "range",
|
|
defaultDate: [moment().add(-1,'hour').format('YYYY-MM-DD HH:mm')],
|
|
minuteIncrement: 1,
|
|
locale: i18next.resolvedLanguage
|
|
});
|
|
onEventChanged('1');
|
|
});
|
|
|
|
$(document).on("i18nshow", function(){
|
|
$('#idEventType').on("change", function(){
|
|
onEventChanged(this.value);
|
|
});
|
|
|
|
$('#search_button').on("click", function(e){
|
|
e.preventDefault();
|
|
this.blur();
|
|
onSearchClicked();
|
|
});
|
|
|
|
$('#export_button').on("click", function(e){
|
|
e.preventDefault();
|
|
this.blur();
|
|
onExportClicked();
|
|
});
|
|
|
|
$('#pagePrevious').on("click", function(e){
|
|
e.preventDefault();
|
|
this.blur();
|
|
prevClicked();
|
|
});
|
|
|
|
$('#pageNext').on("click", function(e){
|
|
e.preventDefault();
|
|
this.blur();
|
|
nextClicked();
|
|
});
|
|
|
|
});
|
|
</script>
|
|
{{- end}} |