feat(cloudron): add tirreno package artifacts

- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents
- Includes package manifest, Dockerfile, source code, documentation, and build artifacts
- Add tirreno-1761840148.tar.gz as a build artifact
- Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package
- Include all necessary files for the tirreno Cloudron package

This adds the complete tirreno Cloudron package artifacts to the repository.
This commit is contained in:
2025-10-30 11:43:06 -05:00
parent 0ce353ea9d
commit 91d52d2de5
1692 changed files with 202851 additions and 0 deletions

View File

@@ -0,0 +1,466 @@
import {Loader} from '../Loader.js?v=2';
import {Tooltip} from '../Tooltip.js?v=2';
import {fireEvent} from '../utils/Event.js?v=2';
import {getQueryParams} from '../utils/DataSource.js?v=2';
import {handleAjaxError} from '../utils/ErrorHandler.js?v=2';
import {TotalTile} from '../TotalTile.js?v=2';
import {renderTotalFrame} from '../DataRenderers.js?v=2';
import {
MIDLINE_HELLIP,
} from '../utils/Constants.js?v=2';
export class BaseGrid {
constructor(gridParams) {
this.config = gridParams;
this.loader = new Loader();
this.tooltip = new Tooltip();
this.totalTile = new TotalTile();
this.firstload = true;
this.renderTotalsLoader = this.renderTotalsLoader.bind(this);
this.initLoad();
if (this.config.dateRangeGrid && !this.config.sequential) {
const onDateFilterChanged = this.onDateFilterChanged.bind(this);
window.addEventListener('dateFilterChanged', onDateFilterChanged, false);
}
if (gridParams.choicesFilterEvents) {
const onChoicesFilterChanged = this.onChoicesFilterChanged.bind(this);
for (let i = 0; i < gridParams.choicesFilterEvents.length; i++) {
window.addEventListener(gridParams.choicesFilterEvents[i], onChoicesFilterChanged, false);
}
}
if (!this.config.sequential) {
const onSearchFilterChanged = this.onSearchFilterChanged.bind(this);
window.addEventListener('searchFilterChanged', onSearchFilterChanged, false);
}
}
initLoad() {
const me = this;
const tableId = this.config.tableId;
$(document).ready(() => {
$.extend($.fn.dataTable.ext.classes, {
sStripeEven: '', sStripeOdd: ''
});
$.fn.dataTable.ext.pager.numbers_length = 9;
$.fn.dataTable.ext.errMode = function() {};
$(`#${tableId}`).on('error.dt', me.onError);
const onBeforeLoad = me.onBeforeLoad.bind(me);
$(`#${tableId}`).on('preXhr.dt', onBeforeLoad);
const onBeforePageChange = me.onBeforePageChange.bind(me);
$(`#${tableId}`).on('page.dt', onBeforePageChange);
const config = me.getDataTableConfig();
$(`#${tableId}`).DataTable(config);
const onTableRowClick = me.onTableRowClick.bind(me);
$(`#${tableId} tbody`).on('click', 'tr', onTableRowClick);
const onDraw = me.onDraw.bind(me);
$(`#${tableId}`).on('draw.dt', onDraw);
$(`#${tableId}`).closest('.dt-container').find('nav').empty();
document.getElementById(tableId).classList.add('hide-body');
if (!me.config.sequential) {
me.loadData();
}
});
}
getDataTableConfig() {
const me = this;
const url = this.config.url;
const columns = this.columns;
const columnDefs = this.columnDefs;
const isSortable = this.getConfigParam('isSortable');
const order = this.orderConfig;
const config = {
ajax: function(data, callback, settings) {
$.ajax({
url: url,
method: 'GET',
data: data,
dataType: 'json',
success: function(response, textStatus, jqXHR) {
callback(response);
me.performAdditional(response, me.config);
me.stopAnimation();
},
error: handleAjaxError,
});
},
processing: true,
serverSide: true,
deferRender: true,
deferLoading: 0,
pageLength: 25,
autoWidth: false,
lengthChange: false,
searching: true,
ordering: isSortable,
info: false,
pagingType: 'simple_numbers',
language: {
paginate: {
previous: '&lt;',
next: '&gt;',
},
},
layout: {
topEnd: null,
bottomEnd: {
paging: {
boundaryNumbers: false,
type: 'simple_numbers',
},
},
},
createdRow: function(row, data, dataIndex) {
$(row).attr('data-item-id', data.id);
},
drawCallback: function(settings) {
me.drawCallback(settings);
me.updateTableFooter(this);
},
columnDefs: columnDefs,
columns: columns,
order: order
};
return config;
}
performAdditional(response, config) {
if (!config.calculateTotals) {
fireEvent('dateFilterChangedCompleted');
return;
}
const ids = response.data.map(item => item.id);
const token = document.head.querySelector('[name=\'csrf-token\'][content]').content;
const dateRange = response.dateRange;
if (dateRange && ids.length) {
const requestData = {
token: token,
ids: ids,
type: config.totals.type,
startDate: dateRange.startDate,
endDate: dateRange.endDate,
};
let preparedBase = {};
response.data.forEach(rec => {
preparedBase[rec.id] = rec;
});
$.ajax({
type: 'GET',
url: '/admin/timeFrameTotal',
data: requestData,
success: (data) => this.onTotalsSuccess(data, config, preparedBase),
error: handleAjaxError,
complete: function() {
fireEvent('dateFilterChangedCompleted');
},
});
} else {
fireEvent('dateFilterChangedCompleted');
}
if (!dateRange && ids.length) {
// actualy making fake response from server
let data = {totals: {}};
let preparedBase = {};
const cols = config.totals.columns;
response.data.forEach(item => {
data.totals[item.id] = {};
preparedBase[item.id] = {};
cols.forEach(col => {
data.totals[item.id][col] = item[col];
preparedBase[item.id][col] = item[col];
});
});
this.onTotalsSuccess(data, config, preparedBase);
}
}
onTotalsSuccess(data, config, base) {
const table = $(`#${config.tableId}`).DataTable();
const columns = config.totals.columns;
let idxs = {};
for (let i = 0; i < columns.length; i++) {
idxs[columns[i]] = -1;
}
table.settings().init().columns.forEach((col, index) => {
columns.forEach(colName => {
if (col.data === colName || col.name === colName) {
idxs[colName] = index;
}
});
});
if (Object.values(idxs).includes(-1)) return;
let rowData;
let id;
table.rows().every(function() {
rowData = this.data();
id = String(rowData.id);
if (id in data.totals) {
for (const col in idxs) {
$(table.cell(this, idxs[col]).node()).html(renderTotalFrame(base[id][col], data.totals[id][col]));
}
}
});
}
drawCallback(settings) {
const me = this;
this.initTooltips();
//this.stopAnimation();
const params = {
tableId: me.config.tableId
};
if (settings && settings.iDraw > 1) {
const total = settings.json.recordsTotal;
const tileId = this.config.tileId;
const tableId = this.config.tableId;
this.totalTile.update(tableId, tileId, total);
this.updateTableTitle(total);
fireEvent('tableLoaded', params);
}
}
updateTableTitle(value) {
const tableId = this.config.tableId;
const wrapper = document.getElementById(tableId).closest('.card');
if (wrapper) {
const span = wrapper.querySelector('header span');
span.textContent = value;
}
}
stopAnimation() {
this.loader.stop();
const el = document.getElementById(`${this.config.tableId}_loader`);
if (el) el.remove();
const table = document.getElementById(this.config.tableId);
table.classList.remove('dim-table');
}
updateTableFooter(dataTable) {
const tableId = this.config.tableId;
const pagerSelector = `#${tableId}_wrapper .dt-paging`;
const api = dataTable.api();
if (api.ajax && typeof api.ajax.json === 'function' && api.ajax.json() === undefined) {
return;
}
$(`#${tableId}`).closest('.dt-container').find('nav').show();
if (api.page.info().pages <= 1) {
$(pagerSelector).hide();
} else {
$(pagerSelector).show();
}
}
initTooltips() {
const tableId = this.config.tableId;
Tooltip.addTooltipsToGridRecords(tableId);
Tooltip.addTooltipToSpans();
Tooltip.addTooltipToParagraphs();
}
onBeforeLoad(e, settings, data) {
if (!this.config.sequential) {
this.startLoader();
}
this.updateTableTitle(MIDLINE_HELLIP);
fireEvent('dateFilterChangedCaught');
//TODO: move to events grid? Or not?
const params = this.config.getParams();
const queryParams = getQueryParams(params);
for (let key in queryParams) {
data[key] = queryParams[key];
}
const token = document.head.querySelector('[name=\'csrf-token\'][content]').content;
data.token = token;
}
onDraw(e, settings) {
if (this.firstload) {
document.getElementById(this.config.tableId).classList.remove('hide-body');
this.firstload = false;
}
}
onBeforePageChange(e, settings) {
const tableId = this.config.tableId;
const pagesPath = `#${tableId}_paginate a`;
[...document.querySelectorAll(pagesPath)].forEach(a => {
a.outerHTML =
a.outerHTML
.replace(/<a/g, '<span')
.replace(/<\/a>/g, '</span>');
});
}
onTableRowClick(event) {
const selection = window.getSelection();
if ('Range' === selection.type) {
return;
}
const row = event.target.closest('tr');
const link = row.querySelector('a');
if (link) {
event.preventDefault();
if (event.ctrlKey || event.metaKey) {
window.open(link.href, '_blank');
} else {
window.location.href = link.href;
}
}
}
//TODO: leave blank and move to the events table
addTableRowsEvents() {
const tableId = this.config.tableId;
const onRowClick = this.onRowClick.bind(this);
if ($(this.table).DataTable().data().any()) {
const rows = document.querySelectorAll(`#${tableId} tbody tr`);
rows.forEach(row => row.addEventListener('click', onRowClick, false));
}
}
startLoader() {
const tableId = this.config.tableId;
const loaderPath = `${tableId}_processing`;
const loaderWrapper = document.getElementById(loaderPath);
const el = document.createElement('p');
el.className = 'text-loader';
loaderWrapper.replaceChildren(el);
this.loader.start(el);
loaderWrapper.style.display = null;
const table = document.getElementById(this.config.tableId);
table.classList.add('dim-table');
}
onRowClick(e) {
const selection = window.getSelection();
if ('Range' === selection.type) {
return;
}
e.preventDefault();
const row = e.target.closest('tr');
const itemId = row.dataset.itemId;
const data = {itemId: itemId};
fireEvent('tableRowClicked', data);
}
onError(e, settings, techNote, message) {
if (settings.jqXHR !== undefined && 403 === settings.jqXHR.status) {
window.location.href = escape('/');
}
//console.warn('An error has been reported by DataTables: ', message);
}
loadData() {
//TODO: create getter for table el: $(me.table).DataTable().ajax.reload()
const me = this;
$(me.table).DataTable().ajax.reload();
}
onDateFilterChanged() {
this.loadData();
}
onSearchFilterChanged() {
this.loadData();
}
onChoicesFilterChanged() {
this.loadData();
}
getConfigParam(key) {
const cfg = this.config;
const value = ('undefined' !== typeof cfg[key]) ? cfg[key] : true;
return value;
}
get orderConfig() {
return this.getConfigParam('isSortable') ? [[1, 'desc']] : [];
}
get table() {
const tableId = this.config.tableId;
const tableEl = document.getElementById(tableId);
return tableEl;
}
renderTotalsLoader(data, type, record, meta) {
const span = document.createElement('span');
const col_name = meta.settings.aoColumns[meta.col].name;
if (this.config.calculateTotals && this.config.totals.columns.includes(col_name)) {
span.className = 'loading-table-total';
span.textContent = MIDLINE_HELLIP;
} else {
span.textContent = data;
}
return span;
}
}

