chg: [js] Replaced moment.js by day.js

3.x-inbox
Sami Mokaddem 2024-01-08 16:21:37 +01:00
parent 3da5d145d2
commit d3dc68903a
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
7 changed files with 378 additions and 347 deletions

View File

@ -2,315 +2,318 @@
use Cake\Core\Configure;
echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'data' => $data,
'top_bar' => [
'children' => [
[
'type' => 'multi_select_actions',
'force-dropdown' => true,
'children' => [
['is-header' => true, 'text' => __('Toggle selected users'), 'icon' => 'user-times',],
[
'text' => __('Disable users'),
'variant' => 'warning',
'outline' => true,
'onclick' => 'disableUsers',
echo $this->element(
'genericElements/IndexTable/index_table',
[
'data' => [
'data' => $data,
'top_bar' => [
'children' => [
[
'type' => 'multi_select_actions',
'force-dropdown' => true,
'children' => [
['is-header' => true, 'text' => __('Toggle selected users'), 'icon' => 'user-times',],
[
'text' => __('Disable users'),
'variant' => 'warning',
'outline' => true,
'onclick' => 'disableUsers',
],
[
'text' => __('Enable users'),
'variant' => 'success',
'outline' => true,
'onclick' => 'enableUsers',
],
['is-header' => true, 'text' => __('Publishing alert'), 'icon' => 'bell',],
[
'text' => __('Disable publishing emailing'),
'onclick' => 'disablePublishingEmailing',
],
[
'text' => __('Enable publishing emailing'),
'onclick' => 'enablePublishingEmailing',
],
],
[
'text' => __('Enable users'),
'variant' => 'success',
'outline' => true,
'onclick' => 'enableUsers',
],
['is-header' => true, 'text' => __('Publishing alert'), 'icon' => 'bell',],
[
'text' => __('Disable publishing emailing'),
'onclick' => 'disablePublishingEmailing',
],
[
'text' => __('Enable publishing emailing'),
'onclick' => 'enablePublishingEmailing',
],
],
'data' => [
'id' => [
'value_path' => 'id'
]
]
],
[
'type' => 'simple',
'children' => [
'data' => [
'type' => 'simple',
'icon' => 'plus',
'text' => __('Add User'),
'class' => 'btn btn-primary',
'popover_url' => '/users/add',
'button' => [
'icon' => 'plus',
'id' => [
'value_path' => 'id'
]
]
]
],
[
'type' => 'context_filters',
],
[
'type' => 'search',
'button' => __('Search'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value',
'allowFilering' => true
],
[
'type' => 'table_action',
],
]
],
'fields' => [
[
'name' => __('ID'),
'sort' => 'id',
'class' => 'short',
'data_path' => 'id'
],
[
'name' => __('Org'),
'sort' => 'org_id',
'element' => 'org',
'data_path' => 'Organisation'
],
[
'name' => __('Role'),
'sort' => 'role_id',
'class' => 'short',
'element' => 'role',
'data_path' => 'Role'
],
[
'name' => __('Email'),
'sort' => 'email',
'data_path' => 'email'
],
[
'name' => '',
'header_title' => __('Contact alert'),
'icon' => 'handshake',
'element' => 'boolean',
'sort' => 'contactalert',
'class' => 'short',
'data_path' => 'contactalert',
'colors' => true,
],
[
'name' => '',
'header_title' => __('Notification'),
'sort' => 'id',
'data_path' => 'id',
'icon' => 'clock',
'element' => 'function',
'class' => 'short',
'function' => function (\Cake\Datasource\EntityInterface $user) use ($periodic_notifications) {
$subscriptions = [];
if ($user['autoalert']) {
$subscriptions[] = 'e';
}
foreach ($periodic_notifications as $period) {
if (!empty($user['User'][$period])) {
$subscriptions[] = substr($period, 13, 1);
}
}
return implode('/', $subscriptions);
}
],
[
'name' => '',
'header_title' => __('PGP public key'),
'icon' => 'key',
'element' => 'boolean',
'sort' => 'gpgkey',
'class' => 'short',
'data_path' => 'gpgkey',
'colors' => true,
],
[
'name' => '',
'header_title' => __('S/MIME public key'),
'icon' => 'lock',
'element' => 'boolean',
'sort' => 'certif_public',
'class' => 'short',
'data_path' => 'certif_public',
'requirement' => Configure::read('SMIME.enabled')
],
[
'name' => __('SID'),
'sort' => 'nids_sid',
'class' => 'short',
'data_path' => 'nids_sid'
],
[
'name' => '',
'header_title' => __('Terms accepted'),
'icon' => 'gavel',
'element' => 'boolean',
'sort' => 'termsaccepted',
'class' => 'short',
'data_path' => 'termsaccepted',
'colors' => true,
],
[
'name' => __('Last Login'),
'sort' => 'current_login',
'element' => 'datetime',
'empty' => __('Never'),
'class' => 'short',
'data_path' => 'current_login'
],
[
'name' => __('Created'),
'sort' => 'date_created',
'element' => 'datetime',
'class' => 'short',
'data_path' => 'date_created'
],
[
'name' => '',
'header_title' => __('Monitored'),
'icon' => 'desktop',
'element' => 'toggle',
'url' => $baseurl . '/admin/users/monitor',
'url_params_vars' => [
],
[
'datapath' => [
'id'
'type' => 'simple',
'children' => [
'data' => [
'type' => 'simple',
'icon' => 'plus',
'text' => __('Add User'),
'class' => 'btn btn-primary',
'popover_url' => '/users/add',
'button' => [
'icon' => 'plus',
]
]
]
],
[
'type' => 'context_filters',
],
[
'type' => 'search',
'button' => __('Search'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value',
'allowFilering' => true
],
[
'type' => 'table_action',
],
]
],
'fields' => [
[
'name' => __('ID'),
'sort' => 'id',
'class' => 'short',
'data_path' => 'id'
],
[
'name' => __('Org'),
'sort' => 'org_id',
'element' => 'org',
'data_path' => 'Organisation'
],
[
'name' => __('Role'),
'sort' => 'role_id',
'class' => 'short',
'element' => 'role',
'data_path' => 'Role'
],
[
'name' => __('Email'),
'sort' => 'email',
'data_path' => 'email'
],
[
'name' => '',
'header_title' => __('Contact alert'),
'icon' => 'handshake',
'element' => 'boolean',
'sort' => 'contactalert',
'class' => 'short',
'data_path' => 'contactalert',
'colors' => true,
],
[
'name' => '',
'header_title' => __('Notification'),
'sort' => 'id',
'data_path' => 'id',
'icon' => 'clock',
'element' => 'function',
'class' => 'short',
'function' => function (\Cake\Datasource\EntityInterface $user) use ($periodic_notifications) {
$subscriptions = [];
if ($user['autoalert']) {
$subscriptions[] = 'e';
}
foreach ($periodic_notifications as $period) {
if (!empty($user['User'][$period])) {
$subscriptions[] = substr($period, 13, 1);
}
}
return implode('/', $subscriptions);
}
],
[
'name' => '',
'header_title' => __('PGP public key'),
'icon' => 'key',
'element' => 'boolean',
'sort' => 'gpgkey',
'class' => 'short',
'data_path' => 'gpgkey',
'colors' => true,
],
[
'name' => '',
'header_title' => __('S/MIME public key'),
'icon' => 'lock',
'element' => 'boolean',
'sort' => 'certif_public',
'class' => 'short',
'data_path' => 'certif_public',
'requirement' => Configure::read('SMIME.enabled')
],
[
'name' => __('SID'),
'sort' => 'nids_sid',
'class' => 'short',
'data_path' => 'nids_sid'
],
[
'name' => '',
'header_title' => __('Terms accepted'),
'icon' => 'gavel',
'element' => 'boolean',
'sort' => 'termsaccepted',
'class' => 'short',
'data_path' => 'termsaccepted',
'colors' => true,
],
[
'name' => __('Last Login'),
'sort' => 'current_login',
'element' => 'datetime',
'empty' => __('Never'),
'class' => 'short',
'data_path' => 'current_login'
],
[
'name' => __('Created'),
'sort' => 'date_created',
'element' => 'datetime',
'class' => 'short',
'data_path' => 'date_created'
],
[
'name' => '',
'header_title' => __('Monitored'),
'icon' => 'desktop',
'element' => 'toggle',
'url' => $baseurl . '/admin/users/monitor',
'url_params_vars' => [
[
'datapath' => [
'id'
]
]
],
'sort' => 'monitored',
'class' => 'short',
'data_path' => 'monitored',
/*'requirement' => $isSiteAdmin && Configure::read('Security.user_monitoring_enabled')*/
],
[
'name' => __('Last API Access'),
'sort' => 'last_api_access',
'element' => 'datetime',
'class' => 'short',
'data_path' => 'last_api_access',
'requirement' => !empty(Configure::read('MISP.store_api_access_time')),
],
[
'name' => (Configure::read('Plugin.CustomAuth_name') ? Configure::read('Plugin.CustomAuth_name') : __('External Auth')),
'sort' => 'external_auth_required',
'element' => 'boolean',
'class' => 'short',
'data_path' => 'external_auth_required',
'requirement' => Configure::read('Plugin.CustomAuth_enable') && empty(Configure::read('Plugin.CustomAuth_required'))
],
[
'name' => '',
'header_title' => __('Monitored'),
'icon' => 'desktop',
'element' => 'toggle',
'url' => $baseurl . '/admin/users/monitor',
'url_params_data_paths' => [
'id'
],
'sort' => 'monitored',
'class' => 'short',
'data_path' => 'monitored',
'requirement' => $isSiteAdmin && Configure::read('Security.user_monitoring_enabled')
],
[
'name' => '',
'header_title' => __('User disabled'),
'icon' => 'times',
'element' => 'boolean',
'sort' => 'disabled',
'class' => 'short',
'data_path' => 'disabled',
'colors' => true,
],
[
'name' => __('Disabled'),
'sort' => 'disabled',
'data_path' => 'disabled',
'element' => 'toggle',
'url' => '/users/toggle/{{0}}',
'url_params_vars' => ['id'],
'toggle_data' => [
'editRequirement' => [
'function' => function ($row, $options) {
return true;
},
],
'skip_full_reload' => true
]
]
],
'title' => __('User index'),
'description' => __('The list of enrolled users in this Cerebrate instance. All of the users have or at one point had access to the system.'),
'pull' => 'right',
'actions' => [
[
'url' => '/users/view',
'url_params_data_paths' => ['id'],
'icon' => 'eye'
],
[
'open_modal' => '/users/edit/[onclick_params_data_path]',
'modal_params_data_path' => 'id',
'icon' => 'edit',
'complex_requirement' => [
'options' => [
'datapath' => [
'role_id' => 'role_id'
]
],
'function' => function ($row, $options) use ($loggedUser, $validRoles) {
if (empty($loggedUser['role']['perm_admin'])) {
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
}
]
],
'sort' => 'monitored',
'class' => 'short',
'data_path' => 'monitored',
/*'requirement' => $isSiteAdmin && Configure::read('Security.user_monitoring_enabled')*/
],
[
'name' => __('Last API Access'),
'sort' => 'last_api_access',
'element' => 'datetime',
'class' => 'short',
'data_path' => 'last_api_access',
'requirement' => !empty(Configure::read('MISP.store_api_access_time')),
],
[
'name' => (Configure::read('Plugin.CustomAuth_name') ? Configure::read('Plugin.CustomAuth_name') : __('External Auth')),
'sort' => 'external_auth_required',
'element' => 'boolean',
'class' => 'short',
'data_path' => 'external_auth_required',
'requirement' => Configure::read('Plugin.CustomAuth_enable') && empty(Configure::read('Plugin.CustomAuth_required'))
],
[
'name' => '',
'header_title' => __('Monitored'),
'icon' => 'desktop',
'element' => 'toggle',
'url' => $baseurl . '/admin/users/monitor',
'url_params_data_paths' => array(
'id'
),
'sort' => 'monitored',
'class' => 'short',
'data_path' => 'monitored',
'requirement' => $isSiteAdmin && Configure::read('Security.user_monitoring_enabled')
],
[
'name' => '',
'header_title' => __('User disabled'),
'icon' => 'times',
'element' => 'boolean',
'sort' => 'disabled',
'class' => 'short',
'data_path' => 'disabled',
'colors' => true,
],
[
'name' => __('Disabled'),
'sort' => 'disabled',
'data_path' => 'disabled',
'element' => 'toggle',
'url' => '/users/toggle/{{0}}',
'url_params_vars' => ['id'],
'toggle_data' => [
'editRequirement' => [
'function' => function ($row, $options) {
[
'open_modal' => '/users/delete/[onclick_params_data_path]',
'modal_params_data_path' => 'id',
'icon' => 'trash',
'complex_requirement' => [
'options' => [
'datapath' => [
'role_id' => 'role_id'
]
],
'function' => function ($row, $options) use ($loggedUser, $validRoles) {
if (empty($loggedUser['role']['perm_admin'])) {
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
},
],
'skip_full_reload' => true
]
}
]
],
]
],
'title' => __('User index'),
'description' => __('The list of enrolled users in this Cerebrate instance. All of the users have or at one point had access to the system.'),
'pull' => 'right',
'actions' => [
[
'url' => '/users/view',
'url_params_data_paths' => ['id'],
'icon' => 'eye'
],
[
'open_modal' => '/users/edit/[onclick_params_data_path]',
'modal_params_data_path' => 'id',
'icon' => 'edit',
'complex_requirement' => [
'options' => [
'datapath' => [
'role_id' => 'role_id'
]
],
'function' => function ($row, $options) use ($loggedUser, $validRoles) {
if (empty($loggedUser['role']['perm_admin'])) {
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
}
]
],
[
'open_modal' => '/users/delete/[onclick_params_data_path]',
'modal_params_data_path' => 'id',
'icon' => 'trash',
'complex_requirement' => [
'options' => [
'datapath' => [
'role_id' => 'role_id'
]
],
'function' => function ($row, $options) use ($loggedUser, $validRoles) {
if (empty($loggedUser['role']['perm_admin'])) {
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
}
]
],
]
]
]);
);
?>
<script>
@ -348,4 +351,4 @@ echo $this->element('genericElements/IndexTable/index_table', [
$idsInput.val(JSON.stringify(idList))
})
}
</script>
</script>

View File

@ -7,9 +7,9 @@ $variant = empty($notification['variant']) ? 'primary' : $notification['variant'
?>
<a
class="notification-item dropdown-item px-2 btn"
<?php if (empty($notification['_useModal'])): ?>
<?php if (empty($notification['_useModal'])) : ?>
href="<?= Router::url($notification['router']) ?>"
<?php else: ?>
<?php else : ?>
onclick="UI.submissionModal('<?= Router::url($notification['router']) ?>', {closeOnSuccess: false})"
<?php endif; ?>
title="<?= sprintf('%s:&#010; %s', $this->ValueGetter->get($notification['text']), $this->ValueGetter->get($notification['details'])) ?>"
@ -36,5 +36,5 @@ $variant = empty($notification['variant']) ? 'primary' : $notification['variant'
</div>
</a>
<script>
document.getElementById('<?= $seed ?>').innerHTML = moment(document.getElementById('<?= $seed ?>').innerHTML).fromNow();
document.getElementById('<?= $seed ?>').innerHTML = dayjs(document.getElementById('<?= $seed ?>').innerHTML).fromNow();
</script>

View File

@ -2,11 +2,14 @@
use Cake\Utility\Inflector;
$tableItems = array_map(function ($fieldName) {
return [
'fieldname' => $fieldName,
];
}, $filters);
$tableItems = array_map(
function ($fieldName) {
return [
'fieldname' => $fieldName,
];
},
$filters
);
$formTypeMap = $this->Form->getConfig('typeMap');
$filteringForm = $this->Bootstrap->table(
@ -70,13 +73,18 @@ $filteringForm = $this->Bootstrap->table(
];
}
$fieldData = array_merge($fieldData, $filtersConfig[$fieldName]);
$this->Form->setTemplates([
'formGroup' => '<div class="col-sm-10">{{input}}</div>',
]);
return $this->element('genericElements/Form/fieldScaffold', [
'fieldData' => $fieldData,
'params' => []
]);
$this->Form->setTemplates(
[
'formGroup' => '<div class="col-sm-10">{{input}}</div>',
]
);
return $this->element(
'genericElements/Form/fieldScaffold',
[
'fieldData' => $fieldData,
'params' => []
]
);
}
],
],
@ -86,44 +94,59 @@ $filteringForm = $this->Bootstrap->table(
$filteringMetafields = '';
if ($metaFieldsEnabled) {
$helpText = $this->Bootstrap->node('sup', [
'class' => ['ms-1 fa fa-info'],
'title' => __('Include help'),
'data-bs-toggle' => 'tooltip',
]);
$helpText = $this->Bootstrap->node(
'sup',
[
'class' => ['ms-1 fa fa-info'],
'title' => __('Include help'),
'data-bs-toggle' => 'tooltip',
]
);
$filteringMetafields = $this->Bootstrap->node('h5', [], __('Meta Fields') . $helpText);
$filteringMetafields .= $this->element('genericElements/IndexTable/metafield_filtering', $metaTemplates);
}
$filteringTags = '';
if ($taggingEnabled) {
$helpText = $this->Bootstrap->node('sup', [
'class' => ['ms-1 fa fa-info'],
'title' => __('Supports negation matches (with the `!` character) and LIKE matches (with the `%` character).&#10;Example: `!exportable`, `%able`'),
'data-bs-toggle' => 'tooltip',
]);
$filteringTags = $this->Bootstrap->node('h5', [
'class' => 'mt-2'
], __('Tags') . $helpText);
$filteringTags .= $this->Tag->tags([], [
'allTags' => $allTags,
'picker' => true,
'editable' => false,
]);
$helpText = $this->Bootstrap->node(
'sup',
[
'class' => ['ms-1 fa fa-info'],
'title' => __('Supports negation matches (with the `!` character) and LIKE matches (with the `%` character).&#10;Example: `!exportable`, `%able`'),
'data-bs-toggle' => 'tooltip',
]
);
$filteringTags = $this->Bootstrap->node(
'h5',
[
'class' => 'mt-2'
],
__('Tags') . $helpText
);
$filteringTags .= $this->Tag->tags(
[],
[
'allTags' => $allTags,
'picker' => true,
'editable' => false,
]
);
}
$modalBody = implode('', [$filteringForm, $filteringMetafields, $filteringTags]);
echo $this->Bootstrap->modal([
'title' => __('Filtering options for {0}', Inflector::singularize($this->request->getParam('controller'))),
'size' => !empty($metaFieldsEnabled) ? 'xl' : 'lg',
'type' => 'confirm',
'bodyHtml' => $modalBody,
'confirmButton' => [
'text' => __('Filter'),
],
'confirmFunction' => 'filterIndex'
]);
echo $this->Bootstrap->modal(
[
'title' => __('Filtering options for {0}', Inflector::singularize($this->request->getParam('controller'))),
'size' => !empty($metaFieldsEnabled) ? 'xl' : 'lg',
'type' => 'confirm',
'bodyHtml' => $modalBody,
'confirmButton' => [
'text' => __('Filter'),
],
'confirmFunction' => 'filterIndex'
]
);
?>
<script>
@ -199,7 +222,7 @@ echo $this->Bootstrap->modal([
$row.find('.fieldOperator').val(operator)
const $formElement = $row.find('.fieldValue');
if ($formElement.attr('type') === 'datetime-local') {
$formElement.val(moment(value).format('yyyy-MM-DDThh:mm:ss'))
$formElement.val(dayjs(value).format('YYYY-MM-DD[T]HH:mm:ss'))
} else if ($formElement.is('select') && Array.isArray(value)) {
let newOptions = [];
value.forEach(aValue => {
@ -243,7 +266,7 @@ echo $this->Bootstrap->modal([
rowData['operator'] = $row.find('select.fieldOperator').val()
const $formElement = $row.find('.fieldValue');
if ($formElement.attr('type') === 'datetime-local') {
rowData['value'] = $formElement.val().length > 0 ? moment($formElement.val()).toISOString() : $formElement.val()
rowData['value'] = $formElement.val().length > 0 ? dayjs($formElement.val()).toISOString() : $formElement.val()
} else if ($formElement.attr('type') === 'radio') {
rowData['value'] = $formElement.filter(':checked').val()
} else {

View File

@ -13,7 +13,6 @@
* @license https://opensource.org/licenses/mit-license.php MIT License
* @var \App\View\AppView $this
*/
use Cake\Core\Configure;
$cakeDescription = 'MISP';
@ -61,7 +60,8 @@ $sidebarOpen = $loggedUser->user_settings_by_name_with_fallback['ui.sidebar.expa
<?= $this->Html->css('select2.min') ?>
<?= $this->Html->css('select2-bootstrap5-vars') ?>
<?= $this->Html->script('apexcharts.min') ?>
<?= $this->Html->script('moment-with-locales.min') ?>
<?= $this->Html->script('dayjs.min') ?>
<?= $this->Html->script('dayjs_plugins/relativeTime.min.js') ?>
<?= $this->Html->css('apexcharts') ?>
<?= $this->fetch('meta') ?>
@ -73,6 +73,11 @@ $sidebarOpen = $loggedUser->user_settings_by_name_with_fallback['ui.sidebar.expa
<?= $this->Html->meta('favicon-misp.png', '/img/favicon-misp.png', ['type' => 'icon']); ?>
</head>
<script>
dayjs.extend(window.dayjs_plugin_relativeTime)
</script>
<body>
<div class="main-wrapper">
<header class="navbar top-navbar navbar-dark">

1
webroot/js/dayjs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).dayjs_plugin_relativeTime=r()}(this,function(){"use strict";return function(p,e,v){p=p||{};var o=e.prototype,M={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function t(e,r,t,n){return o.fromToBase(e,r,t,n)}v.en.relativeTime=M,o.fromToBase=function(e,r,t,n,o){for(var i,d,u=t.$locale().relativeTime||M,f=p.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],a=f.length,s=0;s<a;s+=1){var l=f[s],h=(l.d&&(i=n?v(e).diff(t,l.d,!0):t.diff(e,l.d,!0)),(p.rounding||Math.round)(Math.abs(i))),m=0<i;if(h<=l.r||!l.r){var c=u[(l=h<=1&&0<s?f[s-1]:l).l];o&&(h=o(""+h)),d="string"==typeof c?c.replace("%d",h):c(h,r,l.l,m);break}}if(r)return d;var y=m?u.future:u.past;return"function"==typeof y?y(d):y.replace("%s",d)},o.to=function(e,r){return t(e,r,this,!0)},o.from=function(e,r){return t(e,r,this)};function r(e){return e.$u?v.utc():v()}o.toNow=function(e){return this.to(r(this),e)},o.fromNow=function(e){return this.from(r(this),e)}}});

File diff suppressed because one or more lines are too long