diff --git a/Protest/Front/api.js b/Protest/Front/api.js index e16b5663..032c592d 100644 --- a/Protest/Front/api.js +++ b/Protest/Front/api.js @@ -1,7 +1,6 @@ class Api extends List { constructor(args) { super(); - this.args = args ?? {filter:"", find:"", sort:"", select:null}; this.AddCssDependencies("list.css"); @@ -9,29 +8,76 @@ class Api extends List { this.SetTitle("API links"); this.SetIcon("mono/carabiner.svg"); - this.defaultColumns = ["name", "calls", "data"]; - this.SetupColumns(this.defaultColumns); + this.InitializeComponents(); + this.UpdateAuthorization(); + } + + UpdateAuthorization() { //overrides + this.canWrite = KEEP.authorization.includes("*") || KEEP.authorization.includes("api:write"); + this.createButton.disabled = !this.canWrite; + this.deleteButton.disabled = !this.canWrite; + super.UpdateAuthorization(); + } + + InitializeComponents() { + const columns = ["name", "calls", "data"]; + this.SetupColumns(columns); this.columnsOptions.style.display = "none"; this.SetupToolbar(); this.createButton = this.AddToolbarButton("Create API link", "mono/add.svg?light"); this.deleteButton = this.AddToolbarButton("Delete", "mono/delete.svg?light"); - this.createButton.onclick = ()=> this.CreateDialog(); + this.createButton.onclick = ()=> this.EditDialog(); this.deleteButton.onclick = ()=> this.Delete(); - this.UpdateAuthorization(); - } + this.list.style.right = "unset"; + this.list.style.width = "min(50%, 640px)"; + this.list.style.overflowY = "auto"; + + this.list.style.right = "unset"; + this.list.style.width = "min(50%, 640px)"; + this.list.style.overflowY = "auto"; + + this.listTitle.style.right = "unset"; + this.listTitle.style.width = "min(50%, 640px)"; + + this.stats = document.createElement("div"); + this.stats.style.position = "absolute"; + this.stats.style.left = "calc(min(50%, 640px) + 8px)"; + this.stats.style.right = "4px"; + this.stats.style.top = "0"; + this.stats.style.bottom = "28px"; + this.stats.style.overflowY = "auto"; + this.content.appendChild(this.stats); + + const graph = document.createElement("div"); + graph.style.position = "absolute"; + graph.style.left = "0"; + graph.style.right = "0"; + graph.style.top = "0"; + graph.style.maxWidth = `${ReverseProxy.CANVAS_W+4}px`; + graph.style.height = `${ReverseProxy.CANVAS_H+8}px`; + graph.style.borderRadius = "4px"; + graph.style.backgroundColor = "color-mix(in hsl shorter hue, var(--clr-dark) 50%, transparent 50%)"; + this.stats.appendChild(graph); + + this.canvas = document.createElement("canvas"); + this.canvas.width = ReverseProxy.CANVAS_W; + this.canvas.height = ReverseProxy.CANVAS_H+4; + this.canvas.style.position = "absolute"; + this.canvas.style.right = "2px"; + this.canvas.style.top = "0"; + this.canvas.style.width = `${ReverseProxy.CANVAS_W}px`; + this.canvas.style.height = `${ReverseProxy.CANVAS_H+4}px`; + graph.appendChild(this.canvas); + + this.ctx = this.canvas.getContext("2d"); - UpdateAuthorization() { //overrides - this.canWrite = KEEP.authorization.includes("*") || KEEP.authorization.includes("api:write"); - this.createButton.disabled = !this.canWrite; - this.deleteButton.disabled = !this.canWrite; - super.UpdateAuthorization(); } - CreateDialog() { - const dialog = this.DialogBox("420px"); + EditDialog(object=null) { + const dialog = this.DialogBox("400px"); if (dialog === null) return; const {okButton, innerBox} = dialog; @@ -42,8 +88,8 @@ class Api extends List { innerBox.style.padding = "16px 32px"; innerBox.style.display = "grid"; - innerBox.style.gridTemplateColumns = "auto 150px 275px auto"; - innerBox.style.gridTemplateRows = "repeat(6, 38px) 72px"; + innerBox.style.gridTemplateColumns = "auto 160px 275px 24px auto"; + innerBox.style.gridTemplateRows = "repeat(3, 38px) 12px repeat(5, 32px)"; innerBox.style.alignItems = "center"; let counter = 0; @@ -52,24 +98,99 @@ class Api extends List { const label = document.createElement("div"); label.style.gridArea = `${counter} / 2`; - label.textContent = `${name}:`; + label.textContent = name; - const input = document.createElement(tag); - input.style.gridArea = `${counter} / 3`; - if (type) { - input.type = type; + let input; + + if (tag === "input" && type === "toggle") { + const box = document.createElement("div"); + box.style.gridArea = `${counter} / 3 / ${counter+1} / 4`; + + const toggle = this.CreateToggle(".", false, box); + toggle.label.style.color = "transparent"; + input = toggle.checkbox; + + innerBox.append(label, box); + } + else { + input = document.createElement(tag); + input.style.gridArea = `${counter} / 3`; + if (type) { input.type = type; } + + innerBox.append(label, input); } for (let param in properties) { input[param] = properties[param]; } - innerBox.append(label, input); - - return input; + return [label, input]; }; - const nameInput = AddParameter("Name", "input", "text"); + const [nameLabel, nameInput] = AddParameter("Name:", "input", "text"); + + const [keyLabel, keyInput] = AddParameter("API key:", "input", "text"); + keyInput.setAttribute("readonly", "true"); + + const copyButton = document.createElement("button"); + copyButton.style.gridArea = " 2/ 4"; + copyButton.style.minWidth = "32px"; + copyButton.style.width = "32px"; + copyButton.style.backgroundImage = "url(mono/copy.svg?light)"; + copyButton.style.backgroundSize = "24px"; + copyButton.style.backgroundPosition = "center"; + copyButton.style.backgroundRepeat = "no-repeat"; + innerBox.append(copyButton); + + const [readOnlyLabel, readOnlyInput] = AddParameter("Read-only:", "input", "toggle"); + readOnlyInput.checked = true; + readOnlyInput.disabled = true; + + counter++; + + const labelPermissions = document.createElement("div"); + labelPermissions.textContent = "Permissions:"; + labelPermissions.style.gridArea = `${++counter} / 2`; + innerBox.append(labelPermissions); + + const [devicesLabel, devicesInput] = AddParameter("Devices", "input", "toggle"); + devicesLabel.style.paddingLeft = "24px"; + devicesLabel.style.backgroundImage = "url(mono/devices.svg)"; + devicesLabel.style.backgroundSize = "20px"; + devicesLabel.style.backgroundRepeat = "no-repeat"; + + const [usersLabel, usersInput] = AddParameter("Users", "input", "toggle"); + usersLabel.style.paddingLeft = "24px"; + usersLabel.style.backgroundImage = "url(mono/users.svg)"; + usersLabel.style.backgroundSize = "20px"; + usersLabel.style.backgroundRepeat = "no-repeat"; + + const [issuesLabel, issuesInput] = AddParameter("Issues", "input", "toggle"); + issuesLabel.style.paddingLeft = "24px"; + issuesLabel.style.backgroundImage = "url(mono/issues.svg)"; + issuesLabel.style.backgroundSize = "20px"; + issuesLabel.style.backgroundRepeat = "no-repeat"; + + const [utilitiesLabel, utilitiesInput] = AddParameter("Network utilities", "input", "toggle"); + utilitiesLabel.style.paddingLeft = "24px"; + utilitiesLabel.style.backgroundImage = "url(mono/portscan.svg)"; + utilitiesLabel.style.backgroundSize = "20px"; + utilitiesLabel.style.backgroundRepeat = "no-repeat"; + + keyInput.value = "asd sdf"; + + if (object === null) { + devicesInput.checked = true; + usersInput.checked = true; + } + else { + nameInput.value = object.name; + keyInput.value = object.key; + devicesInput.checked = object.devices; + usersInput.checked = object.users; + utilitiesInput.checked = object.utilities; + issuesInput.checked = object.issues; + } setTimeout(()=>nameInput.focus(), 200); diff --git a/Protest/Front/rbac.js b/Protest/Front/rbac.js index 09afd3a9..d0ab86b7 100644 --- a/Protest/Front/rbac.js +++ b/Protest/Front/rbac.js @@ -325,14 +325,14 @@ class AccessControl extends Tabs { this.permissionsList.push(this.AddPermissionObject("Watchdog", "url(mono/watchdog.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("Reverse proxy", "url(mono/reverseproxy.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("Issues", "url(mono/issues.svg)", toolsGroup, false, true, false)); - this.permissionsList.push(this.AddPermissionObject("Scripts", "url(mono/scripts.svg)", toolsGroup, false, true, false)); + //this.permissionsList.push(this.AddPermissionObject("Scripts", "url(mono/scripts.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("Network utilities", "url(mono/portscan.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("Telnet", "url(mono/telnet.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("Secure shell", "url(mono/ssh.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("WMI", "url(mono/wmi.svg)", toolsGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("SNMP pooling", "url(mono/snmp.svg)", toolsGroup, false, true, false)); - this.permissionsList.push(this.AddPermissionObject("SNMP traps", "url(mono/trap.svg)", toolsGroup, false, true, false)); - + //this.permissionsList.push(this.AddPermissionObject("SNMP traps", "url(mono/trap.svg)", toolsGroup, false, true, false)); + const manageGroup = this.AddPermissionGroup("Manage", "url(mono/logo.svg)"); this.permissionsList.push(this.AddPermissionObject("Settings", "url(mono/wrench.svg)", manageGroup, false, true, false)); this.permissionsList.push(this.AddPermissionObject("RBAC", "url(mono/rbac.svg)", manageGroup, false, true, false)); diff --git a/Protest/Front/reverseproxy.js b/Protest/Front/reverseproxy.js index f639d8fb..9e254a9c 100644 --- a/Protest/Front/reverseproxy.js +++ b/Protest/Front/reverseproxy.js @@ -14,18 +14,6 @@ class ReverseProxy extends List { this.SetTitle("Reverse proxy"); this.SetIcon("mono/reverseproxy.svg"); - const columns = ["name", "protocol", "proxy", "destination"]; - this.SetupColumns(columns); - this.columnsOptions.style.display = "none"; - - this.columnsElements[1].style.width = "15%"; - - this.columnsElements[2].style.left = "40%"; - this.columnsElements[2].style.width = "30%"; - - this.columnsElements[3].style.left = "70%"; - this.columnsElements[3].style.width = "30%"; - this.ws = null; this.graphCount = 0; @@ -49,6 +37,18 @@ class ReverseProxy extends List { } InitializeComponents() { + const columns = ["name", "protocol", "proxy", "destination"]; + this.SetupColumns(columns); + this.columnsOptions.style.display = "none"; + + this.columnsElements[1].style.width = "15%"; + + this.columnsElements[2].style.left = "40%"; + this.columnsElements[2].style.width = "30%"; + + this.columnsElements[3].style.left = "70%"; + this.columnsElements[3].style.width = "30%"; + this.SetupToolbar(); this.createButton = this.AddToolbarButton("Create proxy", "mono/add.svg?light"); this.deleteButton = this.AddToolbarButton("Delete", "mono/delete.svg?light");