Dashboard 2: Multi-User Framework with Role Permissions and Route Authentication
Multi-user support with permission control;
Route-level authentication;
Authentication for simple actions, such as button clicks.
Copy JSON
Note: some third-party nodes may appear with blank styling, and not as they appear in the Node-RED Editor.
Copy [{"id":"58b464389d53622c","type":"subflow","name":"Dashbaord check route","info":"","category":"dashbaord 2 authentication","in":[],"out":[{"x":960,"y":240,"wires":[{"id":"29cab945f38d59ac","port":0}]}],"env":[{"name":"pageName","type":"str","value":""}],"meta":{},"color":"#3FADB5","icon":"font-awesome/fa-lock"},{"id":"7a60da809bd053c4","type":"switch","z":"58b464389d53622c","name":"","property":"payload.page.name","propertyType":"msg","rules":[{"t":"eq","v":"pageName","vt":"env"}],"checkall":"true","repair":false,"outputs":1,"x":450,"y":240,"wires":[["29cab945f38d59ac"]]},{"id":"4db91677f1f692fc","type":"ui-event","z":"58b464389d53622c","ui":"fc791b134c0d96db","name":"","x":210,"y":240,"wires":[["7a60da809bd053c4"]]},{"id":"29cab945f38d59ac","type":"subflow:ed672fb0481728c5","z":"58b464389d53622c","name":"","x":710,"y":240,"wires":[[]]},{"id":"0b18b5e7eb97ea74","type":"subflow","name":"Dashboard check auth","info":"","category":"dashbaord 2 authentication","in":[{"x":320,"y":420,"wires":[{"id":"ca70c0e0dee1ce22"}]}],"out":[{"x":1100,"y":420,"wires":[{"id":"1fdb1b85553f2c7b","port":0}]}],"env":[],"meta":{},"color":"#3FADB5","icon":"font-awesome/fa-unlock-alt"},{"id":"1fdb1b85553f2c7b","type":"switch","z":"0b18b5e7eb97ea74","name":"","property":"_dashboardSession.authenticated","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":770,"y":420,"wires":[[],["102c5f6b1422d9d6"]]},{"id":"102c5f6b1422d9d6","type":"function","z":"0b18b5e7eb97ea74","name":"refresh","func":"msg.payload = \"\"\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":560,"wires":[["2ebf6e522d2425a6"]]},{"id":"2ebf6e522d2425a6","type":"ui-control","z":"0b18b5e7eb97ea74","name":"","ui":"fc791b134c0d96db","events":"all","x":1080,"y":560,"wires":[[]]},{"id":"ca70c0e0dee1ce22","type":"subflow:ed672fb0481728c5","z":"0b18b5e7eb97ea74","name":"","x":490,"y":420,"wires":[["1fdb1b85553f2c7b"]]},{"id":"d8e2d9b6583b0991","type":"subflow","name":"Dashboard get routes","info":"# output\r\nmsg._dashboardRoutes","category":"dashbaord 2 authentication","in":[{"x":100,"y":160,"wires":[{"id":"0d587b5d7d07bace"}]}],"out":[{"x":1100,"y":160,"wires":[{"id":"657d70358024d979","port":0}]}],"env":[],"meta":{},"color":"#3FADB5"},{"id":"02fb394f74231ca9","type":"file in","z":"d8e2d9b6583b0991","name":"","filename":"./dashboardRoute.json","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":520,"y":160,"wires":[["8c96bfe1870f851a"]]},{"id":"8c96bfe1870f851a","type":"json","z":"d8e2d9b6583b0991","name":"","property":"payload","action":"","pretty":false,"x":750,"y":160,"wires":[["657d70358024d979"]]},{"id":"0d587b5d7d07bace","type":"change","z":"d8e2d9b6583b0991","name":"","rules":[{"t":"set","p":"originalPayload","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":160,"wires":[["02fb394f74231ca9"]]},{"id":"657d70358024d979","type":"function","z":"d8e2d9b6583b0991","name":"function 4","func":"msg._dashboardRoutes = msg.payload\nmsg.payload = msg.originalPayload\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":160,"wires":[[]]},{"id":"ed672fb0481728c5","type":"subflow","name":"Dashboard authentication","info":"","category":"dashbaord 2 authentication","in":[{"x":100,"y":120,"wires":[{"id":"f4ef5057d1f907de"}]}],"out":[{"x":1560,"y":200,"wires":[{"id":"092cad94fe637b12","port":0}]}],"env":[],"meta":{},"color":"#3FADB5","icon":"font-awesome/fa-id-card"},{"id":"f4ef5057d1f907de","type":"function","z":"ed672fb0481728c5","name":"function 8","func":"msg.getToken = true\nmsg.topic = \"originalPayload\"\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":120,"wires":[["43b9655e30315bef","b00e68c6d6d2b052"]]},{"id":"2e9c9452ebdd6eb2","type":"function","z":"ed672fb0481728c5","name":"set dashboardSession","func":"var session_token = msg.payload\n\nconst dashboardSessions = global.get(\"dashboardSessions\")\n\nconst searchSession = dashboardSessions.find(u =>\n u.token === session_token\n);\n\n\nvar dashboardSession = {}\n\nif (searchSession) {\n\n dashboardSession = {\n \"authenticated\":true,\n \"user\": searchSession.user,\n \"role\": searchSession.role,\n \"token\": searchSession.token\n\n }\n\n\n\n} else {\n dashboardSession = {\n \"authenticated\": false,\n \"user\": \"anonymous\",\n \"role\": \"anonymous\",\n \"token\": null\n\n }\n}\nmsg.topic = \"dashboardSession\"\nmsg._dashboardSession = dashboardSession\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1120,"y":120,"wires":[["de7a7a46b609153c"]]},{"id":"de7a7a46b609153c","type":"join","z":"ed672fb0481728c5","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1250,"y":200,"wires":[["092cad94fe637b12"]]},{"id":"092cad94fe637b12","type":"function","z":"ed672fb0481728c5","name":"function 7","func":"msg.payload = msg.payload.originalPayload\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1420,"y":200,"wires":[[]]},{"id":"b00e68c6d6d2b052","type":"ui-template","z":"ed672fb0481728c5","group":"","page":"","ui":"fc791b134c0d96db","name":"template_getCookie","order":0,"width":0,"height":0,"head":"","format":"<script>\n export default {\n data() {\n // define variables available component-wide\n // (in <template> and component functions)\n return {\n \n }\n },\n watch: {\n // watch for any changes of \"count\"\n\n msg: function () {\n \n if(this.msg.getToken == true){\n this.send({payload: this.getCookie(\"token\")})\n } \n \n }\n \n },\n computed: {\n // automatically compute this variable\n // whenever VueJS deems appropriate\n \n },\n methods: {\n \n getCookie: function (name) {\n const nameEQ = name + \"=\";\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) { let c=cookies[i]; while (c.charAt(0)===' ' ) c=c.substring(1); if\n (c.indexOf(nameEQ)===0) return c.substring(nameEQ.length, c.length); } return null; }\n },\n mounted() {\n \n \n },\n unmounted() {\n // code here when the component is removed from the Dashboard\n // i.e. when the user navigates away from the page\n }\n }\n</script>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"widget:ui","className":"","x":780,"y":120,"wires":[["2e9c9452ebdd6eb2"]]},{"id":"43b9655e30315bef","type":"junction","z":"ed672fb0481728c5","x":680,"y":200,"wires":[["de7a7a46b609153c"]]},{"id":"fc791b134c0d96db","type":"ui-base","name":"My Dashboard","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control","ui-template","ui-form","ui-audio","ui-markdown","ui-progress","ui-gauge","ui-chart","ui-table","ui-text","ui-switch","ui-slider","ui-radio-group","ui-dropdown","ui-button-group","ui-button","ui-file-input","ui-number-input","ui-text-input"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"temporary","titleBarStyle":"default","showReconnectNotification":true,"notificationDisplayTime":1,"showDisconnectNotification":true,"allowInstall":true},{"id":"fc780dd0345a8d2f","type":"subflow","name":"Dashboard authentication","info":"","category":"dashbaord 2 authentication","in":[],"out":[],"env":[],"meta":{},"color":"#3FADB5","icon":"node-red/parser-json.svg"},{"id":"4ed2f111a063ebd1","type":"ui-form","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"Form login","group":"8c4c5cb02cd4ac92","label":"","order":1,"width":0,"height":0,"options":[{"label":"user","key":"user","type":"text","required":true,"rows":null},{"label":"password","key":"password","type":"password","required":true,"rows":null}],"formValue":{"user":"","password":""},"payload":"","submit":"login","cancel":"clear","resetOnSubmit":false,"topic":"topic","topicType":"msg","splitLayout":"","className":"","passthru":false,"dropdownOptions":[],"x":110,"y":180,"wires":[["c7ba9fd68f3c8e11"]]},{"id":"c7ba9fd68f3c8e11","type":"function","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"set session","func":"const { randomUUID } = crypto\n\nconst user = msg.payload\n\nconst dashboardUsers = global.get(\"dashboardUsers\")\n\nconst searchUser = dashboardUsers.find(u =>\n u.user === user.user && u.password === user.password\n);\n\nif (searchUser) {\n \n const role = searchUser.role\n const token = randomUUID();\n\n\n const userSession = {\n \"token\": token,\n \"user\": user.user,\n \"role\": role\n }\n\n const dashboardSession = {\n \"authenticated\": true,\n \"user\": user.user,\n \"role\": role,\n \"token\": token\n\n }\n\n let dashboardSessions = global.get(\"dashboardSessions\")\n\n dashboardSessions.push(userSession)\n\n global.set(\"dashboardSessions\", dashboardSessions)\n\n\n msg._dashboardSession = dashboardSession\n msg.payload = {\n \"status\": true,\n \"token\": token\n }\n return msg;\n} else {\n\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"crypto","module":"crypto"}],"x":270,"y":180,"wires":[["cf3a1d1d3dfa2201"]]},{"id":"cf3a1d1d3dfa2201","type":"ui-template","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","group":"","page":"7eb94a3a392a10f2","ui":"","name":"template token","order":2,"width":0,"height":0,"head":"","format":"<script>\n export default {\n data() {\n // define variables available component-wide\n // (in <template> and component functions)\n return {\n \n }\n },\n watch: {\n // watch for any changes of \"count\"\n\n msg: function () {\n \n if(this.msg.payload.status == true){\n const token = this.msg.payload.token;\n const dias = 7;\n\n const data = new Date();\n data.setTime(data.getTime() + (dias * 24 * 60 * 60 * 1000));\n const expira = \"expires=\" + data.toUTCString();\n\n document.cookie =\"token =\" + token + \";\" + expira + \";path=/\";\n this.send({payload: true})\n } \n \n }\n },\n computed: {\n \n },\n methods: {\n \n \n },\n mounted() {\n \n \n },\n unmounted() {\n // code here when the component is removed from the Dashboard\n // i.e. when the user navigates away from the page\n }\n }\n</script>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"widget:page","className":"","x":460,"y":160,"wires":[["4b23201edcfeb747"]]},{"id":"5d521eb04da7c9a7","type":"switch","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"switch roles","property":"_dashboardSession.role","propertyType":"msg","rules":[{"t":"eq","v":"admin","vt":"str"},{"t":"eq","v":"user","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":170,"y":280,"wires":[["25acc2c53a42ca87"],["ca1e2cbafe1e1e88"]]},{"id":"25acc2c53a42ca87","type":"function","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"route admin","func":"\n\n\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"admin\"\n);\n\nmsg.payload = searchUser.control\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":260,"wires":[["a28272705347d432"]]},{"id":"ca1e2cbafe1e1e88","type":"function","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"route user","func":"\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"user\"\n);\n\nmsg.payload = searchUser.control\n\n\nreturn msg","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":320,"wires":[["a28272705347d432"]]},{"id":"4b23201edcfeb747","type":"subflow:ed672fb0481728c5","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"","x":730,"y":160,"wires":[["aac0084ae5a5011f"]]},{"id":"e74807e53dacb0b8","type":"link in","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"link in 2","links":["162fcab227ef5ccb"],"x":55,"y":280,"wires":[["5d521eb04da7c9a7"]]},{"id":"162fcab227ef5ccb","type":"link out","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"link out 2","mode":"link","links":["8a62b8ec9fc1c514","e74807e53dacb0b8"],"x":1185,"y":160,"wires":[]},{"id":"a28272705347d432","type":"ui-control","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"","ui":"fc791b134c0d96db","events":"all","x":600,"y":260,"wires":[[]]},{"id":"aac0084ae5a5011f","type":"subflow:d8e2d9b6583b0991","z":"fc780dd0345a8d2f","g":"c5d3c353dfe585ac","name":"","x":1040,"y":160,"wires":[["162fcab227ef5ccb"]]},{"id":"8a62b8ec9fc1c514","type":"link in","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","name":"template_userWidget","links":["85a385823ce15e30","4f3d587309f42763","162fcab227ef5ccb"],"x":65,"y":60,"wires":[["d9b795e8e222373a"]]},{"id":"d9b795e8e222373a","type":"ui-template","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","group":"","page":"","ui":"fc791b134c0d96db","name":"template_userWidget","order":2,"width":0,"height":0,"head":"","format":"<template>\n <Teleport v-if=\"loaded\" to=\"#app-bar-actions\">\n <v-menu\n v-model=\"menu\"\n location=\"bottom end\"\n offset-y\n >\n <!-- Trigger -->\n <template #activator=\"{ props }\">\n <div class=\"user-info\" v-bind=\"props\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"\n fill=\"currentColor\" class=\"bi bi-person-circle\" viewBox=\"0 0 16 16\">\n <path d=\"M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0\" />\n <path fill-rule=\"evenodd\"\n d=\"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1\" />\n </svg>\n <span>{{ userName }}</span>\n </div>\n </template>\n\n \n <v-list>\n <v-list-item @click=\"logout\">\n <v-list-item-title>Exit</v-list-item-title>\n </v-list-item>\n </v-list>\n </v-menu>\n </Teleport>\n</template>\n\n<script>\nexport default {\n data() {\n return {\n loaded: false,\n userName: \"\",\n menu: false\n };\n },\n watch: {\n msg() {\n if (this.msg._dashboardSession.user != null) {\n this.userName = this.msg._dashboardSession.user;\n }\n }\n },\n mounted() {\n this.loaded = true;\n },\n methods: {\n deleteCookieToken() {\n document.cookie = \"token=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;\";\n },\n logout() {\n this.deleteCookieToken();\n this.send({payload: true});\n \n }\n }\n};\n</script>\n\n<style>\n.user-info {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 6px;\n}\n\n.user-info:hover {\n background: rgba(0, 0, 0, 0.1);\n}\n</style>\n","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"widget:ui","className":"","x":240,"y":60,"wires":[["14ad6ccfc5b680f1"]]},{"id":"14ad6ccfc5b680f1","type":"subflow:ed672fb0481728c5","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","name":"","x":520,"y":60,"wires":[["7da5ddc51e1be34a"]]},{"id":"e6b750ed9c98930b","type":"function","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","name":"route admin","func":"\n\n\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"anonymous\"\n);\n\nmsg.payload = searchUser.control\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":60,"wires":[["f00b0cd2d3931a15"]]},{"id":"f00b0cd2d3931a15","type":"ui-control","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","name":"","ui":"fc791b134c0d96db","events":"all","x":1160,"y":60,"wires":[[]]},{"id":"7da5ddc51e1be34a","type":"subflow:d8e2d9b6583b0991","z":"fc780dd0345a8d2f","g":"84ea63d340c01d4a","name":"","x":770,"y":60,"wires":[["e6b750ed9c98930b"]]},{"id":"abb3b817e762867d","type":"subflow:ed672fb0481728c5","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"","x":310,"y":440,"wires":[["3a59eacb356bdc16"]]},{"id":"5750ef774d73aa0d","type":"switch","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"switch authenticated","property":"_dashboardSession.authenticated","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":820,"y":440,"wires":[["85a385823ce15e30"],["4f3d587309f42763"]]},{"id":"85a385823ce15e30","type":"link out","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"link out 3","mode":"link","links":["8a62b8ec9fc1c514","38e8d7bbb002206d"],"x":965,"y":420,"wires":[]},{"id":"38e8d7bbb002206d","type":"link in","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"link in 3","links":["85a385823ce15e30"],"x":65,"y":560,"wires":[["c48a61181a7a93f4"]]},{"id":"f635b2bc8575b140","type":"comment","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"true","info":"","x":1040,"y":420,"wires":[]},{"id":"d412b4e1bbed6d73","type":"function","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"route admin","func":"\n\n\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"admin\"\n);\n\nmsg.payload = {\n pages: searchUser.control.pages\n\n}\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":540,"wires":[["2521425ad78b2636"]]},{"id":"c48a61181a7a93f4","type":"switch","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"switch roles","property":"_dashboardSession.role","propertyType":"msg","rules":[{"t":"eq","v":"admin","vt":"str"},{"t":"eq","v":"user","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":190,"y":560,"wires":[["d412b4e1bbed6d73"],["20ba0cdfef448f5e"]]},{"id":"20ba0cdfef448f5e","type":"function","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"route user","func":"\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"user\"\n);\n\nconst pageName = msg.payload.page.name\n\nconst exists = searchUser.control.pages.show.includes(pageName);\n\n\nif (exists){\n msg.payload = {\n pages: searchUser.control.pages\n\n }\n}else {\n msg.payload = searchUser.control\n \n}\n\nreturn msg","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":580,"wires":[["2521425ad78b2636"]]},{"id":"98674e561ae5ab2e","type":"comment","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"true","info":"","x":90,"y":520,"wires":[]},{"id":"4f3d587309f42763","type":"link out","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"link out 4","mode":"link","links":["8a62b8ec9fc1c514","2973d44c77ac8d4e"],"x":965,"y":480,"wires":[]},{"id":"5dde8ff228082c19","type":"comment","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"false","info":"","x":1040,"y":480,"wires":[]},{"id":"4435e17d139210ed","type":"ui-event","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","ui":"fc791b134c0d96db","name":"","x":90,"y":440,"wires":[["abb3b817e762867d"]]},{"id":"2e4a7ba3d6aecba7","type":"function","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"route anonymous","func":"\n\n\nconst dashboardRoutes = msg._dashboardRoutes\n\nconst searchUser = dashboardRoutes.find(u =>\n u.role === \"anonymous\"\n);\n\nconst pageName = msg.payload.page.name\n\nconst exists = searchUser.control.pages.show.includes(pageName);\n\n\nif (exists) {\n msg.payload = {\n pages: searchUser.control.pages\n\n }\n} else {\n msg.payload = searchUser.control\n\n}\n\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":660,"wires":[["2521425ad78b2636"]]},{"id":"2973d44c77ac8d4e","type":"link in","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"link in switch authenticated false","links":["4f3d587309f42763"],"x":65,"y":660,"wires":[["2e4a7ba3d6aecba7"]]},{"id":"cc9c18e33b096425","type":"comment","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"false","info":"","x":90,"y":620,"wires":[]},{"id":"2521425ad78b2636","type":"ui-control","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"","ui":"fc791b134c0d96db","events":"all","x":600,"y":660,"wires":[[]]},{"id":"3a59eacb356bdc16","type":"subflow:d8e2d9b6583b0991","z":"fc780dd0345a8d2f","g":"b6845753ad4151c3","name":"","x":560,"y":440,"wires":[["5750ef774d73aa0d"]]},{"id":"c5d3c353dfe585ac","type":"group","z":"fc780dd0345a8d2f","name":"Logs in and saves the token in the page's cookie.","style":{"label":true},"nodes":["4ed2f111a063ebd1","c7ba9fd68f3c8e11","cf3a1d1d3dfa2201","5d521eb04da7c9a7","25acc2c53a42ca87","ca1e2cbafe1e1e88","4b23201edcfeb747","e74807e53dacb0b8","162fcab227ef5ccb","a28272705347d432","aac0084ae5a5011f"],"x":14,"y":119,"w":1212,"h":242},{"id":"84ea63d340c01d4a","type":"group","z":"fc780dd0345a8d2f","name":"widget that shows user and deletes token","style":{"label":true},"nodes":["8a62b8ec9fc1c514","d9b795e8e222373a","14ad6ccfc5b680f1","e6b750ed9c98930b","f00b0cd2d3931a15","7da5ddc51e1be34a"],"x":24,"y":19,"w":1222,"h":82},{"id":"b6845753ad4151c3","type":"group","z":"fc780dd0345a8d2f","name":"Check all routes when you log into the dashboard.","style":{"label":true},"nodes":["abb3b817e762867d","5750ef774d73aa0d","85a385823ce15e30","38e8d7bbb002206d","f635b2bc8575b140","d412b4e1bbed6d73","c48a61181a7a93f4","20ba0cdfef448f5e","98674e561ae5ab2e","4f3d587309f42763","5dde8ff228082c19","4435e17d139210ed","2e4a7ba3d6aecba7","2973d44c77ac8d4e","cc9c18e33b096425","2521425ad78b2636","3a59eacb356bdc16"],"x":14,"y":379,"w":1102,"h":322},{"id":"8c4c5cb02cd4ac92","type":"ui-group","name":"Group Name","page":"7eb94a3a392a10f2","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"7eb94a3a392a10f2","type":"ui-page","name":"login","ui":"fc791b134c0d96db","path":"/login","icon":"home","layout":"grid","theme":"81188254a75a0155","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":3,"className":"","visible":"true","disabled":"false"},{"id":"81188254a75a0155","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"density":"default","pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}},{"id":"29e360b71b280f37","type":"tab","label":"Dashbord 2 multi user","disabled":false,"info":"","env":[]},{"id":"6721d131b2debcdb","type":"group","z":"29e360b71b280f37","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["1f55502a6fb5f983","e6224f1e342cb62b","b126a6dc9791e0b3","8e1e06022c0f3b73","9ca50e5c61df2a1f","6af985caad14eb53","930c45706c4b9942","a9085ceb03477703","0ae8e0ce8e82c040","31255c2f26ac7384"],"x":14,"y":139,"w":852,"h":302},{"id":"1d51f180991e70d4","type":"group","z":"29e360b71b280f37","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["65d6717312e2a084","bc7c1039686b92b1","b68ac0cfc28f48b6","1f268c229fcdd63b"],"x":14,"y":459,"w":732,"h":122},{"id":"658b3faaa527d2ce","type":"group","z":"29e360b71b280f37","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["af29e706415d7618","7f6a1f943c4eb0bc","ddbf73b63b5f9895"],"x":14,"y":599,"w":452,"h":122},{"id":"9c2af251e8c4e3fa","type":"subflow:fc780dd0345a8d2f","z":"29e360b71b280f37","name":"","x":150,"y":100,"wires":[]},{"id":"47d4d2cbae8b040c","type":"file","z":"29e360b71b280f37","name":"","filename":"./dashboardRoute.json","filenameType":"str","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":640,"y":40,"wires":[[]]},{"id":"37f2ba186d71110f","type":"function","z":"29e360b71b280f37","name":"set user , roles, session, routes","func":"const users = [\n\n {\n \"user\": \"admin\",\n \"password\": \"admin\",\n \"role\": \"admin\"\n },\n\n {\n \"user\": \"user\",\n \"password\": \"user\",\n \"role\": \"user\"\n }\n\n]\n\n\nglobal.set(\"dashboardUsers\", users)\nglobal.set(\"dashboardSessions\", [])\n\n\n\nconst dashboardRoutes = [\n {\n \"role\": \"admin\",\n \"control\": {\n page: \"admin_route\",\n pages: {\n show: ['admin_route', 'user_route', 'anonymous_route', 'login'],\n hide: []\n }\n\n }\n },\n {\n \"role\": \"user\",\n \"control\": {\n page: \"anonymous_route\",\n pages: {\n show: ['anonymous_route', 'user_route', 'login'],\n hide: ['admin_route']\n }\n\n }\n },\n {\n \"role\": \"anonymous\",\n \"control\": {\n page: \"anonymous_route\",\n pages: {\n show: ['anonymous_route', 'login'],\n hide: ['admin_route', 'user_route']\n }\n\n }\n },\n\n]\nmsg.payload = dashboardRoutes\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":40,"wires":[["47d4d2cbae8b040c"]]},{"id":"1a132540bcf42777","type":"inject","z":"29e360b71b280f37","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":40,"wires":[["37f2ba186d71110f"]]},{"id":"1f55502a6fb5f983","type":"ui-number-input","z":"29e360b71b280f37","g":"6721d131b2debcdb","group":"20cec62065ebad36","name":"","label":"number","order":2,"width":0,"height":0,"topic":"topic","topicType":"msg","min":0,"max":10,"step":1,"tooltip":"","passthru":true,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","spinner":"default","x":100,"y":220,"wires":[["31255c2f26ac7384"]]},{"id":"e6224f1e342cb62b","type":"comment","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"anonymous_route","info":"","x":130,"y":180,"wires":[]},{"id":"65d6717312e2a084","type":"ui-number-input","z":"29e360b71b280f37","g":"1d51f180991e70d4","group":"1c4a53690396041f","name":"","label":"number","order":2,"width":0,"height":0,"topic":"topic","topicType":"msg","min":0,"max":10,"step":1,"tooltip":"","passthru":true,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","spinner":"default","x":100,"y":540,"wires":[["b68ac0cfc28f48b6"]]},{"id":"bc7c1039686b92b1","type":"comment","z":"29e360b71b280f37","g":"1d51f180991e70d4","name":"admin_route","info":"","x":110,"y":500,"wires":[]},{"id":"b68ac0cfc28f48b6","type":"subflow:0b18b5e7eb97ea74","z":"29e360b71b280f37","g":"1d51f180991e70d4","name":"","x":340,"y":540,"wires":[["1f268c229fcdd63b"]]},{"id":"b126a6dc9791e0b3","type":"subflow:58b464389d53622c","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"","env":[{"name":"pageName","value":"anonymous_route","type":"str"}],"x":140,"y":360,"wires":[["8e1e06022c0f3b73"]]},{"id":"8e1e06022c0f3b73","type":"switch","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"switch roles","property":"_dashboardSession.role","propertyType":"msg","rules":[{"t":"eq","v":"admin","vt":"str"},{"t":"eq","v":"user","vt":"str"},{"t":"eq","v":"anonymous","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":350,"y":360,"wires":[["9ca50e5c61df2a1f"],["a9085ceb03477703"],["6af985caad14eb53"]]},{"id":"9ca50e5c61df2a1f","type":"change","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"admin user","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":320,"wires":[["930c45706c4b9942"]]},{"id":"6af985caad14eb53","type":"change","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"anonymous user","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":400,"wires":[["930c45706c4b9942"]]},{"id":"930c45706c4b9942","type":"ui-text","z":"29e360b71b280f37","g":"6721d131b2debcdb","group":"20cec62065ebad36","order":1,"width":0,"height":0,"name":"","label":"text","format":"{{msg.payload}}","layout":"row-spread","style":false,"font":"","fontSize":16,"color":"#717171","wrapText":false,"className":"","value":"payload","valueType":"msg","x":790,"y":340,"wires":[]},{"id":"af29e706415d7618","type":"ui-number-input","z":"29e360b71b280f37","g":"658b3faaa527d2ce","group":"08bf565a9081a101","name":"","label":"number","order":1,"width":0,"height":0,"topic":"topic","topicType":"msg","min":0,"max":10,"step":1,"tooltip":"","passthru":true,"sendOnBlur":true,"sendOnEnter":true,"className":"","clearable":false,"icon":"","iconPosition":"left","iconInnerPosition":"inside","spinner":"default","x":100,"y":680,"wires":[["ddbf73b63b5f9895"]]},{"id":"7f6a1f943c4eb0bc","type":"comment","z":"29e360b71b280f37","g":"658b3faaa527d2ce","name":"user_route","info":"","x":100,"y":640,"wires":[]},{"id":"ddbf73b63b5f9895","type":"subflow:0b18b5e7eb97ea74","z":"29e360b71b280f37","g":"658b3faaa527d2ce","name":"","x":340,"y":680,"wires":[[]]},{"id":"1f268c229fcdd63b","type":"ui-text","z":"29e360b71b280f37","g":"1d51f180991e70d4","group":"1c4a53690396041f","order":1,"width":0,"height":0,"name":"","label":"value authenticated","format":"{{msg.payload}}","layout":"row-left","style":false,"font":"","fontSize":16,"color":"#717171","wrapText":false,"className":"","value":"payload","valueType":"msg","x":630,"y":540,"wires":[]},{"id":"a9085ceb03477703","type":"change","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"user ","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":360,"wires":[["930c45706c4b9942"]]},{"id":"0ae8e0ce8e82c040","type":"debug","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":620,"y":220,"wires":[]},{"id":"31255c2f26ac7384","type":"subflow:ed672fb0481728c5","z":"29e360b71b280f37","g":"6721d131b2debcdb","name":"","x":330,"y":220,"wires":[["0ae8e0ce8e82c040"]]},{"id":"20cec62065ebad36","type":"ui-group","name":"anonymous_route","page":"c28ac92ff6b2c999","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"1c4a53690396041f","type":"ui-group","name":"admin_route","page":"25dbe91d1e077f19","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"08bf565a9081a101","type":"ui-group","name":"user_route","page":"d5dca3a7ebb6c644","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"c28ac92ff6b2c999","type":"ui-page","name":"anonymous_route","ui":"fc791b134c0d96db","path":"/anonymous_route","icon":"home","layout":"grid","theme":"81188254a75a0155","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":4,"className":"","visible":"true","disabled":"false"},{"id":"25dbe91d1e077f19","type":"ui-page","name":"admin_route","ui":"fc791b134c0d96db","path":"/admin_route","icon":"home","layout":"grid","theme":"81188254a75a0155","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":2,"className":"","visible":"true","disabled":"false"},{"id":"d5dca3a7ebb6c644","type":"ui-page","name":"user_route","ui":"fc791b134c0d96db","path":"/user_route","icon":"home","layout":"grid","theme":"81188254a75a0155","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":1,"className":"","visible":"true","disabled":"false"},{"id":"7776c6b3141d3ffd","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.29.0"}}]