View File

@@ -0,0 +1,115 @@
import {BaseGrid} from './Base.js?v=2';
import {fireEvent} from '../utils/Event.js?v=2';
export class BaseGridWithPanel extends BaseGrid {
constructor(gridParams) {
super(gridParams);
this.config = gridParams;
this.markerClass = 'marker';
this.allPanels = {
'event': {
id: 'event-card',
closedEvent: 'eventPanelClosed',
close: 'closeEventPanel',
rowClicked: 'eventTableRowClicked',
},
'logbook': {
id: 'logbook-card',
closedEvent: 'logbookPanelClosed',
close: 'closeLogbookPanel',
rowClicked: 'logbookTableRowClicked',
},
'email': {
id: 'email-card',
closedEvent: 'emailPanelClosed',
close: 'closeEmailPanel',
rowClicked: 'emailTableRowClicked',
},
'device': {
id: 'device-card',
closedEvent: 'devicePanelClosed',
close: 'closeDevicePanel',
rowClicked: 'deviceTableRowClicked',
},
'phone': {
id: 'phone-card',
closedEvent: 'phonePanelClosed',
close: 'closePhonePanel',
rowClicked: 'phoneTableRowClicked',
},
};
this.panelType = gridParams.panelType;
this.currentPanel = this.allPanels[this.panelType];
const onDetailsPanelClosed = this.onDetailsPanelClosed.bind(this);
window.addEventListener(this.currentPanel.closedEvent, onDetailsPanelClosed, false);
const onTableRowClicked = this.onTableRowClicked.bind(this);
window.addEventListener(this.currentPanel.rowClicked, onTableRowClicked, false);
}
drawCallback(settings) {
super.drawCallback(settings);
this.addTableRowsEvents();
}
onDetailsPanelClosed() {
const markerClass = this.markerClass;
const tableId = this.config.tableId;
$(`#${tableId} tbody tr`).removeClass(markerClass);
}
onRowClick(e) {
const selection = window.getSelection();
if ('Range' === selection.type) {
return;
}
e.preventDefault();
const row = e.target.closest('tr');
const itemId = row.dataset.itemId;
const data = {itemId: itemId};
fireEvent(this.currentPanel.rowClicked, data);
}
onTableRowClicked(e) {
e.preventDefault();
const itemId = e.detail.itemId;
const targetRow = this.table.querySelector(`tr[data-item-id="${itemId}"]`);
const markerClass = this.markerClass;
const isRowMarkered = targetRow.classList.contains(markerClass);
if (isRowMarkered) {
fireEvent(this.currentPanel.close);
targetRow.classList.remove(markerClass);
} else {
// close other panels
for (const panel in this.allPanels) {
if (panel !== this.panelType) {
const card = document.querySelector(`.details-card#${this.allPanels[panel].id}`);
if (card && !card.classList.contains('is-hidden')) {
fireEvent(this.allPanels[panel].closedEvent);
card.classList.add('is-hidden');
}
}
}
// unmark other rows in the same table
const rows = this.table.querySelectorAll('tr[data-item-id]');
rows.forEach(row => row.classList.remove(markerClass));
// mark current row
targetRow.classList.add(markerClass);
}
}
}

