From 6fb4351cafd1abdcc073580f29303f3a6df002f7 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 1 Jan 2020 10:57:19 +0100 Subject: Split up client/server in separate npm packages (1.0.2) --- client.js | 363 ------------------------------ client/client.js | 363 ++++++++++++++++++++++++++++++ client/package-lock.json | 71 ++++++ client/package.json | 28 +++ client/startup.sh | 9 + package-lock.json | 573 ----------------------------------------------- package.json | 31 --- server/package-lock.json | 503 +++++++++++++++++++++++++++++++++++++++++ server/package.json | 28 +++ server/serverstore.js | 161 +++++++++++++ serverstore.js | 161 ------------- startup.sh | 9 - 12 files changed, 1163 insertions(+), 1137 deletions(-) delete mode 100755 client.js create mode 100755 client/client.js create mode 100644 client/package-lock.json create mode 100644 client/package.json create mode 100755 client/startup.sh delete mode 100644 package-lock.json delete mode 100644 package.json create mode 100644 server/package-lock.json create mode 100644 server/package.json create mode 100755 server/serverstore.js delete mode 100755 serverstore.js delete mode 100755 startup.sh diff --git a/client.js b/client.js deleted file mode 100755 index efd721c..0000000 --- a/client.js +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/env node - -var fs=require("fs"), - path=require("path"), - https=require("https"), - crypto=require("crypto"), - read=require("read"), - toClipboard=require("to-clipboard"), - notifier=require("node-notifier"); - -var HOSTNAME=process.argv[2]||"tomsmeding.com",HTTPSPORT=443; -console.log("Using server "+HOSTNAME); - - -var lockfiledesc; -var lockfilename="/tmp/.lock_serverstore_client_"+HOSTNAME; -try {lockfiledesc=fs.openSync(lockfilename,"wx");} -catch(e){ - var lockedpid=+fs.readFileSync(lockfilename); - var canoverwrite=false; - if(isNaN(lockedpid))canoverwrite=true; - try {process.kill(lockedpid,0);} - catch(e){canoverwrite=true;} - if(!canoverwrite){ - console.log("Another copy of the serverstore client with the same hostname seems to be running."); - console.log("If this is not the case, or intentional, delete the file "+lockfilename+" and try again."); - process.exit(1); - } - lockfiledesc=fs.openSync(lockfilename,"w"); -} -fs.writeSync(lockfiledesc,process.pid+"\n"); -process.on("exit",function(){ - fs.closeSync(lockfiledesc); - fs.unlinkSync(lockfilename); -}); - - -var userid="0",password="-"; - - -var HOMEDIR=process.env.HOME||process.env.HOMEPATH||process.env.HOMEDIR||process.cwd(); -var WATCHDIR; -if(process.platform=="darwin"){ - WATCHDIR=HOMEDIR+"/Desktop"; -} else { - WATCHDIR=HOMEDIR+"/screenshots"; -} -var ignored=[]; - -var currentState=[]; - -function notify(message) { - notifier.notify({ - title: "serverstore", - message: message, - }); -} - -//lots of code taken/modified from tomsmeding/gvajnez -function collectDirState(dir){ - if(!dir)dir=directory; - //console.log("collectDirState("+dir+")"); - var list=fs.readdirSync(dir); - var result=[]; - var statinfo,i,j; - for(i=0;i60||(now-namedate)/1000>60)continue; //1 minute limit - setTimeout(function(n){ - return function(){sendfile(n);}; - }(changes[i].name),100); - } -} - -function authhash(challenge,password){ - var s=challenge+password; - var hasher=crypto.createHash("sha256"); - hasher.update(s); - return hasher.digest("hex"); -} - -function getchallenge(cb){ - console.log("Going to request challenge..."); - var req=https.request({ - hostname:HOSTNAME, - port:HTTPSPORT, - path:"/ss/challenge", - method:"GET", - keepAlive:true //speed up the next request - },function(res){ - var body=""; - res.on("data",function(data){ - body+=data; - }); - res.on("end",function(){ - if(res.statusCode!=200){ - notify("Could not request challenge! Is your internet connection alive?\n"+body); - return; - } - console.log("challenge = "+body); - cb(body); - }); - }); - req.on("error",function(err){ - console.log(err); - }); - req.end(); -} -function sendfile(fname,retries){ - retries=retries!=null?retries:3; - var barefname; - var idx=fname.lastIndexOf("/"); - if(idx==-1)barefname=fname; - else barefname=fname.slice(idx+1); - getchallenge(function(challenge){ - var req=https.request({ - hostname:HOSTNAME, - port:HTTPSPORT, - path:"/ss/image/"+userid+"/"+authhash(challenge,password)+"/"+escape(barefname), - method:"POST", - headers:{ - "Content-Type":"image/png" - } - },function(res){ - var body=""; - res.on("data",function(data){ - body+=data; - }); - res.on("end",function(){ - if(res.statusCode!=200){ - if(retries>0)sendfile(fname,retries-1); - else notify("Could not upload image! Are your credentials still okay?\n"+body); - return; - } - console.log("Successful upload"); - toClipboard.sync(body.trim()); - notify("Uploaded, link copied"); - try { - fs.unlinkSync(fname); - } catch(e){ - console.log(e); - } - }); - }); - req.on("error",function(err){ - console.log(err); - }); - try{req.end(fs.readFileSync(fname));} - catch(e){console.log(e);} - }); -} - - -function userExists(userid,cb){ - var req=https.request({ - hostname:HOSTNAME, - port:HTTPSPORT, - path:"/ss/exists/"+userid, - method:"GET" - },function(res){ - if(res.statusCode==200)cb(true); - else if(res.statusCode==404)cb(false); - else { - console.log("Server returned status code "+res.statusCode+" for exists query!"); - } - }); - req.on("error",function(err){ - console.log(err); - }); - req.end(); -} - -function checkLogin(userid,password,cb,retries){ - retries=retries!=null?retries:3; - getchallenge(function(challenge){ - var req=https.request({ - hostname:HOSTNAME, - port:HTTPSPORT, - path:"/ss/checklogin/"+userid+"/"+authhash(challenge,password), - method:"GET" - },function(res){ - if(res.statusCode==200)cb(true); - else if(res.statusCode==404||res.statusCode==403){ - if(retries>0)checkLogin(userid,password,cb,retries-1); - else cb(false); - } else { - console.log("Server returned status code "+res.statusCode+" for checklogin query!"); - } - }); - req.on("error",function(err){ - console.log(err); - }); - req.end(); - }); -} - -function registerUser(userid,password){ - var req=https.request({ - hostname:HOSTNAME, - port:HTTPSPORT, - path:"/ss/registerx/"+userid, - method:"POST", - headers:{ - "Content-Type":"text/plain" - } - },function(res){ - var body=""; - res.on("data",function(data){ - body+=data; - }); - res.on("end",function(){ - if(res.statusCode==200)console.log("Successfully registered user "+userid); - else if(res.statusCode==409)console.log("Conflict: "+body); - else console.log("Error: "+body); - }); - }); - req.on("error",function(err){ - console.log(err); - }); - req.end(password); -} - -var stdinFD = null; -if (!process.stdin.isTTY) { - stdinFD = fs.openSync("/dev/stdin", "r"); -} - -function readStdinLine(options, callback) { - console.log("Entering read with " + JSON.stringify(options)); - if (stdinFD) { - var input = "", buf = Buffer.alloc(1), ch; - while (true) { - if (fs.readSync(stdinFD, buf, 0, 1, null) < 1) { - console.log("Error reading from stdin"); - process.exit(1); - } - ch = buf.toString() - if (ch == "\n") break; - input += ch; - } - callback(input); - } else { - read(options, function(err, res) { - console.log("Returned from read with " + JSON.stringify(options)); - if (err) { - console.log("Error reading from stdin: " + err); - process.exit(1); - } - callback(res); - }); - } -} - -function readUserPass(callback) { - readStdinLine({prompt: "Username? "}, function(res) { - userid = res; - - readStdinLine({prompt: "Password? ", silent: true}, function(passinput) { - var hasher = crypto.createHash("sha256"); - hasher.update(passinput); - password = hasher.digest("hex"); - - callback(); - }); - }); -} - - - -readUserPass(function() { - console.log("\nChecking existence..."); - - userExists(userid,function(exists){ - if(exists){ - checkLogin(userid,password,function(ok){ - if(ok)console.log("User login ok."); - else { - console.log("Username or password incorrect!"); - process.exit(); - } - }); - return; - } - readStdinLine({prompt: "That username doesn't seem to exist. Register it? [y/N] "}, function(response) { - response = response[0]; - if(response=="y"||response=="Y")registerUser(userid,password); - else { - console.log("Not registered. Exiting."); - process.exit(); - } - }); - }); - - var timeout=null; - var watcher=fs.watch(WATCHDIR,{persistent:true,recursive:false},function(ev,fname){ - //console.log("change in directory "+WATCHDIR+" (fname "+fname+")"); - if(timeout)return; - timeout=setTimeout(function(){ - var newstate=collectDirState(WATCHDIR); - var changes=collectChanges(WATCHDIR,newstate).map(function(o){o.name=o.name.replace(/^\.\//,"");return o;}); - currentState=newstate; - if(changes.length!=0)handleChanges(changes); - timeout=null; - //console.log(currentState); - },500); - }); - currentState=collectDirState(WATCHDIR); - console.log("-- (Client ready.)"); -}); diff --git a/client/client.js b/client/client.js new file mode 100755 index 0000000..efd721c --- /dev/null +++ b/client/client.js @@ -0,0 +1,363 @@ +#!/usr/bin/env node + +var fs=require("fs"), + path=require("path"), + https=require("https"), + crypto=require("crypto"), + read=require("read"), + toClipboard=require("to-clipboard"), + notifier=require("node-notifier"); + +var HOSTNAME=process.argv[2]||"tomsmeding.com",HTTPSPORT=443; +console.log("Using server "+HOSTNAME); + + +var lockfiledesc; +var lockfilename="/tmp/.lock_serverstore_client_"+HOSTNAME; +try {lockfiledesc=fs.openSync(lockfilename,"wx");} +catch(e){ + var lockedpid=+fs.readFileSync(lockfilename); + var canoverwrite=false; + if(isNaN(lockedpid))canoverwrite=true; + try {process.kill(lockedpid,0);} + catch(e){canoverwrite=true;} + if(!canoverwrite){ + console.log("Another copy of the serverstore client with the same hostname seems to be running."); + console.log("If this is not the case, or intentional, delete the file "+lockfilename+" and try again."); + process.exit(1); + } + lockfiledesc=fs.openSync(lockfilename,"w"); +} +fs.writeSync(lockfiledesc,process.pid+"\n"); +process.on("exit",function(){ + fs.closeSync(lockfiledesc); + fs.unlinkSync(lockfilename); +}); + + +var userid="0",password="-"; + + +var HOMEDIR=process.env.HOME||process.env.HOMEPATH||process.env.HOMEDIR||process.cwd(); +var WATCHDIR; +if(process.platform=="darwin"){ + WATCHDIR=HOMEDIR+"/Desktop"; +} else { + WATCHDIR=HOMEDIR+"/screenshots"; +} +var ignored=[]; + +var currentState=[]; + +function notify(message) { + notifier.notify({ + title: "serverstore", + message: message, + }); +} + +//lots of code taken/modified from tomsmeding/gvajnez +function collectDirState(dir){ + if(!dir)dir=directory; + //console.log("collectDirState("+dir+")"); + var list=fs.readdirSync(dir); + var result=[]; + var statinfo,i,j; + for(i=0;i60||(now-namedate)/1000>60)continue; //1 minute limit + setTimeout(function(n){ + return function(){sendfile(n);}; + }(changes[i].name),100); + } +} + +function authhash(challenge,password){ + var s=challenge+password; + var hasher=crypto.createHash("sha256"); + hasher.update(s); + return hasher.digest("hex"); +} + +function getchallenge(cb){ + console.log("Going to request challenge..."); + var req=https.request({ + hostname:HOSTNAME, + port:HTTPSPORT, + path:"/ss/challenge", + method:"GET", + keepAlive:true //speed up the next request + },function(res){ + var body=""; + res.on("data",function(data){ + body+=data; + }); + res.on("end",function(){ + if(res.statusCode!=200){ + notify("Could not request challenge! Is your internet connection alive?\n"+body); + return; + } + console.log("challenge = "+body); + cb(body); + }); + }); + req.on("error",function(err){ + console.log(err); + }); + req.end(); +} +function sendfile(fname,retries){ + retries=retries!=null?retries:3; + var barefname; + var idx=fname.lastIndexOf("/"); + if(idx==-1)barefname=fname; + else barefname=fname.slice(idx+1); + getchallenge(function(challenge){ + var req=https.request({ + hostname:HOSTNAME, + port:HTTPSPORT, + path:"/ss/image/"+userid+"/"+authhash(challenge,password)+"/"+escape(barefname), + method:"POST", + headers:{ + "Content-Type":"image/png" + } + },function(res){ + var body=""; + res.on("data",function(data){ + body+=data; + }); + res.on("end",function(){ + if(res.statusCode!=200){ + if(retries>0)sendfile(fname,retries-1); + else notify("Could not upload image! Are your credentials still okay?\n"+body); + return; + } + console.log("Successful upload"); + toClipboard.sync(body.trim()); + notify("Uploaded, link copied"); + try { + fs.unlinkSync(fname); + } catch(e){ + console.log(e); + } + }); + }); + req.on("error",function(err){ + console.log(err); + }); + try{req.end(fs.readFileSync(fname));} + catch(e){console.log(e);} + }); +} + + +function userExists(userid,cb){ + var req=https.request({ + hostname:HOSTNAME, + port:HTTPSPORT, + path:"/ss/exists/"+userid, + method:"GET" + },function(res){ + if(res.statusCode==200)cb(true); + else if(res.statusCode==404)cb(false); + else { + console.log("Server returned status code "+res.statusCode+" for exists query!"); + } + }); + req.on("error",function(err){ + console.log(err); + }); + req.end(); +} + +function checkLogin(userid,password,cb,retries){ + retries=retries!=null?retries:3; + getchallenge(function(challenge){ + var req=https.request({ + hostname:HOSTNAME, + port:HTTPSPORT, + path:"/ss/checklogin/"+userid+"/"+authhash(challenge,password), + method:"GET" + },function(res){ + if(res.statusCode==200)cb(true); + else if(res.statusCode==404||res.statusCode==403){ + if(retries>0)checkLogin(userid,password,cb,retries-1); + else cb(false); + } else { + console.log("Server returned status code "+res.statusCode+" for checklogin query!"); + } + }); + req.on("error",function(err){ + console.log(err); + }); + req.end(); + }); +} + +function registerUser(userid,password){ + var req=https.request({ + hostname:HOSTNAME, + port:HTTPSPORT, + path:"/ss/registerx/"+userid, + method:"POST", + headers:{ + "Content-Type":"text/plain" + } + },function(res){ + var body=""; + res.on("data",function(data){ + body+=data; + }); + res.on("end",function(){ + if(res.statusCode==200)console.log("Successfully registered user "+userid); + else if(res.statusCode==409)console.log("Conflict: "+body); + else console.log("Error: "+body); + }); + }); + req.on("error",function(err){ + console.log(err); + }); + req.end(password); +} + +var stdinFD = null; +if (!process.stdin.isTTY) { + stdinFD = fs.openSync("/dev/stdin", "r"); +} + +function readStdinLine(options, callback) { + console.log("Entering read with " + JSON.stringify(options)); + if (stdinFD) { + var input = "", buf = Buffer.alloc(1), ch; + while (true) { + if (fs.readSync(stdinFD, buf, 0, 1, null) < 1) { + console.log("Error reading from stdin"); + process.exit(1); + } + ch = buf.toString() + if (ch == "\n") break; + input += ch; + } + callback(input); + } else { + read(options, function(err, res) { + console.log("Returned from read with " + JSON.stringify(options)); + if (err) { + console.log("Error reading from stdin: " + err); + process.exit(1); + } + callback(res); + }); + } +} + +function readUserPass(callback) { + readStdinLine({prompt: "Username? "}, function(res) { + userid = res; + + readStdinLine({prompt: "Password? ", silent: true}, function(passinput) { + var hasher = crypto.createHash("sha256"); + hasher.update(passinput); + password = hasher.digest("hex"); + + callback(); + }); + }); +} + + + +readUserPass(function() { + console.log("\nChecking existence..."); + + userExists(userid,function(exists){ + if(exists){ + checkLogin(userid,password,function(ok){ + if(ok)console.log("User login ok."); + else { + console.log("Username or password incorrect!"); + process.exit(); + } + }); + return; + } + readStdinLine({prompt: "That username doesn't seem to exist. Register it? [y/N] "}, function(response) { + response = response[0]; + if(response=="y"||response=="Y")registerUser(userid,password); + else { + console.log("Not registered. Exiting."); + process.exit(); + } + }); + }); + + var timeout=null; + var watcher=fs.watch(WATCHDIR,{persistent:true,recursive:false},function(ev,fname){ + //console.log("change in directory "+WATCHDIR+" (fname "+fname+")"); + if(timeout)return; + timeout=setTimeout(function(){ + var newstate=collectDirState(WATCHDIR); + var changes=collectChanges(WATCHDIR,newstate).map(function(o){o.name=o.name.replace(/^\.\//,"");return o;}); + currentState=newstate; + if(changes.length!=0)handleChanges(changes); + timeout=null; + //console.log(currentState); + },500); + }); + currentState=collectDirState(WATCHDIR); + console.log("-- (Client ready.)"); +}); diff --git a/client/package-lock.json b/client/package-lock.json new file mode 100644 index 0000000..fb70d66 --- /dev/null +++ b/client/package-lock.json @@ -0,0 +1,71 @@ +{ + "name": "serverstore-client", + "version": "1.0.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "to-clipboard": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/to-clipboard/-/to-clipboard-0.4.0.tgz", + "integrity": "sha1-pSpX+KTVZlVK8LKz++KUM6tH2oI=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } +} diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..34084df --- /dev/null +++ b/client/package.json @@ -0,0 +1,28 @@ +{ + "name": "serverstore-client", + "version": "1.0.2", + "description": "A Puush alternative", + "main": "client.js", + "repository": { + "type": "git", + "url": "https://git.tomsmeding.com/serverstore" + }, + "dependencies": { + "node-notifier": "^5.4.0", + "read": "^1.0.7", + "to-clipboard": "~0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "image", + "hosting", + "server", + "client", + "screenshot" + ], + "author": "Tom Smeding (https://tomsmeding.com)", + "license": "MIT" +} diff --git a/client/startup.sh b/client/startup.sh new file mode 100755 index 0000000..a9ee756 --- /dev/null +++ b/client/startup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +cd "$(dirname "$0")" + +echo "Enter username \n password \n" +IFS="" read username +IFS="" read -s password +printf "%s\n%s\n" "$username" "$password" | nohup ./client.js >client.out 2>&1 & +echo $! +disown diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index ab94d5b..0000000 --- a/package-lock.json +++ /dev/null @@ -1,573 +0,0 @@ -{ - "name": "serverstore", - "version": "1.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" - }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "requires": { - "is-relative": "^0.2.1", - "is-windows": "^0.2.0" - } - }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "requires": { - "is-unc-path": "^0.1.1" - } - }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "requires": { - "unc-path-regex": "^0.1.0" - } - }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "node-notifier": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", - "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", - "requires": { - "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "node-persist": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz", - "integrity": "sha1-5lK784haBNrWo1PXQXYXfIORRwc=", - "requires": { - "is-absolute": "^0.2.6", - "mkdirp": "~0.5.1", - "q": "~1.1.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "q": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz", - "integrity": "sha1-Y1fikSBnAdmfGXq4TlforRlvKok=" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "requires": { - "mute-stream": "~0.0.4" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "to-clipboard": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/to-clipboard/-/to-clipboard-0.4.0.tgz", - "integrity": "sha1-pSpX+KTVZlVK8LKz++KUM6tH2oI=" - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 21d7d74..0000000 --- a/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "serverstore", - "version": "1.0.1", - "description": "A Puush alternative", - "main": "serverstore.js", - "repository": { - "type": "git", - "url": "https://git.tomsmeding.com/serverstore" - }, - "dependencies": { - "body-parser": "^1.19.0", - "express": "^4.17.1", - "glob": "^5.0.15", - "node-notifier": "^5.4.0", - "node-persist": "^2.1.0", - "read": "^1.0.7", - "to-clipboard": "~0" - }, - "devDependencies": {}, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [ - "image", - "hosting", - "server", - "screenshot" - ], - "author": "Tom Smeding (https://tomsmeding.com)", - "license": "MIT" -} diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..5ab5b85 --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,503 @@ +{ + "name": "serverstore-server", + "version": "1.0.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "requires": { + "is-relative": "^0.2.1", + "is-windows": "^0.2.0" + } + }, + "is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "requires": { + "is-unc-path": "^0.1.1" + } + }, + "is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "requires": { + "unc-path-regex": "^0.1.0" + } + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "requires": { + "mime-db": "1.42.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-persist": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz", + "integrity": "sha1-5lK784haBNrWo1PXQXYXfIORRwc=", + "requires": { + "is-absolute": "^0.2.6", + "mkdirp": "~0.5.1", + "q": "~1.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "q": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz", + "integrity": "sha1-Y1fikSBnAdmfGXq4TlforRlvKok=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..b46ba8f --- /dev/null +++ b/server/package.json @@ -0,0 +1,28 @@ +{ + "name": "serverstore-server", + "version": "1.0.2", + "description": "A Puush alternative", + "main": "serverstore.js", + "repository": { + "type": "git", + "url": "https://git.tomsmeding.com/serverstore" + }, + "dependencies": { + "body-parser": "^1.19.0", + "express": "^4.17.1", + "glob": "^5.0.15", + "node-persist": "^2.1.0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "image", + "hosting", + "server", + "screenshot" + ], + "author": "Tom Smeding (https://tomsmeding.com)", + "license": "MIT" +} diff --git a/server/serverstore.js b/server/serverstore.js new file mode 100755 index 0000000..1d04530 --- /dev/null +++ b/server/serverstore.js @@ -0,0 +1,161 @@ +#!/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."); +}); diff --git a/serverstore.js b/serverstore.js deleted file mode 100755 index 1d04530..0000000 --- a/serverstore.js +++ /dev/null @@ -1,161 +0,0 @@ -#!/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."); -}); diff --git a/startup.sh b/startup.sh deleted file mode 100755 index a9ee756..0000000 --- a/startup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -cd "$(dirname "$0")" - -echo "Enter username \n password \n" -IFS="" read username -IFS="" read -s password -printf "%s\n%s\n" "$username" "$password" | nohup ./client.js >client.out 2>&1 & -echo $! -disown -- cgit v1.2.3