2FA in NodeRED (Two Factor Authentication)
Two Factor Authentication made for NodeRED needs. Control payload flow with an Android prompt. This is best used when the automatic trigger needs a possible human oversight.
Features:
- Android Notification
- Automatic Timeout
- Custom Default Action
- Allow/Reject
- Progress bar
- Subflow deployment
You will need the following Android Apps:
Download a complete Tasker profile from TaskerNET
This Setup leans on the following guides: Perfect Autonotifications, Credentials in NodeRED,
Settings
- default2fa - Default behaviour true|false
- timer - timeout in seconds
- AR Device - name of AutoRemote device served with credential system
- title - title of the notification
- text - text of the notification
- 2FApath - path for HTTP request
- ID - unique ID
More about me:
If you want to get the latest updates to this project you can follow me via your preferred social media:
And if you feeling like buying me a coffee or supporting me in a more continuous way:
I hope you have enjoyed the project!
[{"id":"b44411e6.28ae6","type":"subflow","name":"2FA","info":"","category":"","in":[{"x":320,"y":240,"wires":[{"id":"54d21981.c2c698"}]}],"out":[{"x":1040,"y":220,"wires":[{"id":"d6bdef4b.09f4b","port":0}]}],"env":[{"name":"default2fa","type":"bool","value":"false"},{"name":"timer","type":"num","value":"20"},{"name":"ARdevice","type":"str","value":""},{"name":"title","type":"str","value":""},{"name":"text","type":"str","value":""},{"name":"2FApath","type":"str","value":""},{"name":"ID","type":"str","value":""}],"color":"#DDAA99"},{"id":"54d21981.c2c698","type":"function","z":"b44411e6.28ae6","name":"Set alarm","func":"var x = env.get(\"timer\");\nvar timer = x *1000;\nvar time = new Date();\nvar timeseconds = time.getTime();\nvar alarm = timeseconds + timer;\n\n\nflow.set(\"$parent.alarm\", alarm);\nflow.set(\"$parent.time\", timeseconds);\nflow.set(\"$parent.authentication\", \"pending\");\n\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":240,"wires":[["978a4770.9effd8","d6bdef4b.09f4b"]]},{"id":"7aedd4b4.d3497c","type":"delay","z":"b44411e6.28ae6","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":740,"y":320,"wires":[["d6bdef4b.09f4b"]]},{"id":"978a4770.9effd8","type":"function","z":"b44411e6.28ae6","name":"2FA Push","func":"var device = env.get(\"ARdevice\");\nvar timer = env.get(\"timer\");\nvar title = env.get(\"title\");\nvar text = env.get(\"text\");\nvar path = env.get(\"2FApath\");\nvar ID = env.get(\"ID\");\nvar default2fa = env.get(\"default2fa\");\nvar status2fa;\n\nif(default2fa === true){\n status2fa = \"approved\";\n}\n\nif(default2fa === false){\n status2fa = \"declined\";\n}\n\n\nvar key = global.get(device);\nvar time = flow.get(\"$parent.time\");\nvar alarm = flow.get(\"$parent.alarm\");\nvar url = \"https://autoremotejoaomgcd.appspot.com/sendmessage\";\nvar command = \"2FA\";\nvar body = {\n \"title\": {\n \"title\": title,\n \"titleexpanded\": title\n },\n \"text\": {\n \"text\": text,\n \"textexpanded\": text\n },\n \"icons\": {\n \"navbaricon\": \"android.resource://net.dinglisch.android.taskerm/hl_device_access_new_account\",\n \"bigicon\": \"android.resource://net.dinglisch.android.taskerm/hl_device_access_new_account\"\n },\n \"notificationid\": ID,\n \"persistent\": true,\n \"priority\": 1,\n \"default2fa\": default2fa,\n \"status2fa\" : status2fa,\n \"path\" : path,\n \"timer\": timer, // in seconds\n \"start\": time, // in ms\n \"alarm\": alarm, // in ms\n \"buttons\": [\n {\n \"button1\": {\n \"icon\": \"\",\n \"label\": \"Allow\",\n \"command\": \"2faresponse_true\"\n },\n \n \"button2\": {\n \"icon\": \"\",\n \"label\": \"Deny\",\n \"command\": \"2faresponse_false\"\n }\n \n }\n ]\n};\nmsg.data = body;\nvar x = JSON.stringify(body);\nvar encodedBody = encodeURIComponent(x);\n\nmsg.url = url + \"?key=\" + key + \"&message=\" +command + \"=:=\"+ encodedBody;\nreturn msg;\n\n\n","outputs":1,"noerr":0,"x":620,"y":360,"wires":[["d3f75fc.8c556a"]]},{"id":"d3f75fc.8c556a","type":"http request","z":"b44411e6.28ae6","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":850,"y":360,"wires":[[]]},{"id":"d6bdef4b.09f4b","type":"function","z":"b44411e6.28ae6","name":"Timer","func":"var authentication = flow.get(\"$parent.authentication\");\nvar default2fa = env.get(\"default2fa\");\nvar alarm = flow.get(\"$parent.alarm\");\n\nvar time = new Date();\nvar timeseconds = time.getTime();\n\n//2FA message approved (1)\nif(authentication === \"approved\"){ \n flow.set(\"$parent.authentication\", \"pending\");\n return[msg, null, null];\n}\n\n//2FA message declined (2)\nif(authentication === \"declined\"){\n flow.set(\"$parent.authentication\", \"pending\");\n return[null, msg, null];\n}\n\n//pending for 2FA message (3)\nif(authentication === \"pending\"){\n if(timeseconds < alarm){ //loop\n return[null, null, msg];\n }\n \n if(timeseconds => alarm){\n if(default2fa === true){ // timeout & default approved\n \n return[msg, null, null];\n }\n if(default2fa === false){ // timeout & default declined\n \n return[null, msg, null];\n }\n }\n}","outputs":3,"noerr":0,"x":710,"y":240,"wires":[[],[],["7aedd4b4.d3497c"]]},{"id":"957c5748.7d80c8","type":"tab","label":"2FA","disabled":false,"info":"\n\nTwo Factor Authentication made for NodeRED needs. Control payload flow with an Android prompt. This is best used when the automatic trigger needs a possible human oversight.\n\n - [Complete instructions]([https://notenoughtech.com/home-automation/nodered-home-automation/two-factor-authentication-in-nodered/](https://notenoughtech.com/home-automation/nodered-home-automation/two-factor-authentication-in-nodered/)\n\n\n**Features**:\n- Android Notification\n- Automatic Timeout\n- Custom Default Action\n- Allow/Reject\n- Progress bar\n- Subflow deployment\n\nYou will need the following Android Apps:\n\nDownload a complete Tasker profile from [TaskerNET](https://taskernet.com/shares/?user=AS35m8mukRNi0KvTv9JF6LyKMewcG%2BW7EzpF3a%2FGvwJJTFwWQ1%2BU3QCMEmxTS%2F07urNK%2FTAL&id=Project%3A2FA)\n\n - [Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&hl=en)\n - [AutoNotification](https://play.google.com/store/apps/details?id=com.joaomgcd.autonotification&hl=en)\n - [AutoTools](https://play.google.com/store/apps/details?id=com.joaomgcd.autotools&hl=en)\n - [AutoRemote](https://play.google.com/store/apps/details?id=com.joaomgcd.autoremote&hl=en)\n - [AutoApps](https://play.google.com/store/apps/details?id=com.joaomgcd.autoappshub&hl=en)\n \n This Setup leans on the following guides:\n [Perfect Autonotifications](https://notenoughtech.com/tasker/tasker-projects/tasker-perfect-autonotifications/), [Credentials in NodeRED](https://notenoughtech.com/home-automation/nodered-home-automation/serving-credentials-with-nodered/),\n\n# Settings\n\n - **default2fa** - Default behaviour true|false\n - **timer** - timeout in seconds\n - **AR Device** - name of AutoRemote device served with credential system\n - **title** - title of the notification\n - **text** - text of the notification\n - **2FApath** - path for HTTP request\n - **ID** - unique ID \n "},{"id":"2231f728.d595f8","type":"inject","z":"957c5748.7d80c8","name":"message","topic":"message","payload":"test","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":100,"wires":[["4891f3f2.4e03ac"]]},{"id":"55a0ab1b.bd2e14","type":"debug","z":"957c5748.7d80c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":100,"wires":[]},{"id":"d1c68f7a.c9846","type":"http in","z":"957c5748.7d80c8","name":"","url":"/2fa/test","method":"post","upload":false,"swaggerDoc":"","x":170,"y":240,"wires":[["ca4106fd.8cb2a8","bdcdfdd.c1ec3"]]},{"id":"bdcdfdd.c1ec3","type":"function","z":"957c5748.7d80c8","name":"2FA authenticate","func":"var x = msg.payload.authentication;\n\nif(x === true){\n flow.set(\"authentication\", \"approved\");\n}\nif(x === false){\n flow.set(\"authentication\", \"declined\");\n}\n\n","outputs":1,"noerr":0,"x":370,"y":240,"wires":[[]]},{"id":"ca4106fd.8cb2a8","type":"http response","z":"957c5748.7d80c8","name":"","statusCode":"","headers":{},"x":340,"y":300,"wires":[]},{"id":"4891f3f2.4e03ac","type":"subflow:b44411e6.28ae6","z":"957c5748.7d80c8","name":"","env":[{"name":"timer","value":"30","type":"num"},{"name":"ARdevice","value":"ARmi9","type":"str"},{"name":"title","value":"NodeRED Authentication","type":"str"},{"name":"text","value":"Confirm the action","type":"str"},{"name":"2FApath","value":"/2fa/test","type":"str"},{"name":"ID","value":"ID","type":"str"},{"name":"default","value":"true","type":"bool"},{"name":"path","value":"path","type":"str"}],"x":330,"y":100,"wires":[["55a0ab1b.bd2e14"]]}]