-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathdashboard_2_user_access.json
1 lines (1 loc) · 29.2 KB
/
dashboard_2_user_access.json
1
[{"id":"374680912e969123","type":"comment","z":"0e3249ddee2000e3","name":"User Access","info":"## Links\n\nMulti tenancy dashboard: https://dashboard.flowfuse.com/user/multi-tenancy.html\n\n\n## TODO\n\n- Logout button\n- User admin screen\n- Delete old sessions DONE\n- Account space not updated after logon \n- Move from Logontime to lasttime DONE","x":110,"y":5500,"wires":[]},{"id":"113ab1e0953a26e9","type":"ui-button","z":"0e3249ddee2000e3","group":"d7b93c2197360295","name":"","label":"New Random Number","order":5,"width":0,"height":0,"emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":260,"y":5900,"wires":[["993f142de43c0d61","e9ac72af818b17c5"]]},{"id":"406776d658632e3b","type":"ui-control","z":"0e3249ddee2000e3","name":"","ui":"cb79bc4520925e32","events":"all","x":200,"y":5620,"wires":[["993f142de43c0d61","b3522fffa4942d72"]]},{"id":"993f142de43c0d61","type":"debug","z":"0e3249ddee2000e3","name":"_client test","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":410,"y":5720,"wires":[]},{"id":"b3522fffa4942d72","type":"function","z":"0e3249ddee2000e3","name":"Access Validation","func":"let thispage = \"User Access\";\nlet now = new Date();\n\nmsg.thispage = thispage;\nlet useraccess = flow.get(\"useraccess\");\nif ((Array.isArray(useraccess.users) ? 1 : 0) + (Array.isArray(useraccess.sessions) ? 1 : 0) + (typeof useraccess.settings === \"object\" ? 1 : 0) !== 3) {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Invalid useraccess config\" });\n return [null, null];\n}\n\n// Check if session exists and update the last time\nfor (let j = 0; j < useraccess.sessions.length; j++) {\n if (useraccess.sessions[j].socketId === msg._client.socketId) {\n useraccess.sessions[j].lasttime = now.getTime();\n if (msg.payload === \"lost\") {\n useraccess.sessions.splice(j, 1);\n }\n flow.set(\"useraccess\", useraccess);\n break;\n }\n}\n\nnode.status({ fill: \"yellow\", shape: \"ring\", text: msg.payload + \" | \" + msg._client.socketId });\nif (msg.payload === \"change\") {\n if (msg.name === thispage) {\n\n // Check the session list and see if the user is already logged on\n let sessionnum = -1;\n if (useraccess.sessions.length > 0) {\n // Delete any stored session beyond the timeout period\n let now = new Date();\n for (let j = useraccess.sessions.length-1; j >= 0; j--) {\n if (now.getTime() - useraccess.sessions[j].lasttime > useraccess.settings.timeout*1000) {\n useraccess.sessions.splice(j,1);\n flow.set(\"useraccess\", useraccess);\n }\n }\n // Check for remaining active sessions\n for (let j = 0; j < useraccess.sessions.length; j++) {\n if (useraccess.sessions[j].socketId === msg._client.socketId) {\n sessionnum = j;\n useraccess.sessions[j].lasttime = now.getTime();\n msg._client.user = useraccess.sessions[j].user;\n break;\n }\n }\n }\n if (sessionnum === -1) {\n // Need to display the logon screen\n msg.topic = \"login\";\n msg.payload = \"\";\n node.status({ fill: \"red\", shape: \"ring\", text: \"No session | \" + msg._client.socketId });\n return [msg, null];\n } else {\n // user is authenticated\n node.status({ fill: \"green\", shape: \"ring\", text: \"Valid session | \" + msg._client.socketId });\n return [null, msg];\n }\n\n\n }\n}\n","outputs":2,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":5620,"wires":[["64ed6f2f152bdde5"],["ec997289b14216ae"]]},{"id":"64ed6f2f152bdde5","type":"ui-template","z":"0e3249ddee2000e3","group":"","page":"566245f730fd3fa2","ui":"","name":"Login Dialog","order":0,"width":0,"height":0,"head":"","format":"<template>\n <div class=\"text-center pa-4\">\n <v-dialog v-model=\"dialog\" transition=\"dialog-bottom-transition\" fullscreen>\n <v-card color=\"white\">\n <div width=\"100%\" height=\"100%\">\n\n<div>\n <v-img class=\"mx-auto my-6\" max-width=\"228\"\n src=\"https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-light.svg\"></v-img>\n\n <v-card class=\"mx-auto pa-12 pb-8\" elevation=\"8\" max-width=\"448\" rounded=\"lg\">\n <div class=\"text-subtitle-1 text-medium-emphasis\">User name</div>\n\n <v-text-field density=\"compact\" placeholder=\"User name\" prepend-inner-icon=\"mdi-account-circle\"\n variant=\"outlined\" v-model=\"username\"></v-text-field>\n\n <div class=\"text-subtitle-1 text-medium-emphasis d-flex align-center justify-space-between\">\n Password\n </div>\n\n <v-text-field :append-inner-icon=\"visible ? 'mdi-eye-off' : 'mdi-eye'\" :type=\"visible ? 'text' : 'password'\"\n density=\"compact\" placeholder=\"Enter your password\" prepend-inner-icon=\"mdi-lock-outline\" variant=\"outlined\"\n @click:append-inner=\"visible = !visible\" v-model=\"password\"></v-text-field>\n\n <v-card class=\"mb-12\" :color=\"color\" variant=\"tonal\">\n <v-card-text class=\"text-medium-emphasis text-caption\">\n {{ message }}\n </v-card-text>\n </v-card>\n\n <v-btn class=\"mb-8\" color=\"blue\" size=\"large\" variant=\"tonal\" block @click=\"LoginButton\">\n Log In\n </v-btn>\n\n <v-card-text class=\"text-center\">\n </v-card-text>\n </v-card>\n</div>\n\n\n </div>\n\n </v-card>\n </v-dialog>\n </div>\n</template>\n\n\n\n\n<script>\nexport default {\n data() {\n return {\n dialog: false,\n color: \"surface-variant\",\n message: \"\",\n username: \"\",\n password: \"\"\n }\n },\n watch: {\n msg: function(){\n // only show the dialog if msg.payload is an object and the socket id in the message\n // matches our socket id (which means the popup was initiated from this session) or\n // there is no _client property present which indicates it should be shown on all sessions.\n if (this.msg.topic===\"close\") {\n this.dialog = false;\n } else {\n if (!this.msg._client || this.msg._client.socketId === this.$socket.id) { \n console.log(\"OK we are in\");\n if (typeof this.msg.payload !== object) msg.payload = {};\n this.message = this.msg.payload.message ?? \"Access to this page is restricted. Please provide your user name and password in order to access this page.\";\n this.color = this.msg.payload.color ?? \"surface-variant\"; \n this.dialog = true;\n }\n }\n // prevent redraw on deploy\n this.msg.payload = null;\n }\n },\n methods:{\n LoginButton:function(){\n // Do not hide the dialog, in case login fails\n //this.dialog = false;\n this.msg.topic = \"authenticate\";\n this.msg.payload = { username: this.username, password: this.password };\n this.send(this.msg);\n }\n },\n computed : {\n },\n unmounted () {\n this.dialog = false;\n }\n}\n</script>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"widget:page","className":"","x":710,"y":5620,"wires":[["b72412039542cee6","6a9ef363e491f75f"]]},{"id":"b72412039542cee6","type":"function","z":"0e3249ddee2000e3","name":"Validate credentials","func":"let useraccess = flow.get(\"useraccess\");\nif ((Array.isArray(useraccess.users) ? 1 : 0) + (Array.isArray(useraccess.sessions) ? 1 : 0) + (typeof useraccess.settings === \"object\" ? 1 : 0) !== 3) {\n node.status({fill:\"red\",shape:\"ring\",text:\"Invalid useraccess config\"});\n return [null, null];\n}\n\n// Check if an authentication request is received (logon attempt)\nif (msg.topic===\"authenticate\") {\n let authenticated = false;\n //node.warn(\"Check authetication\");\n // Check if the username/password is valid\n for (let i=0; i<useraccess.users.length; i++) {\n //node.warn(\"Useraccess loop: \" + i);\n if ((msg.payload.username === useraccess.users[i].username) && (msg.payload.password === useraccess.users[i].password)) {\n msg._client.user = useraccess.users[i];\n authenticated = true;\n //node.warn(\"User found: \" + i);\n // Store the logon details and session internally\n let sessionnum = -1;\n if (useraccess.sessions.length > 0) {\n for (let j=0; j<useraccess.sessions.length;j++) {\n if (useraccess.sessions[j].socketId === msg._client.socketId) {\n sessionnum = j;\n node.warn(\"Session found: \"+j);\n break;\n }\n }\n }\n if (sessionnum > -1) {\n // Session exists, update it\n let now = new Date();\n useraccess.sessions[sessionnum].user = msg._client.user;\n useraccess.sessions[sessionnum].lasttime = now.getTime();\n node.status({ fill: \"green\", shape: \"ring\", text: \"New login, existing session: \" + msg._client.user.name});\n flow.set(\"useraccess\", useraccess);\n } else {\n let now = new Date();\n // New session, log it\n useraccess.sessions.push({ \"socketId\": msg._client.socketId, \"user\": msg._client.user, \"logontime\": now.getTime(), \"lasttime\": now.getTime() });\n node.status({ fill: \"green\", shape: \"ring\", text: \"New login, new session: \" + msg._client.user.name });\n flow.set(\"useraccess\", useraccess);\n }\n break;\n } \n }\n if (authenticated) {\n // Check if the user has access to the page\n if (msg._client.user.pages.includes(msg.thispage)) {\n msg.topic = \"close\";\n msg.payload = \"\";\n return [msg, msg];\n } else {\n msg.topic = \"login\";\n msg.payload = { color: \"red\", message: \"Insufficient access to visit this page.\" };\n node.status({ fill: \"red\", shape: \"ring\", text: \"New login, no page access: \" + msg._client.user.name });\n return [msg, null]; \n }\n } else {\n msg.topic = \"login\";\n msg.payload = { color: \"red\", message: \"Invalid username or password.\" };\n node.status({ fill: \"red\", shape: \"ring\", text: \"Invalid user\" });\n return [msg, null];\n }\n\n}\n","outputs":2,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":930,"y":5620,"wires":[["64ed6f2f152bdde5","3a8e202a4aa5b0a4"],["68ccb793a6382f7e","ec997289b14216ae"]]},{"id":"3a8e202a4aa5b0a4","type":"debug","z":"0e3249ddee2000e3","name":"Credential check output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1210,"y":5580,"wires":[]},{"id":"86a19423988a8e30","type":"inject","z":"0e3249ddee2000e3","name":"User access defaults","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"users\":[{\"id\":\"1234ABC\",\"name\":\"Test User\",\"username\":\"a\",\"password\":\"b\",\"pages\":[\"User Access\"]},{\"id\":\"FHEMMEC\",\"name\":\"Second User\",\"username\":\"c\",\"password\":\"d\",\"pages\":[\"User Access\"]}],\"sessions\":[],\"settings\":{\"timeout\":3600,\"startpage\":\"Weather\"}}","payloadType":"json","x":150,"y":5560,"wires":[["8a6c70ff28bc40a8"]]},{"id":"8a6c70ff28bc40a8","type":"change","z":"0e3249ddee2000e3","name":"","rules":[{"t":"set","p":"useraccess","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":5560,"wires":[["a4022c88c98a4789"]]},{"id":"6b7d48a1821f7c97","type":"ui-template","z":"0e3249ddee2000e3","group":"","page":"566245f730fd3fa2","ui":"","name":"Account Menu","order":0,"width":0,"height":0,"head":"","format":"<template>\n <Teleport v-if=\"mounted\" to=\"#app-bar-actions\">\n <v-menu color=\"white\">\n <template v-slot:activator=\"{ props }\">\n <v-avatar color=\"red\" v-bind=\"props\">\n <span class=\"text-h7\">{{ initials }}</span>\n </v-avatar>\n <strong> </strong>\n </template>\n <v-card class=\"mx-auto\" width=\"256\" >\n <v-layout >\n <v-navigation-drawer absolute permanent color=\"white\">\n <v-list>\n <v-list-item prepend-icon=\"mdi-account-circle-outline\" :subtitle=\"user.id\"\n :title=\"user.name\">\n </v-list-item>\n </v-list>\n\n <v-divider></v-divider>\n\n <v-list lines=\"false\" density=\"compact\" nav>\n <v-list-item color=\"primary\" @click=\"send({topic: 'logout', payload: null})\">\n <template v-slot:prepend><v-icon icon=\"mdi-logout\"></v-icon></template>\n <v-list-item-title>Logout</v-list-item-title>\n </v-list-item>\n </v-list>\n </v-navigation-drawer>\n\n <v-main style=\"height: 354px;\"></v-main>\n </v-layout>\n </v-card>\n </v-menu>\n </Teleport>\n</template>\n<script>\n export default {\n data() {\n return {\n mounted: false,\n initials: \"\",\n user: {}\n }\n },\n mounted() {\n this.mounted = true\n },\n watch: {\n msg: function(){ \n if (!this.msg._client || this.msg._client.socketId === this.$socket.id) {\n if(this.msg.payload !== undefined) { \n this.initials = this.msg.payload.initials ?? \"\";\n this.user = this.msg.payload.user ?? {}; \n }\n }\n }\n }\n }\n</script>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"widget:page","className":"","x":1480,"y":5620,"wires":[["32368f8910cb55cb","7c7b20dd6933a71a"]]},{"id":"68ccb793a6382f7e","type":"function","z":"0e3249ddee2000e3","name":"Update account toolbar","func":"let arr = msg._client.user.name.split(\" \");\nmsg.payload = { \"initials\": arr[0].substring(0, 1) + arr[1].substring(0, 1), \"user\": msg._client.user };\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1230,"y":5620,"wires":[["6b7d48a1821f7c97"]]},{"id":"6a9ef363e491f75f","type":"debug","z":"0e3249ddee2000e3","name":"Login Screen submit","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":920,"y":5580,"wires":[]},{"id":"914dd70ad6b32a3d","type":"change","z":"0e3249ddee2000e3","name":"Name","rules":[{"t":"set","p":"payload","pt":"msg","to":"_client.user.name","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":5780,"wires":[["e4bf0c1b40cd0b43"]]},{"id":"e4bf0c1b40cd0b43","type":"ui-text","z":"0e3249ddee2000e3","group":"d7b93c2197360295","order":1,"width":0,"height":0,"name":"","label":"Name","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":870,"y":5780,"wires":[]},{"id":"9c318e1fd314d1ca","type":"change","z":"0e3249ddee2000e3","name":"Userid","rules":[{"t":"set","p":"payload","pt":"msg","to":"_client.user.username","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":5820,"wires":[["608a228e32868f92"]]},{"id":"608a228e32868f92","type":"ui-text","z":"0e3249ddee2000e3","group":"d7b93c2197360295","order":2,"width":0,"height":0,"name":"","label":"User Name","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":890,"y":5820,"wires":[]},{"id":"74a597f27f6a4744","type":"ui-text","z":"0e3249ddee2000e3","group":"d7b93c2197360295","order":3,"width":0,"height":0,"name":"","label":"Random Number","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":910,"y":5900,"wires":[]},{"id":"e9ac72af818b17c5","type":"function","z":"0e3249ddee2000e3","name":"Random","func":"msg.payload = Math.floor(Math.random()*100);\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":5900,"wires":[["74a597f27f6a4744"]]},{"id":"8431e7f8a632256d","type":"change","z":"0e3249ddee2000e3","name":"Userid","rules":[{"t":"set","p":"payload","pt":"msg","to":"_client.user.id","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":5860,"wires":[["0e412b04721edd0b"]]},{"id":"0e412b04721edd0b","type":"ui-text","z":"0e3249ddee2000e3","group":"d7b93c2197360295","order":6,"width":0,"height":0,"name":"","label":"User ID","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":880,"y":5860,"wires":[]},{"id":"831277ebbfe18be6","type":"debug","z":"0e3249ddee2000e3","name":"Valid Session","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":780,"y":5720,"wires":[]},{"id":"0f9fe08110f03b12","type":"ui-text","z":"0e3249ddee2000e3","group":"d7b93c2197360295","order":4,"width":0,"height":0,"name":"","label":"Everyone","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":880,"y":5940,"wires":[]},{"id":"3c6d487e6aeb6e55","type":"function","z":"0e3249ddee2000e3","name":"Random","func":"msg.payload = Math.floor(Math.random()*100);\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":5940,"wires":[["0f9fe08110f03b12"]]},{"id":"b78066842d9c0f0d","type":"inject","z":"0e3249ddee2000e3","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"2","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":490,"y":5940,"wires":[["3c6d487e6aeb6e55"]]},{"id":"32368f8910cb55cb","type":"debug","z":"0e3249ddee2000e3","name":"debug 378","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1690,"y":5560,"wires":[]},{"id":"7c7b20dd6933a71a","type":"switch","z":"0e3249ddee2000e3","name":"Menu selection","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"logout","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1690,"y":5620,"wires":[["504cceba396ab7c0"]]},{"id":"504cceba396ab7c0","type":"function","z":"0e3249ddee2000e3","name":"Handle logout","func":"let useraccess = flow.get(\"useraccess\");\nif ((Array.isArray(useraccess.users) ? 1 : 0) + (Array.isArray(useraccess.sessions) ? 1 : 0) + (typeof useraccess.settings === \"object\" ? 1 : 0) !== 3) {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Invalid useraccess config\" });\n return [null, null];\n}\n\n// Check if session exists and update the last time\nfor (let j = 0; j < useraccess.sessions.length; j++) {\n if (useraccess.sessions[j].socketId === msg._client.socketId) {\n // this is the sesssion\n useraccess.sessions.splice(j, 1);\n flow.set(\"useraccess\", useraccess);\n \n break;\n }\n}\n\nmsg.payload = { \"page\": useraccess.settings.startpage };\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1920,"y":5620,"wires":[["3b168c3a44fb0fd2"]]},{"id":"3b168c3a44fb0fd2","type":"ui-control","z":"0e3249ddee2000e3","name":"","ui":"cb79bc4520925e32","events":"all","x":2120,"y":5620,"wires":[[]]},{"id":"af9d84956d3ddeab","type":"change","z":"0e3249ddee2000e3","name":"Add Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"[{\"title\":\"User ID\",\"value\":\"id\",\"sortable\":true},{\"title\":\"Full Name\",\"value\":\"name\",\"sortable\":true},{\"title\":\"User Name\",\"value\":\"username\",\"sortable\":true},{\"title\":\"Page Access\",\"value\":\"pagestxt\"},{\"title\":\"Actions\",\"value\":\"edit\"}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":6180,"wires":[["048ce69d359921c0"]]},{"id":"048ce69d359921c0","type":"ui-template","z":"0e3249ddee2000e3","group":"50745a3fddb8a49e","page":"","ui":"","name":"User List","order":1,"width":"0","height":"0","head":"","format":"<template>\n <!-- Provide an input text box to search the content -->\n <v-text-field v-model=\"search\" label=\"Search\" prepend-inner-icon=\"mdi-magnify\" single-line variant=\"outlined\"\n hide-details></v-text-field>\n <v-data-table v-model:search=\"search\" :items=\"msg?.payload\" :headers=\"msg?.headers\">\n\n <template v-slot:item.edit=\"{ item }\">\n\n <v-container>\n <v-row align=\"center\" justify=\"center\">\n <v-col cols=\"auto\">\n <v-btn prepend-icon=\"mdi-file-edit-outline\" variant=\"tonal\" @click=\"send({topic: 'edit', payload: item})\">\n Edit\n </v-btn>\n </v-col>\n <v-col cols=\"auto\">\n <v-btn prepend-icon=\"mdi-delete-outline\" variant=\"tonal\" @click=\"send({topic: 'delete', payload: item})\">\n Delete\n </v-btn>\n </v-col>\n </v-row>\n </v-container>\n\n </template>\n\n\n </v-data-table>\n</template>\n\n<script>\n export default {\n data () {\n return {\n search: ''\n }\n },\n methods: {\n // add a function to determine the color of the progress bar given the row's item\n\n\n\n }\n }\n</script>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":800,"y":6180,"wires":[["3293fa30c5828070","ede002a80124e1de"]]},{"id":"5ee76184e6e7d57b","type":"link in","z":"0e3249ddee2000e3","name":"User Changes","links":["a4022c88c98a4789"],"x":245,"y":6100,"wires":[["87583a5e57bbc79b"]]},{"id":"a4022c88c98a4789","type":"link out","z":"0e3249ddee2000e3","name":"link out 74","mode":"link","links":["5ee76184e6e7d57b"],"x":525,"y":5560,"wires":[]},{"id":"87583a5e57bbc79b","type":"function","z":"0e3249ddee2000e3","name":"Purge passwords","func":"let useraccess = flow.get(\"useraccess\");\nif ((Array.isArray(useraccess.users) ? 1 : 0) + (Array.isArray(useraccess.sessions) ? 1 : 0) + (typeof useraccess.settings === \"object\" ? 1 : 0) !== 3) {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Invalid useraccess config\" });\n return [null, null];\n}\n\nmsg.payload = JSON.parse(JSON.stringify(useraccess.users));\n\nfor (let i = 0; i<msg.payload.length; i++) {\n delete msg.payload[i].password;\n msg.payload[i].edit = msg.payload[i].id;\n msg.payload[i].pagestxt = \"\";\n for (let j = 0; j<msg.payload[i].pages.length; j++) {\n msg.payload[i].pagestxt += msg.payload[i].pages[j] + \", \";\n }\n if (msg.payload[i].pagestxt !== \"\") {\n msg.payload[i].pagestxt = msg.payload[i].pagestxt.slice(0, -2); \n }\n delete msg.payload[i].pages;\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":6100,"wires":[["af9d84956d3ddeab","e8ea93608f3e6676"]]},{"id":"e8ea93608f3e6676","type":"debug","z":"0e3249ddee2000e3","name":"Formatted data","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":6100,"wires":[]},{"id":"921c9dfc0406c745","type":"inject","z":"0e3249ddee2000e3","name":"Test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":6160,"wires":[["87583a5e57bbc79b"]]},{"id":"3293fa30c5828070","type":"debug","z":"0e3249ddee2000e3","name":"User selection","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1020,"y":6140,"wires":[]},{"id":"ede002a80124e1de","type":"switch","z":"0e3249ddee2000e3","name":"Topic?","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"edit","vt":"str"},{"t":"eq","v":"delete","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":990,"y":6180,"wires":[["34f59d9d1e8ca812","5e803c73a6cc05ed","ea459382a2956c7d","5617dcf752f042d0"],[]]},{"id":"2935010c9908737a","type":"ui-control","z":"0e3249ddee2000e3","name":"To Edit Page","ui":"cb79bc4520925e32","events":"all","x":1530,"y":6160,"wires":[[]]},{"id":"34f59d9d1e8ca812","type":"function","z":"0e3249ddee2000e3","name":"Handle logout","func":"msg.payload = { \"page\": \"User Details\" };\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1320,"y":6160,"wires":[["2935010c9908737a"]]},{"id":"5e803c73a6cc05ed","type":"change","z":"0e3249ddee2000e3","name":"Name","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.name","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1250,"y":6220,"wires":[["15b7a4e07023338e"]]},{"id":"15b7a4e07023338e","type":"ui-text","z":"0e3249ddee2000e3","group":"8c3173ee8b65ede4","order":1,"width":0,"height":0,"name":"","label":"Name","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":1410,"y":6220,"wires":[]},{"id":"ea459382a2956c7d","type":"change","z":"0e3249ddee2000e3","name":"Userid","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.username","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1250,"y":6260,"wires":[["f3d231e1e3f73aeb"]]},{"id":"f3d231e1e3f73aeb","type":"ui-text","z":"0e3249ddee2000e3","group":"8c3173ee8b65ede4","order":2,"width":0,"height":0,"name":"","label":"User Name","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":1430,"y":6260,"wires":[]},{"id":"5617dcf752f042d0","type":"change","z":"0e3249ddee2000e3","name":"Userid","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.userid","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1250,"y":6300,"wires":[["c2f821055808d050"]]},{"id":"c2f821055808d050","type":"ui-text","z":"0e3249ddee2000e3","group":"8c3173ee8b65ede4","order":3,"width":0,"height":0,"name":"","label":"User ID","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","className":"","x":1420,"y":6300,"wires":[]},{"id":"4174b97a6cc4a7f8","type":"inject","z":"0e3249ddee2000e3","name":"Test Data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"id\":\"1234ABC\",\"name\":\"Test User\",\"username\":\"a\",\"edit\":\"1234ABC\",\"pagestxt\":\"User Access\"},{\"id\":\"FHEMMEC\",\"name\":\"Second User\",\"username\":\"c\",\"edit\":\"FHEMMEC\",\"pagestxt\":\"User Access\"}]","payloadType":"json","x":420,"y":6180,"wires":[["af9d84956d3ddeab"]]},{"id":"ec997289b14216ae","type":"junction","z":"0e3249ddee2000e3","x":640,"y":5720,"wires":[["831277ebbfe18be6","914dd70ad6b32a3d","9c318e1fd314d1ca","8431e7f8a632256d"]]},{"id":"d7b93c2197360295","type":"ui-group","name":"User Details","page":"566245f730fd3fa2","width":"6","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"cb79bc4520925e32","type":"ui-base","name":"My UI","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control","ui-text"],"showPathInSidebar":false},{"id":"566245f730fd3fa2","type":"ui-page","name":"User Access","ui":"cb79bc4520925e32","path":"/user1","icon":"home","layout":"grid","theme":"0d92c765bfad87e6","order":5,"className":"","visible":true,"disabled":"false"},{"id":"50745a3fddb8a49e","type":"ui-group","name":"User List","page":"4a3e5c66d6086fee","width":"12","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"8c3173ee8b65ede4","type":"ui-group","name":"User Details","page":"3c09c41d22450231","width":"6","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"0d92c765bfad87e6","type":"ui-theme","name":"Basic Blue Theme","colors":{"surface":"#4d58ff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}},{"id":"4a3e5c66d6086fee","type":"ui-page","name":"User Administration","ui":"cb79bc4520925e32","path":"/page15","icon":"home","layout":"grid","theme":"0d92c765bfad87e6","order":17,"className":"","visible":"true","disabled":"false"},{"id":"3c09c41d22450231","type":"ui-page","name":"User Details","ui":"cb79bc4520925e32","path":"/userdetails","icon":"home","layout":"grid","theme":"0d92c765bfad87e6","order":1,"className":"","visible":"false","disabled":"false"}]