Merge branch 'pr/FreddleSpl0it/4527' into feature/bootstrap5
This commit is contained in:
2
data/web/js/build/000-jquery-3.6.0.min.js
vendored
Normal file
2
data/web/js/build/000-jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
data/web/js/build/000-jquery.min.js
vendored
4
data/web/js/build/000-jquery.min.js
vendored
File diff suppressed because one or more lines are too long
7
data/web/js/build/001-bootstrap.bundle.min.js
vendored
Normal file
7
data/web/js/build/001-bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
data/web/js/build/001-bootstrap.min.js
vendored
7
data/web/js/build/001-bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
3583
data/web/js/build/004-bootstrap-select.js
Normal file
3583
data/web/js/build/004-bootstrap-select.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
2
data/web/js/build/006-notifications.min.js
vendored
2
data/web/js/build/006-notifications.min.js
vendored
File diff suppressed because one or more lines are too long
7
data/web/js/build/008-Chart.min.js
vendored
7
data/web/js/build/008-Chart.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
13269
data/web/js/build/008-chart.js
Normal file
13269
data/web/js/build/008-chart.js
Normal file
File diff suppressed because it is too large
Load Diff
7
data/web/js/build/008-chartjs-plugin-datalabels.js
Normal file
7
data/web/js/build/008-chartjs-plugin-datalabels.js
Normal file
File diff suppressed because one or more lines are too long
18694
data/web/js/build/011-datatables.js
Normal file
18694
data/web/js/build/011-datatables.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,778 +0,0 @@
|
||||
//Copyright 2014-2015 Google Inc. All rights reserved.
|
||||
|
||||
//Use of this source code is governed by a BSD-style
|
||||
//license that can be found in the LICENSE file or at
|
||||
//https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
// ref: https://github.com/google/u2f-ref-code/blob/master/u2f-gae-demo/war/js/u2f-api.js
|
||||
|
||||
/**
|
||||
* @fileoverview The U2F api.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Modification:
|
||||
* Wrap implementation so that we can exit if window.u2f is already supplied by the browser (see below).
|
||||
*/
|
||||
(function (root) {
|
||||
/**
|
||||
* Modification:
|
||||
* Only continue load this library if window.u2f is not already supplied by the browser.
|
||||
*/
|
||||
var browserImplementsU2f = !!((typeof root.u2f !== 'undefined') && root.u2f.register);
|
||||
|
||||
if (browserImplementsU2f) {
|
||||
root.u2f.isSupported = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespace for the U2F api.
|
||||
* @type {Object}
|
||||
*/
|
||||
var u2f = root.u2f || {};
|
||||
|
||||
/**
|
||||
* Modification:
|
||||
* Check if browser supports U2F API before this wrapper was added.
|
||||
*/
|
||||
u2f.isSupported = !!(((typeof u2f !== 'undefined') && u2f.register) || ((typeof chrome !== 'undefined') && chrome.runtime));
|
||||
|
||||
/**
|
||||
* FIDO U2F Javascript API Version
|
||||
* @number
|
||||
*/
|
||||
var js_api_version;
|
||||
|
||||
/**
|
||||
* The U2F extension id
|
||||
* @const {string}
|
||||
*/
|
||||
// The Chrome packaged app extension ID.
|
||||
// Uncomment this if you want to deploy a server instance that uses
|
||||
// the package Chrome app and does not require installing the U2F Chrome extension.
|
||||
u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd';
|
||||
// The U2F Chrome extension ID.
|
||||
// Uncomment this if you want to deploy a server instance that uses
|
||||
// the U2F Chrome extension to authenticate.
|
||||
// u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne';
|
||||
|
||||
|
||||
/**
|
||||
* Message types for messsages to/from the extension
|
||||
* @const
|
||||
* @enum {string}
|
||||
*/
|
||||
u2f.MessageTypes = {
|
||||
'U2F_REGISTER_REQUEST': 'u2f_register_request',
|
||||
'U2F_REGISTER_RESPONSE': 'u2f_register_response',
|
||||
'U2F_SIGN_REQUEST': 'u2f_sign_request',
|
||||
'U2F_SIGN_RESPONSE': 'u2f_sign_response',
|
||||
'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request',
|
||||
'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response status codes
|
||||
* @const
|
||||
* @enum {number}
|
||||
*/
|
||||
u2f.ErrorCodes = {
|
||||
'OK': 0,
|
||||
'OTHER_ERROR': 1,
|
||||
'BAD_REQUEST': 2,
|
||||
'CONFIGURATION_UNSUPPORTED': 3,
|
||||
'DEVICE_INELIGIBLE': 4,
|
||||
'TIMEOUT': 5
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A message for registration requests
|
||||
* @typedef {{
|
||||
* type: u2f.MessageTypes,
|
||||
* appId: ?string,
|
||||
* timeoutSeconds: ?number,
|
||||
* requestId: ?number
|
||||
* }}
|
||||
*/
|
||||
u2f.U2fRequest;
|
||||
|
||||
|
||||
/**
|
||||
* A message for registration responses
|
||||
* @typedef {{
|
||||
* type: u2f.MessageTypes,
|
||||
* responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse),
|
||||
* requestId: ?number
|
||||
* }}
|
||||
*/
|
||||
u2f.U2fResponse;
|
||||
|
||||
|
||||
/**
|
||||
* An error object for responses
|
||||
* @typedef {{
|
||||
* errorCode: u2f.ErrorCodes,
|
||||
* errorMessage: ?string
|
||||
* }}
|
||||
*/
|
||||
u2f.Error;
|
||||
|
||||
/**
|
||||
* Data object for a single sign request.
|
||||
* @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC}}
|
||||
*/
|
||||
u2f.Transport;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a single sign request.
|
||||
* @typedef {Array<u2f.Transport>}
|
||||
*/
|
||||
u2f.Transports;
|
||||
|
||||
/**
|
||||
* Data object for a single sign request.
|
||||
* @typedef {{
|
||||
* version: string,
|
||||
* challenge: string,
|
||||
* keyHandle: string,
|
||||
* appId: string
|
||||
* }}
|
||||
*/
|
||||
u2f.SignRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a sign response.
|
||||
* @typedef {{
|
||||
* keyHandle: string,
|
||||
* signatureData: string,
|
||||
* clientData: string
|
||||
* }}
|
||||
*/
|
||||
u2f.SignResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a registration request.
|
||||
* @typedef {{
|
||||
* version: string,
|
||||
* challenge: string
|
||||
* }}
|
||||
*/
|
||||
u2f.RegisterRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a registration response.
|
||||
* @typedef {{
|
||||
* version: string,
|
||||
* keyHandle: string,
|
||||
* transports: Transports,
|
||||
* appId: string
|
||||
* }}
|
||||
*/
|
||||
u2f.RegisterResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a registered key.
|
||||
* @typedef {{
|
||||
* version: string,
|
||||
* keyHandle: string,
|
||||
* transports: ?Transports,
|
||||
* appId: ?string
|
||||
* }}
|
||||
*/
|
||||
u2f.RegisteredKey;
|
||||
|
||||
|
||||
/**
|
||||
* Data object for a get API register response.
|
||||
* @typedef {{
|
||||
* js_api_version: number
|
||||
* }}
|
||||
*/
|
||||
u2f.GetJsApiVersionResponse;
|
||||
|
||||
|
||||
//Low level MessagePort API support
|
||||
|
||||
/**
|
||||
* Sets up a MessagePort to the U2F extension using the
|
||||
* available mechanisms.
|
||||
* @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
|
||||
*/
|
||||
u2f.getMessagePort = function (callback) {
|
||||
if (typeof chrome != 'undefined' && chrome.runtime) {
|
||||
// The actual message here does not matter, but we need to get a reply
|
||||
// for the callback to run. Thus, send an empty signature request
|
||||
// in order to get a failure response.
|
||||
var msg = {
|
||||
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
|
||||
signRequests: []
|
||||
};
|
||||
chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function () {
|
||||
if (!chrome.runtime.lastError) {
|
||||
// We are on a whitelisted origin and can talk directly
|
||||
// with the extension.
|
||||
u2f.getChromeRuntimePort_(callback);
|
||||
} else {
|
||||
// chrome.runtime was available, but we couldn't message
|
||||
// the extension directly, use iframe
|
||||
u2f.getIframePort_(callback);
|
||||
}
|
||||
});
|
||||
} else if (u2f.isAndroidChrome_()) {
|
||||
u2f.getAuthenticatorPort_(callback);
|
||||
} else if (u2f.isIosChrome_()) {
|
||||
u2f.getIosPort_(callback);
|
||||
} else {
|
||||
// chrome.runtime was not available at all, which is normal
|
||||
// when this origin doesn't have access to any extensions.
|
||||
u2f.getIframePort_(callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect chrome running on android based on the browser's useragent.
|
||||
* @private
|
||||
*/
|
||||
u2f.isAndroidChrome_ = function () {
|
||||
var userAgent = navigator.userAgent;
|
||||
return userAgent.indexOf('Chrome') != -1 &&
|
||||
userAgent.indexOf('Android') != -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect chrome running on iOS based on the browser's platform.
|
||||
* @private
|
||||
*/
|
||||
u2f.isIosChrome_ = function () {
|
||||
return ["iPhone", "iPad", "iPod"].indexOf(navigator.platform) > -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects directly to the extension via chrome.runtime.connect.
|
||||
* @param {function(u2f.WrappedChromeRuntimePort_)} callback
|
||||
* @private
|
||||
*/
|
||||
u2f.getChromeRuntimePort_ = function (callback) {
|
||||
var port = chrome.runtime.connect(u2f.EXTENSION_ID,
|
||||
{ 'includeTlsChannelId': true });
|
||||
setTimeout(function () {
|
||||
callback(new u2f.WrappedChromeRuntimePort_(port));
|
||||
}, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a 'port' abstraction to the Authenticator app.
|
||||
* @param {function(u2f.WrappedAuthenticatorPort_)} callback
|
||||
* @private
|
||||
*/
|
||||
u2f.getAuthenticatorPort_ = function (callback) {
|
||||
setTimeout(function () {
|
||||
callback(new u2f.WrappedAuthenticatorPort_());
|
||||
}, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a 'port' abstraction to the iOS client app.
|
||||
* @param {function(u2f.WrappedIosPort_)} callback
|
||||
* @private
|
||||
*/
|
||||
u2f.getIosPort_ = function (callback) {
|
||||
setTimeout(function () {
|
||||
callback(new u2f.WrappedIosPort_());
|
||||
}, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* A wrapper for chrome.runtime.Port that is compatible with MessagePort.
|
||||
* @param {Port} port
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
u2f.WrappedChromeRuntimePort_ = function (port) {
|
||||
this.port_ = port;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format and return a sign request compliant with the JS API version supported by the extension.
|
||||
* @param {Array<u2f.SignRequest>} signRequests
|
||||
* @param {number} timeoutSeconds
|
||||
* @param {number} reqId
|
||||
* @return {Object}
|
||||
*/
|
||||
u2f.formatSignRequest_ =
|
||||
function (appId, challenge, registeredKeys, timeoutSeconds, reqId) {
|
||||
if (js_api_version === undefined || js_api_version < 1.1) {
|
||||
// Adapt request to the 1.0 JS API
|
||||
var signRequests = [];
|
||||
for (var i = 0; i < registeredKeys.length; i++) {
|
||||
signRequests[i] = {
|
||||
version: registeredKeys[i].version,
|
||||
challenge: challenge,
|
||||
keyHandle: registeredKeys[i].keyHandle,
|
||||
appId: appId
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
|
||||
signRequests: signRequests,
|
||||
timeoutSeconds: timeoutSeconds,
|
||||
requestId: reqId
|
||||
};
|
||||
}
|
||||
// JS 1.1 API
|
||||
return {
|
||||
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
|
||||
appId: appId,
|
||||
challenge: challenge,
|
||||
registeredKeys: registeredKeys,
|
||||
timeoutSeconds: timeoutSeconds,
|
||||
requestId: reqId
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Format and return a register request compliant with the JS API version supported by the extension..
|
||||
* @param {Array<u2f.SignRequest>} signRequests
|
||||
* @param {Array<u2f.RegisterRequest>} signRequests
|
||||
* @param {number} timeoutSeconds
|
||||
* @param {number} reqId
|
||||
* @return {Object}
|
||||
*/
|
||||
u2f.formatRegisterRequest_ =
|
||||
function (appId, registeredKeys, registerRequests, timeoutSeconds, reqId) {
|
||||
if (js_api_version === undefined || js_api_version < 1.1) {
|
||||
// Adapt request to the 1.0 JS API
|
||||
for (var i = 0; i < registerRequests.length; i++) {
|
||||
registerRequests[i].appId = appId;
|
||||
}
|
||||
var signRequests = [];
|
||||
for (var i = 0; i < registeredKeys.length; i++) {
|
||||
signRequests[i] = {
|
||||
version: registeredKeys[i].version,
|
||||
challenge: registerRequests[0],
|
||||
keyHandle: registeredKeys[i].keyHandle,
|
||||
appId: appId
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
|
||||
signRequests: signRequests,
|
||||
registerRequests: registerRequests,
|
||||
timeoutSeconds: timeoutSeconds,
|
||||
requestId: reqId
|
||||
};
|
||||
}
|
||||
// JS 1.1 API
|
||||
return {
|
||||
type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
|
||||
appId: appId,
|
||||
registerRequests: registerRequests,
|
||||
registeredKeys: registeredKeys,
|
||||
timeoutSeconds: timeoutSeconds,
|
||||
requestId: reqId
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Posts a message on the underlying channel.
|
||||
* @param {Object} message
|
||||
*/
|
||||
u2f.WrappedChromeRuntimePort_.prototype.postMessage = function (message) {
|
||||
this.port_.postMessage(message);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Emulates the HTML 5 addEventListener interface. Works only for the
|
||||
* onmessage event, which is hooked up to the chrome.runtime.Port.onMessage.
|
||||
* @param {string} eventName
|
||||
* @param {function({data: Object})} handler
|
||||
*/
|
||||
u2f.WrappedChromeRuntimePort_.prototype.addEventListener =
|
||||
function (eventName, handler) {
|
||||
var name = eventName.toLowerCase();
|
||||
if (name == 'message' || name == 'onmessage') {
|
||||
this.port_.onMessage.addListener(function (message) {
|
||||
// Emulate a minimal MessageEvent object
|
||||
handler({ 'data': message });
|
||||
});
|
||||
} else {
|
||||
console.error('WrappedChromeRuntimePort only supports onMessage');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrap the Authenticator app with a MessagePort interface.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_ = function () {
|
||||
this.requestId_ = -1;
|
||||
this.requestObject_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the Authenticator intent.
|
||||
* @param {Object} message
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_.prototype.postMessage = function (message) {
|
||||
var intentUrl =
|
||||
u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ +
|
||||
';S.request=' + encodeURIComponent(JSON.stringify(message)) +
|
||||
';end';
|
||||
document.location = intentUrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tells what type of port this is.
|
||||
* @return {String} port type
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_.prototype.getPortType = function () {
|
||||
return "WrappedAuthenticatorPort_";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Emulates the HTML 5 addEventListener interface.
|
||||
* @param {string} eventName
|
||||
* @param {function({data: Object})} handler
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_.prototype.addEventListener = function (eventName, handler) {
|
||||
var name = eventName.toLowerCase();
|
||||
if (name == 'message') {
|
||||
var self = this;
|
||||
/* Register a callback to that executes when
|
||||
* chrome injects the response. */
|
||||
window.addEventListener(
|
||||
'message', self.onRequestUpdate_.bind(self, handler), false);
|
||||
} else {
|
||||
console.error('WrappedAuthenticatorPort only supports message');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback invoked when a response is received from the Authenticator.
|
||||
* @param function({data: Object}) callback
|
||||
* @param {Object} message message Object
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ =
|
||||
function (callback, message) {
|
||||
var messageObject = JSON.parse(message.data);
|
||||
var intentUrl = messageObject['intentURL'];
|
||||
|
||||
var errorCode = messageObject['errorCode'];
|
||||
var responseObject = null;
|
||||
if (messageObject.hasOwnProperty('data')) {
|
||||
responseObject = /** @type {Object} */ (
|
||||
JSON.parse(messageObject['data']));
|
||||
}
|
||||
|
||||
callback({ 'data': responseObject });
|
||||
};
|
||||
|
||||
/**
|
||||
* Base URL for intents to Authenticator.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ =
|
||||
'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE';
|
||||
|
||||
/**
|
||||
* Wrap the iOS client app with a MessagePort interface.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
u2f.WrappedIosPort_ = function () { };
|
||||
|
||||
/**
|
||||
* Launch the iOS client app request
|
||||
* @param {Object} message
|
||||
*/
|
||||
u2f.WrappedIosPort_.prototype.postMessage = function (message) {
|
||||
var str = JSON.stringify(message);
|
||||
var url = "u2f://auth?" + encodeURI(str);
|
||||
location.replace(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tells what type of port this is.
|
||||
* @return {String} port type
|
||||
*/
|
||||
u2f.WrappedIosPort_.prototype.getPortType = function () {
|
||||
return "WrappedIosPort_";
|
||||
};
|
||||
|
||||
/**
|
||||
* Emulates the HTML 5 addEventListener interface.
|
||||
* @param {string} eventName
|
||||
* @param {function({data: Object})} handler
|
||||
*/
|
||||
u2f.WrappedIosPort_.prototype.addEventListener = function (eventName, handler) {
|
||||
var name = eventName.toLowerCase();
|
||||
if (name !== 'message') {
|
||||
console.error('WrappedIosPort only supports message');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up an embedded trampoline iframe, sourced from the extension.
|
||||
* @param {function(MessagePort)} callback
|
||||
* @private
|
||||
*/
|
||||
u2f.getIframePort_ = function (callback) {
|
||||
// Create the iframe
|
||||
var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID;
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.src = iframeOrigin + '/u2f-comms.html';
|
||||
iframe.setAttribute('style', 'display:none');
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
var channel = new MessageChannel();
|
||||
var ready = function (message) {
|
||||
if (message.data == 'ready') {
|
||||
channel.port1.removeEventListener('message', ready);
|
||||
callback(channel.port1);
|
||||
} else {
|
||||
console.error('First event on iframe port was not "ready"');
|
||||
}
|
||||
};
|
||||
channel.port1.addEventListener('message', ready);
|
||||
channel.port1.start();
|
||||
|
||||
iframe.addEventListener('load', function () {
|
||||
// Deliver the port to the iframe and initialize
|
||||
iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
//High-level JS API
|
||||
|
||||
/**
|
||||
* Default extension response timeout in seconds.
|
||||
* @const
|
||||
*/
|
||||
u2f.EXTENSION_TIMEOUT_SEC = 30;
|
||||
|
||||
/**
|
||||
* A singleton instance for a MessagePort to the extension.
|
||||
* @type {MessagePort|u2f.WrappedChromeRuntimePort_}
|
||||
* @private
|
||||
*/
|
||||
u2f.port_ = null;
|
||||
|
||||
/**
|
||||
* Callbacks waiting for a port
|
||||
* @type {Array<function((MessagePort|u2f.WrappedChromeRuntimePort_))>}
|
||||
* @private
|
||||
*/
|
||||
u2f.waitingForPort_ = [];
|
||||
|
||||
/**
|
||||
* A counter for requestIds.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
u2f.reqCounter_ = 0;
|
||||
|
||||
/**
|
||||
* A map from requestIds to client callbacks
|
||||
* @type {Object.<number,(function((u2f.Error|u2f.RegisterResponse))
|
||||
* |function((u2f.Error|u2f.SignResponse)))>}
|
||||
* @private
|
||||
*/
|
||||
u2f.callbackMap_ = {};
|
||||
|
||||
/**
|
||||
* Creates or retrieves the MessagePort singleton to use.
|
||||
* @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
|
||||
* @private
|
||||
*/
|
||||
u2f.getPortSingleton_ = function (callback) {
|
||||
if (u2f.port_) {
|
||||
callback(u2f.port_);
|
||||
} else {
|
||||
if (u2f.waitingForPort_.length == 0) {
|
||||
u2f.getMessagePort(function (port) {
|
||||
u2f.port_ = port;
|
||||
u2f.port_.addEventListener('message',
|
||||
/** @type {function(Event)} */(u2f.responseHandler_));
|
||||
|
||||
// Careful, here be async callbacks. Maybe.
|
||||
while (u2f.waitingForPort_.length)
|
||||
u2f.waitingForPort_.shift()(u2f.port_);
|
||||
});
|
||||
}
|
||||
u2f.waitingForPort_.push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles response messages from the extension.
|
||||
* @param {MessageEvent.<u2f.Response>} message
|
||||
* @private
|
||||
*/
|
||||
u2f.responseHandler_ = function (message) {
|
||||
var response = message.data;
|
||||
var reqId = response['requestId'];
|
||||
if (!reqId || !u2f.callbackMap_[reqId]) {
|
||||
console.error('Unknown or missing requestId in response.');
|
||||
return;
|
||||
}
|
||||
var cb = u2f.callbackMap_[reqId];
|
||||
delete u2f.callbackMap_[reqId];
|
||||
cb(response['responseData']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatches an array of sign requests to available U2F tokens.
|
||||
* If the JS API version supported by the extension is unknown, it first sends a
|
||||
* message to the extension to find out the supported API version and then it sends
|
||||
* the sign request.
|
||||
* @param {string=} appId
|
||||
* @param {string=} challenge
|
||||
* @param {Array<u2f.RegisteredKey>} registeredKeys
|
||||
* @param {function((u2f.Error|u2f.SignResponse))} callback
|
||||
* @param {number=} opt_timeoutSeconds
|
||||
*/
|
||||
u2f.sign = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
|
||||
if (js_api_version === undefined) {
|
||||
// Send a message to get the extension to JS API version, then send the actual sign request.
|
||||
u2f.getApiVersion(
|
||||
function (response) {
|
||||
js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
|
||||
console.log("Extension JS API Version: ", js_api_version);
|
||||
u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
|
||||
});
|
||||
} else {
|
||||
// We know the JS API version. Send the actual sign request in the supported API version.
|
||||
u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatches an array of sign requests to available U2F tokens.
|
||||
* @param {string=} appId
|
||||
* @param {string=} challenge
|
||||
* @param {Array<u2f.RegisteredKey>} registeredKeys
|
||||
* @param {function((u2f.Error|u2f.SignResponse))} callback
|
||||
* @param {number=} opt_timeoutSeconds
|
||||
*/
|
||||
u2f.sendSignRequest = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
|
||||
u2f.getPortSingleton_(function (port) {
|
||||
var reqId = ++u2f.reqCounter_;
|
||||
u2f.callbackMap_[reqId] = callback;
|
||||
var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
|
||||
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
|
||||
var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId);
|
||||
port.postMessage(req);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatches register requests to available U2F tokens. An array of sign
|
||||
* requests identifies already registered tokens.
|
||||
* If the JS API version supported by the extension is unknown, it first sends a
|
||||
* message to the extension to find out the supported API version and then it sends
|
||||
* the register request.
|
||||
* @param {string=} appId
|
||||
* @param {Array<u2f.RegisterRequest>} registerRequests
|
||||
* @param {Array<u2f.RegisteredKey>} registeredKeys
|
||||
* @param {function((u2f.Error|u2f.RegisterResponse))} callback
|
||||
* @param {number=} opt_timeoutSeconds
|
||||
*/
|
||||
u2f.register = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
|
||||
if (js_api_version === undefined) {
|
||||
// Send a message to get the extension to JS API version, then send the actual register request.
|
||||
u2f.getApiVersion(
|
||||
function (response) {
|
||||
js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
|
||||
console.log("Extension JS API Version: ", js_api_version);
|
||||
u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
|
||||
callback, opt_timeoutSeconds);
|
||||
});
|
||||
} else {
|
||||
// We know the JS API version. Send the actual register request in the supported API version.
|
||||
u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
|
||||
callback, opt_timeoutSeconds);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatches register requests to available U2F tokens. An array of sign
|
||||
* requests identifies already registered tokens.
|
||||
* @param {string=} appId
|
||||
* @param {Array<u2f.RegisterRequest>} registerRequests
|
||||
* @param {Array<u2f.RegisteredKey>} registeredKeys
|
||||
* @param {function((u2f.Error|u2f.RegisterResponse))} callback
|
||||
* @param {number=} opt_timeoutSeconds
|
||||
*/
|
||||
u2f.sendRegisterRequest = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
|
||||
u2f.getPortSingleton_(function (port) {
|
||||
var reqId = ++u2f.reqCounter_;
|
||||
u2f.callbackMap_[reqId] = callback;
|
||||
var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
|
||||
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
|
||||
var req = u2f.formatRegisterRequest_(
|
||||
appId, registeredKeys, registerRequests, timeoutSeconds, reqId);
|
||||
port.postMessage(req);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches a message to the extension to find out the supported
|
||||
* JS API version.
|
||||
* If the user is on a mobile phone and is thus using Google Authenticator instead
|
||||
* of the Chrome extension, don't send the request and simply return 0.
|
||||
* @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback
|
||||
* @param {number=} opt_timeoutSeconds
|
||||
*/
|
||||
u2f.getApiVersion = function (callback, opt_timeoutSeconds) {
|
||||
u2f.getPortSingleton_(function (port) {
|
||||
// If we are using Android Google Authenticator or iOS client app,
|
||||
// do not fire an intent to ask which JS API version to use.
|
||||
if (port.getPortType) {
|
||||
var apiVersion;
|
||||
switch (port.getPortType()) {
|
||||
case 'WrappedIosPort_':
|
||||
case 'WrappedAuthenticatorPort_':
|
||||
apiVersion = 1.1;
|
||||
break;
|
||||
|
||||
default:
|
||||
apiVersion = 0;
|
||||
break;
|
||||
}
|
||||
callback({ 'js_api_version': apiVersion });
|
||||
return;
|
||||
}
|
||||
var reqId = ++u2f.reqCounter_;
|
||||
u2f.callbackMap_[reqId] = callback;
|
||||
var req = {
|
||||
type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,
|
||||
timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ?
|
||||
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC),
|
||||
requestId: reqId
|
||||
};
|
||||
port.postMessage(req);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Modification:
|
||||
* Assign u2f back to window (root) scope.
|
||||
*/
|
||||
root.u2f = u2f;
|
||||
}(this));
|
@@ -355,11 +355,8 @@ $(document).ready(function() {
|
||||
data_array[i] = decodeURIComponent(data_array[i]);
|
||||
$("#ItemsToDelete").append("<li>" + escapeHtml(data_array[i]) + "</li>");
|
||||
}
|
||||
});
|
||||
$('#ConfirmDeleteModal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
})
|
||||
})
|
||||
$('#ConfirmDeleteModal').modal('show')
|
||||
.one('click', '#IsConfirmed', function(e) {
|
||||
if (is_active($('#IsConfirmed'))) { return false; }
|
||||
$.ajax({
|
||||
|
@@ -1,239 +0,0 @@
|
||||
!function ($) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// TABCOLLAPSE CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var TabCollapse = function (el, options) {
|
||||
this.options = options;
|
||||
this.$tabs = $(el);
|
||||
|
||||
this._accordionVisible = false; //content is attached to tabs at first
|
||||
this._initAccordion();
|
||||
this._checkStateOnResize();
|
||||
|
||||
|
||||
// checkState() has gone to setTimeout for making it possible to attach listeners to
|
||||
// shown-accordion.bs.tabcollapse event on page load.
|
||||
// See https://github.com/flatlogic/bootstrap-tabcollapse/issues/23
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.checkState();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
TabCollapse.DEFAULTS = {
|
||||
accordionClass: 'visible-xs',
|
||||
tabsClass: 'hidden-xs',
|
||||
accordionTemplate: function(heading, groupId, parentId, active) {
|
||||
return '<div class="panel panel-default">' +
|
||||
' <div class="panel-heading">' +
|
||||
' <h4 class="panel-title">' +
|
||||
' </h4>' +
|
||||
' </div>' +
|
||||
' <div id="' + groupId + '" class="panel-collapse collapse ' + (active ? 'in' : '') + '">' +
|
||||
' <div class="panel-body js-tabcollapse-panel-body">' +
|
||||
' </div>' +
|
||||
' </div>' +
|
||||
'</div>'
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
TabCollapse.prototype.checkState = function(){
|
||||
if (this.$tabs.is(':visible') && this._accordionVisible){
|
||||
this.showTabs();
|
||||
this._accordionVisible = false;
|
||||
} else if (this.$accordion.is(':visible') && !this._accordionVisible){
|
||||
this.showAccordion();
|
||||
this._accordionVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
TabCollapse.prototype.showTabs = function(){
|
||||
var view = this;
|
||||
this.$tabs.trigger($.Event('show-tabs.bs.tabcollapse'));
|
||||
|
||||
var $panelHeadings = this.$accordion.find('.js-tabcollapse-panel-heading').detach();
|
||||
|
||||
$panelHeadings.each(function() {
|
||||
var $panelHeading = $(this),
|
||||
$parentLi = $panelHeading.data('bs.tabcollapse.parentLi');
|
||||
|
||||
var $oldHeading = view._panelHeadingToTabHeading($panelHeading);
|
||||
|
||||
$parentLi.removeClass('active');
|
||||
if ($parentLi.parent().hasClass('dropdown-menu') && !$parentLi.siblings('li').hasClass('active')) {
|
||||
$parentLi.parent().parent().removeClass('active');
|
||||
}
|
||||
|
||||
if (!$oldHeading.hasClass('collapsed')) {
|
||||
$parentLi.addClass('active');
|
||||
$('.tab-pane').removeClass('active');
|
||||
$($panelHeading.attr('href')).addClass('active');
|
||||
if ($parentLi.parent().hasClass('dropdown-menu')) {
|
||||
$parentLi.parent().parent().addClass('active');
|
||||
}
|
||||
} else {
|
||||
$oldHeading.removeClass('collapsed');
|
||||
}
|
||||
|
||||
$parentLi.append($panelHeading);
|
||||
});
|
||||
|
||||
if (!$('li').hasClass('active')) {
|
||||
$('li').first().addClass('active')
|
||||
}
|
||||
|
||||
var $panelBodies = this.$accordion.find('.js-tabcollapse-panel-body');
|
||||
$panelBodies.each(function(){
|
||||
var $panelBody = $(this),
|
||||
$tabPane = $panelBody.data('bs.tabcollapse.tabpane');
|
||||
$tabPane.append($panelBody.contents().detach());
|
||||
});
|
||||
this.$accordion.html('');
|
||||
|
||||
if(this.options.updateLinks) {
|
||||
var $tabContents = this.getTabContentElement();
|
||||
$tabContents.find('[data-toggle-was="tab"], [data-toggle-was="pill"]').each(function() {
|
||||
var $el = $(this);
|
||||
var href = $el.attr('href').replace(/-collapse$/g, '');
|
||||
$el.attr({
|
||||
'data-toggle': $el.attr('data-toggle-was'),
|
||||
'data-toggle-was': '',
|
||||
'data-parent': '',
|
||||
href: href
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.$tabs.trigger($.Event('shown-tabs.bs.tabcollapse'));
|
||||
};
|
||||
|
||||
TabCollapse.prototype.getTabContentElement = function(){
|
||||
var $tabContents = $(this.options.tabContentSelector);
|
||||
if($tabContents.length === 0) {
|
||||
$tabContents = this.$tabs.siblings('.tab-content');
|
||||
}
|
||||
return $tabContents;
|
||||
};
|
||||
|
||||
TabCollapse.prototype.showAccordion = function(){
|
||||
this.$tabs.trigger($.Event('show-accordion.bs.tabcollapse'));
|
||||
|
||||
var $headings = this.$tabs.find('li:not(.dropdown) [data-toggle="tab"], li:not(.dropdown) [data-toggle="pill"]'),
|
||||
view = this;
|
||||
$headings.each(function(){
|
||||
var $heading = $(this),
|
||||
$parentLi = $heading.parent();
|
||||
$heading.data('bs.tabcollapse.parentLi', $parentLi);
|
||||
view.$accordion.append(view._createAccordionGroup(view.$accordion.attr('id'), $heading.detach()));
|
||||
});
|
||||
|
||||
if(this.options.updateLinks) {
|
||||
var parentId = this.$accordion.attr('id');
|
||||
var $selector = this.$accordion.find('.js-tabcollapse-panel-body');
|
||||
$selector.find('[data-toggle="tab"], [data-toggle="pill"]').each(function() {
|
||||
var $el = $(this);
|
||||
var href = $el.attr('href') + '-collapse';
|
||||
$el.attr({
|
||||
'data-toggle-was': $el.attr('data-toggle'),
|
||||
'data-toggle': 'collapse',
|
||||
'data-parent': '#' + parentId,
|
||||
href: href
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.$tabs.trigger($.Event('shown-accordion.bs.tabcollapse'));
|
||||
};
|
||||
|
||||
TabCollapse.prototype._panelHeadingToTabHeading = function($heading) {
|
||||
var href = $heading.attr('href').replace(/-collapse$/g, '');
|
||||
$heading.attr({
|
||||
'data-toggle': 'tab',
|
||||
'href': href,
|
||||
'data-parent': ''
|
||||
});
|
||||
return $heading;
|
||||
};
|
||||
|
||||
TabCollapse.prototype._tabHeadingToPanelHeading = function($heading, groupId, parentId, active) {
|
||||
$heading.addClass('js-tabcollapse-panel-heading ' + (active ? '' : 'collapsed'));
|
||||
$heading.attr({
|
||||
'data-toggle': 'collapse',
|
||||
'data-parent': '#' + parentId,
|
||||
'href': '#' + groupId
|
||||
});
|
||||
return $heading;
|
||||
};
|
||||
|
||||
TabCollapse.prototype._checkStateOnResize = function(){
|
||||
var view = this;
|
||||
$(window).resize(function(){
|
||||
clearTimeout(view._resizeTimeout);
|
||||
view._resizeTimeout = setTimeout(function(){
|
||||
view.checkState();
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
TabCollapse.prototype._initAccordion = function(){
|
||||
var randomString = function() {
|
||||
var result = "",
|
||||
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < 5; i++ ) {
|
||||
result += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
var srcId = this.$tabs.attr('id'),
|
||||
accordionId = (srcId ? srcId : randomString()) + '-accordion';
|
||||
|
||||
this.$accordion = $('<div class="panel-group ' + this.options.accordionClass + '" id="' + accordionId +'"></div>');
|
||||
this.$tabs.after(this.$accordion);
|
||||
this.$tabs.addClass(this.options.tabsClass);
|
||||
this.getTabContentElement().addClass(this.options.tabsClass);
|
||||
};
|
||||
|
||||
TabCollapse.prototype._createAccordionGroup = function(parentId, $heading){
|
||||
var tabSelector = $heading.attr('data-target'),
|
||||
active = $heading.data('bs.tabcollapse.parentLi').is('.active');
|
||||
|
||||
if (!tabSelector) {
|
||||
tabSelector = $heading.attr('href');
|
||||
tabSelector = tabSelector && tabSelector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
|
||||
}
|
||||
|
||||
var $tabPane = $(tabSelector),
|
||||
groupId = $tabPane.attr('id') + '-collapse',
|
||||
$panel = $(this.options.accordionTemplate($heading, groupId, parentId, active));
|
||||
$panel.find('.panel-heading > .panel-title').append(this._tabHeadingToPanelHeading($heading, groupId, parentId, active));
|
||||
$panel.find('.panel-body').append($tabPane.contents().detach())
|
||||
.data('bs.tabcollapse.tabpane', $tabPane);
|
||||
|
||||
return $panel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// TABCOLLAPSE PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
$.fn.tabCollapse = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this);
|
||||
var data = $this.data('bs.tabcollapse');
|
||||
var options = $.extend({}, TabCollapse.DEFAULTS, $this.data(), typeof option === 'object' && option);
|
||||
|
||||
if (!data) $this.data('bs.tabcollapse', new TabCollapse(this, options));
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.tabCollapse.Constructor = TabCollapse;
|
||||
|
||||
|
||||
}(window.jQuery);
|
10
data/web/js/build/013-footable.min.js
vendored
10
data/web/js/build/013-footable.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -55,14 +55,14 @@ $(document).ready(function() {
|
||||
|
||||
// tooltips
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
|
||||
// remember last navigation pill
|
||||
(function () {
|
||||
'use strict';
|
||||
if ($('a[data-toggle="tab"]').length) {
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
// remember desktop tabs
|
||||
$('button[data-bs-toggle="tab"]').on('click', function (e) {
|
||||
if ($(this).data('dont-remember') == 1) {
|
||||
return true;
|
||||
}
|
||||
@@ -71,8 +71,28 @@ $(document).ready(function() {
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
localStorage.setItem(key, $(e.target).attr('href'));
|
||||
|
||||
var tab_id = $(e.target).attr('data-bs-target').substring(1);
|
||||
localStorage.setItem(key, tab_id);
|
||||
});
|
||||
// remember mobile tabs
|
||||
$('button[data-bs-target^="#collapse-tab-"]').on('click', function (e) {
|
||||
// only remember tab if its being opened
|
||||
if ($(this).hasClass('collapsed')) return false;
|
||||
var tab_id = $(this).closest('div[role="tabpanel"]').attr('id');
|
||||
|
||||
if ($(this).data('dont-remember') == 1) {
|
||||
return true;
|
||||
}
|
||||
var id = $(this).parents('[role="tablist"]').attr('id');;
|
||||
var key = 'lastTag';
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
|
||||
localStorage.setItem(key, tab_id);
|
||||
});
|
||||
// open last tab
|
||||
$('[role="tablist"]').each(function (idx, elem) {
|
||||
var id = $(elem).attr('id');
|
||||
var key = 'lastTag';
|
||||
@@ -81,10 +101,11 @@ $(document).ready(function() {
|
||||
}
|
||||
var lastTab = localStorage.getItem(key);
|
||||
if (lastTab) {
|
||||
$('[href="' + lastTab + '"]').tab('show');
|
||||
$('[data-bs-target="#' + lastTab + '"]').click();
|
||||
var tab = $('[id^="' + lastTab + '"]');
|
||||
$(tab).find('.card-body.collapse').collapse('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// IE fix to hide scrollbars when table body is empty
|
||||
@@ -119,7 +140,7 @@ $(document).ready(function() {
|
||||
shake(password_field);
|
||||
}
|
||||
else {
|
||||
$(hibp_result).attr('class', 'hibp-out label label-info');
|
||||
$(hibp_result).attr('class', 'hibp-out badge fs-5 bg-info');
|
||||
$(hibp_result).text(lang_footer.loading);
|
||||
var password_digest = $.sha1($(password_field).val())
|
||||
var digest_five = password_digest.substring(0, 5).toUpperCase();
|
||||
@@ -130,16 +151,16 @@ $(document).ready(function() {
|
||||
type: 'GET',
|
||||
success: function(res) {
|
||||
if (res.search(compl_digest) > -1){
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-danger');
|
||||
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-danger');
|
||||
$(hibp_result).text(lang_footer.hibp_nok)
|
||||
} else {
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-success');
|
||||
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-success');
|
||||
$(hibp_result).text(lang_footer.hibp_ok)
|
||||
}
|
||||
$(hibp_field).removeClass('task-running');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-warning');
|
||||
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-warning');
|
||||
$(hibp_result).text('API error: ' + xhr.responseText)
|
||||
$(hibp_field).removeClass('task-running');
|
||||
}
|
||||
@@ -150,8 +171,8 @@ $(document).ready(function() {
|
||||
// Disable disallowed inputs
|
||||
$('[data-acl="0"]').each(function(event){
|
||||
if ($(this).is("a")) {
|
||||
$(this).removeAttr("data-toggle");
|
||||
$(this).removeAttr("data-target");
|
||||
$(this).removeAttr("data-bs-toggle");
|
||||
$(this).removeAttr("data-bs-target");
|
||||
$(this).removeAttr("data-action");
|
||||
$(this).click(function(event) {
|
||||
event.preventDefault();
|
||||
@@ -166,8 +187,8 @@ $(document).ready(function() {
|
||||
if ($(this).hasClass('btn-group')) {
|
||||
$(this).find('a').each(function(){
|
||||
$(this).removeClass('dropdown-toggle')
|
||||
.removeAttr('data-toggle')
|
||||
.removeAttr('data-target')
|
||||
.removeAttr('data-bs-toggle')
|
||||
.removeAttr('data-bs-target')
|
||||
.removeAttr('data-action')
|
||||
.removeAttr('id')
|
||||
.attr("disabled", true);
|
||||
@@ -182,7 +203,7 @@ $(document).ready(function() {
|
||||
} else if ($(this).hasClass('input-group')) {
|
||||
$(this).find('input').each(function() {
|
||||
$(this).removeClass('dropdown-toggle')
|
||||
.removeAttr('data-toggle')
|
||||
.removeAttr('data-bs-toggle')
|
||||
.attr("disabled", true);
|
||||
$(this).click(function(event) {
|
||||
event.preventDefault();
|
||||
@@ -226,7 +247,7 @@ $(document).ready(function() {
|
||||
$('#containerName').text(container);
|
||||
$('#triggerRestartContainer').click(function(){
|
||||
$(this).prop("disabled",true);
|
||||
$(this).html('<i class="bi bi-arrow-repeat icon-spin"></i> ');
|
||||
$(this).html('<div class="spinner-border text-secondary" role="status"><span class="visually-hidden">Loading...</span></div>');
|
||||
$('#statusTriggerRestartContainer').html(lang_footer.restarting_container);
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
@@ -253,25 +274,9 @@ $(document).ready(function() {
|
||||
});
|
||||
})
|
||||
|
||||
// responsive tabs
|
||||
$('.responsive-tabs').tabCollapse({
|
||||
tabsClass: 'hidden-xs',
|
||||
accordionClass: 'js-tabcollapse-panel-group visible-xs'
|
||||
});
|
||||
$(document).on("shown.bs.collapse shown.bs.tab", function (e) {
|
||||
var target = $(e.target);
|
||||
if($(window).width() <= 767) {
|
||||
var offset = target.offset().top - 112;
|
||||
$("html, body").stop().animate({
|
||||
scrollTop: offset
|
||||
}, 100);
|
||||
}
|
||||
if(target.hasClass('panel-collapse')){
|
||||
var id = e.target.id.replace(/-collapse$/g, '');
|
||||
if(id){
|
||||
localStorage.setItem('lastTag', '#'+id);
|
||||
}
|
||||
}
|
||||
// Jquery Datatables, enable responsive plugin
|
||||
$.extend($.fn.dataTable.defaults, {
|
||||
responsive: true
|
||||
});
|
||||
|
||||
// tag boxes
|
||||
|
@@ -53,237 +53,422 @@ jQuery(function($){
|
||||
$("#show_rspamd_global_filters").click(function() {
|
||||
$.get("inc/ajax/show_rspamd_global_filters.php");
|
||||
$("#confirm_show_rspamd_global_filters").hide();
|
||||
$("#rspamd_global_filters").removeClass("hidden");
|
||||
$("#rspamd_global_filters").removeClass("d-none");
|
||||
});
|
||||
$("#super_delete").click(function() { return confirm(lang.queue_ays); });
|
||||
$(".refresh_table").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var table_name = $(this).data('table');
|
||||
$('#' + table_name).find("tr.footable-empty").remove();
|
||||
draw_table = $(this).data('draw');
|
||||
eval(draw_table + '()');
|
||||
$('#' + table_name).DataTable().ajax.reload();
|
||||
});
|
||||
function table_admin_ready(ft, name) {
|
||||
heading = ft.$el.parents('.panel').find('.panel-heading')
|
||||
var ft_paging = ft.use(FooTable.Paging)
|
||||
$(heading).children('.table-lines').text(function(){
|
||||
return ft_paging.totalRows;
|
||||
})
|
||||
}
|
||||
function draw_domain_admins() {
|
||||
ft_domainadmins = FooTable.init('#domainadminstable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
|
||||
{"name":"selected_domains","title":lang.admin_domains,"breakpoints":"xs sm"},
|
||||
{"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/domain-admin/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw domain admin table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#domainadminstable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/domain-admin/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'domainadminstable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"state": {"enabled": true},
|
||||
"filtering": {"enabled": true,"delay": 1200,"position": "left","connectors": false,"placeholder": lang.filter_table},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang.username,
|
||||
data: 'username',
|
||||
},
|
||||
{
|
||||
title: "TFA",
|
||||
data: 'tfa_active',
|
||||
render: function (data, type) {
|
||||
if(data == 1) return '<i class="bi bi-check-lg"></i>';
|
||||
else return '<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.admin_domains,
|
||||
data: 'tfa_active',
|
||||
render: function (data, type) {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active',
|
||||
render: function (data, type) {
|
||||
if(data == 1) return '<i class="bi bi-check-lg"></i>';
|
||||
else return '<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
],
|
||||
initComplete: function(settings, json){
|
||||
console.log(settings.aoColumns);
|
||||
}
|
||||
});
|
||||
}
|
||||
function draw_oauth2_clients() {
|
||||
ft_oauth2clientstable = FooTable.init('#oauth2clientstable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
|
||||
{"name":"client_id","type":"text","title":lang.oauth2_client_id,"style":{"width":"200px"}},
|
||||
{"name":"client_secret","title":lang.oauth2_client_secret,"breakpoints":"xs sm md","style":{"width":"200px"}},
|
||||
{"name":"redirect_uri","title":lang.oauth2_redirect_uri, "type": "text"},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/oauth2-client/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw oauth2 clients table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#oauth2clientstable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/oauth2-client/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'oauth2clientstable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id',
|
||||
},
|
||||
{
|
||||
title: lang.oauth2_client_id,
|
||||
data: 'client_id'
|
||||
},
|
||||
{
|
||||
title: lang.oauth2_client_secret,
|
||||
data: 'client_secret'
|
||||
},
|
||||
{
|
||||
title: lang.oauth2_redirect_uri,
|
||||
data: 'redirect_uri'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_admins() {
|
||||
ft_admins = FooTable.init('#adminstable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"sorted": true,"name":"usr","title":lang.username,"style":{"width":"250px"}},
|
||||
{"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/admin/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw admin table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#adminstable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/admin/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'adminstable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"filtering": {"enabled": false},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang.username,
|
||||
data: 'username',
|
||||
},
|
||||
{
|
||||
title: "TFA",
|
||||
data: 'tfa_active',
|
||||
render: function (data, type) {
|
||||
if(data == 1) return '<i class="bi bi-check-lg"></i>';
|
||||
else return '<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active',
|
||||
render: function (data, type) {
|
||||
if(data == 1) return '<i class="bi bi-check-lg"></i>';
|
||||
else return '<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_fwd_hosts() {
|
||||
ft_forwardinghoststable = FooTable.init('#forwardinghoststable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"host","type":"text","title":lang.host,"style":{"width":"250px"}},
|
||||
{"name":"source","title":lang.source,"breakpoints":"xs sm"},
|
||||
{"name":"keep_spam","title":lang.spamfilter, "type": "text","style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 'yes'==value?'<i class="bi bi-x-lg"></i>':'no'==value&&'<i class="bi bi-check-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/fwdhost/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw forwarding hosts table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#forwardinghoststable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/fwdhost/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'forwardinghoststable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang.host,
|
||||
data: 'host',
|
||||
},
|
||||
{
|
||||
title: lang.source,
|
||||
data: 'source'
|
||||
},
|
||||
{
|
||||
title: lang.spamfilter,
|
||||
data: 'keep_spam'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_relayhosts() {
|
||||
ft_relayhoststable = FooTable.init('#relayhoststable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
|
||||
{"name":"hostname","type":"text","title":lang.host,"style":{"width":"250px"}},
|
||||
{"name":"username","title":lang.username,"breakpoints":"xs sm"},
|
||||
{"name":"in_use_by","title":lang.in_use_by,"style":{"min-width":"200px","width":"200px"}, "type": "text","breakpoints":"xs sm"},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/relayhost/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw forwarding hosts table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#relayhoststable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/relayhost/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'relayhoststable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id',
|
||||
},
|
||||
{
|
||||
title: lang.host,
|
||||
data: 'hostname'
|
||||
},
|
||||
{
|
||||
title: lang.username,
|
||||
data: 'username'
|
||||
},
|
||||
{
|
||||
title: lang.in_use_by,
|
||||
data: 'in_use_by'
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_transport_maps() {
|
||||
ft_transportstable = FooTable.init('#transportstable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
|
||||
{"name":"destination","type":"text","title":lang.destination,"style":{"min-width":"300px","width":"300px"}},
|
||||
{"name":"nexthop","type":"text","title":lang.nexthop,"style":{"min-width":"200px","width":"200px"}},
|
||||
{"name":"username","title":lang.username,"breakpoints":"xs sm"},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/transport/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw transports table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#transportstable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/transport/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'transportstable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle",
|
||||
"on": {
|
||||
"ready.ft.table": function(e, ft){
|
||||
$('.mx-info').tooltip();
|
||||
}
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id',
|
||||
},
|
||||
{
|
||||
title: lang.destination,
|
||||
data: 'destination'
|
||||
},
|
||||
{
|
||||
title: lang.nexthop,
|
||||
data: 'nexthop'
|
||||
},
|
||||
{
|
||||
title: lang.username,
|
||||
data: 'username'
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_queue() {
|
||||
ft_queuetable = FooTable.init('#queuetable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"queue_id","type":"text","title":"QID","style":{"width":"50px"}},
|
||||
{"name":"queue_name","type":"text","title":"Queue","style":{"width":"120px"}},
|
||||
{"name":"arrival_time","sorted": true,"direction": "DESC","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.arrival_time,"style":{"width":"170px"}},
|
||||
{"name":"message_size","style":{"whiteSpace":"nowrap"},"title":lang.message_size,"formatter": function(value){
|
||||
return humanFileSize(value);
|
||||
}},
|
||||
{"name":"sender","title":lang.sender, "type": "text","breakpoints":"xs sm"},
|
||||
{"name":"recipients","title":lang.recipients, "type": "text","style":{"word-break":"break-all","min-width":"300px"},"breakpoints":"xs sm md"},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/mailq/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw forwarding hosts table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#queuetable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/mailq/all",
|
||||
dataSrc: function(data){
|
||||
return process_table_data(data, 'queuetable');
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
|
||||
"sorting": {"enabled": true},
|
||||
"toggleSelector": "table tbody span.footable-toggle",
|
||||
"on": {
|
||||
"ready.ft.table": function(e, ft){
|
||||
table_admin_ready(ft, 'queuetable');
|
||||
}
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'QID',
|
||||
data: 'queue_id',
|
||||
},
|
||||
{
|
||||
title: 'Queue',
|
||||
data: 'queue_name'
|
||||
},
|
||||
{
|
||||
title: lang.arrival_time,
|
||||
data: 'arrival_time',
|
||||
render: function (data, type){
|
||||
var date = new Date(data ? data * 1000 : 0);
|
||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.message_size,
|
||||
data: 'message_size',
|
||||
render: function (data, type){
|
||||
return humanFileSize(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.sender,
|
||||
data: 'sender'
|
||||
},
|
||||
{
|
||||
title: lang.recipients,
|
||||
data: 'recipients'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
function process_table_data(data, table) {
|
||||
if (table == 'relayhoststable') {
|
||||
$.each(data, function (i, item) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="#" data-toggle="modal" data-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-caret-right-fill"></i> Test</a>' +
|
||||
'<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
|
||||
'<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-rlyhost" data-api-url="delete/relayhost" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
if (item.used_by_mailboxes == '') { item.in_use_by = item.used_by_domains; }
|
||||
@@ -294,14 +479,14 @@ jQuery(function($){
|
||||
} else if (table == 'transportstable') {
|
||||
$.each(data, function (i, item) {
|
||||
if (item.is_mx_based) {
|
||||
item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
|
||||
item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-bs-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
|
||||
}
|
||||
if (item.username) {
|
||||
item.username = '<i style="color:#' + intToRGB(hashCode(item.nexthop)) + ';" class="bi bi-square-fill"></i> ' + item.username;
|
||||
}
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="#" data-toggle="modal" data-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-caret-right-fill"></i> Test</a>' +
|
||||
'<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
|
||||
'<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-transport" data-api-url="delete/transport" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.chkbox = '<input type="checkbox" data-id="transports" name="multi_select" value="' + item.id + '" />';
|
||||
@@ -313,21 +498,21 @@ jQuery(function($){
|
||||
return escapeHtml(i);
|
||||
});
|
||||
item.recipients = rcpts.join('<hr style="margin:1px!important">');
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="#" data-toggle="modal" data-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-default">' + lang.queue_show_message + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-secondary">' + lang.queue_show_message + '</a>' +
|
||||
'</div>';
|
||||
});
|
||||
} else if (table == 'forwardinghoststable') {
|
||||
$.each(data, function (i, item) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-fwdhost" data-api-url="delete/fwdhost" data-item="' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.chkbox = '<input type="checkbox" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
|
||||
});
|
||||
} else if (table == 'oauth2clientstable') {
|
||||
$.each(data, function (i, item) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-oauth2-client" data-api-url="delete/oauth2-client" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.scope = "profile";
|
||||
@@ -339,8 +524,8 @@ jQuery(function($){
|
||||
item.selected_domains = escapeHtml(item.selected_domains);
|
||||
item.selected_domains = item.selected_domains.toString().replace(/,/g, "<br>");
|
||||
item.chkbox = '<input type="checkbox" data-id="domain_admins" name="multi_select" value="' + item.username + '" />';
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-domain-admin" data-api-url="delete/domain-admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-third btn-success"><i class="bi bi-person-fill"></i> Login</a>' +
|
||||
'</div>';
|
||||
@@ -353,22 +538,38 @@ jQuery(function($){
|
||||
item.usr = item.username;
|
||||
}
|
||||
item.chkbox = '<input type="checkbox" data-id="admins" name="multi_select" value="' + item.username + '" />';
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-admin" data-api-url="delete/admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
});
|
||||
}
|
||||
return data
|
||||
};
|
||||
// Initial table drawings
|
||||
draw_domain_admins();
|
||||
draw_admins();
|
||||
draw_fwd_hosts();
|
||||
draw_relayhosts();
|
||||
draw_oauth2_clients();
|
||||
draw_transport_maps();
|
||||
draw_queue();
|
||||
|
||||
// detect element visibility changes
|
||||
function onVisible(element, callback) {
|
||||
$(element).ready(function() {
|
||||
element_object = document.querySelector(element)
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.intersectionRatio > 0) {
|
||||
callback(element_object);
|
||||
observer.disconnect();
|
||||
}
|
||||
});
|
||||
}).observe(element_object);
|
||||
});
|
||||
}
|
||||
// Draw Table if tab is active
|
||||
onVisible("[id^=adminstable]", () => draw_admins());
|
||||
onVisible("[id^=domainadminstable]", () => draw_domain_admins());
|
||||
onVisible("[id^=oauth2clientstable]", () => draw_oauth2_clients());
|
||||
onVisible("[id^=forwardinghoststable]", () => draw_fwd_hosts());
|
||||
onVisible("[id^=relayhoststable]", () => draw_relayhosts());
|
||||
onVisible("[id^=transportstable]", () => draw_transport_maps());
|
||||
onVisible("[id^=queuetable]", () => draw_queue());
|
||||
|
||||
|
||||
$('body').on('click', 'span.footable-toggle', function () {
|
||||
event.stopPropagation();
|
||||
@@ -483,11 +684,11 @@ jQuery(function($){
|
||||
if (type == "app_link") {
|
||||
cols = '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="app" required></td>';
|
||||
cols += '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="href" required></td>';
|
||||
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-default" type="button">' + lang.remove_row + '</a></td>';
|
||||
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary" type="button">' + lang.remove_row + '</a></td>';
|
||||
} else if (type == "f2b_regex") {
|
||||
cols = '<td><input style="text-align:center" class="input-sm input-xs-lg form-control" data-id="f2b_regex" type="text" value="+" disabled></td>';
|
||||
cols += '<td><input class="input-sm input-xs-lg form-control regex-input" data-id="f2b_regex" type="text" name="regex" required></td>';
|
||||
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-default" type="button">' + lang.remove_row + '</a></td>';
|
||||
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary" type="button">' + lang.remove_row + '</a></td>';
|
||||
}
|
||||
row.append(cols);
|
||||
table_id.append(row);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -66,22 +66,14 @@ jQuery(function($){
|
||||
return re.test(email);
|
||||
}
|
||||
function draw_wl_policy_domain_table() {
|
||||
ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_domain_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang_user.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#wl_policy_domain_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/policy_wl_domain/' + table_for_domain,
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw mailbox policy wl table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
$.each(data, function (i, item) {
|
||||
if (!validateEmail(item.object)) {
|
||||
item.chkbox = '<input type="checkbox" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
|
||||
@@ -90,35 +82,50 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled title="' + lang_user.spamfilter_table_domain_policy + '" />';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
}
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'prefid',
|
||||
},
|
||||
{
|
||||
title: lang_user.spamfilter_table_rule,
|
||||
data: 'value'
|
||||
},
|
||||
{
|
||||
title: 'Scope',
|
||||
data: 'object'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_bl_policy_domain_table() {
|
||||
ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_domain_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang_user.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#bl_policy_domain_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/policy_bl_domain/' + table_for_domain,
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw mailbox policy bl table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
$.each(data, function (i, item) {
|
||||
if (!validateEmail(item.object)) {
|
||||
item.chkbox = '<input type="checkbox" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
|
||||
@@ -127,18 +134,58 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled tooltip="' + lang_user.spamfilter_table_domain_policy + '" />';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
}
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'prefid',
|
||||
},
|
||||
{
|
||||
title: lang_user.spamfilter_table_rule,
|
||||
data: 'value'
|
||||
},
|
||||
{
|
||||
title: 'Scope',
|
||||
data: 'object'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
draw_wl_policy_domain_table();
|
||||
draw_bl_policy_domain_table();
|
||||
|
||||
|
||||
// detect element visibility changes
|
||||
function onVisible(element, callback) {
|
||||
$(element).ready(function() {
|
||||
element_object = document.querySelector(element)
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.intersectionRatio > 0) {
|
||||
callback(element_object);
|
||||
observer.disconnect();
|
||||
}
|
||||
});
|
||||
}).observe(element_object);
|
||||
});
|
||||
}
|
||||
// Draw Table if tab is active
|
||||
onVisible("[id^=wl_policy_domain_table]", () => draw_wl_policy_domain_table());
|
||||
onVisible("[id^=bl_policy_domain_table]", () => draw_bl_policy_domain_table());
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -40,17 +40,17 @@ jQuery(function($){
|
||||
if (value.score > 0) highlightClass = 'negative'
|
||||
else if (value.score < 0) highlightClass = 'positive'
|
||||
else highlightClass = 'neutral'
|
||||
$('#qid_detail_symbols').append('<span data-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
||||
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
||||
});
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||
}
|
||||
if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
|
||||
if (data.action === "add header") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
|
||||
} else if (data.action === "reject") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
|
||||
} else if (data.action === "rewrite subject") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
|
||||
}
|
||||
}
|
||||
if (typeof data.recipients !== 'undefined') {
|
||||
|
@@ -7,67 +7,20 @@ jQuery(function($){
|
||||
var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};
|
||||
function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})}
|
||||
function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e<B.length-1);return i.toFixed(1)+" "+B[e]}
|
||||
// Set paging
|
||||
$('[data-page-size]').on('click', function(e){
|
||||
e.preventDefault();
|
||||
var new_size = $(this).data('page-size');
|
||||
var parent_ul = $(this).closest('ul');
|
||||
var table_id = $(parent_ul).data('table-id');
|
||||
FooTable.get('#' + table_id).pageSize(new_size);
|
||||
//$(this).parent().addClass('active').siblings().removeClass('active')
|
||||
heading = $(this).parents('.panel').find('.panel-heading')
|
||||
var n_results = $(heading).children('.table-lines').text().split(' / ')[1];
|
||||
$(heading).children('.table-lines').text(function(){
|
||||
if (new_size > n_results) {
|
||||
new_size = n_results;
|
||||
}
|
||||
return new_size + ' / ' + n_results;
|
||||
})
|
||||
});
|
||||
$(".refresh_table").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var table_name = $(this).data('table');
|
||||
$('#' + table_name).find("tr.footable-empty").remove();
|
||||
draw_table = $(this).data('draw');
|
||||
eval(draw_table + '()');
|
||||
$('#' + table_name).DataTable().ajax.reload();
|
||||
});
|
||||
function table_quarantine_ready(ft, name) {
|
||||
$('.refresh_table').prop("disabled", false);
|
||||
heading = ft.$el.parents('.panel').find('.panel-heading')
|
||||
var ft_paging = ft.use(FooTable.Paging)
|
||||
$(heading).children('.table-lines').text(function(){
|
||||
var total_rows = ft_paging.totalRows;
|
||||
var size = ft_paging.size;
|
||||
if (size > total_rows) {
|
||||
size = total_rows;
|
||||
}
|
||||
return size + ' / ' + total_rows;
|
||||
})
|
||||
}
|
||||
function draw_quarantine_table() {
|
||||
ft_quarantinetable = FooTable.init('#quarantinetable', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"id","type":"ID","filterable": false,"sorted": true,"direction":"DESC","title":"ID","style":{"width":"50px"}},
|
||||
{"name":"qid","breakpoints":"all","type":"text","title":lang.qid,"style":{"width":"125px"}},
|
||||
{"name":"sender","title":lang.sender},
|
||||
{"name":"subject","title":lang.subj, "type": "text"},
|
||||
{"name":"rspamdaction","title":lang.rspamd_result, "type": "html"},
|
||||
{"name":"rcpt","title":lang.rcpt, "type": "text"},
|
||||
{"name":"virus","title":lang.danger, "type": "text"},
|
||||
{"name":"score","title": lang.spam_score, "type": "text"},
|
||||
{"name":"notified","title":lang.notified, "type": "text"},
|
||||
{"name":"created","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.received,"style":{"width":"170px"}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right"},"style":{"min-width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/quarantine/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw quarantine table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#quarantinetable').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/quarantine/all",
|
||||
dataSrc: function(data){
|
||||
$.each(data, function (i, item) {
|
||||
if (item.subject === null) {
|
||||
item.subject = '';
|
||||
@@ -78,16 +31,16 @@ jQuery(function($){
|
||||
item.score = '-';
|
||||
}
|
||||
if (item.virus_flag > 0) {
|
||||
item.virus = '<span class="label label-danger">' + lang.high_danger + '</span>';
|
||||
item.virus = '<span class="badge fs-5 bg-danger">' + lang.high_danger + '</span>';
|
||||
} else {
|
||||
item.virus = '<span class="label label-default">' + lang.neutral_danger + '</span>';
|
||||
item.virus = '<span class="badge fs-5 bg-secondary">' + lang.neutral_danger + '</span>';
|
||||
}
|
||||
if (item.action === "reject") {
|
||||
item.rspamdaction = '<span class="label label-danger">' + lang.rejected + '</span>';
|
||||
item.rspamdaction = '<span class="badge fs-5 bg-danger">' + lang.rejected + '</span>';
|
||||
} else if (item.action === "add header") {
|
||||
item.rspamdaction = '<span class="label label-warning">' + lang.junk_folder + '</span>';
|
||||
item.rspamdaction = '<span class="badge fs-5 bg-warning">' + lang.junk_folder + '</span>';
|
||||
} else if (item.action === "rewrite subject") {
|
||||
item.rspamdaction = '<span class="label label-warning">' + lang.rewrite_subject + '</span>';
|
||||
item.rspamdaction = '<span class="badge fs-5 bg-warning">' + lang.rewrite_subject + '</span>';
|
||||
}
|
||||
if(item.notified > 0) {
|
||||
item.notified = '✔';
|
||||
@@ -95,7 +48,7 @@ jQuery(function($){
|
||||
item.notified = '✖';
|
||||
}
|
||||
if (acl_data.login_as === 1) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-info show_qid_info"><i class="bi bi-box-arrow-up-right"></i> ' + lang.show_item + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="del-single-qitem" data-api-url="delete/qitem" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
@@ -107,25 +60,76 @@ jQuery(function($){
|
||||
}
|
||||
item.chkbox = '<input type="checkbox" data-id="qitems" name="multi_select" value="' + item.id + '" />';
|
||||
});
|
||||
}
|
||||
}),
|
||||
"empty": lang.empty,
|
||||
"paging": {"enabled": true,"limit": 5,"size": pagination_size},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {"enabled": true},
|
||||
"filtering": {"enabled": true,"position": "left","connectors": false,"placeholder": lang.filter_table},
|
||||
"toggleSelector": "table tbody span.footable-toggle",
|
||||
"on": {
|
||||
"destroy.ft.table": function(e, ft){
|
||||
$('.refresh_table').attr('disabled', 'true');
|
||||
},
|
||||
"ready.ft.table": function(e, ft){
|
||||
table_quarantine_ready(ft, 'quarantinetable');
|
||||
},
|
||||
"after.ft.filtering": function(e, ft){
|
||||
table_quarantine_ready(ft, 'quarantinetable');
|
||||
|
||||
return data;
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id',
|
||||
},
|
||||
{
|
||||
title: lang.qid,
|
||||
data: 'qid'
|
||||
},
|
||||
{
|
||||
title: lang.sender,
|
||||
data: 'sender'
|
||||
},
|
||||
{
|
||||
title: lang.subj,
|
||||
data: 'sender'
|
||||
},
|
||||
{
|
||||
title: lang.rspamd_result,
|
||||
data: 'rspamdaction'
|
||||
},
|
||||
{
|
||||
title: lang.rcpt,
|
||||
data: 'rcpt'
|
||||
},
|
||||
{
|
||||
title: lang.danger,
|
||||
data: 'virus'
|
||||
},
|
||||
{
|
||||
title: lang.spam_score,
|
||||
data: 'score'
|
||||
},
|
||||
{
|
||||
title: lang.notified,
|
||||
data: 'notified'
|
||||
},
|
||||
{
|
||||
title: lang.received,
|
||||
data: 'created',
|
||||
render: function (data,type) {
|
||||
var date = new Date(data ? data * 1000 : 0);
|
||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -175,9 +179,9 @@ jQuery(function($){
|
||||
if (value.score > 0) highlightClass = 'negative'
|
||||
else if (value.score < 0) highlightClass = 'positive'
|
||||
else highlightClass = 'neutral'
|
||||
$('#qid_detail_symbols').append('<span data-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
||||
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
||||
});
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$('[data-bs-toggle="tooltip"]').tooltip()
|
||||
}
|
||||
if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
|
||||
$.each(data.fuzzy_hashes, function (index, value) {
|
||||
@@ -188,11 +192,11 @@ jQuery(function($){
|
||||
}
|
||||
if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
|
||||
if (data.action == "add header") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
|
||||
} else if (data.action == "reject") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
|
||||
} else if (data.action == "rewrite subject") {
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
|
||||
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
|
||||
}
|
||||
}
|
||||
if (typeof data.recipients !== 'undefined') {
|
||||
|
@@ -101,7 +101,7 @@ jQuery(function($){
|
||||
$.each(data.sasl, function (i, item) {
|
||||
var datetime = new Date(item.datetime.replace(/-/g, "/"));
|
||||
var local_datetime = datetime.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
||||
var service = '<div class="label label-default">' + item.service.toUpperCase() + '</div>';
|
||||
var service = '<div class="badge fs-5 bg-secondary">' + item.service.toUpperCase() + '</div>';
|
||||
var app_password = item.app_password ? ' <a href="/edit/app-passwd/' + item.app_password + '"><i class="bi bi-app-indicator"></i> ' + escapeHtml(item.app_password_name || "App") + '</a>' : '';
|
||||
var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.he.net/ip/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";
|
||||
var ip_location = item.location ? ' <span class="flag-icon flag-icon-' + item.location.toLowerCase() + '"></span>' : '';
|
||||
@@ -128,26 +128,18 @@ jQuery(function($){
|
||||
}
|
||||
|
||||
function draw_tla_table() {
|
||||
ft_tla_table = FooTable.init('#tla_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"min-width":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"address","title":lang.alias},
|
||||
{"name":"validity","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.alias_valid_until,"style":{"width":"170px"}},
|
||||
{"sorted": true,"sortValue": function(value){res = new Date(value);return res.getTime();},"direction":"DESC","name":"created","formatter":function date_format(datetime) { var date = new Date(datetime.replace(/-/g, "/")); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.created_on,"style":{"width":"170px"}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/time_limited_aliases',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw tla table');
|
||||
},
|
||||
success: function (data) {
|
||||
$('#tla_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: "/api/v1/get/time_limited_aliases",
|
||||
dataSrc: function(data){
|
||||
console.log(data);
|
||||
$.each(data, function (i, item) {
|
||||
if (acl_data.spam_alias === 1) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-tla" data-api-url="delete/time_limited_alias" data-item="' + encodeURIComponent(item.address) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.chkbox = '<input type="checkbox" data-id="tla" name="multi_select" value="' + encodeURIComponent(item.address) + '" />';
|
||||
@@ -158,49 +150,59 @@ jQuery(function($){
|
||||
item.action = '<span>-</span>';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang.alias,
|
||||
data: 'address'
|
||||
},
|
||||
{
|
||||
title: lang.alias_valid_until,
|
||||
data: 'validity',
|
||||
render: function (data, type) {
|
||||
var date = new Date(data ? data * 1000 : 0);
|
||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_sync_job_table() {
|
||||
ft_syncjob_table = FooTable.init('#sync_job_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"min-width":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
|
||||
{"name":"server_w_port","title":"Server","breakpoints":"xs sm md","style":{"word-break":"break-all"}},
|
||||
{"name":"enc1","title":lang.encryption,"breakpoints":"all"},
|
||||
{"name":"user1","title":lang.username},
|
||||
{"name":"exclude","title":lang.excludes,"breakpoints":"all"},
|
||||
{"name":"mins_interval","title":lang.interval + " (min)","breakpoints":"all"},
|
||||
{"name":"last_run","title":lang.last_run,"breakpoints":"xs sm md"},
|
||||
{"name":"exit_status","filterable": false,"title":lang.syncjob_last_run_result},
|
||||
{"name":"log","title":"Log"},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"is_running","filterable": false,"style":{"maxWidth":"120px","width":"100px"},"title":lang.status},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"260px","width":"260px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#sync_job_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/syncjobs/' + encodeURIComponent(mailcow_cc_username) + '/no_log',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw sync job table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
console.log(data);
|
||||
$.each(data, function (i, item) {
|
||||
item.user1 = escapeHtml(item.user1);
|
||||
item.log = '<a href="#syncjobLogModal" data-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
|
||||
item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
|
||||
if (!item.exclude > 0) {
|
||||
item.exclude = '-';
|
||||
} else {
|
||||
@@ -208,8 +210,8 @@ jQuery(function($){
|
||||
}
|
||||
item.server_w_port = escapeHtml(item.user1 + '@' + item.host1 + ':' + item.port1);
|
||||
if (acl_data.syncjobs === 1) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.chkbox = '<input type="checkbox" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
|
||||
@@ -219,9 +221,9 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled />';
|
||||
}
|
||||
if (item.is_running == 1) {
|
||||
item.is_running = '<span id="active-script" class="label label-success">' + lang.running + '</span>';
|
||||
item.is_running = '<span id="active-script" class="badge fs-5 bg-success">' + lang.running + '</span>';
|
||||
} else {
|
||||
item.is_running = '<span id="inactive-script" class="label label-warning">' + lang.waiting + '</span>';
|
||||
item.is_running = '<span id="inactive-script" class="badge fs-5 bg-warning">' + lang.waiting + '</span>';
|
||||
}
|
||||
if (!item.last_run > 0) {
|
||||
item.last_run = lang.waiting;
|
||||
@@ -239,39 +241,91 @@ jQuery(function($){
|
||||
}
|
||||
item.exit_status = item.success + ' ' + item.exit_status;
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id'
|
||||
},
|
||||
{
|
||||
title: 'Server',
|
||||
data: 'server_w_port'
|
||||
},
|
||||
{
|
||||
title: lang.encryption,
|
||||
data: 'enc1'
|
||||
},
|
||||
{
|
||||
title: lang.username,
|
||||
data: 'user1'
|
||||
},
|
||||
{
|
||||
title: lang.excludes,
|
||||
data: 'exclude'
|
||||
},
|
||||
{
|
||||
title: lang.interval + " (min)",
|
||||
data: 'mins_interval'
|
||||
},
|
||||
{
|
||||
title: lang.last_run,
|
||||
data: 'last_run'
|
||||
},
|
||||
{
|
||||
title: lang.syncjob_last_run_result,
|
||||
data: 'exit_status'
|
||||
},
|
||||
{
|
||||
title: 'Log',
|
||||
data: 'log'
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active',
|
||||
render: function (data, type) {
|
||||
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.status,
|
||||
data: 'is_running'
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_app_passwd_table() {
|
||||
ft_apppasswd_table = FooTable.init('#app_passwd_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
|
||||
{"name":"name","title":lang.app_name},
|
||||
{"name":"protocols","title":lang.allowed_protocols},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#app_passwd_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/app-passwd/all',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw app passwd table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
console.log(data);
|
||||
$.each(data, function (i, item) {
|
||||
item.name = escapeHtml(item.name)
|
||||
item.protocols = []
|
||||
@@ -283,8 +337,8 @@ jQuery(function($){
|
||||
if (item.sieve_access == 1) { item.protocols.push("<code>Sieve</code>"); }
|
||||
item.protocols = item.protocols.join(" ")
|
||||
if (acl_data.app_passwds === 1) {
|
||||
item.action = '<div class="btn-group footable-actions">' +
|
||||
'<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
|
||||
'<a href="#" data-action="delete_selected" data-id="single-apppasswd" data-api-url="delete/app-passwd" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
item.chkbox = '<input type="checkbox" data-id="apppasswd" name="multi_select" value="' + item.id + '" />';
|
||||
@@ -294,37 +348,63 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled />';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
},
|
||||
"toggleSelector": "table tbody span.footable-toggle"
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'id'
|
||||
},
|
||||
{
|
||||
title: lang.app_name,
|
||||
data: 'name'
|
||||
},
|
||||
{
|
||||
title: lang.allowed_protocols,
|
||||
data: 'protocols'
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active',
|
||||
render: function (data, type) {
|
||||
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.action,
|
||||
data: 'action',
|
||||
className: 'text-md-end dt-sm-head-hidden dt-body-right'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_wl_policy_mailbox_table() {
|
||||
ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_mailbox_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#wl_policy_mailbox_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/policy_wl_mailbox',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw mailbox policy wl table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
console.log(data);
|
||||
$.each(data, function (i, item) {
|
||||
if (validateEmail(item.object)) {
|
||||
item.chkbox = '<input type="checkbox" data-id="policy_wl_mailbox" name="multi_select" value="' + item.prefid + '" />';
|
||||
@@ -336,36 +416,51 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled />';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"state": {"enabled": true},
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
}
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'prefid'
|
||||
},
|
||||
{
|
||||
title: lang.spamfilter_table_rule,
|
||||
data: 'name'
|
||||
},
|
||||
{
|
||||
title:'Scope',
|
||||
data: 'object'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
function draw_bl_policy_mailbox_table() {
|
||||
ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_mailbox_table', {
|
||||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
$('#bl_policy_mailbox_table').DataTable({
|
||||
processing: true,
|
||||
serverSide: false,
|
||||
language: lang_datatables,
|
||||
ajax: {
|
||||
type: "GET",
|
||||
url: '/api/v1/get/policy_bl_mailbox',
|
||||
jsonp: false,
|
||||
error: function () {
|
||||
console.log('Cannot draw mailbox policy bl table');
|
||||
},
|
||||
success: function (data) {
|
||||
dataSrc: function(data){
|
||||
console.log(data);
|
||||
$.each(data, function (i, item) {
|
||||
if (validateEmail(item.object)) {
|
||||
item.chkbox = '<input type="checkbox" data-id="policy_bl_mailbox" name="multi_select" value="' + item.prefid + '" />';
|
||||
@@ -377,31 +472,42 @@ jQuery(function($){
|
||||
item.chkbox = '<input type="checkbox" disabled />';
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}),
|
||||
"paging": {
|
||||
"enabled": true,
|
||||
"limit": 5,
|
||||
"size": pagination_size
|
||||
},
|
||||
"state": {"enabled": true},
|
||||
"sorting": {
|
||||
"enabled": true
|
||||
}
|
||||
columns: [
|
||||
{
|
||||
// placeholder, so checkbox will not block child row toggle
|
||||
title: '',
|
||||
data: null,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
data: 'chkbox',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
data: 'prefid'
|
||||
},
|
||||
{
|
||||
title: lang.spamfilter_table_rule,
|
||||
data: 'name'
|
||||
},
|
||||
{
|
||||
title:'Scope',
|
||||
data: 'object'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
$('body').on('click', 'span.footable-toggle', function () {
|
||||
event.stopPropagation();
|
||||
})
|
||||
|
||||
draw_sync_job_table();
|
||||
draw_app_passwd_table();
|
||||
draw_tla_table();
|
||||
draw_wl_policy_mailbox_table();
|
||||
draw_bl_policy_mailbox_table();
|
||||
last_logins('get');
|
||||
|
||||
// FIDO2 friendly name modal
|
||||
$('#fido2ChangeFn').on('show.bs.modal', function (e) {
|
||||
rename_link = $(e.relatedTarget)
|
||||
@@ -433,4 +539,27 @@ jQuery(function($){
|
||||
$('#userFilterModal').on('hidden.bs.modal', function () {
|
||||
$('#user_sieve_filter').text(lang.loading);
|
||||
});
|
||||
|
||||
// detect element visibility changes
|
||||
function onVisible(element, callback) {
|
||||
$(element).ready(function() {
|
||||
element_object = document.querySelector(element)
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.intersectionRatio > 0) {
|
||||
callback(element_object);
|
||||
observer.disconnect();
|
||||
}
|
||||
});
|
||||
}).observe(element_object);
|
||||
});
|
||||
}
|
||||
|
||||
// Load only if the tab is visible
|
||||
onVisible("[id^=tla_table]", () => draw_tla_table());
|
||||
onVisible("[id^=bl_policy_mailbox_table]", () => draw_bl_policy_mailbox_table());
|
||||
onVisible("[id^=wl_policy_mailbox_table]", () => draw_wl_policy_mailbox_table());
|
||||
onVisible("[id^=sync_job_table]", () => draw_sync_job_table());
|
||||
onVisible("[id^=app_passwd_table]", () => draw_app_passwd_table());
|
||||
last_logins('get');
|
||||
});
|
||||
|
Reference in New Issue
Block a user