Docs + flows work

This commit is contained in:
Jokob-sk
2023-08-05 06:52:23 +10:00
parent b4dd34355e
commit 4fbaccc0f2
8 changed files with 168 additions and 48 deletions

View File

@@ -21,8 +21,6 @@ There is also an in-app Help / FAQ section that should be answering frequently a
#### 🔝 Popular/Suggested #### 🔝 Popular/Suggested
- [API endpoints details](/docs/API.md)
- [Plugin system details and how to develop your own](/front/plugins/README.md)
- [Network treemap configuration](/docs/NETWORK_TREE.md) - [Network treemap configuration](/docs/NETWORK_TREE.md)
- [Gmail as SMTP server for sending emails](/docs/SMTP_GMAIL.md) - [Gmail as SMTP server for sending emails](/docs/SMTP_GMAIL.md)
- [Subnets and VLANs configuration for arp-scan](/docs/SUBNETS.md) - [Subnets and VLANs configuration for arp-scan](/docs/SUBNETS.md)
@@ -40,11 +38,17 @@ There is also an in-app Help / FAQ section that should be answering frequently a
#### ♻ Misc #### ♻ Misc
- [New Version notifications](/docs/VERSIONS.md)
- [Version history (legacy)](/docs/VERSIONS_HISTORY.md) - [Version history (legacy)](/docs/VERSIONS_HISTORY.md)
- [Database structure](/docs/DATABASE.md)
- [Reverse proxy (Nginx, Apache, SWAG)](/docs/REVERSE_PROXY.md) - [Reverse proxy (Nginx, Apache, SWAG)](/docs/REVERSE_PROXY.md)
#### 👩💻For Developers👨💻
- [APP code structure](/pialert/README.md)
- [Database structure](/docs/DATABASE.md)
- [API endpoints details](/docs/API.md)
- [Plugin system details and how to develop your own](/front/plugins/README.md)
- [New Version notifications](/docs/VERSIONS.md)
Feel free to suggest or submit new docs via a PR. Feel free to suggest or submit new docs via a PR.
## 👨‍💻 Development priorities ## 👨‍💻 Development priorities

0
front/flows.php Normal file → Executable file
View File

View File

@@ -312,7 +312,7 @@ function saveSettings()
$temp = '['.$temp.']'; // wrap brackets $temp = '['.$temp.']'; // wrap brackets
$txt .= $settingKey . "=" . $temp . "\n"; $txt .= $settingKey . "=" . $temp . "\n";
} elseif ($settingType == 'json') { } elseif ($settingType == 'json' || substr($settingType, -9) === ".template") {
$txt .= $settingKey . "=" . $settingValue . "\n"; $txt .= $settingKey . "=" . $settingValue . "\n";
} }
} }

View File

@@ -442,7 +442,7 @@
"INCLUDED_SECTIONS_name" : "Notify on", "INCLUDED_SECTIONS_name" : "Notify on",
"INCLUDED_SECTIONS_description" : "Specifies which events trigger notifications. Remove the event type(s) you don not want to get notified on. This setting overrides device-specific settings in the UI. (<code>CTRL + Click</code> to select/deselect).", "INCLUDED_SECTIONS_description" : "Specifies which events trigger notifications. Remove the event type(s) you don not want to get notified on. This setting overrides device-specific settings in the UI. (<code>CTRL + Click</code> to select/deselect).",
"SCAN_CYCLE_MINUTES_name" : "Scan cycle delay", "SCAN_CYCLE_MINUTES_name" : "Scan cycle delay",
"SCAN_CYCLE_MINUTES_description" : "The delay between scans in minutes. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.", "SCAN_CYCLE_MINUTES_description" : "The delay between scans in minutes. Only related to arp-scan, PiHole, DHCP_ACTIVE scans. If using arp-scan, the scan time itself depends on the number of IP addresses to check. This is influenced by the network mask set in the <a href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a> at the top. Every IP takes a couple seconds to scan.",
"DAYS_TO_KEEP_EVENTS_name" : "Delete events older than", "DAYS_TO_KEEP_EVENTS_name" : "Delete events older than",
"DAYS_TO_KEEP_EVENTS_description" : "This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.", "DAYS_TO_KEEP_EVENTS_description" : "This is a maintenance setting. This specifies the number of days worth of event entries that will be kept. All older events will be deleted periodically. Also applies on Plugin Events History.",
"HRS_TO_KEEP_NEWDEV_name" : "Keep new devices for", "HRS_TO_KEEP_NEWDEV_name" : "Keep new devices for",

View File

