From 848db6a4e3f7091dc4a2e20dcae47f6669801e99 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 29 Oct 2016 23:21:32 +0200 Subject: todo: Introducing multi-user TODO! --- modules/todo/todo.js | 121 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 15 deletions(-) (limited to 'modules/todo/todo.js') diff --git a/modules/todo/todo.js b/modules/todo/todo.js index 9e53c76..58322f2 100644 --- a/modules/todo/todo.js +++ b/modules/todo/todo.js @@ -3,7 +3,11 @@ // {"key":"tasks","value":[{"id":1,"subject":"kaas rep","repweeks":0,"date":"2016-10-25T07:46:54.493Z"},{"id":2,"subject":"kaas","repweeks":0,"date":"2016-10-27T07:46:54.493Z"}]} var cmn=require("../$common.js"), - persist=require("node-persist"); + persist=require("node-persist"), + bcrypt=require("bcrypt"), + basicAuth=require("basic-auth"); + +var bcryptHashRounds=10; var moddir=null; @@ -14,45 +18,132 @@ persist=persist.create({ }); persist.initSync(); -//tasks: [{id: Int,subject: String,repweeks: Int,date: Date}] +//tasks: {"user": [{id: Int,subject: String,repweeks: Int,date: Date}]} +//accounts: {"user": hash (String)} //repweeks==0 implies no repetition var nextid=persist.getItemSync("nextid"); -if(nextid==null)nextid=1; +if(nextid==null){ + nextid=1; + persist.setItemSync("nextid",nextid); +} var tasks=persist.getItemSync("tasks"); (function(){ - if(!tasks){ - tasks=[]; + if(tasks==null){ + tasks={}; persist.setItemSync("tasks",tasks); } else { - for(var task of tasks){ - task.date=new Date(task.date); - if(nextid<=task.id)nextid=task.id+1; + for(var user in tasks){ + for(var task of tasks[user]){ + task.date=new Date(task.date); + if(nextid<=task.id)nextid=task.id+1; + } } persist.setItemSync("nextid",nextid); } })(); +var accounts=persist.getItemSync("accounts"); +if(accounts==null){ + accounts={}; + persist.setItemSync("accounts",accounts); +} + + +function sendUnauth(res){ + res.set("WWW-Authenticate","Basic realm=Authorization required"); + return res.sendStatus(401); +} + +function unknownUserHandler(req,res,next){ + res.sendFile(moddir+"/unknownuser.html"); +} + +function authMiddleware(req,res,next){ + var user=basicAuth(req); + req.authuser=null; + if(!user||!user.name){ + sendUnauth(res); + return; + } + req.authuser=user.name; + if(accounts[req.authuser]){ + bcrypt.compare(user.pass,accounts[req.authuser],function(err,ok){ + if(ok)next(); + else sendUnauth(res); + }); + } else { + unknownUserHandler(req,res,next); + } +} + +function asciiValid(str){ + var i,c; + for(i=0;i=127)return false; + } + return true; +} module.exports=function(app,io,_moddir){ moddir=_moddir; - app.all("/todo/task",cmn.authgen()); + + //first the endpoints that need to bypass authMiddleware + app.get("/todo/authfail",function(req,res){ + sendUnauth(res); + }); + app.post("/todo/createuser",function(req,res){ + var user=basicAuth(req); + if(!user||!user.name){ + res.status(400).send("No credentials sent"); + return; + } + if(user.name.length<3||user.name.length>32||!asciiValid(user.name)){ + res.status(400).send("Invalid username"); + return; + } + if(user.pass.length<3||user.pass.length>32||!asciiValid(user.pass)){ + res.status(400).send("Invalid password"); + return; + } + if(accounts[user.name]){ + res.status(400).send("User already exists"); + return; + } + bcrypt.hash(user.pass,bcryptHashRounds,function(err,hash){ + if(!hash){ + res.status(500).send("Something went wrong..."); + console.log(err); + return; + } + accounts[user.name]=hash; + tasks[user.name]=[]; + persist.setItemSync("accounts",accounts); + persist.setItemSync("tasks",tasks); + res.status(200).end(); + }); + }); + + app.all(["/todo","/todo/*"],authMiddleware); //for all the other endpoints + app.get("/todo",function(req,res){ res.sendFile(moddir+"/todo.html"); }); app.get("/todo/list",function(req,res){ - res.json(tasks); + res.json(tasks[req.authuser]); }); app.delete("/todo/task",function(req,res){ var id=+req.body; var i; var fail=false; - if(id<0||~~id!=id||isNaN(id)){ + var usertasks=tasks[req.authuser]; + if(id<0||~~id!=id||isNaN(id)||!usertasks){ fail=true; } else { - for(i=0;i