diff --git a/front/css/app.css b/front/css/app.css index 5afd72ee..c65c03fc 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -25,6 +25,7 @@ color:white; background-color: black; font-family: 'Courier New', monospace; + font-size: .85em; } .logs-row textarea @@ -58,7 +59,7 @@ } .logs-small { - height: 100px; + height: 150px; } .log-file { diff --git a/front/deviceDetails.php b/front/deviceDetails.php index 4e261a1a..03c44d92 100755 --- a/front/deviceDetails.php +++ b/front/deviceDetails.php @@ -824,7 +824,7 @@ function initializeCombos () { initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false); // Initiate dropdown - // initSettingDropdown(settingKey, // Identifier for the setting + // generateSetOptions(settingKey, // Identifier for the setting // valuesArray, // Array of values to be pre-selected in the dropdown // targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced) // callbackToGenerateEntries, // Callback function to generate entries based on options @@ -832,12 +832,12 @@ function initializeCombos () { // nameTransformer) // callback to transform name - initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', atob ) - initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' ) - initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' ) - initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' ) - initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' ) - initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' ) + generateOptionsOrSetOptions("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"]) + generateOptionsOrSetOptions("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' ) + generateOptionsOrSetOptions("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' ) + generateOptionsOrSetOptions("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' ) + generateOptionsOrSetOptions("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' ) + generateOptionsOrSetOptions("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' ) // Initialize static combos initializeComboSkipRepeated (); diff --git a/front/js/common.js b/front/js/common.js index 93e40f65..d659ff71 100755 --- a/front/js/common.js +++ b/front/js/common.js @@ -160,12 +160,7 @@ function cacheSettings() } } - console.log(resolved); - console.log(resolvedOptionsOld); - console.log(resolvedOptions); - - setCache(`pia_set_${set.Code_Name}`, set.Value) - + setCache(`pia_set_${set.Code_Name}`, set.Value) setCache(`pia_set_opt_${set.Code_Name}`, resolvedOptions) }); }).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization @@ -756,7 +751,7 @@ function isRandomMAC(mac) return input; } // Empty array - if (input === '[]') { + if (input === '[]' || input === '') { return []; } diff --git a/front/js/db_methods.js b/front/js/db_methods.js index 4678629d..fede8f45 100755 --- a/front/js/db_methods.js +++ b/front/js/db_methods.js @@ -5,49 +5,95 @@ // -------------------------------------------------- // Read data and place intotarget location, callback processies the results -function readData(sqlQuery, processDataCallback, valuesArray, targetLocation, targetField, nameTransformer) { - - var apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`; - $.get(apiUrl, function(data) { - // Process the JSON data using the provided callback function +function renderList( + options, + processDataCallback, + valuesArray, + placeholder, + targetField, + transformers +) { + // Check if there are options provided + if (options.length > 0) { + // Determine if the first option's name is an SQL query + const sqlQuery = isSQLQuery(options[0].name) ? options[0].name : ""; - data = JSON.parse(data) + // If there is an SQL query, fetch additional options + if (sqlQuery) { + // remove first item containing the SQL query + options.shift(); - var htmlResult = processDataCallback(data, valuesArray, targetField, nameTransformer); + const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`; - // Place the resulting HTML into the specified placeholder div - $("#" + targetLocation).replaceWith(htmlResult); - }); + $.get(apiUrl, function (sqlOptionsData) { + + // Parse the returned SQL data + const sqlOption = JSON.parse(sqlOptionsData); + + // Concatenate options from SQL query with the supplied options + options = options.concat(sqlOption); + + // Process the combined options + setTimeout(() => { + processDataCallback( + options, + valuesArray, + targetField, + transformers, + placeholder + ); + }, 1); + }); + } else { + // No SQL query, directly process the supplied options + setTimeout(() => { + processDataCallback( + options, + valuesArray, + targetField, + transformers, + placeholder + ); + }, 1); + } + } else { + // No options provided, directly process with empty options + setTimeout(() => { + processDataCallback( + options, + valuesArray, + targetField, + transformers, + placeholder + ); + }, 1); + } } + // -------------------------------------------------- // Check if database is locked function checkDbLock() { - $.ajax({ - url: 'log/db_is_locked.log', // Replace with the actual path to your PHP file - type: 'GET', - - success: function(response) { - console.log(response); - if (response == 0) { - // console.log('Database is not locked'); - $(".header-status-locked-db").hide() - - } else { - console.log('🟥 Database is locked:'); - console.log(response); - $(".header-status-locked-db").show() - } - }, - error: function() { - console.log('🟥 Error checking database lock status'); - $(".header-status-locked-db").show() - } - }); + $.ajax({ + url: "log/db_is_locked.log", // Replace with the actual path to your PHP file + type: "GET", + + success: function (response) { + console.log(response); + if (response == 0) { + // console.log('Database is not locked'); + $(".header-status-locked-db").hide(); + } else { + console.log("🟥 Database is locked:"); + console.log(response); + $(".header-status-locked-db").show(); + } + }, + error: function () { + console.log("🟥 Error checking database lock status"); + $(".header-status-locked-db").show(); + }, + }); } setInterval(checkDbLock(), 1000); - - - - diff --git a/front/js/settings_utils.js b/front/js/settings_utils.js index 29fc7f41..dd81e5b9 100755 --- a/front/js/settings_utils.js +++ b/front/js/settings_utils.js @@ -1,248 +1,242 @@ // ------------------------------------------------------------------- - // Get all plugin prefixes of a given type - function getPluginsByType(pluginsData, pluginType, onlyEnabled) - { +// Get all plugin prefixes of a given type +function getPluginsByType(pluginsData, pluginType, onlyEnabled) { + var result = []; - var result = [] - - pluginsData.forEach((plug) => { - - if(plug.plugin_type == pluginType) - { - // collect all, or if only enabled, check if NOT disabled - if (onlyEnabled == false || (onlyEnabled && getSetting(plug.unique_prefix + '_RUN') != 'disabled')) { - result.push(plug.unique_prefix) - } + pluginsData.forEach((plug) => { + if (plug.plugin_type == pluginType) { + // collect all, or if only enabled, check if NOT disabled + if ( + onlyEnabled == false || + (onlyEnabled && getSetting(plug.unique_prefix + "_RUN") != "disabled") + ) { + result.push(plug.unique_prefix); } - }); + } + }); - return result; - } + return result; +} - // ------------------------------------------------------------------- - // Get plugin code name base on prefix - function getPluginCodeName(pluginsData, prefix) - { - var result = "" +// ------------------------------------------------------------------- +// Get plugin code name base on prefix +function getPluginCodeName(pluginsData, prefix) { + var result = ""; - pluginsData.forEach((plug) => { + pluginsData.forEach((plug) => { + if (plug.unique_prefix == prefix) { + id = plug.code_name; - if (plug.unique_prefix == prefix ) { - id = plug.code_name; - - // console.log(id) - result = plug.code_name; - } - }); + // console.log(id) + result = plug.code_name; + } + }); - return result; - } + return result; +} +// ------------------------------------------------------------------- +// Get plugin type base on prefix +function getPluginType(pluginsData, prefix) { + var result = "core"; - // ------------------------------------------------------------------- - // Get plugin type base on prefix - function getPluginType(pluginsData, prefix) - { - var result = "core" + pluginsData.forEach((plug) => { + if (plug.unique_prefix == prefix) { + id = plug.plugin_type; - pluginsData.forEach((plug) => { + // console.log(id) + result = plug.plugin_type; + } + }); - if (plug.unique_prefix == prefix ) { - id = plug.plugin_type; - - // console.log(id) - result = plug.plugin_type; - } - }); + return result; +} - return result; - } +// ------------------------------------------------------------------- +// Get plugin config based on prefix +function getPluginConfig(pluginsData, prefix) { + result = ""; - // ------------------------------------------------------------------- - // Get plugin config based on prefix - function getPluginConfig(pluginsData, prefix) - { + pluginsData.forEach((plug) => { + if (plug.unique_prefix == prefix) { + // console.log(id) + result = plug; + } + }); - result = "" + return result; +} - pluginsData.forEach((plug) => { +// ------------------------------------------------------------------- +// Generate plugin HTML card based on prefixes in an array +function pluginCards(prefixesOfEnabledPlugins, includeSettings) { + html = ""; - if (plug.unique_prefix == prefix ) { - - // console.log(id) - result = plug; - } - }); + prefixesOfEnabledPlugins.forEach((prefix) => { + includeSettings_html = ""; - return result; - } - - // ------------------------------------------------------------------- - // Generate plugin HTML card based on prefixes in an array - function pluginCards(prefixesOfEnabledPlugins, includeSettings) - { - html = "" - - prefixesOfEnabledPlugins.forEach((prefix) => { - - includeSettings_html = '' - - includeSettings.forEach((set) => { - - includeSettings_html += ` + includeSettings.forEach((set) => { + includeSettings_html += `
- -
- ${getSetting(prefix + '_' + set)} + +
+ ${getSetting(prefix + "_" + set)}
- ` - }); + `; + }); - html += ` + html += `
- ` + `; + }); + + return html; +} + +// ----------------------------------------------------------------------------- +// Open or close all settings +// ----------------------------------------------------------------------------- +function toggleAllSettings(openOrClose = "") { + inStr = " in"; + allOpen = true; + openIcon = "fa-angle-double-down"; + closeIcon = "fa-angle-double-up"; + + $(".panel-collapse").each(function () { + if ($(this).attr("class").indexOf(inStr) == -1) { + allOpen = false; + } + }); + + if (allOpen == false || openOrClose == "open") { + // open all + openAllSettings(); + $("#toggleSettings").attr( + "class", + $("#toggleSettings").attr("class").replace(openIcon, closeIcon) + ); + } else { + // close all + $('div[data-myid="collapsible"]').each(function () { + $(this).attr("class", "panel-collapse collapse "); }); - - return html; + $("#toggleSettings").attr( + "class", + $("#toggleSettings").attr("class").replace(closeIcon, openIcon) + ); } +} +function openAllSettings() { + $('div[data-myid="collapsible"]').each(function () { + $(this).attr("class", "panel-collapse collapse in"); + }); + $('div[data-myid="collapsible"]').each(function () { + $(this).attr("style", "height:inherit"); + }); +} - // ----------------------------------------------------------------------------- - // Open or close all settings - // ----------------------------------------------------------------------------- - function toggleAllSettings(openOrClose = '') - { - inStr = ' in'; - allOpen = true; - openIcon = 'fa-angle-double-down'; - closeIcon = 'fa-angle-double-up'; +// ------------------------------------------------------------------- +// Checks if all schedules are the same +function schedulesAreSynchronized(prefixesOfEnabledPlugins, pluginsData) { + plug_schedules = []; - $('.panel-collapse').each(function(){ - if($(this).attr('class').indexOf(inStr) == -1) - { - allOpen = false; + prefixesOfEnabledPlugins.forEach((prefix) => { + pluginsData.forEach((plug) => { + if (plug.unique_prefix == prefix) { + plug_schedules.push( + getSetting(prefix + "_RUN_SCHD").replace(/\s/g, "") + ); // replace all white characters to compare them easier } - }) - - if(allOpen == false || openOrClose == 'open') - { - // open all - openAllSettings() - $('#toggleSettings').attr('class', $('#toggleSettings').attr('class').replace(openIcon, closeIcon)) - - } - else{ - // close all - $('div[data-myid="collapsible"]').each(function(){$(this).attr('class', 'panel-collapse collapse ')}) - $('#toggleSettings').attr('class', $('#toggleSettings').attr('class').replace(closeIcon, openIcon)) - } - - } - - function openAllSettings() { - $('div[data-myid="collapsible"]').each(function(){$(this).attr('class', 'panel-collapse collapse in')}) - $('div[data-myid="collapsible"]').each(function(){$(this).attr('style', 'height:inherit')}) - } - - - // ------------------------------------------------------------------- - // Checks if all schedules are the same - function schedulesAreSynchronized(prefixesOfEnabledPlugins, pluginsData) - { - plug_schedules = [] - - prefixesOfEnabledPlugins.forEach((prefix) => { - pluginsData.forEach((plug) => { - - if (plug.unique_prefix == prefix) { - - plug_schedules.push(getSetting(prefix+"_RUN_SCHD").replace(/\s/g, "")) // replace all white characters to compare them easier - - } - - }); }); + }); - // Check if all plug_schedules are the same - if (plug_schedules.length > 0) { - const firstSchedule = plug_schedules[0]; - return plug_schedules.every((schedule) => schedule === firstSchedule); - } - - return true; // Return true if no schedules are found + // Check if all plug_schedules are the same + if (plug_schedules.length > 0) { + const firstSchedule = plug_schedules[0]; + return plug_schedules.every((schedule) => schedule === firstSchedule); } - // ------------------------------------------------------------------- - // Checks if value is already encoded - function isSHA256(value) { - // Check if the value is a string and has a length of 64 characters - if (typeof value === "string" && value.length === 64) { - // Check if the value contains only hexadecimal characters - return /^[0-9a-fA-F]+$/.test(value); - } else { - return false; - } - } + return true; // Return true if no schedules are found +} - // ------------------------------------------------------------------- - // Utility function to check if the value is already Base64 - function isBase64(value) { - const base64Regex = /^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/; - return base64Regex.test(value); +// ------------------------------------------------------------------- +// Checks if value is already encoded +function isSHA256(value) { + // Check if the value is a string and has a length of 64 characters + if (typeof value === "string" && value.length === 64) { + // Check if the value contains only hexadecimal characters + return /^[0-9a-fA-F]+$/.test(value); + } else { + return false; } +} + +// ------------------------------------------------------------------- +// Utility function to check if the value is already Base64 +function isBase64(value) { + const base64Regex = + /^(?:[A-Za-z0-9+\/]{4})*?(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/; + return base64Regex.test(value); +} // ------------------------------------------------------------------- // Validation // ------------------------------------------------------------------- function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) { - // check if the required UI_LANG setting is in the array - if not something went wrong - $.each(settingsArray, function(index, value) { - if (value[1] == "UI_LANG") { - if(isEmpty(value[3]) == true) - { - console.log(`⚠ Error: Required setting UI_LANG not found`); - showModalOk('ERROR', getString('settings_missing_block')); + $.each(settingsArray, function (index, value) { + if (value[1] == "UI_LANG") { + if (isEmpty(value[3]) == true) { + console.log(`⚠ Error: Required setting UI_LANG not found`); + showModalOk("ERROR", getString("settings_missing_block")); - return false; - } + return false; } + } }); - const settingsCodeNames = settingsJSON_DB.map(setting => setting.Code_Name); - const detailedCodeNames = settingsArray.map(item => item[1]); + const settingsCodeNames = settingsJSON_DB.map((setting) => setting.Code_Name); + const detailedCodeNames = settingsArray.map((item) => item[1]); - const missingCodeNamesOnPage = detailedCodeNames.filter(codeName => !settingsCodeNames.includes(codeName)); - const missingCodeNamesInDB = settingsCodeNames.filter(codeName => !detailedCodeNames.includes(codeName)); + const missingCodeNamesOnPage = detailedCodeNames.filter( + (codeName) => !settingsCodeNames.includes(codeName) + ); + const missingCodeNamesInDB = settingsCodeNames.filter( + (codeName) => !detailedCodeNames.includes(codeName) + ); // check if the number of settings on the page and in the DB are the same if (missingCodeNamesOnPage.length !== missingCodeNamesInDB.length) { + console.log( + `⚠ Error: The following settings are missing in the DB or on the page (Reload page to fix):` + ); + console.log(missingCodeNamesOnPage); + console.log(missingCodeNamesInDB); - console.log(`⚠ Error: The following settings are missing in the DB or on the page (Reload page to fix):`); - console.log(missingCodeNamesOnPage); - console.log(missingCodeNamesInDB); + showModalOk("ERROR", getString("settings_missing_block")); - showModalOk('ERROR', getString('settings_missing_block')); - - return false; - } + return false; + } // all OK return true; @@ -253,104 +247,102 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) { // --------------------------------------------------------- // Add item to list -function addList(element, clearInput = true) -{ - const fromId = $(element).attr('my-input-from'); - const toId = $(element).attr('my-input-to'); +function addList(element, clearInput = true) { + const fromId = $(element).attr("my-input-from"); + const toId = $(element).attr("my-input-to"); const input = $(`#${fromId}`).val(); console.log(`fromId | toId | input : ${fromId} | ${toId} | ${input}`); - const newOption = $("").attr("value", input).text(input); - + const newOption = $("") + .attr("value", input) + .text(input); + const el = $(`#${toId}`).append(newOption); - + // clear input - if (clearInput) - { + if (clearInput) { $(`#${fromId}`).val(""); } // Initialize interaction options only for the newly added option initListInteractionOptions(newOption); - + settingsChanged(); } // --------------------------------------------------------- -function removeFromList(element) -{ - settingsChanged(); - $(`#${$(element).attr('my-input-to')}`).find("option:last").remove(); - +function removeFromList(element) { + settingsChanged(); + $(`#${$(element).attr("my-input-to")}`) + .find("option:last") + .remove(); } // --------------------------------------------------------- -function addInterface() -{ - ipMask = $('#ipMask').val(); - ipInterface = $('#ipInterface').val(); +function addInterface() { + ipMask = $("#ipMask").val(); + ipInterface = $("#ipInterface").val(); full = ipMask + " --interface=" + ipInterface; - console.log(full) + console.log(full); - if(ipMask == "" || ipInterface == "") - { - showModalOk ('Validation error', 'Specify both, the network mask and the interface'); + if (ipMask == "" || ipInterface == "") { + showModalOk( + "Validation error", + "Specify both, the network mask and the interface" + ); } else { - $('#SCAN_SUBNETS').append($('').attr('value', full).text(full)); + $("#SCAN_SUBNETS").append( + $("").attr("value", full).text(full) + ); - $('#ipMask').val(''); - $('#ipInterface').val(''); + $("#ipMask").val(""); + $("#ipInterface").val(""); settingsChanged(); } } - // ------------------------------------------------------------------- // Function to remove an item from the select element function removeOptionItem(option) { - settingsChanged(); + settingsChanged(); option.remove(); } // ------------------------------------------------------------------- // Update value of an item from the select element - function updateOptionItem(option, value) { - settingsChanged(); +function updateOptionItem(option, value) { + settingsChanged(); option.html(value); option.val(value); } // ------------------------------------------------------------------- // Remove all options -function removeAllOptions(element) -{ - settingsChanged(); - $(`#${$(element).attr('my-input-to')}`).empty(); - +function removeAllOptions(element) { + settingsChanged(); + $(`#${$(element).attr("my-input-to")}`).empty(); } // ------------------------------------------------------------------- -// Function to initialize remove functionality on select options +// Function to initialize remove functionality on select options // Counter to track number of clicks let clickCounter = 0; // Function to initialize list interaction options function initListInteractionOptions(element) { - if(element) - { + if (element) { $options = $(element); - } else - { + } else { $options = $(`.interactable-option`); } // Attach click event listener to options - $options.on('click', function() { + $options.on("click", function () { const $option = $(this); // Increment click counter @@ -362,13 +354,15 @@ function initListInteractionOptions(element) { if (clickCounter === 1) { // Single-click action showModalFieldInput( - ` ${getString('Gen_Update_Value')}`, - getString('settings_update_item_warning'), - getString('Gen_Cancel'), - getString('Gen_Update'), + ` ${getString( + "Gen_Update_Value" + )}`, + getString("settings_update_item_warning"), + getString("Gen_Cancel"), + getString("Gen_Update"), $option.html(), - function() { - updateOptionItem($option, $(`#modal-field-input-field`).val()) + function () { + updateOptionItem($option, $(`#modal-field-input-field`).val()); } ); } else if (clickCounter === 2) { @@ -380,30 +374,29 @@ function initListInteractionOptions(element) { clickCounter = 0; }, 300); // Adjust delay as needed }); - } - // ------------------------------------------------------------------- // Function to filter rows based on input text function filterRows(inputText) { - - if(!inputText) - { - inputText = '' + if (!inputText) { + inputText = ""; } - $('.table_row').each(function() { + $(".table_row").each(function () { // Check if the row id ends with '__metadata' - var idAttribute = $(this).attr('id'); - if (idAttribute && idAttribute.endsWith('__metadata')) { + var idAttribute = $(this).attr("id"); + if (idAttribute && idAttribute.endsWith("__metadata")) { $(this).hide(); // Hide the row if it ends with '__metadata' return; // Skip to the next iteration } - var description = $(this).find('.setting_description').text().toLowerCase(); - var codeName = $(this).find('.setting_name code').text().toLowerCase(); - if (description.includes(inputText.toLowerCase()) || codeName.includes(inputText.toLowerCase())) { + var description = $(this).find(".setting_description").text().toLowerCase(); + var codeName = $(this).find(".setting_name code").text().toLowerCase(); + if ( + description.includes(inputText.toLowerCase()) || + codeName.includes(inputText.toLowerCase()) + ) { $(this).show(); // Show the row if it matches the input text } else { $(this).hide(); // Hide the row if it doesn't match the input text @@ -411,168 +404,296 @@ function filterRows(inputText) { }); } - setTimeout(() => { +setTimeout(() => { + // Event listener for input change + $("#settingsSearch").on("input", function () { + var searchText = $(this).val(); + // hide the setting overview dashboard + $("#settingsOverview").collapse("hide"); - // Event listener for input change - $('#settingsSearch').on('input', function() { - var searchText = $(this).val(); - // hide the setting overview dashboard - $('#settingsOverview').collapse('hide'); + filterRows(searchText); + }); - filterRows(searchText); - }); + // Event listener for input focus + // var firstFocus = true; + $("#settingsSearch").on("focus", function () { + openAllSettings(); + }); +}, 1000); - // Event listener for input focus - // var firstFocus = true; - $('#settingsSearch').on('focus', function() { - openAllSettings() - }); +// ----------------------------------------------------------------------------- +// handling events on the backend initiated by the front end END +// ----------------------------------------------------------------------------- - - - }, 1000); - - - - // ----------------------------------------------------------------------------- - // handling events on the backend initiated by the front end END - // ----------------------------------------------------------------------------- - - -// --------------------------------------------------------- +// --------------------------------------------------------- // UNUSED? -function getParam(targetId, key, skipCache = false) { - +function getParam(targetId, key, skipCache = false) { skipCacheQuery = ""; - if(skipCache) - { + if (skipCache) { skipCacheQuery = "&skipcache"; } // get parameter value - $.get('php/server/parameters.php?action=get&defaultValue=0¶meter='+ key + skipCacheQuery, function(data) { + $.get( + "php/server/parameters.php?action=get&defaultValue=0¶meter=" + + key + + skipCacheQuery, + function (data) { + var result = data; - var result = data; - - result = result.replaceAll('"', ''); - - document.getElementById(targetId).innerHTML = result.replaceAll('"', ''); - }); + result = result.replaceAll('"', ""); + + document.getElementById(targetId).innerHTML = result.replaceAll('"', ""); + } + ); } - // ----------------------------------------------------------------------------- - // Show/hide the metadata settings - // ----------------------------------------------------------------------------- - function toggleMetadata(element) - { - const id = $(element).attr('my-to-toggle'); +// ----------------------------------------------------------------------------- +// Show/hide the metadata settings +// ----------------------------------------------------------------------------- +function toggleMetadata(element) { + const id = $(element).attr("my-to-toggle"); - $(`#${id}`).toggle(); + $(`#${id}`).toggle(); +} + +// --------------------------------------------------------- +// Helper methods +// --------------------------------------------------------- +// Toggle readonly mode of the target element specified by the id in the "my-input-toggle-readonly" attribute +function overrideToggle(element) { + settingsChanged(); + + targetId = $(element).attr("my-input-toggle-readonly"); + + inputElement = $(`#${targetId}`)[0]; + + if (!inputElement) { + console.error("Input element not found!"); + return; } - - - // --------------------------------------------------------- - // Helper methods - // --------------------------------------------------------- - // Toggle readonly mode of the target element specified by the id in the "my-input-toggle-readonly" attribute - function overrideToggle(element) { - settingsChanged(); - - targetId = $(element).attr("my-input-toggle-readonly"); - - inputElement = $(`#${targetId}`)[0]; - - if (!inputElement) { - console.error("Input element not found!"); - return; - } - - if (inputElement.type === "text" || inputElement.type === "password") { - inputElement.readOnly = !inputElement.readOnly; - } else if (inputElement.type === "checkbox") { - inputElement.disabled = !inputElement.disabled; - } else { - console.warn("Unsupported input type. Only text, password, and checkbox inputs are supported."); - } - + if (inputElement.type === "text" || inputElement.type === "password") { + inputElement.readOnly = !inputElement.readOnly; + } else if (inputElement.type === "checkbox") { + inputElement.disabled = !inputElement.disabled; + } else { + console.warn( + "Unsupported input type. Only text, password, and checkbox inputs are supported." + ); } +} - // --------------------------------------------------------- - // generate a list of options for a input select - function generateOptions(pluginsData, set, input, dataType, isMultiSelect = false, editable = false, transformers = []) { - let multi = isMultiSelect ? "multiple" : ""; - let valuesArray = createArray(set['Value']); - let settingKey = set['Code_Name']; - // editable ? classNames += " interactable-option" : classNames = "" + +// Refactored function to generate options or set options based on the provided parameters +function generateOptionsOrSetOptions( + codeName, + valuesArray, // Array of values to be pre-selected in the dropdown + placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced) + callbackToGenerateEntries, // Callback function to generate entries based on options + targetField, // Target field or element where selected value should be applied or updated + transformers = [] // Transformers to be applied to the values +) { + + console.log(codeName); + + // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function + options = arrayToObject(createArray(getSettingOptions(codeName))) + + // Call to render lists + renderList( + options, + callbackToGenerateEntries, + valuesArray, + placeholder, + targetField, + transformers + ); - // generate different ID depending on if it's the source for the value to be saved or only used as an input - // isValueSource ? id = settingKey : id = settingKey + '_input'; + // valuesArray = valuesArray.map((value) => applyTransformers(value, transformers)); - // main selection dropdown wrapper - input += ` - `; + + // // Replace the specified placeholder div with the resulting HTML + // setTimeout(() => { + // $("#" + targetLocation).replaceWith(input); + // }, 50); + + + + // } + // else { - // if available transformers are applied - valuesArray = valuesArray.map(value => applyTransformers(value, transformers)); + // optionsArray.forEach((option) => { + // let transformedOption = nameTransformer ? nameTransformer(option) : option; + // let selected = valuesArray.includes(option) ? "selected" : ""; + // input += ``; + // }); + // input += ``; - // get all options - optionsArray = createArray(getSettingOptions(settingKey)) + // setTimeout(() => { + // $("#" + targetLocation).replaceWith(input); + // }, 500); + // } - // loop over all options and select the ones selected in the valuesArray (saved by the user) - if(optionsArray.length > 0 ) - { - // check if needs to be processed ASYNC - if(isSQLQuery(optionsArray[0])) - { - // create temporary placeholder - targetLocation = settingKey + "_temp_" - input += ``; + // return input; +} - // callback to the DB - readData(optionsArray[0], generateDropdownOptions, valuesArray, targetLocation, settingKey); - } else // sync processing - { - optionsArray.forEach(option => { - let selected = valuesArray.includes(option) ? 'selected' : ''; - input += ``; - }); - } - } else // this is an interactable list with default and user-defined values - { - // generates [1x 📝 | 2x 🚮] - valuesArray.forEach(option => { - input += ``; - }); - } - - input += ``; - - // add values from the setting options - execute AJAX callback + SQL query resolution - // initSettingDropdown(settingKey, valuesArray, targetLocation, generateDropdownOptions); - return input; - } + + +// // ----------------------------------------------------------------------------- +// // (ASYNC) Initiate dropdown +// function generateSetOptions( +// settingKey, // Identifier for the setting +// valuesArray, // Array of values to be pre-selected in the dropdown +// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced) +// callbackToGenerateEntries, // Callback function to generate entries based on options +// targetField, // Target field or element where selected value should be applied or updated +// nameTransformer +// ) { +// // callback to transform the name (e.g. base64) +// var optionsHtml = ""; + +// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function +// optionsArray = createArray(getSettingOptions(settingKey)); + +// // check if the result is a SQL query +// if (optionsArray.length > 0 && isSQLQuery(optionsArray[0])) { + +// readData( +// optionsArray[0], +// callbackToGenerateEntries, +// valuesArray, +// targetLocation, +// targetField, +// nameTransformer +// ); +// } // this should be already an array, e.g. from a setting or pre-defined +// else { +// optionsArray.forEach((option) => { +// let selected = valuesArray.includes(option) ? "selected" : ""; +// optionsHtml += ``; +// }); + +// // Replace the specified placeholder div with the resulting HTML +// setTimeout(() => { +// $("#" + targetLocation).replaceWith(optionsHtml); +// }, 50); +// } +// } + +// // --------------------------------------------------------- +// // generate a list of options for a input select +// function generateOptions( +// settingKey, +// input, +// dataType, +// isMultiSelect = false, +// editable = false, +// transformers = [] +// ) { +// let multi = isMultiSelect ? "multiple" : ""; +// let valuesArray = createArray(set["Value"]); + +// // main selection dropdown wrapper +// input += ` +// `; + +// // add values from the setting options - execute AJAX callback + SQL query resolution +// // generateSetOptions(settingKey, valuesArray, targetLocation, generateOptions); + +// return input; +// } // ------------------------------------------------------------ // Function to apply transformers to a value function applyTransformers(val, transformers) { - transformers.forEach(transformer => { + transformers.forEach((transformer) => { switch (transformer) { - case 'sha256': + case "sha256": // Implement sha256 hashing logic if (!isSHA256(val)) { val = CryptoJS.SHA256(val).toString(CryptoJS.enc.Hex); } break; - case 'base64': + case "base64": // Implement base64 logic if (!isBase64(val)) { val = btoa(val); - } + } + break; + default: + console.warn(`Unknown transformer: ${transformer}`); + } + }); + return val; +} + +// ------------------------------------------------------------ +// Function to reverse transformers applied to a value +function reverseTransformers(val, transformers) { + transformers.reverse().forEach((transformer) => { + switch (transformer) { + case "sha256": + // Reversing sha256 is not possible since it's a one-way hash function + console.warn("Reversing sha256 is not possible"); + break; + case "base64": + // Implement base64 decoding logic + console.log("💌"); + if (isBase64(val)) { + val = atob(val); + } break; default: console.warn(`Unknown transformer: ${transformer}`); @@ -582,26 +703,25 @@ function applyTransformers(val, transformers) { } - // ------------------------------------------------------------ // Function to initialize relevant variables based on HTML element const handleElementOptions = (codeName, elementOptions, transformers, val) => { - let inputType = 'text'; + let inputType = "text"; let readOnly = ""; let isMultiSelect = false; - let cssClasses = ''; - let placeholder = ''; - let suffix = ''; - let separator = ''; + let cssClasses = ""; + let placeholder = ""; + let suffix = ""; + let separator = ""; let editable = false; let valRes = val; let sourceIds = []; let getStringKey = ""; - let onClick = "alert('Not implemented');"; + let onClick = "alert('Not implemented');"; - elementOptions.forEach(option => { + elementOptions.forEach((option) => { if (option.prefillValue) { - valRes = option.prefillValue === 'null' ? "" : option.prefillValue; + valRes = option.prefillValue === "null" ? "" : option.prefillValue; } if (option.type) { inputType = option.type; @@ -625,9 +745,9 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => { suffix = option.suffix; } if (option.sourceSuffixes) { - $.each(option.sourceSuffixes, function(index, suf) { - sourceIds.push(codeName + suf) - }) + $.each(option.sourceSuffixes, function (index, suf) { + sourceIds.push(codeName + suf); + }); } if (option.separator) { separator = option.separator; @@ -640,8 +760,8 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => { } }); - if (transformers.includes('sha256')) { - inputType = 'password'; + if (transformers.includes("sha256")) { + inputType = "password"; } return { @@ -656,9 +776,133 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => { editable, valRes, getStringKey, - onClick + onClick, }; }; + +// ----------------------------------------------------------------------------- +// Data processors +// ----------------------------------------------------------------------------- + +// -------------------------------------------------- +// Creates an object from an array +function arrayToObject(array) { + const obj = []; + array.forEach((item, index) => { + obj.push({ id: item, name: item }) + }); + return obj; +} + +// ----------------------------------------------------------------------------- +// Processor to generate options +function generateOptions(options, valuesArray, targetField, transformers, placeholder) { + var optionsHtml = ""; + + resultArray = [] + selectedArray = [] + cssClass = "" + + // determine if options or values are used in teh listing + if (valuesArray.length > 0 && options.length > 0){ + + // multiselect list -> options only + selected the ones in valuesArray + resultArray = options; + selectedArray = valuesArray + + } else if (valuesArray.length > 0 && options.length == 0){ + + // editable list -> values only + resultArray = arrayToObject(valuesArray) + cssClass = "interactable-option" + } else if (options.length > 0){ + + // dropdown -> options only (value == 1 STRING not ARRAY) + resultArray = options; + } + + + + resultArray.forEach(function(item) { + + labelName = item.name + + // console.log(nameTransformer); + // console.log(labelName); + + if(labelName != '❌None') + { + labelName = reverseTransformers(labelName, transformers) + } + + // what's teh source? + // if options & vlaues -> source is options + select + // if values only ignore options + // if options.length == 0 -> editable list -> combine -> don't select + // if not selected -> all options (combined) and all values combined + // if selected -> options (combined) only + + // needs to happen always if options ued as source + let selected = options.length != 0 && valuesArray.includes(item.id) ? 'selected' : ''; + + optionsHtml += ``; + }); + + // Place the resulting HTML into the specified placeholder div + $("#" + placeholder).replaceWith(optionsHtml); +} + + +// ----------------------------------------------------------------------------- +// Processor to generate a list +function generateList(options, valuesArray, targetField, transformers, placeholder) { + var listHtml = ""; + options.forEach(function(item) { + + labelName = item.name + + if(labelName != '❌None') + { + labelName = reverseTransformers(labelName, transformers) + } + + let selected = valuesArray.includes(item.id) ? 'selected' : ''; + + listHtml += `
  • ${labelName}
  • `; + }); + // Place the resulting HTML into the specified placeholder div + $("#" + placeholder).replaceWith(listHtml); +} + +// ----------------------------------------------------------------------------- +// Processor to generate a list in the deviceDetails page +function genListWithInputSet(options, valuesArray, targetField, transformers, placeholder) { + + var listHtml = ""; + + options.forEach(function(item) { + + let selected = valuesArray.includes(item.id) ? 'selected' : ''; + + // console.log(item); + + labelName = item.name + + if(labelName != '❌None') + { + labelName = reverseTransformers(labelName, transformers) + console.log(transformers); + } + + listHtml += `
  • + ${labelName} +
  • `; + + }); + + // Place the resulting HTML into the specified placeholder div + $("#" + placeholder).replaceWith(listHtml); +} diff --git a/front/js/ui_components.js b/front/js/ui_components.js index eeb43294..9158b185 100755 --- a/front/js/ui_components.js +++ b/front/js/ui_components.js @@ -78,50 +78,50 @@ function initDeviceSelectors() { -// ----------------------------------------------------------------------------- -// (ASYNC) Initiate dropdown -function initSettingDropdown(settingKey, // Identifier for the setting - valuesArray, // Array of values to be pre-selected in the dropdown - targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced) - callbackToGenerateEntries, // Callback function to generate entries based on options - targetField, // Target field or element where selected value should be applied or updated - nameTransformer) // callback to transform the name (e.g. base64) -{ +// // ----------------------------------------------------------------------------- +// // (ASYNC) Initiate dropdown +// function generateSetOptions(settingKey, // Identifier for the setting +// valuesArray, // Array of values to be pre-selected in the dropdown +// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced) +// callbackToGenerateEntries, // Callback function to generate entries based on options +// targetField, // Target field or element where selected value should be applied or updated +// nameTransformer) // callback to transform the name (e.g. base64) +// { - var optionsHtml = "" +// var optionsHtml = "" - // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function - optionsArray = createArray(getSettingOptions(settingKey)) +// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function +// optionsArray = createArray(getSettingOptions(settingKey)) - // check if the result is a SQL query - if(optionsArray.length > 0 && isSQLQuery(optionsArray[0])) - { +// // check if the result is a SQL query +// if(optionsArray.length > 0 && isSQLQuery(optionsArray[0])) +// { - if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") { - console.log("isSQLQuery in initSettingDropdown"); +// if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") { +// console.log("isSQLQuery in generateSetOptions"); - } - readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer); +// } +// readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer); - } else // this should be already an array, e.g. from a setting or pre-defined - { - optionsArray.forEach(option => { - let selected = valuesArray.includes(option) ? 'selected' : ''; - optionsHtml += ``; - }); +// } else // this should be already an array, e.g. from a setting or pre-defined +// { +// optionsArray.forEach(option => { +// let selected = valuesArray.includes(option) ? 'selected' : ''; +// optionsHtml += ``; +// }); - // Replace the specified placeholder div with the resulting HTML - setTimeout(() => { +// // Replace the specified placeholder div with the resulting HTML +// setTimeout(() => { - $("#" + targetLocation).replaceWith(optionsHtml); +// $("#" + targetLocation).replaceWith(optionsHtml); - }, 50); - } +// }, 50); +// } -} +// } // ----------------------------------------------------------------------------- @@ -153,86 +153,6 @@ function hideUIelements(settingKey) { } -// ----------------------------------------------------------------------------- -// Data processors -// ----------------------------------------------------------------------------- - - -// ----------------------------------------------------------------------------- -// Processor to generate options for a dropdown menu -function generateDropdownOptions(data, valuesArray, targetField, nameTransformer) { - var optionsHtml = ""; - data.forEach(function(item) { - - labelName = item.name - - // console.log(nameTransformer); - // console.log(labelName); - - // if(nameTransformer && nameTransformer != '' && labelName != '❌None') - // { - // console.log(labelName); - // labelName = nameTransformer(labelName) - // console.log(labelName); - // } - - let selected = valuesArray.includes(item.id) ? 'selected' : ''; - - optionsHtml += ``; - }); - return `${optionsHtml}`; -} - - -// ----------------------------------------------------------------------------- -// Processor to generate a list -function generateList(data, valuesArray, targetField, nameTransformer) { - var listHtml = ""; - data.forEach(function(item) { - - labelName = item.name - - if(nameTransformer && nameTransformer != '' && labelName != '❌None') - { - labelName = nameTransformer(labelName) - } - - let selected = valuesArray.includes(item.id) ? 'selected' : ''; - - listHtml += `
  • ${labelName}
  • `; - }); - - return listHtml; -} - -// ----------------------------------------------------------------------------- -// Processor to generate a list in the deviceDetails page -function genListWithInputSet(data, valuesArray, targetField, nameTransformer) { - - var listHtml = ""; - - console.log(data); - data.forEach(function(item) { - - let selected = valuesArray.includes(item.id) ? 'selected' : ''; - - // console.log(item); - - labelName = item.name - - if(nameTransformer && nameTransformer != '' && labelName != '❌None') - { - labelName = nameTransformer(labelName) - } - - listHtml += `
  • - ${labelName} -
  • `; - - }); - - return listHtml; -} // ----------------------------------------------------------------------------- diff --git a/front/maintenance.php b/front/maintenance.php index c7ed68d5..f3c98df0 100755 --- a/front/maintenance.php +++ b/front/maintenance.php @@ -735,35 +735,22 @@ function performLogManage() { // -------------------------------------------------------- // scroll down the log areas -function scrollDown() -{ - setTimeout(() => { - +function scrollDown() { + var elementToCheck = $("#tab_Logging_id"); // Check if the parent
  • is active if (elementToCheck.parent().hasClass("active")) { - { - var areaIDs = ['app_log', 'app_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'app_pholus_log', 'app_pholus_lastrun_log', 'app_php_log']; - - for (let i = 0; i < areaIDs.length; i++) { + var textAreas = $("#logsPlc textarea"); - var tempArea = $('#' + areaIDs[i]); - - if (tempArea.length > 0) - { - $(tempArea[0]).scrollTop(tempArea[0].scrollHeight); - } - - } - } + textAreas.each(function() { + $(this).scrollTop(this.scrollHeight); + }); } - - }, 200); - - + } + // -------------------------------------------------------- // Manage displayed columns // -------------------------------------------------------- @@ -890,6 +877,7 @@ function renderLogs(customData) { // data: { items: JSON.stringify(customData) }, // Send customData as JSON success: function(response) { $('#logsPlc').html(response); // Replace container content with fetched HTML + scrollDown(); // scroll down the logs }, error: function(xhr, status, error) { console.error('Error fetching infoboxes:', error); @@ -903,8 +891,7 @@ window.onload = function asyncFooter() { initializeSelectedColumns(); renderLogs(); - scrollDown(); // scroll down the logs - + // initializeTabs(); $("#lastCommit").append('GitHub last commit'); diff --git a/front/multiEditCore.php b/front/multiEditCore.php index aac32609..c8f6bb38 100755 --- a/front/multiEditCore.php +++ b/front/multiEditCore.php @@ -1,6 +1,4 @@ - -
    @@ -128,9 +126,9 @@ // render based on element type if (lastElementObj.elementType === 'select') { - targetLocation = columns[j].Code_Name + "_initSettingDropdown" + targetLocation = columns[j].Code_Name + "_generateSetOptions" - initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions) + generateOptionsOrSetOptions(columns[j].Code_Name, [], targetLocation, generateOptions) // Handle Icons as tehy need a preview if(columns[j].Code_Name == 'NEWDEV_dev_Icon') diff --git a/front/php/components/logs.php b/front/php/components/logs.php index feeb0242..ebec8adf 100755 --- a/front/php/components/logs.php +++ b/front/php/components/logs.php @@ -53,7 +53,7 @@ function renderLogArea($params) { $html = '
    -
    diff --git a/front/php/server/util.php b/front/php/server/util.php index 0f60c859..8c4216b5 100755 --- a/front/php/server/util.php +++ b/front/php/server/util.php @@ -370,18 +370,7 @@ function saveSettings() $temp = '['.$temp.']'; // wrap brackets $txt .= $settingKey . "=" . $temp . "\n"; - // $temp = ''; - // if (is_array($settingValue) == FALSE) { - // $settingValue = json_decode($settingValue); - // } - // if (count($setting) > 3 && is_array($settingValue) == true) { - // foreach ($settingValue as $val) { - // $temp .= "'" . encode_single_quotes($val) . "',"; - // } - // $temp = substr_replace($temp, "", -1); // remove last comma ',' - // } - // $temp = '[' . $temp . ']'; // wrap brackets - // $txt .= $settingKey . "=" . $temp . "\n"; + } else { $txt .= $settingKey . "='⭕Not handled⭕'\n"; } diff --git a/front/php/templates/footer.php b/front/php/templates/footer.php index 21a4d363..6cb84352 100755 --- a/front/php/templates/footer.php +++ b/front/php/templates/footer.php @@ -55,7 +55,7 @@ - + diff --git a/front/php/templates/header.php b/front/php/templates/header.php index 2896fc2e..57c2b177 100755 --- a/front/php/templates/header.php +++ b/front/php/templates/header.php @@ -33,6 +33,8 @@ require dirname(__FILE__).'/security.php'; + + diff --git a/front/plugins/newdev_template/config.json b/front/plugins/newdev_template/config.json index d9573841..a9a68016 100755 --- a/front/plugins/newdev_template/config.json +++ b/front/plugins/newdev_template/config.json @@ -28,7 +28,63 @@ "settings": [ { "function": "ignored_MACs", - "type": {"dataType": "array","elements": [ {"elementType": "input","elementOptions": [{ "placeholder": "Enter value" },{ "suffix": "_in" },{ "cssClasses": "col-sm-10" },{ "prefillValue": "null" }],"transformers": [] }, {"elementType": "button","elementOptions": [{ "sourceSuffixes": ["_in"] },{ "separator": "" },{ "cssClasses": "col-sm-12" },{ "onClick": "addList(this, false)" },{ "getStringKey": "Gen_Add" }],"transformers": [] }, {"elementType": "button","elementOptions": [{ "sourceSuffixes": [] },{ "separator": "" },{ "cssClasses": "col-sm-6" },{ "onClick": "removeAllOptions(this)" },{ "getStringKey": "Gen_Remove_All" }],"transformers": []},{"elementType": "button","elementOptions": [{ "sourceSuffixes": [] },{ "separator": "" },{ "cssClasses": "col-sm-6" },{ "onClick": "removeFromList(this)" },{ "getStringKey": "Gen_Remove_Last" }],"transformers": []}, {"elementType": "select","elementOptions": [{ "multiple": "true" },{ "readonly": "true" },{ "editable": "true" }],"transformers": [] }]}, + "type": { + "dataType": "array", + "elements": [ + { + "elementType": "input", + "elementOptions": [ + { "placeholder": "Enter value" }, + { "suffix": "_in" }, + { "cssClasses": "col-sm-10" }, + { "prefillValue": "null" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": ["_in"] }, + { "separator": "" }, + { "cssClasses": "col-sm-12" }, + { "onClick": "addList(this, false)" }, + { "getStringKey": "Gen_Add" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-6" }, + { "onClick": "removeAllOptions(this)" }, + { "getStringKey": "Gen_Remove_All" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-6" }, + { "onClick": "removeFromList(this)" }, + { "getStringKey": "Gen_Remove_Last" } + ], + "transformers": [] + }, + { + "elementType": "select", + "elementOptions": [ + { "multiple": "true" }, + { "readonly": "true" }, + { "editable": "true" } + ], + "transformers": [] + } + ] + }, "default_value": [], "options": [], "localized": ["name", "description"], @@ -47,7 +103,63 @@ }, { "function": "ignored_IPs", - "type": {"dataType": "array","elements": [ {"elementType": "input","elementOptions": [{ "placeholder": "Enter value" },{ "suffix": "_in" },{ "cssClasses": "col-sm-10" },{ "prefillValue": "null" }],"transformers": [] }, {"elementType": "button","elementOptions": [{ "sourceSuffixes": ["_in"] },{ "separator": "" },{ "cssClasses": "col-sm-12" },{ "onClick": "addList(this, false)" },{ "getStringKey": "Gen_Add" }],"transformers": [] }, {"elementType": "button","elementOptions": [{ "sourceSuffixes": [] },{ "separator": "" },{ "cssClasses": "col-sm-6" },{ "onClick": "removeAllOptions(this)" },{ "getStringKey": "Gen_Remove_All" }],"transformers": []},{"elementType": "button","elementOptions": [{ "sourceSuffixes": [] },{ "separator": "" },{ "cssClasses": "col-sm-6" },{ "onClick": "removeFromList(this)" },{ "getStringKey": "Gen_Remove_Last" }],"transformers": []}, {"elementType": "select","elementOptions": [{ "multiple": "true" },{ "readonly": "true" },{ "editable": "true" }],"transformers": [] }]}, + "type": { + "dataType": "array", + "elements": [ + { + "elementType": "input", + "elementOptions": [ + { "placeholder": "Enter value" }, + { "suffix": "_in" }, + { "cssClasses": "col-sm-10" }, + { "prefillValue": "null" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": ["_in"] }, + { "separator": "" }, + { "cssClasses": "col-sm-12" }, + { "onClick": "addList(this, false)" }, + { "getStringKey": "Gen_Add" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-6" }, + { "onClick": "removeAllOptions(this)" }, + { "getStringKey": "Gen_Remove_All" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-6" }, + { "onClick": "removeFromList(this)" }, + { "getStringKey": "Gen_Remove_Last" } + ], + "transformers": [] + }, + { + "elementType": "select", + "elementOptions": [ + { "multiple": "true" }, + { "readonly": "true" }, + { "editable": "true" } + ], + "transformers": [] + } + ] + }, "default_value": [], "options": [], "localized": ["name", "description"], @@ -66,7 +178,16 @@ }, { "function": "dev_MAC", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "maxLength": 50, "default_value": "", "options": [], @@ -86,7 +207,16 @@ }, { "function": "dev_Name", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "maxLength": 50, "default_value": "(unknown)", "options": [], @@ -106,7 +236,12 @@ }, { "function": "dev_Owner", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "maxLength": 30, "default_value": "", "options": ["{value}"], @@ -133,7 +268,12 @@ }, { "function": "dev_DeviceType", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "maxLength": 30, "default_value": "", "options": ["{value}"], @@ -165,7 +305,16 @@ }, { "function": "dev_Vendor", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "maxLength": 250, "default_value": "", "options": [], @@ -185,7 +334,16 @@ }, { "function": "dev_Favorite", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -204,7 +362,12 @@ }, { "function": "dev_Group", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "maxLength": 10, "default_value": "", "options": ["{value}"], @@ -231,7 +394,12 @@ }, { "function": "dev_Comments", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "input", "elementOptions": [], "transformers": [] } + ] + }, "default_value": "", "options": [], "localized": ["name", "description"], @@ -250,7 +418,16 @@ }, { "function": "dev_FirstConnection", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "format": "date-time", "default_value": "", "options": [], @@ -270,7 +447,16 @@ }, { "function": "dev_LastConnection", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "format": "date-time", "default_value": "", "options": [], @@ -290,7 +476,16 @@ }, { "function": "dev_LastIP", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "maxLength": 50, "default_value": "", "options": [], @@ -310,7 +505,16 @@ }, { "function": "dev_StaticIP", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -329,7 +533,16 @@ }, { "function": "dev_ScanCycle", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 1, "options": [], "localized": ["name", "description"], @@ -348,7 +561,16 @@ }, { "function": "dev_LogEvents", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 1, "options": [], "localized": ["name", "description"], @@ -367,7 +589,16 @@ }, { "function": "dev_AlertEvents", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 1, "options": [], "localized": ["name", "description"], @@ -386,7 +617,16 @@ }, { "function": "dev_AlertDeviceDown", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -405,7 +645,12 @@ }, { "function": "dev_SkipRepeated", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "default_value": 0, "options": ["{value}"], "options_params": [ @@ -431,7 +676,16 @@ }, { "function": "dev_LastNotification", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "format": "date-time", "default_value": "", "options": [], @@ -451,7 +705,16 @@ }, { "function": "dev_PresentLastScan", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 1, "options": [], "localized": ["name", "description"], @@ -470,7 +733,16 @@ }, { "function": "dev_NewDevice", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 1, "options": [], "localized": ["name", "description"], @@ -489,7 +761,12 @@ }, { "function": "dev_Location", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "maxLength": 250, "default_value": "", "options": ["{value}"], @@ -516,7 +793,16 @@ }, { "function": "dev_Archived", - "type": {"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -535,7 +821,12 @@ }, { "function": "dev_Network_Node_MAC_ADDR", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "default_value": "", "options": ["{value}"], "options_params": [ @@ -566,7 +857,16 @@ }, { "function": "dev_Network_Node_port", - "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "readonly": "true" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -585,7 +885,12 @@ }, { "function": "dev_Icon", - "type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}, + "type": { + "dataType": "string", + "elements": [ + { "elementType": "select", "elementOptions": [], "transformers": [] } + ] + }, "default_value": "", "options": ["{value}"], "options_params": [ @@ -611,7 +916,16 @@ }, { "function": "LESS_NAME_CLEANUP", - "type": {"dataType":"boolean", "elements": [{"elementType" : "input", "elementOptions" : [{"type":"checkbox"}] ,"transformers": []}]}, + "type": { + "dataType": "boolean", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "checkbox" }], + "transformers": [] + } + ] + }, "default_value": 0, "options": [], "localized": ["name", "description"], @@ -630,8 +944,75 @@ }, { "function": "NAME_CLEANUP_REGEX", - "type": {"dataType":"string", "elements": [{"elementType" : "textarea", "elementOptions" : [] ,"transformers": ["base64"]}]}, - "default_value": ["XC5fYWlycGxheQ==", "XC5fdGNw", "XC5sb2NhbGRvbWFpbg==", "XC5sb2NhbA==", "XC5fZXNwaG9tZWxpYg==", "XC5fZ29vZ2xlY2FzdA==", "XC5sYW4=", "XC5ob21l", "LVthLWZBLUYwLTldezMyfQ==", "Iy4q" ], + "type": { + "dataType": "array", + "elements": [ + { + "elementType": "input", + "elementOptions": [ + { "placeholder": "Enter value" }, + { "suffix": "_in" }, + { "cssClasses": "col-sm-10" }, + { "prefillValue": "null" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-3" }, + { "onClick": "removeAllOptions(this)" }, + { "getStringKey": "Gen_Remove_All" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": [] }, + { "separator": "" }, + { "cssClasses": "col-sm-3" }, + { "onClick": "removeFromList(this)" }, + { "getStringKey": "Gen_Remove_Last" } + ], + "transformers": [] + }, + { + "elementType": "button", + "elementOptions": [ + { "sourceSuffixes": ["_in"] }, + { "separator": "" }, + { "cssClasses": "col-sm-2" }, + { "onClick": "addList(this, false)" }, + { "getStringKey": "Gen_Add" } + ], + "transformers": [] + }, + { + "elementType": "select", + "elementOptions": [ + { "multiple": "true" }, + { "readonly": "true" }, + { "editable": "true" } + ], + "transformers": ["base64"] + } + ] + }, + "default_value": [ + "XC5fYWlycGxheQ==", + "XC5fdGNw", + "XC5sb2NhbGRvbWFpbg==", + "XC5sb2NhbA==", + "XC5fZXNwaG9tZWxpYg==", + "XC5fZ29vZ2xlY2FzdA==", + "XC5sYW4=", + "XC5ob21l", + "LVthLWZBLUYwLTldezMyfQ==", + "Iy4q" + ], "options": [], "localized": ["name", "description"], "name": [ diff --git a/front/plugins/nmap_dev_scan/nmap_dev.py b/front/plugins/nmap_dev_scan/nmap_dev.py index 5c43e82b..aad6f769 100755 --- a/front/plugins/nmap_dev_scan/nmap_dev.py +++ b/front/plugins/nmap_dev_scan/nmap_dev.py @@ -84,7 +84,7 @@ def execute_scan(subnets_list, timeout): for interface in subnets_list: nmap_output = execute_scan_on_interface(interface, timeout) - mylog('verbose', [f"[{pluginName}] nmap_output: ", nmap_output]) + # mylog('verbose', [f"[{pluginName}] nmap_output XML: ", nmap_output]) if nmap_output: # Proceed only if nmap output is not empty # Parse the XML output using python-nmap diff --git a/front/settings.php b/front/settings.php index bfae0bff..c5c2effb 100755 --- a/front/settings.php +++ b/front/settings.php @@ -50,7 +50,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX ?> - + @@ -237,7 +237,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX // only proceed if everything was loaded correctly if(!exception_occurred) { - initSettingsPage(settingsData, pluginsData, generateDropdownOptions); + initSettingsPage(settingsData, pluginsData); } }) } @@ -374,7 +374,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX // go thru all settings and collect settings per settings prefix settingsData.forEach((set) => { - const val = set['Value']; + const valIn = set['Value']; const codeName = set['Code_Name']; const setType = set['Type']; const isMetadata = codeName.includes('__metadata'); @@ -382,7 +382,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`)); // not initialized properly, reload - if(isMetadata && val == "" ) + if(isMetadata && valIn == "" ) { console.warn(`Metadata setting value is empty: ${codeName}`); clearCache(); @@ -481,12 +481,22 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX valRes, getStringKey, onClick - } = handleElementOptions(codeName, elementOptions, transformers, val); + } = handleElementOptions(codeName, elementOptions, transformers, valIn); + + // override + val = valRes; // Generate HTML based on dataType and elementType switch (elementType) { case 'select': - inputHtml = generateOptions(pluginsData, set, inputHtml, dataType, isMultiSelect, editable, transformers); + let multi = isMultiSelect ? "multiple" : ""; + + inputHtml += ``; + + generateOptionsOrSetOptions(codeName, createArray(val), `${codeName}_temp_`, generateOptions, targetField = null, transformers); + break; case 'input': @@ -500,7 +510,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX my-data-type="${dataType}" id="${codeName}${suffix}" type="${inputType}" - value="${valRes}" + value="${val}" ${readOnly} ${checked} placeholder="${placeholder}" @@ -530,7 +540,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX break; default: - console.warn(`Unknown element type: ${elementType}`); + console.warn(`🟥Unknown element type: ${elementType}`); } }); @@ -538,7 +548,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX // process events (e.g. run ascan, or test a notification) if associated with the setting let eventsHtml = ""; - const eventsList = createArray(set['Events']); + const eventsList = createArray(set['Events']); if (eventsList.length > 0) { // console.log(eventsList) @@ -569,7 +579,10 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX } // init finished - initListInteractionOptions() // init remove and edit listitem click gestures + setTimeout(() => { + initListInteractionOptions() // init remove and edit listitem click gestures + }, 50); + setupSmoothScrolling() hideSpinner() @@ -616,6 +629,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX const setTypeObject = JSON.parse(setType.replace(/'/g, '"')); // console.log(setTypeObject); + const dataType = setTypeObject.dataType; const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]; const { elementType, elementOptions = [], transformers = [] } = lastElementObj; const { @@ -635,20 +649,20 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX let value; - if (setTypeObject.dataType === "string" || - (setTypeObject.dataType === "integer" && (inputType === "number" || inputType === "text"))) { + if (dataType === "string" || + (dataType === "integer" && (inputType === "number" || inputType === "text"))) { value = $('#' + setCodeName).val(); value = applyTransformers(value, transformers); - settingsArray.push([prefix, setCodeName, setTypeObject.dataType, value]); + settingsArray.push([prefix, setCodeName, dataType, value]); } else if (inputType === 'checkbox') { value = $(`#${setCodeName}`).is(':checked') ? 1 : 0; value = applyTransformers(value, transformers); - settingsArray.push([prefix, setCodeName, setTypeObject.dataType, value]); + settingsArray.push([prefix, setCodeName, dataType, value]); - } else if (setTypeObject.dataType === "array" ) { + } else if (dataType === "array" ) { // make sure to collect all if set as "editable" or selected only otherwise $(`#${setCodeName}`).attr("my-editable") == "true" ? additionalSelector = "" : additionalSelector = ":selected" @@ -657,25 +671,27 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX $(`#${setCodeName} option${additionalSelector}`).each(function() { const vl = $(this).val(); if (vl !== '') { - temps.push(vl); + temps.push(applyTransformers(vl, transformers)); } }); value = JSON.stringify(temps); - value = applyTransformers(value, transformers); - settingsArray.push([prefix, setCodeName, setTypeObject.dataType, value]); + settingsArray.push([prefix, setCodeName, dataType, value]); - } else if (setTypeObject.dataType === "json") { + } else if (dataType === "json") { value = $('#' + setCodeName).val(); value = applyTransformers(value, transformers); value = JSON.stringify(value, null, 2) - settingsArray.push([prefix, setCodeName, setTypeObject.dataType, value]); + settingsArray.push([prefix, setCodeName, dataType, value]); } else { + + console.error(`[saveSettings] Couldn't determnine how to handle (setCodeName|dataType|inputType):(${setCodeName}|${dataType}|${inputType})`); + value = $('#' + setCodeName).val(); value = applyTransformers(value, transformers); - settingsArray.push([prefix, setCodeName, setTypeObject.dataType, value]); + settingsArray.push([prefix, setCodeName, dataType, value]); } }); @@ -702,7 +718,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX window.onbeforeunload = null; // Reloads the current page - // setTimeout("clearCache()", 5000); + setTimeout("clearCache()", 5000); } else{ // something went wrong // write_notification(data, 'interrupt') diff --git a/server/plugin.py b/server/plugin.py index 952ec8fb..61ed752e 100755 --- a/server/plugin.py +++ b/server/plugin.py @@ -42,11 +42,6 @@ class plugin_param: mylog('debug', f'[Plugins] dType: {dataType}') - # noConversion = ['text', 'string', 'integer', 'boolean', 'password', 'password.SHA256', 'readonly', 'integer.select', 'text.select', 'integer.checkbox' ] - # arrayConversion = ['text.multiselect', 'list', 'list.select', 'subnets'] - # jsonConversion = ['.template'] - - if dataType == 'array': # store number of returned values