@@ -34,12 +34,106 @@
"name" : "dev_AlertEvents", "name" : "dev_AlertEvents",
"type" : "setting", "type" : "setting",
"value" : "KNWN_dev_AlertEvents" "value" : "KNWN_dev_AlertEvents"
},
{
"name" : "trigger_ids",
"type" : "array",
"value" : "trigger.Object_PrimaryID"
},
{
"name" : "trigger_objects",
"type" : "array",
"value" : "trigger"
} }
], ],
"settings":[ "settings":[
{
"function": "flows",
"type": "json",
"maxLength": 50,
"default_value": [{
"name":"apply_template",
"trigger": [
{
"object_event": "new",
"object_filter": ""
}
],
"steps": [
{
"step_type":"wait",
"params": [
{
"days": 3,
"hours": 0,
"minutes": 0,
"seconds": 0
}
]
},
{
"step_type":"condition",
"params": [
{
"left": {
"value": "triggers[0].object['dev_NewDevice']",
"use_quotes": true,
"js_template": "'{value}'.toString()"
},
"operator": {
"value" : "==",
"data_type": "boolean"
},
"right": {
"value": true,
"use_quotes": false,
"js_template": "'{value}'.toString()"
}
}
]
},
{
"step_type":"action",
"params": [
{
"type": "plugin",
"params":
{
"unique_prefix": "KNWN",
"overrides":[
{
"object_path": "settings.0",
"key":"function",
"value":"target_macs",
"target_property":"default_value",
"desired_value": "triggers.keys"
}
]
}
}
]
}
]
}],
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Flows"
}
],
"description": [
{
"language_code": "en_us",
"string": "The flow."
}
]
},
{ {
"function": "target_macs", "function": "target_macs",
"type": "list.readonly", "type": "list.readonly",
"maxLength": 50, "maxLength": 50,
"default_value": [], "default_value": [],
"options": [], "options": [],
@@ -74,9 +168,13 @@
}, },
{ {
"function": "dev_Name", "function": "dev_Name",
"type": "readonly", "type": "text.template",
"maxLength": 50, "maxLength": 50,
"default_value": "(unknown)", "default_value": "(unknown)",
"value": {
"value":"(unknown)",
"override": true
},
"options": [], "options": [],
"localized": ["name", "description"], "localized": ["name", "description"],
"name": [ "name": [

View File

@@ -204,42 +204,34 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
// Render different input types based on the settings type // Render different input types based on the settings type
let input = ""; let input = "";
if (set['Type'] === 'text' || set['Type'] === 'string' || set['Type'] === 'date-time') { const setType = set['Type'].toLowerCase();
input = `<input class="form-control" onChange="settingsChanged()" my-data-type="${set['Type']}" id="${set['Code_Name']}" value="${set['Value']}"/>`;
} else if (set['Type'] === 'password') { if (setType.startsWith('text') || setType.startsWith('string') || setType.startsWith('date-time') ) {
input = `<input onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control input" id="${set['Code_Name']}" type="password" value="${set['Value']}"/>`;
} else if (set['Type'] === 'readonly') { if(setType.includes(".select"))
input = `<input class="form-control input" my-data-type="${set['Type']}" id="${set['Code_Name']}" value="${set['Value']}" readonly/>`; {
} else if (set['Type'] === 'boolean' || set['Type'] === 'integer.checkbox') { input = generateInputOptions(set, input, isMultiSelect = false)
} else if(setType.includes(".multiselect"))
{
input = generateInputOptions(set, input, isMultiSelect = true)
} else{
input = `<input class="form-control" onChange="settingsChanged()" my-data-type="${setType}" id="${set['Code_Name']}" value="${set['Value']}"/>`;
}
} else if (setType === 'integer') {
input = `<input onChange="settingsChanged()" my-data-type="${setType}" class="form-control" id="${set['Code_Name']}" type="number" value="${set['Value']}"/>`;
} else if (setType === 'password') {
input = `<input onChange="settingsChanged()" my-data-type="${setType}" class="form-control input" id="${set['Code_Name']}" type="password" value="${set['Value']}"/>`;
} else if (setType === 'readonly') {
input = `<input class="form-control input" my-data-type="${setType}" id="${set['Code_Name']}" value="${set['Value']}" readonly/>`;
} else if (setType === 'boolean' || setType === 'integer.checkbox') {
let checked = set['Value'] === 'True' || set['Value'] === '1' ? 'checked' : ''; let checked = set['Value'] === 'True' || set['Value'] === '1' ? 'checked' : '';
input = `<input onChange="settingsChanged()" my-data-type="${set['Type']}" class="checkbox" id="${set['Code_Name']}" type="checkbox" value="${set['Value']}" ${checked} />`; input = `<input onChange="settingsChanged()" my-data-type="${setType}" class="checkbox" id="${set['Code_Name']}" type="checkbox" value="${set['Value']}" ${checked} />`;
} else if (set['Type'] === 'integer') { } else if (setType === 'integer.select') {
input = `<input onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control" id="${set['Code_Name']}" type="number" value="${set['Value']}"/>`;
} else if (set['Type'] === 'text.select' || set['Type'] === 'integer.select') {
input = `<select onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control" name="${set['Code_Name']}" id="${set['Code_Name']}">`;
values = createArray(set['Value']); input = generateInputOptions(set, input)
options = createArray(set['Options']);
} else if (setType === 'subnets') {
options.forEach(option => {
let selected = values.includes(option) ? 'selected' : '';
input += `<option value="${option}" ${selected}>${option}</option>`;
});
input += '</select>';
} else if (set['Type'] === 'text.multiselect') {
input = `<select onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control" name="${set['Code_Name']}" id="${set['Code_Name']}" multiple>`;
values = createArray(set['Value']);
options = createArray(set['Options']);
options.forEach(option => {
let selected = values.includes(option) ? 'selected' : '';
input += `<option value="${option}" ${selected}>${option}</option>`;
});
input += '</select>';
} else if (set['Type'] === 'subnets') {
input = ` input = `
<div class="row form-group"> <div class="row form-group">
<div class="col-xs-5"> <div class="col-xs-5">
@@ -253,7 +245,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<select class="form-control" my-data-type="${set['Type']}" name="${set['Code_Name']}" id="${set['Code_Name']}" multiple readonly>`; <select class="form-control" my-data-type="${setType}" name="${set['Code_Name']}" id="${set['Code_Name']}" multiple readonly>`;
options = createArray(set['Value']); options = createArray(set['Value']);
@@ -264,7 +256,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
input += '</select></div>' + input += '</select></div>' +
'<div><button class="btn btn-primary" onclick="removeInterfaces()">Remove all</button></div>'; '<div><button class="btn btn-primary" onclick="removeInterfaces()">Remove all</button></div>';
} else if (set['Type'] === 'list') { } else if (setType === 'list') {
settingKeyOfLists.push(set['Code_Name']); settingKeyOfLists.push(set['Code_Name']);
@@ -278,8 +270,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<select class="form-control" my-data-type="${set['Type']}" name="${set['Code_Name']}" id="${set['Code_Name']}" multiple readonly>`; <select class="form-control" my-data-type="${setType}" name="${set['Code_Name']}" id="${set['Code_Name']}" multiple readonly>`;
let options = createArray(set['Value']); let options = createArray(set['Value']);
@@ -289,8 +280,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
input += '</select></div>' + input += '</select></div>' +
`<div><button class="btn btn-primary" my-input="${set['Code_Name']}" onclick="removeFromList(this)">Remove last</button></div>`; `<div><button class="btn btn-primary" my-input="${set['Code_Name']}" onclick="removeFromList(this)">Remove last</button></div>`;
} else if (set['Type'] === 'json') { } else if (setType === 'json') {
input = `<textarea class="form-control input" my-data-type="${set['Type']}" id="${set['Code_Name']}" readonly>${JSON.stringify(set['Value'], null, 2)}</textarea>`; input = `<textarea class="form-control input" my-data-type="${setType}" id="${set['Code_Name']}" readonly>${JSON.stringify(set['Value'], null, 2)}</textarea>`;
} }
let eventsHtml = ""; let eventsHtml = "";
@@ -327,6 +318,26 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
} }
//
function generateInputOptions(set, input, isMultiSelect = false)
{
multi = isMultiSelect ? "multiple" : "";
input = `<select onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control" name="${set['Code_Name']}" id="${set['Code_Name']}" ${multi}>`;
values = createArray(set['Value']);
options = createArray(set['Options']);
options.forEach(option => {
let selected = values.includes(option) ? 'selected' : '';
input += `<option value="${option}" ${selected}>${option}</option>`;
});
input += '</select>';
return input;
}
// todo fix // todo fix
function createArray(input) { function createArray(input) {
// Empty array // Empty array

0
pialert/flows.py Normal file → Executable file
View File

View File

@@ -283,6 +283,7 @@ def plugin_param_from_glob_set(globalSetting):
noConversion = ['text', 'string', 'integer', 'boolean', 'password', 'readonly', 'integer.select', 'text.select', 'integer.checkbox' ] noConversion = ['text', 'string', 'integer', 'boolean', 'password', 'readonly', 'integer.select', 'text.select', 'integer.checkbox' ]
arrayConversion = ['text.multiselect', 'list'] arrayConversion = ['text.multiselect', 'list']
jsonConversion = ['.template']
if setTyp in noConversion: if setTyp in noConversion:
return setVal return setVal
@@ -290,6 +291,12 @@ def plugin_param_from_glob_set(globalSetting):
if setTyp in arrayConversion: if setTyp in arrayConversion:
return flatten_array(setVal) return flatten_array(setVal)
for item in jsonConversion:
if setTyp.endswith(item):
return json.dumps(setVal)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Gets the setting value # Gets the setting value
def get_plugin_setting_value(plugin, function_key): def get_plugin_setting_value(plugin, function_key):