View File

@@ -0,0 +1,79 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderTime,
renderBlacklistButtons,
renderBlacklistItem,
renderBlacklistType,
renderClickableImportantUserWithScore,
} from '../DataRenderers.js?v=2';
export class BlacklistGrid extends BaseGrid {
get orderConfig() {
return [[1, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'blacklist-user-col',
targets: 0
},
{
className: 'blacklist-timestamp-col',
targets: 1
},
{
className: 'blacklist-type-col',
targets: 2
},
{
className: 'blacklist-value-col',
targets: 3
},
{
className: 'blacklist-button-col',
targets: 4
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'score',
render: (data, type, record) => {
return renderClickableImportantUserWithScore(record, 'medium');
}
},
{
data: 'created',
render: (data, type, record) => {
return renderTime(data);
}
},
{
data: 'type',
render: (data, type, record) => {
return renderBlacklistType(record);
}
},
{
data: 'value',
render: (data, _ype, record) => {
return renderBlacklistItem(record);
}
},
{
data: 'entity_id',
orderable: false,
render: (data, type, record) => {
return renderBlacklistButtons(record);
}
}
];
return columns;
}
}

View File

@@ -0,0 +1,61 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderClickableBotId,
renderDevice,
renderOs,
renderBoolean,
} from '../DataRenderers.js?v=2';
export class BotsGrid extends BaseGrid {
get columnDefs() {
const columnDefs = [
{
className: 'bot-id-col',
targets: 0
},
{
className: 'bot-type-col',
targets: 1
},
{
className: 'bot-os-col',
targets: 2
},
{
className: 'bot-modified-col',
targets: 3
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'id',
render: (data, type, record) => {
return renderClickableBotId(record);
}
},
{
data: 'device',
render: (data, type, record) => {
return renderDevice(record);
}
},
{
data: 'os_name',
render: (data, type, record) => {
return renderOs(record);
}
},
{
data: 'modified',
render: renderBoolean
}
];
return columns;
}
}

