#!/usr/bin/env node var fs=require("fs"), path=require("path"), app=require("express")(), bodyParser=require("body-parser"), crypto=require("crypto"), Persist=require("node-persist"), glob=require("glob"); var HOSTNAME="tomsmeding.com",HTTPPORT=42420; Persist.initSync({}); var challenge=null; function renewChallenge(){ var entropy=crypto.randomBytes(512); var hasher=crypto.createHash("sha256"); hasher.update(entropy); challenge=hasher.digest("hex"); } setInterval(renewChallenge,8000); renewChallenge(); var gencode=(function(){ const startn=42424242; const alphabet="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var lastn=Persist.getItemSync("gencode_lastn"); if(lastn==null)lastn=startn; return function gencode(){ var code="",coden=lastn; while(coden){ code+=alphabet[coden%alphabet.length]; coden=~~(coden/alphabet.length); } if(lastn==0x7fffffff)lastn=0; //maximum value of a 32-bit int else lastn++; Persist.setItemSync("gencode_lastn",lastn); if(lastn==startn)throw new Error("RUN OUT OF INDICES PANIC PANIC"); while(code.length<6)code+="a"; return code; }; })(); app.use(bodyParser.raw({ limit:"3mb", type:"image/*" })); app.use(bodyParser.text({ type:"text/plain" })); app.get("/ss/challenge",function(req,res){ res.end(challenge); }); app.param("userid",function(req,res,next,userid){ var password=Persist.getItemSync("user_"+userid); if(!password){ res.sendStatus(404); res.end("Non-existent userid"); return; } req.ssuser=[userid,password]; next(); }); app.param("authhash",function(req,res,next,authhash){ var s=challenge+req.ssuser[1]; var hasher=crypto.createHash("sha256"); hasher.update(s); var hashres=hasher.digest("hex"); if(hashres!=authhash){ res.sendStatus(403); res.end("Invalid answer to challenge"); return; } next(); }); app.param("fname",function(req,res,next,fname){ req.sscode=gencode(); req.ssfname=req.sscode+"_"+fname.replace(/[\x00-\x1F\/]/g,"").replace(/^\.+/,""); next(); }); app.post("/ss/image/:userid/:authhash/:fname",function(req,res){ try { if(!fs.statSync("images").isDirectory())throw new Error; } catch(e){ fs.mkdirSync("images"); if(!fs.statSync("images").isDirectory())throw new Error; } if(!fs.existsSync("images/"+req.ssuser[0])){ fs.mkdirSync("images/"+req.ssuser[0]); } fs.writeFileSync("images/"+req.ssuser[0]+"/"+req.ssfname,req.body); res.end("https://"+HOSTNAME+"/ss/get/"+req.ssuser[0]+"/"+req.sscode); }); app.param("reguserid",function(req,res,next,reguserid){ req.ssreguserid=reguserid; next(); }); app.post("/ss/registerx/:reguserid",function(req,res){ //pass password in body var password=req.body; if(Persist.getItemSync("user_"+req.ssreguserid)){ res.sendStatus(409); //Conflict res.end("That userid already exists"); return; } Persist.setItemSync("user_"+req.ssreguserid,password); res.sendStatus(200); res.end(); }); app.get("/ss/exists/:reguserid",function(req,res){ res.sendStatus(Persist.getItemSync("user_"+req.ssreguserid)?200:404); res.end(); }); app.get("/ss/checklogin/:userid/:authhash",function(req,res){ res.sendStatus(200); //login checking is done in the authhash param res.end(); }); app.param("ssimgcode",function(req,res,next,ssimgcode){ req.ssimgcode=ssimgcode.replace(/[^a-zA-Z0-9]/g,""); if(req.ssimgcode.length!=6){ res.sendStatus(404); res.end("Invalid or unknown image code"); return; } next(); }); app.get("/ss/get/:userid/:ssimgcode",function(req,res){ var files=glob.sync(__dirname+"/images/"+req.ssuser[0]+"/"+req.ssimgcode+"*"); if(files.length==0){ res.sendStatus(404); res.end("Unknown image code"); return; } if(files.length>1){ console.log("More than one file matched; internal error"); console.log(files); res.sendStatus(500); res.end("More than one file matched; internal error"); return; } res.sendFile(files[0]); }); app.listen(42420,function(){ console.log("Server started."); });