using handlebars templating engine, refactored server code and storage code
This commit is contained in:
parent
1ad71904bc
commit
f9c2eb1ae4
|
@ -14,6 +14,16 @@
|
|||
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
|
||||
"dev": true
|
||||
},
|
||||
"align-text": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
|
||||
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc="
|
||||
},
|
||||
"amdefine": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
|
@ -79,6 +89,11 @@
|
|||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||
"dev": true
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
|
||||
"integrity": "sha1-UidltQw1EEkOUtfc/ghe+bqWlY8="
|
||||
},
|
||||
"asn1.js": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
|
||||
|
@ -103,6 +118,11 @@
|
|||
"integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=",
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
||||
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
|
||||
},
|
||||
"async-each": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
||||
|
@ -146,8 +166,7 @@
|
|||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.2.0",
|
||||
|
@ -174,8 +193,7 @@
|
|||
"brace-expansion": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
|
||||
"integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k="
|
||||
},
|
||||
"braces": {
|
||||
"version": "1.8.5",
|
||||
|
@ -300,9 +318,9 @@
|
|||
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM="
|
||||
},
|
||||
"bytes": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
|
||||
"integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
|
||||
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo="
|
||||
},
|
||||
"cached-path-relative": {
|
||||
"version": "1.0.1",
|
||||
|
@ -310,6 +328,18 @@
|
|||
"integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
|
||||
"integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
|
||||
"optional": true
|
||||
},
|
||||
"center-align": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
||||
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
|
||||
"optional": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
|
@ -328,17 +358,29 @@
|
|||
"integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
|
||||
"integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"wordwrap": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
|
||||
"integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
|
||||
"integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o="
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz",
|
||||
"integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0="
|
||||
},
|
||||
"combine-source-map": {
|
||||
"version": "0.7.2",
|
||||
|
@ -349,8 +391,7 @@
|
|||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.5.2",
|
||||
|
@ -522,6 +563,17 @@
|
|||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
|
||||
"integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4="
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||
"optional": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
|
||||
"integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ="
|
||||
},
|
||||
"defined": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
||||
|
@ -676,6 +728,18 @@
|
|||
"resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz",
|
||||
"integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI="
|
||||
},
|
||||
"express-handlebars": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz",
|
||||
"integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=",
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
|
||||
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extglob": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
|
||||
|
@ -717,6 +781,11 @@
|
|||
"integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
|
||||
"dev": true
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
|
||||
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
|
||||
|
@ -1436,8 +1505,7 @@
|
|||
"function-bind": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
|
||||
"integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=",
|
||||
"dev": true
|
||||
"integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E="
|
||||
},
|
||||
"get-stdin": {
|
||||
"version": "5.0.1",
|
||||
|
@ -1468,6 +1536,18 @@
|
|||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
|
||||
"integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
|
||||
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s="
|
||||
}
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
|
||||
|
@ -1534,8 +1614,7 @@
|
|||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
|
@ -1568,8 +1647,7 @@
|
|||
"is-buffer": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
|
||||
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
|
||||
"dev": true
|
||||
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
|
||||
},
|
||||
"is-dotfile": {
|
||||
"version": "1.0.3",
|
||||
|
@ -1710,8 +1788,7 @@
|
|||
"kind-of": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ="
|
||||
},
|
||||
"labeled-stream-splicer": {
|
||||
"version": "2.0.0",
|
||||
|
@ -1719,6 +1796,12 @@
|
|||
"integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=",
|
||||
"dev": true
|
||||
},
|
||||
"lazy-cache": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
|
||||
"integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
|
||||
"optional": true
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
|
@ -1742,10 +1825,15 @@
|
|||
"integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=",
|
||||
"dev": true
|
||||
},
|
||||
"longest": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
||||
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.0.tgz",
|
||||
"integrity": "sha512-aHGs865JXz6bkB4AHL+3AhyvTFKL3iZamKVWjIUKnXOXyasJvqPK8WAjOnAQKQZVpeXDVz19u1DD0r/12bWAdQ==",
|
||||
"integrity": "sha1-Wb5JpoO42YapOfHKYP22mJ9LIEY=",
|
||||
"dev": true
|
||||
},
|
||||
"media-typer": {
|
||||
|
@ -1805,8 +1893,7 @@
|
|||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true
|
||||
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
|
@ -1860,7 +1947,7 @@
|
|||
"node-fetch": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz",
|
||||
"integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ=="
|
||||
"integrity": "sha1-iZyz0KPJL5UsR/G4dvTIrqvUANU="
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "2.1.1",
|
||||
|
@ -1868,6 +1955,16 @@
|
|||
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
||||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
|
||||
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
|
||||
},
|
||||
"object.assign": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
|
||||
"integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw="
|
||||
},
|
||||
"object.omit": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
||||
|
@ -1882,8 +1979,19 @@
|
|||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
|
||||
},
|
||||
"optimist": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||
}
|
||||
}
|
||||
},
|
||||
"os-browserify": {
|
||||
"version": "0.1.2",
|
||||
|
@ -1940,8 +2048,7 @@
|
|||
"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=",
|
||||
"dev": true
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.5",
|
||||
|
@ -2003,6 +2110,11 @@
|
|||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"dev": true
|
||||
},
|
||||
"promise": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
|
||||
"integrity": "sha1-SJZUxpJha4qlWwck+oCbt9tJxb8="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz",
|
||||
|
@ -2157,8 +2269,7 @@
|
|||
"repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
|
||||
"dev": true
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.3.3",
|
||||
|
@ -2166,6 +2277,12 @@
|
|||
"integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=",
|
||||
"dev": true
|
||||
},
|
||||
"right-align": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
|
||||
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
|
||||
"optional": true
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
|
||||
|
@ -2237,8 +2354,7 @@
|
|||
"source-map": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
|
||||
"dev": true
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.3.1",
|
||||
|
@ -2444,6 +2560,18 @@
|
|||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "2.8.28",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.28.tgz",
|
||||
"integrity": "sha512-WqKNbmNJKzIdIEQu/U2ytgGBbhCy2PVks94GoetczOAJ/zCgVu2CuO7gguI5KPFGPtUtI1dmPQl6h0D4cPzypA==",
|
||||
"optional": true
|
||||
},
|
||||
"uglify-to-browserify": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
|
||||
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
|
||||
"optional": true
|
||||
},
|
||||
"umd": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz",
|
||||
|
@ -2525,11 +2653,21 @@
|
|||
"integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
|
||||
"dev": true
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
|
||||
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
|
||||
"optional": true
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.17",
|
||||
|
@ -2552,6 +2690,12 @@
|
|||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
|
||||
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
"dependencies": {
|
||||
"aws-sdk": "^2.62.0",
|
||||
"body-parser": "^1.17.2",
|
||||
"bytes": "^2.5.0",
|
||||
"color-convert": "^1.9.0",
|
||||
"connect-busboy": "0.0.2",
|
||||
"convict": "^3.0.0",
|
||||
"express": "^4.15.3",
|
||||
"express-handlebars": "^3.0.0",
|
||||
"fs-extra": "^3.0.1",
|
||||
"node-fetch": "^1.7.1",
|
||||
"path": "^0.12.7",
|
||||
|
@ -16,6 +19,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^14.4.0",
|
||||
"buffer-shims": "^1.0.0",
|
||||
"cross-env": "^5.0.0",
|
||||
"prettier": "^1.3.1",
|
||||
"watchify": "^3.9.0"
|
||||
|
|
|
@ -1,36 +1,50 @@
|
|||
const express = require('express');
|
||||
const exphbs = require('express-handlebars');
|
||||
const busboy = require('connect-busboy');
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const bodyParser = require('body-parser');
|
||||
const crypto = require('crypto');
|
||||
const conf = require('./config.js');
|
||||
const stream = require('stream');
|
||||
const fetch = require('node-fetch');
|
||||
const bytes = require('bytes');
|
||||
const conf = require('./config.js');
|
||||
const storage = require('./storage.js');
|
||||
|
||||
let isProduction =
|
||||
let notLocalHost =
|
||||
conf.env === 'production' &&
|
||||
conf.s3_bucket !== 'localhost' &&
|
||||
conf.bitly_key !== 'localhost';
|
||||
|
||||
const AWS = require('aws-sdk');
|
||||
const s3 = new AWS.S3();
|
||||
|
||||
const app = express();
|
||||
const redis = require('redis');
|
||||
const redis_client = redis.createClient();
|
||||
|
||||
redis_client.on('error', err => {
|
||||
console.log(err);
|
||||
});
|
||||
app.engine('handlebars', exphbs({ defaultLayout: 'main' }));
|
||||
app.set('view engine', 'handlebars');
|
||||
|
||||
app.use(busboy());
|
||||
app.use(bodyParser.json());
|
||||
|
||||
app.use(express.static(path.join(__dirname, '../public')));
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.render('index');
|
||||
});
|
||||
|
||||
app.get('/download/:id', (req, res) => {
|
||||
res.sendFile(path.join(__dirname + '/../public/download.html'));
|
||||
let id = req.params.id;
|
||||
storage.filename(id).then(filename => {
|
||||
storage
|
||||
.length(id)
|
||||
.then(contentLength => {
|
||||
res.render('download', {
|
||||
filename: filename,
|
||||
filesize: bytes(contentLength)
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
res.render('download');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/assets/download/:id', (req, res) => {
|
||||
|
@ -40,10 +54,9 @@ app.get('/assets/download/:id', (req, res) => {
|
|||
return;
|
||||
}
|
||||
|
||||
redis_client.hget(id, 'filename', (err, reply) => {
|
||||
if (!reply) {
|
||||
res.sendStatus(404);
|
||||
} else {
|
||||
storage
|
||||
.filename(id)
|
||||
.then(reply => {
|
||||
storage.length(id).then(contentLength => {
|
||||
res.writeHead(200, {
|
||||
'Content-Disposition': 'attachment; filename=' + reply,
|
||||
|
@ -54,8 +67,8 @@ app.get('/assets/download/:id', (req, res) => {
|
|||
|
||||
let file_stream = storage.get(id);
|
||||
|
||||
file_stream.on('close', () => {
|
||||
storage.forceDelete(id, redis_client).then(err => {
|
||||
file_stream.on(notLocalHost ? 'finish' : 'close', () => {
|
||||
storage.forceDelete(id).then(err => {
|
||||
if (!err) {
|
||||
console.log('Deleted.');
|
||||
}
|
||||
|
@ -63,8 +76,10 @@ app.get('/assets/download/:id', (req, res) => {
|
|||
});
|
||||
|
||||
file_stream.pipe(res);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
res.sendStatus(404);
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/delete/:id', (req, res) => {
|
||||
|
@ -82,10 +97,10 @@ app.post('/delete/:id', (req, res) => {
|
|||
}
|
||||
|
||||
storage
|
||||
.delete(id, redis_client, delete_token)
|
||||
.delete(id, delete_token)
|
||||
.then(err => {
|
||||
if (!err) {
|
||||
console.log('Deleted off s3.');
|
||||
console.log('Deleted.');
|
||||
}
|
||||
})
|
||||
.catch(err => res.sendStatus(404));
|
||||
|
@ -102,11 +117,9 @@ app.post('/upload/:id', (req, res, next) => {
|
|||
console.log('Uploading: ' + filename);
|
||||
let url = `${req.protocol}://${req.get('host')}/download/${req.params.id}/`;
|
||||
|
||||
storage
|
||||
.set(req.params.id, file, filename, redis_client, url)
|
||||
.then(linkAndID => {
|
||||
res.json(linkAndID);
|
||||
});
|
||||
storage.set(req.params.id, file, filename, url).then(linkAndID => {
|
||||
res.json(linkAndID);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,30 +7,51 @@ const path = require('path');
|
|||
const fetch = require('node-fetch');
|
||||
const crypto = require('crypto');
|
||||
|
||||
let isProduction =
|
||||
const redis = require('redis');
|
||||
const redis_client = redis.createClient();
|
||||
|
||||
redis_client.on('error', err => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
let notLocalhost =
|
||||
conf.env === 'production' &&
|
||||
conf.s3_bucket !== 'localhost' &&
|
||||
conf.bitly_key !== 'localhost';
|
||||
|
||||
if (isProduction) {
|
||||
if (notLocalhost) {
|
||||
module.exports = {
|
||||
length: AWSLength,
|
||||
get: AWSGet,
|
||||
set: AWSSet,
|
||||
delete: AWSDelete,
|
||||
forceDelete: AWSForceDelete
|
||||
filename: filename,
|
||||
length: awsLength,
|
||||
get: awsGet,
|
||||
set: awsSet,
|
||||
delete: awsDelete,
|
||||
forceDelete: awsForceDelete
|
||||
};
|
||||
} else {
|
||||
module.exports = {
|
||||
length: LocalLength,
|
||||
get: LocalGet,
|
||||
set: LocalSet,
|
||||
delete: LocalDelete,
|
||||
forceDelete: LocalForceDelete
|
||||
filename: filename,
|
||||
length: localLength,
|
||||
get: localGet,
|
||||
set: localSet,
|
||||
delete: localDelete,
|
||||
forceDelete: localForceDelete
|
||||
};
|
||||
}
|
||||
|
||||
function LocalLength(id) {
|
||||
function filename(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
redis_client.hget(id, 'filename', (err, reply) => {
|
||||
if (!err) {
|
||||
resolve(reply);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function localLength(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
resolve(fs.statSync(__dirname + '/../static/' + id).size);
|
||||
|
@ -40,69 +61,67 @@ function LocalLength(id) {
|
|||
});
|
||||
}
|
||||
|
||||
function LocalGet(id) {
|
||||
function localGet(id) {
|
||||
return fs.createReadStream(__dirname + '/../static/' + id);
|
||||
}
|
||||
|
||||
function LocalSet(id, file, filename, client, url) {
|
||||
function localSet(id, file, filename, url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fstream = fs.createWriteStream(__dirname + '/../static/' + id);
|
||||
file.pipe(fstream);
|
||||
fstream.on('close', () => {
|
||||
let uuid = crypto.randomBytes(10).toString('hex');
|
||||
|
||||
client.hmset([id, 'filename', filename, 'delete', uuid]);
|
||||
client.expire(id, 86400000);
|
||||
redis_client.hmset([id, 'filename', filename, 'delete', uuid]);
|
||||
redis_client.expire(id, 86400000);
|
||||
console.log('Upload Finished of ' + filename);
|
||||
resolve({
|
||||
uuid: uuid,
|
||||
url: url
|
||||
});
|
||||
});
|
||||
|
||||
fstream.on('error', () => reject());
|
||||
});
|
||||
}
|
||||
|
||||
function LocalDelete(id, client, delete_token) {
|
||||
function localDelete(id, delete_token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
client.hget(id, 'delete', (err, reply) => {
|
||||
redis_client.hget(id, 'delete', (err, reply) => {
|
||||
if (!reply || delete_token !== reply) {
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
reject();
|
||||
})
|
||||
);
|
||||
reject();
|
||||
} else {
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
client.del(id);
|
||||
resolve(fs.unlinkSync(__dirname + '/../static/' + id));
|
||||
})
|
||||
);
|
||||
redis_client.del(id);
|
||||
resolve(fs.unlinkSync(__dirname + '/../static/' + id));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function LocalForceDelete(id, client) {
|
||||
function localForceDelete(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
client.del(id);
|
||||
redis_client.del(id);
|
||||
resolve(fs.unlinkSync(__dirname + '/../static/' + id));
|
||||
});
|
||||
}
|
||||
|
||||
function AWSLength(id) {
|
||||
function awsLength(id) {
|
||||
let params = {
|
||||
Bucket: conf.s3_bucket,
|
||||
Key: id
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.headObject(params, function(err, data) {
|
||||
resolve(data.ContentLength);
|
||||
if (!err) {
|
||||
resolve(data.ContentLength);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function AWSGet(id) {
|
||||
function awsGet(id) {
|
||||
let params = {
|
||||
Bucket: conf.s3_bucket,
|
||||
Key: id
|
||||
|
@ -111,7 +130,7 @@ function AWSGet(id) {
|
|||
return s3.getObject(params).createReadStream();
|
||||
}
|
||||
|
||||
function AWSSet(id, file, filename, client, url) {
|
||||
function awsSet(id, file, filename, url) {
|
||||
let params = {
|
||||
Bucket: conf.s3_bucket,
|
||||
Key: id,
|
||||
|
@ -122,87 +141,72 @@ function AWSSet(id, file, filename, client, url) {
|
|||
s3.upload(params, function(err, data) {
|
||||
if (err) {
|
||||
console.log(err, err.stack); // an error occurred
|
||||
reject();
|
||||
} else {
|
||||
let uuid = crypto.randomBytes(10).toString('hex');
|
||||
|
||||
client.hmset([id, 'filename', filename, 'delete', uuid]);
|
||||
redis_client.hmset([id, 'filename', filename, 'delete', uuid]);
|
||||
|
||||
client.expire(id, 86400000);
|
||||
redis_client.expire(id, 86400000);
|
||||
console.log('Upload Finished of ' + filename);
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
if (conf.bitly_key) {
|
||||
fetch(
|
||||
'https://api-ssl.bitly.com/v3/shorten?access_token=' +
|
||||
conf.bitly_key +
|
||||
'&longUrl=' +
|
||||
encodeURIComponent(url) +
|
||||
'&format=txt'
|
||||
)
|
||||
.then(res => {
|
||||
return res.text();
|
||||
})
|
||||
.then(body => {
|
||||
resolve({
|
||||
uuid: uuid,
|
||||
url: body
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (conf.bitly_key) {
|
||||
fetch(
|
||||
'https://api-ssl.bitly.com/v3/shorten?access_token=' +
|
||||
conf.bitly_key +
|
||||
'&longUrl=' +
|
||||
encodeURIComponent(url) +
|
||||
'&format=txt'
|
||||
)
|
||||
.then(res => {
|
||||
return res.text();
|
||||
})
|
||||
.then(body => {
|
||||
resolve({
|
||||
uuid: uuid,
|
||||
url: url
|
||||
url: body
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
} else {
|
||||
resolve({
|
||||
uuid: uuid,
|
||||
url: url
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function AWSDelete(id, client, delete_token) {
|
||||
function awsDelete(id, delete_token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
client.hget(id, 'delete', (err, reply) => {
|
||||
redis_client.hget(id, 'delete', (err, reply) => {
|
||||
if (!reply || delete_token !== reply) {
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
reject();
|
||||
})
|
||||
);
|
||||
reject();
|
||||
} else {
|
||||
client.del(id);
|
||||
redis_client.del(id);
|
||||
let params = {
|
||||
Bucket: conf.s3_bucket,
|
||||
Key: id
|
||||
};
|
||||
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
s3.deleteObject(params, function(err, data) {
|
||||
resolve(err);
|
||||
});
|
||||
})
|
||||
);
|
||||
s3.deleteObject(params, function(err, data) {
|
||||
resolve(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function AWSForceDelete(id, client) {
|
||||
function awsForceDelete(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
client.del(id);
|
||||
redis_client.del(id);
|
||||
let params = {
|
||||
Bucket: conf.s3_bucket,
|
||||
Key: id
|
||||
};
|
||||
|
||||
resolve(
|
||||
new Promise((resolve, reject) => {
|
||||
s3.deleteObject(params, function(err, data) {
|
||||
resolve(err);
|
||||
});
|
||||
})
|
||||
);
|
||||
s3.deleteObject(params, function(err, data) {
|
||||
resolve(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
|
||||
<div class="main-window">
|
||||
<div id="download">
|
||||
{{#if filename}}
|
||||
<div class="title">
|
||||
Your friend is sending you a file:
|
||||
</div>
|
||||
|
||||
<span> {{{filename}}} ({{{filesize}}})
|
||||
|
||||
<div class="share-window">
|
||||
<button id="download-btn" onclick="download()">Download File</button>
|
||||
<img id="expired-img" src="/resources/link_expired.png"/>
|
||||
|
@ -21,6 +25,18 @@
|
|||
<div class="send-new" id="send-file">
|
||||
Send your own files
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="title">
|
||||
This link has expired or never existed in the first place.
|
||||
</div>
|
||||
|
||||
<div class="share-window">
|
||||
<img src="/resources/link_expired.png"/>
|
||||
</div>
|
||||
<div class="send-new" id="send-file">
|
||||
Send your own files
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
<head>
|
||||
<title>Firefox Fileshare</title>
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||
<script src="/bundle.js"></script>
|
||||
<script src="./bundle.js"></script>
|
||||
<link rel="stylesheet" href="https://code.cdn.mozilla.net/fonts/fira.css">
|
||||
<link rel="stylesheet" type="text/css" href="/main.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./main.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -0,0 +1 @@
|
|||
{{{body}}}
|
Loading…
Reference in New Issue