View File

@@ -0,0 +1,100 @@
import {BaseGrid} from './Base.js?v=2';
import {fireEvent} from '../utils/Event.js?v=2';
import {renderClickableCountry} from '../DataRenderers.js?v=2';
export class CountriesGrid extends BaseGrid {
get orderConfig() {
return [[0, 'asc']];
}
drawCallback(settings) {
super.drawCallback(settings);
if (settings && settings.iDraw > 1) {
const data = settings.json.data;
fireEvent('countriesGridLoaded', {data: data});
}
}
get columnDefs() {
const columnDefs = [
{
className: 'country-country-col',
targets: 0
},
{
className: 'country-iso-col',
targets: 1
},
{
className: 'country-cnt-col',
targets: 2
},
{
className: 'country-cnt-col',
targets: 3
},
{
className: 'country-cnt-col',
targets: 4
},
{
visible: false,
targets: 5
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'full_country',
name: 'full_country',
render: (data, type, record) => {
return renderClickableCountry(record, false);
}
},
{
data: 'country_iso',
name: 'country_iso'
},
{
data: 'total_account',
name: 'total_account',
render: this.renderTotalsLoader,
},
{
data: 'total_visit',
name: 'total_visit',
render: this.renderTotalsLoader,
},
{
data: 'total_ip',
name: 'total_ip',
render: this.renderTotalsLoader,
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
updateTableFooter(dataTable) {
const tableId = this.config.tableId;
const pagerSelector = `#${tableId}_wrapper .dt-paging`;
const api = dataTable.api();
if (api.ajax && typeof api.ajax.json === 'function' && api.ajax.json() === undefined) {
$(`${pagerSelector} nav`).empty();
return;
}
$(pagerSelector).hide();
}
}

View File

@@ -0,0 +1,91 @@
import {BaseGridWithPanel} from './BaseWithPanel.js?v=2';
import {
renderDate,
renderBoolean,
renderDevice,
renderOs,
renderBrowser,
renderLanguage,
} from '../DataRenderers.js?v=2';
export class DevicesGrid extends BaseGridWithPanel {
get columnDefs() {
const columnDefs = [
{
className: 'device-date-col',
targets: 0
},
{
className: 'device-type-col',
targets: 1
},
{
className: 'device-os-col',
targets: 2
},
{
className: 'device-browser-col',
targets: 3
},
{
className: 'device-language-col',
targets: 4
},
{
className: 'device-modified-col',
targets: 5
},
{
visible: false,
targets: 6
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'created',
render: (data, type, record) => {
return renderDate(data);
},
},
{
data: 'device',
render: (data, type, record) => {
return renderDevice(record);
}
},
{
data: 'os_name',
render: (data, type, record) => {
return renderOs(record);
}
},
{
data: 'browser_name',
render: (data, type, record) => {
return renderBrowser(record);
}
},
{
data: 'lang',
render: (data, type, record) => {
return renderLanguage(record);
},
},
{
data: 'modified',
render: renderBoolean
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
}

View File

@@ -0,0 +1,131 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderClickableDomain,
renderBoolean,
renderDate,
renderDefaultIfEmptyElement,
renderUserCounter,
} from '../DataRenderers.js?v=2';
export class DomainsGrid extends BaseGrid {
get orderConfig() {
return [[6, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'domain-domain-col',
targets: 0
},
{
className: 'domain-cnt-col',
targets: 1
},
{
className: 'domain-cnt-col',
targets: 2
},
{
className: 'domain-cnt-col',
targets: 3
},
{
className: 'domain-cnt-col',
targets: 4
},
{
className: 'domain-date-col',
targets: 5
},
{
className: 'domain-cnt-col',
targets: 6
},
{
className: 'domain-cnt-col',
targets: 7
},
{
visible: false,
targets: 8
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'domain',
render: (data, type, record) => {
return renderClickableDomain(record);
}
},
{
data: 'free_email_provider',
render: (data, type, record) => {
const free_email_provider = record.free_email_provider;
return renderBoolean(free_email_provider);
}
},
{
data: 'tranco_rank',
name: 'tranco_rank',
render: (data, type, record) => {
let rank = renderDefaultIfEmptyElement(data);
if (data) {
rank = data;
}
return rank;
}
},
{
data: 'disabled',
render: (data, type, record) => {
const unavailable = record.disabled;
return renderBoolean(unavailable);
}
},
{
data: 'disposable_domains',
render: (data, type, record) => {
const disposable = record.disposable_domains;
return renderBoolean(disposable);
}
},
{
data: 'creation_date',
render: (data, type, record) => {
const creation_date = record.creation_date;
if (creation_date) {
return renderDate(creation_date);
} else {
return renderDefaultIfEmptyElement(creation_date);
}
}
},
{
data: 'total_account',
name: 'total_account',
render: this.renderTotalsLoader,
},
{
data: 'fraud',
name: 'fraud',
render: (data, type, record) => {
return renderUserCounter(data, 1);
}
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
}

View File

@@ -0,0 +1,118 @@
import {BaseGridWithPanel} from './BaseWithPanel.js?v=2';
import {
renderBoolean,
renderReputation,
renderEmail,
renderDefaultIfEmptyElement,
} from '../DataRenderers.js?v=2';
export class EmailsGrid extends BaseGridWithPanel {
get orderConfig() {
return [];
}
get columnDefs() {
const columnDefs = [
{
className: 'email-email-col',
targets: 0
},
{
className: 'email-reputation-col',
targets: 1
},
{
className: 'email-free-provider-col',
targets: 2
},
{
className: 'email-no-breach-col',
targets: 3
},
{
className: 'email-total-breaches-col',
targets: 4
},
{
className: 'email-disposable-col',
targets: 5
},
{
className: 'email-spam-col',
targets: 6
},
{
className: 'email-blacklist-col',
targets: 7
},
// TODO: return alert_list back in next release
//{
// className: 'medium-yes-no-col',
// targets: 8
//}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'email',
render: (data, type, record) => {
return renderEmail(record);
}
},
{
data: 'reputation',
render: (data, type, record) => {
return renderReputation(record);
}
},
{
data: 'free_email_provider',
render: renderBoolean
},
//{
// data: 'profiles',
// orderable: false,
// render: (data, type, record) => {
// // revert profiles to `no profiles`
// return renderBoolean(data === null ? null : !data);
// }
//},
{
data: 'data_breach',
orderable: false,
render: (data, type, record) => {
// revert data breach to `no breach`
return renderBoolean(data === null ? null : !data);
}
},
{
data: 'data_breaches',
render: renderDefaultIfEmptyElement
},
{
data: 'disposable_domains',
render: renderBoolean
},
{
data: 'blockemails',
render: renderBoolean
},
{
data: 'fraud_detected',
render: renderBoolean
},
// TODO: return alert_list back in next release
//{
// data: 'alert_list',
// render: renderBoolean
//}
];
return columns;
}
}

View File

@@ -0,0 +1,130 @@
import {BaseGridWithPanel} from './BaseWithPanel.js?v=2';
import {
renderResourceWithQueryAndEventType,
renderDeviceWithOs,
renderIpType,
renderIpWithCountry,
renderUserForEvent,
renderTimestampForEvent,
} from '../DataRenderers.js?v=2';
export class EventsGrid extends BaseGridWithPanel {
// 7, 8 - invisible time and id columns to prevent sorting buttons appearence
get orderConfig() {
return this.config.sessionGroup && !this.config.singleUser
? [[6, 'desc'], [7, 'desc'], [8, 'desc']]
: [[7, 'desc'], [8, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'event-user-col',
targets: 0
},
{
className: 'event-timestamp-col',
targets: 1
},
{
className: 'event-event-type-col',
targets: 2
},
{
className: 'event-ip-col',
targets: 3
},
{
className: 'event-ip-type-col',
targets: 4
},
{
className: 'event-device-col',
targets: 5
},
{
visible: false,
targets: 6
},
{
visible: false,
targets: 7
},
{
visible: false,
targets: 8
},
];
return columnDefs;
}
get columns() {
const userIdRender = (record) => {
return renderUserForEvent(record, 'medium', this.config.sessionGroup, this.config.singleUser);
};
const timestampRender = (record) => {
return renderTimestampForEvent(record, this.config.sessionGroup, this.config.singleUser);
};
const columns = [
{
data: 'userid',
render: (data, type, record) => {
return userIdRender(record);
},
orderable: false
},
{
data: 'time',
render: (data, type, record) => {
return timestampRender(record);
},
orderable: false
},
{
data: 'type',
render: (data, type, record) => {
return renderResourceWithQueryAndEventType(record);
},
orderable: false
},
{
data: 'ip',
render: (data, type, record) => {
return renderIpWithCountry(record);
},
orderable: false
},
{
data: 'ip_type',
name: 'ip_type',
render: (data, type, record) => {
return renderIpType(record);
},
orderable: false
},
{
data: 'device',
render: (data, type, record) => {
return renderDeviceWithOs(record);
},
orderable: false
},
{
data: 'session_id',
name: 'session_id',
},
{
data: 'time',
name: 'time',
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
}

View File

@@ -0,0 +1,136 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderIpType,
renderUserCounter,
renderNetName,
renderFullCountry,
renderAsn,
renderClickableIpWithCountry,
} from '../DataRenderers.js?v=2';
export class IpsGrid extends BaseGrid {
get orderConfig() {
return [[this.config.orderByLastseen ? 7 : 6, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'ip-ip-col',
targets: 0
},
{
className: 'ip-country-col',
targets: 1
},
{
className: 'ip-asn-col',
targets: 2
},
{
className: 'ip-newtwork-col',
targets: 3
},
{
className: 'ip-ip-type-col',
targets: 4
},
{
className: 'ip-cnt-col',
targets: 5
},
{
className: 'ip-cnt-col',
targets: 6
},
{
visible: false,
targets: 7
},
{
visible: false,
targets: 8
}
// TODO: return alert_list back in next release
//{
// className: 'yes-no-col',
// targets: 9
//}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'ip',
name: 'ip',
render: (data, type, record) => {
const rec = {
ip: record.ip,
ipid: record.id,
country_iso: record.country_iso,
full_country: record.full_country,
isp_name: record.netname,
};
return renderClickableIpWithCountry(rec);
}
},
{
data: 'full_country',
render: renderFullCountry,
},
{
data: 'asn',
name: 'asn',
render: (data, type, record) => {
return renderAsn(record);
},
},
{
data: 'netname',
name: 'netname',
render: (data, type, record) => {
return renderNetName(record, 'short');
}
},
{
data: 'ip_type',
name: 'ip_type',
orderable: false,
render: (data, type, record) => {
return renderIpType(record);
}
},
{
data: 'total_visit',
name: 'total_visit',
render: this.renderTotalsLoader
},
{
data: 'total_account',
name: 'total_account',
render: (data, type, record) => {
return renderUserCounter(data, 2);
}
},
{
data: 'lastseen',
name: 'lastseen',
},
{
data: 'id',
name: 'id',
},
// TODO: return alert_list back in next release
//{
// data: 'alert_list',
// render: renderBoolean
//}
];
return columns;
}
}

View File

@@ -0,0 +1,96 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderClickableAsn,
renderNetName,
renderUserCounter,
} from '../DataRenderers.js?v=2';
export class IspsGrid extends BaseGrid {
get orderConfig() {
return [[3, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'isp-asn-col',
targets: 0
},
{
className: 'isp-network-col',
targets: 1
},
{
className: 'isp-cnt-col',
targets: 2
},
{
className: 'isp-cnt-col',
targets: 3
},
{
className: 'isp-cnt-col',
targets: 4
},
{
className: 'isp-cnt-col',
targets: 5
},
{
visible: false,
targets: 6
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'asn',
name: 'asn',
render: (data, type, record) => {
record['ispid'] = record.id;
return renderClickableAsn(record);
}
},
{
data: 'name',
name: 'name',
render: (data, type, record) => {
record.netname = data;
return renderNetName(record, 'long');
}
},
{
data: 'total_visit',
name: 'total_visit',
render: this.renderTotalsLoader
},
{
data: 'total_ip',
name: 'total_ip',
render: this.renderTotalsLoader
},
{
data: 'total_account',
name: 'total_account',
render: this.renderTotalsLoader
},
{
data: 'fraud',
name: 'fraud',
render: (data, type, record) => {
return renderUserCounter(data, 1);
}
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
}

View File

@@ -0,0 +1,66 @@
import {BaseGridWithPanel} from './BaseWithPanel.js?v=2';
import {
renderIp,
renderTimeMs,
renderErrorType,
renderSensorErrorColumn,
} from '../DataRenderers.js?v=2';
export class LogbookGrid extends BaseGridWithPanel {
get orderConfig() {
return [[2, 'desc'], [1, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'logbook-ip-col',
targets: 0
},
{
className: 'logbook-timestamp-col',
targets: 1
},
{
className: 'logbook-status-col',
targets: 2
},
{
className: 'logbook-message-col',
targets: 3
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'ip',
render: (data, type, record) => {
return renderIp(record);
}
},
{
data: 'started',
render: renderTimeMs,
},
{
data: 'error_type',
render: (data, type, record) => {
return renderErrorType(record);
}
},
{
data: 'error_text',
render: (data, type, record) => {
return renderSensorErrorColumn(record);
}
},
];
return columns;
}
}

View File

@@ -0,0 +1,107 @@
import {BaseGridWithPanel} from './BaseWithPanel.js?v=2';
import {
renderClickableBotId,
renderDevice,
renderOs,
renderBoolean,
renderPhone,
renderFullCountry,
renderPhoneCarrierName,
renderPhoneType,
renderUserCounter,
} from '../DataRenderers.js?v=2';
export class PhonesGrid extends BaseGridWithPanel {
get orderConfig() {
return [];
}
get columnDefs() {
const columnDefs = [
{
className: 'phone-phonenumber-col',
targets: 0
},
{
className: 'phone-invalid-col',
targets: 1
},
{
className: 'phone-country-col',
targets: 2
},
{
className: 'phone-carrier-col',
targets: 3
},
{
className: 'phone-type-col',
targets: 4
},
{
className: 'phone-users-col',
targets: 5
},
{
className: 'phone-blacklist-col',
targets: 6
},
// TODO: return alert_list back in next release
//{
// className: 'yes-no-col',
// targets: 6
//}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'phonenumber',
render: (data, type, record) => {
return renderPhone(record);
}
},
{
data: 'invalid',
render: renderBoolean
},
{
data: 'full_country',
render: renderFullCountry
},
{
data: 'carrier_name',
render: (data, type, record) => {
return renderPhoneCarrierName(record);
}
},
{
data: 'type',
render: (data, type, record) => {
return renderPhoneType(record);
}
},
{
data: 'shared',
name: 'shared',
render: (data, type, record) => {
return renderUserCounter(data, 2);
}
},
{
data: 'fraud_detected',
render: renderBoolean
},
// TODO: return alert_list back in next release
//{
// data: 'alert_list',
// render: renderBoolean
//}
];
return columns;
}
}

View File

@@ -0,0 +1,99 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderClickableResourceWithoutQuery,
renderHttpCode,
renderBoolean,
} from '../DataRenderers.js?v=2';
export class ResourcesGrid extends BaseGrid {
get orderConfig() {
return [[7, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'resource-url-col',
targets: 0
},
{
className: 'resource-cnt-col',
targets: 1
},
{
className: 'resource-cnt-col',
targets: 2
},
{
className: 'resource-cnt-col',
targets: 3
},
{
className: 'resource-cnt-col',
targets: 4
},
{
className: 'resource-cnt-col',
targets: 5
},
{
className: 'resource-cnt-col',
targets: 6
},
{
visible: false,
targets: 7
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'title',
render: (data, type, record) => {
return renderClickableResourceWithoutQuery(record);
}
},
{
data: 'http_code',
render: (data, type, record) => {
return renderHttpCode(record);
}
},
{
data: 'total_account',
name: 'total_account',
render: this.renderTotalsLoader
},
{
data: 'total_country',
name: 'total_country',
render: this.renderTotalsLoader
},
{
data: 'total_ip',
name: 'total_ip',
render: this.renderTotalsLoader
},
{
data: 'total_visit',
name: 'total_visit',
render: this.renderTotalsLoader
},
{
data: 'suspicious',
render: renderBoolean,
orderable: false
},
{
data: 'id',
name: 'id',
}
];
return columns;
}
}

View File

@@ -0,0 +1,90 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderTime,
renderDate,
renderUserFirstname,
renderUserLastname,
renderUserActionButtons,
renderClickableImportantUserWithScore,
} from '../DataRenderers.js?v=2';
export class ReviewQueueGrid extends BaseGrid {
get orderConfig() {
return [[1, 'desc']];
}
onTableRowClick(event) {}
get columnDefs() {
const columnDefs = [
{
className: 'review-queue-user-col',
targets: 0
},
{
className: 'review-queue-timestamp-col',
targets: 1
},
{
className: 'review-queue-name-col',
targets: 2
},
{
className: 'review-queue-name-col',
targets: 3
},
{
className: 'review-queue-date-col',
targets: 4
},
{
className: 'review-queue-button-col',
targets: 5
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'score',
render: (data, type, record) => {
return renderClickableImportantUserWithScore(record, 'medium');
}
},
{
data: 'added_to_review',
render: renderTime
},
{
data: 'firstname',
render: (data, type, record) => {
return renderUserFirstname(record);
},
},
{
data: 'lastname',
render: (data, type, record) => {
return renderUserLastname(record);
},
},
{
data: 'created',
render: (data, type, record) => {
return renderDate(data);
},
},
{
orderable: false,
data: 'actions',
render: (data, type, record) => {
return renderUserActionButtons(record);
},
},
];
return columns;
}
}

View File

@@ -0,0 +1,91 @@
import {BaseGrid} from './Base.js?v=2';
import {fireEvent} from '../utils/Event.js?v=2';
import {handleAjaxError} from '../utils/ErrorHandler.js?v=2';
import {renderDefaultIfEmptyElement} from '../DataRenderers.js?v=2';
export class TopTenGrid extends BaseGrid {
get columnDefs() {
const columnDefs = [
{
className: 'top-ten-aggregating-col',
targets: 0
},
{
targets: 1
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'item',
render: (data, type, record) => {
return this.config.renderItemColumn(record);
},
},
{
data: 'value',
render: renderDefaultIfEmptyElement,
}
];
return columns;
}
getDataTableConfig() {
const me = this;
const columns = this.columns;
const columnDefs = this.columnDefs;
const mode = this.config.mode;
const token = document.head.querySelector('[name=\'csrf-token\'][content]').content;
const config = {
ajax: function(data, callback, settings) {
$.ajax({
url: `/admin/loadTopTen?mode=${mode}&token=${token}`,
method: 'GET',
data: data,
dataType: 'json',
success: function(response, textStatus, jqXHR) {
callback(response);
me.stopAnimation();
},
error: handleAjaxError,
complete: function() {
fireEvent('dateFilterChangedCompleted');
},
});
},
processing: true,
serverSide: true,
searching: false,
deferLoading: 0,
pageLength: 10,
paging: false,
info: false,
lengthChange: false,
ordering: false,
autoWidth: false,
info: false,
createdRow: function(row, data, dataIndex) {
$(row).attr('data-item-id', data.id);
},
drawCallback: function(settings) {
me.drawCallback(settings);
me.updateTableFooter(this);
},
columnDefs: columnDefs,
columns: columns
};
return config;
}
}

View File

@@ -0,0 +1,83 @@
import {BaseGrid} from './Base.js?v=2';
import {
currentPlanRender,
currentStatusRender,
currentUsageRender,
currentBillingEndRender,
updateCardButtonRender,
} from '../DataRenderers.js?v=2';
export class UsageStatsGrid extends BaseGrid {
// do not update counter tile
updateTableTitle(value) {
}
// do not use pagination
updateTableFooter(dataTable) {
const tableId = this.config.tableId;
const pagerSelector = `#${tableId}_wrapper .dt-paging`;
$(pagerSelector).hide();
}
get columnDefs() {
const columnDefs = [
{
className: 'subscription-plan-col',
targets: 0
},
{
className: 'subscription-status-col',
targets: 1
},
{
className: 'subscription-usage-col',
targets: 2
},
{
className: 'billing-date-col',
targets: 3
},
{
className: 'action-button-col',
targets: 4
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'sub_plan_api_calls',
render: currentPlanRender,
orderable: false,
},
{
data: 'sub_status',
render: currentStatusRender,
orderable: false,
},
{
data: 'sub_calls_used',
render: currentUsageRender,
orderable: false,
},
{
data: 'sub_next_billed',
render: currentBillingEndRender,
orderable: false,
},
{
data: 'sub_update_url',
render: updateCardButtonRender,
orderable: false,
},
];
return columns;
}
}

View File

@@ -0,0 +1,104 @@
import {BaseGrid} from './Base.js?v=2';
import {
renderClickableImportantUserWithScore,
renderDate,
renderUserFirstname,
renderUserId,
renderUserLastname,
renderUserReviewedStatus,
renderTime,
} from '../DataRenderers.js?v=2';
export class UsersGrid extends BaseGrid {
get orderConfig() {
return [[4, 'desc']];
}
get columnDefs() {
const columnDefs = [
{
className: 'user-user-col',
targets: 0
},
{
className: 'user-userid-col',
targets: 1
},
{
className: 'user-name-col',
targets: 2
},
{
className: 'user-name-col',
targets: 3
},
{
className: 'user-date-col',
targets: 4
},
{
className: 'user-timestamp-col',
targets: 5
},
{
className: 'user-status-col',
targets: 6
},
{
visible: false,
targets: 7
}
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'score',
render: (data, type, record) => {
return renderClickableImportantUserWithScore(record, 'medium');
}
},
{
data: 'accounttitle',
render: renderUserId
},
{
data: 'firstname',
render: (data, type, record) => {
return renderUserFirstname(record);
},
},
{
data: 'lastname',
render: (data, type, record) => {
return renderUserLastname(record);
},
},
{
data: 'created',
render: renderDate,
},
{
data: 'lastseen',
render: renderTime,
},
{
data: 'fraud',
render: (data, type, record) => {
return renderUserReviewedStatus(record);
},
},
{
data: 'id',
name: 'id',
},
];
return columns;
}
}

View File

@@ -0,0 +1,73 @@
import {BaseGrid} from '../Base.js?v=2';
import {
renderDate,
renderAuditField,
renderAuditValue,
renderAuditParent,
} from '../../DataRenderers.js?v=2';
export class FieldAuditTrailGrid extends BaseGrid {
get orderConfig() {
return [];
}
get columnDefs() {
const columnDefs = [
{
className: 'field-audit-trail-date-col',
targets: 0
},
{
className: 'field-audit-trail-field-col',
targets: 1
},
{
className: 'field-audit-trail-value-col',
targets: 2
},
{
className: 'field-audit-trail-value-col',
targets: 3
},
{
className: 'field-audit-trail-parent-col',
targets: 4
},
];
return columnDefs;
}
get columns() {
const columns = [
{
data: 'created',
render: (data, type, record) => {
return renderDate(data);
},
},
{
data: 'field_id',
render: (data, type, record) => {
return renderAuditField(record);
},
},
{
data: 'old_value',
render: renderAuditValue,
},
{
data: 'new_value',
render: renderAuditValue,
},
{
data: 'parent_id',
render: (data, type, record) => {
return renderAuditParent(record);
},
},
];
return columns;
}
}