commit d9f266b720f47b48e882660a4f6014c915bba4f9 Author: DeadF2K Date: Sun Feb 28 22:53:22 2021 +0100 v1.0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24423c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +node_modules/**/* +.expo/* +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ +web-report/ +.idea/* +lettalk-release-key.keystore +*.iml +*.pem +trash +*.env +# macOS +.DS_Store diff --git a/db/posts.db b/db/posts.db new file mode 100644 index 0000000..e69de29 diff --git a/db/sessions.db b/db/sessions.db new file mode 100644 index 0000000..e69de29 diff --git a/db/users.db b/db/users.db new file mode 100644 index 0000000..3a9a135 --- /dev/null +++ b/db/users.db @@ -0,0 +1 @@ +{"email":"admin@ghd.de","username":"admin","password":"$2b$10$30zu4TwSjMdjmnGQ.Nr6C./Tu71kEhlUHkHso2bnkKkn7Pm2q.u3e","role":"admin","_id":"VxsdGrHioVlUga4q"} \ No newline at end of file diff --git a/init.setup b/init.setup new file mode 100644 index 0000000..21f3cab --- /dev/null +++ b/init.setup @@ -0,0 +1,66 @@ +#!/bin/bash + +#update sytem +sudo apt-get -y update +sudo apt-get -y upgrade + +#enable and start ssh +sudo systemctl enable ssh +sudo systemctl start ssh + +#install remote desktop +sudo apt-get -y install xrdp + +#install nodejs +sudo apt-get -y install nodejs + +#install npm +sudo apt-get -y install npm + +#install firefox +sudo apt-get -y install firefox-esr + +cd `dirname $0` +echo "`dirname $0`" +#get correct node modules + +rm -rf node_modules +npm install express +npm install bcrypt +npm install nedb +npm install express-session +npm install nedb-session-store + + +#add server.start to autostart if not found +find="`grep server.start /etc/rc.local`" +if [ "$find" = "" ] +then + echo "adding server startup to /etc/rc.local" + cp /etc/rc.local "`pwd`" + sed -i '$d' rc.local + echo "`pwd`/server.start" >> rc.local + echo "exit 0" >> rc.local + sudo mv rc.local /etc/rc.local +else + echo "server startup already in /etc/rc.local" +fi + +#add firefox start in kiosk mode after logged in +find="`grep firefox ~/.profile`" +if [ "$find" = "" ] +then + echo "adding firefox start to ~/.profile" + echo "firefox --kiosk http://localhost:8080/info &" >> ~/.profile +else + echo "firefox start already found in ~/.profile" +fi + +sudo chmod +x server.start + +echo "network/mac adress:`hostname -I`" + +#system restart +echo "System will restart in 10s. ^C to cancel" +sleep 10 +sudo reboot -h now \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..718d0e8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1010 @@ +{ + "name": "NodeHelp", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "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" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-jB0yCBl4W/kVHM2whjfyqnxTmOHkCX4kHEa5nYKSoGeYe8YrjTYTc87/6bwt1g8cmV0QrbhKriETg9jWtcREhg==", + "dev": true, + "requires": { + "node-addon-api": "^3.0.0", + "node-pre-gyp": "0.15.0" + } + }, + "binary-search-tree": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz", + "integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=", + "requires": { + "underscore": "~1.4.4" + } + }, + "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==", + "dev": true, + "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==" + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "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 + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "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=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "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" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "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=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true + }, + "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" + } + }, + "express-session": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", + "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", + "dev": true, + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.0", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "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=" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "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" + } + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "requires": { + "immediate": "~3.0.5" + } + }, + "localforage": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.9.0.tgz", + "integrity": "sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==", + "requires": { + "lie": "3.1.1" + } + }, + "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.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nedb": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz", + "integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=", + "requires": { + "async": "0.2.10", + "binary-search-tree": "0.2.5", + "localforage": "^1.3.0", + "mkdirp": "~0.5.1", + "underscore": "~1.4.4" + } + }, + "nedb-session-store": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nedb-session-store/-/nedb-session-store-1.1.2.tgz", + "integrity": "sha512-ahASrYzxP17k7Rn9AHIMMkFj8ibGWa8m1MJVajIP89HnCRyk93H7VtQReiiz/xiBFKxDm9MwOB71OAPv1Ybhzg==", + "requires": { + "nedb": "^1.5.0" + } + }, + "needle": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", + "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", + "dev": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-addon-api": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.2.tgz", + "integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg==", + "dev": true + }, + "node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "dev": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "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" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "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=", + "dev": true + }, + "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=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", + "dev": true + }, + "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" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "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==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "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" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "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" + } + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dev": true, + "requires": { + "random-bytes": "~1.0.0" + } + }, + "underscore": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", + "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "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=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9a2a0d3 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "NodeHelp", + "version": "1.0.0", + "dependencies": { + "body-parser": "^1.19.0", + "express": "^4.17.1", + "nedb": "^1.8.0", + "nedb-session-store": "^1.1.2" + }, + "devDependencies": { + "bcrypt": "^5.0.0", + "express-session": "^1.17.1" + } +} diff --git a/public/admin-login.html b/public/admin-login.html new file mode 100644 index 0000000..d3291a3 --- /dev/null +++ b/public/admin-login.html @@ -0,0 +1,61 @@ + + + + + + Admin-Page + + + + + + + +
+
+
+

Adminseite

+
+
+ +
+ + + + +
+
+
+
+
+
+ +
+ + +
+
+
+
+ + diff --git a/public/admin.js b/public/admin.js new file mode 100644 index 0000000..4dfbff6 --- /dev/null +++ b/public/admin.js @@ -0,0 +1,189 @@ +document.addEventListener("DOMContentLoaded", function(){ + var form = document.getElementById("formNewUser"); + form.addEventListener("submit", function(e){ + e.preventDefault(); + console.log("Sending Formular") + async function register(){ + var email = document.getElementById("email").value; + var username = document.getElementById("username").value; + var bodyContent = {email:email, username:username}; + var response = await fetch("/newmod", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify(bodyContent) + }); + var data = await response.json(); + console.log(data); + loadMods(); + } + register(); + }); + + document.getElementById("changePwBtn").onclick = function(){ + window.location = "/new-password"; + } + + /*changin page*/ + var pageUp = document.getElementById("pageUp"); + var pageDown = document.getElementById("pageDown"); + + pageUp.addEventListener("click", () => { + if(maxPages > currentPage+1) { + currentPage++; + loadMods(); + } + }); + + pageDown.addEventListener("click", () => { + if(currentPage > 0){ + currentPage--; + + loadMods(); + } + }); + + /*logout*/ + var lgoBtn = document.getElementById("lgoBtn"); + lgoBtn.addEventListener("click", () => { + window.location = "/logout"; + }); + + var maxPages; + var currentPage = 0; + var maxDisplayed = 8; + async function loadMods(){ + var response = await fetch("/getmods", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + var data = await response.json(); + try{ + showMods(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + maxPages = data.users.length / 8; + console.log(maxPages, currentPage+1) + }catch(error){ + document.getElementById("table").innerHTML = ""; //empty table + } + }; + loadMods(); + + function showMods(pdata){ + document.getElementById("table").innerHTML = ""; //empty table + var container = document.getElementById("table"); //insert in table + pdata.forEach(element => { + var row = document.createElement("div"); + var status; + var susbuttonstate; + if(element.suspended) { + status = "suspended" + susbuttonstate = "icon-pause" + } else { + status = "notSuspended" + susbuttonstate = "icon-play" + } + row.classList.add("row"); + row.innerHTML = ` +
+

${element.username}

+
+
+ + +
+ ` + container.appendChild(row) + }); + } + + async function toggleSus(pun){ + var response = await fetch("/toggleSus", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({username:pun}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadMods(); + } + }; + + async function deleteMod(username){ + var response = await fetch("/deleteMod", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({username:username}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadMods(); + } + }; + + var mngBtn = document.getElementById("mngBtn"); + mngBtn.addEventListener("click", () => { + window.location = "/manage-posts"; + }); + + + document.addEventListener("click", function(e){ + if(e.target && e.target.classList.contains("susButton")){ + var un = e.target.getAttribute("data-username"); + toggleSus(un); + }else if(e.target && e.target.classList.contains("remButton")){ + var username = e.target.getAttribute("data-username"); + deleteMod(username); + } + }) + + + /*-----New User Popup-----*/ + const openPopupBtns = document.querySelectorAll("[data-popup-target]"); + const closePopupBtns = document.querySelectorAll("[data-close-btn]"); + const overlay = document.getElementById("overlay"); + + openPopupBtns.forEach(btn => { + btn.addEventListener("click", () => { + const popup = document.querySelector(btn.dataset.popupTarget); + openPopup(popup); + }) + }); + + closePopupBtns.forEach(btn => { + btn.addEventListener("click", () => { + const popup = btn.closest(".popup") + closePopup(popup); + }) + }); + + function openPopup(popup) { + if (popup == null) return + popup.classList.add("active"); + overlay.classList.add("active"); + } + + function closePopup(popup) { + if (popup == null) return + popup.classList.remove("active"); + overlay.classList.remove("active"); + } + +}); diff --git a/public/change-pw.html b/public/change-pw.html new file mode 100644 index 0000000..eb23577 --- /dev/null +++ b/public/change-pw.html @@ -0,0 +1,37 @@ + + + + + + Change Password + + + + +
+
+
+

Change Password

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + \ No newline at end of file diff --git a/public/change-pw.js b/public/change-pw.js new file mode 100644 index 0000000..eb3de1a --- /dev/null +++ b/public/change-pw.js @@ -0,0 +1,30 @@ +//write code in next section +//will run when DOM is loaded +document.addEventListener("DOMContentLoaded", function(){ + var form = document.getElementById("loginform"); + async function login() { + var old_pw = document.getElementById("old_pw").value; + var new_pw_1 = document.getElementById("new_pw_1").value; + var new_pw_2 = document.getElementById("new_pw_2").value; + + var body = {old_password:old_pw, new_password_1:new_pw_1, new_password_2:new_pw_2}; + var response = await fetch("/changepw", { + method:"POST", + headers:{ + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify(body) + }) + var data = await response.json(); + console.log("Data: "); + console.log(data); + if(data.suc){ + window.location = "/main" + } + } + form.addEventListener("submit", function(e){ + e.preventDefault(); + login(); + }); +}); \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..54ef92b --- /dev/null +++ b/public/index.html @@ -0,0 +1,37 @@ + + + + + + Login + + + + +
+
+
+

Login

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/public/info-page.html b/public/info-page.html new file mode 100644 index 0000000..d3339a6 --- /dev/null +++ b/public/info-page.html @@ -0,0 +1,31 @@ + + + + + + InfoTafel + + + + + + + +
+
+
+

Infoseite

+

Brought to you by Th-Nürnberg

+
+
+

+
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/public/info-page.js b/public/info-page.js new file mode 100644 index 0000000..e83c94f --- /dev/null +++ b/public/info-page.js @@ -0,0 +1,84 @@ +document.addEventListener("DOMContentLoaded", function(){ + var SwitchTime = 10; // in Seconds + + document.getElementById("topper").onclick = function(){ + window.location = "/main"; + } + + var maxPages; + var currentPage = 0; + var maxDisplayed = 6; + async function loadPosts(){ + var response = await fetch("/getliveposts", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + + var data = await response.json(); + //console.log(data); + try{ + showPosts(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + //console.log(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + maxPages = data.posts.length / maxDisplayed; + //console.log(maxPages, currentPage+1) + }catch(error){ + document.getElementById("content").innerHTML = ""; //empty content + } + }; + loadPosts(); + + function showPosts(pdata){ + var container = document.getElementById("content"); //insert in content + container.innerHTML = "" //empty content + pdata.forEach(element => { + var post = document.createElement("div"); + post.classList.add("post"); + post.style.backgroundColor = element.bcolor; + post.innerHTML = ` +
+

${element.title}

+
+
+ ${element.text} +
+ ` + container.appendChild(post) + }); + } + + function startTime() { + var today = new Date(); + var h = today.getHours(); + var m = today.getMinutes(); + var s = today.getSeconds(); + h = checkTime(h); + m = checkTime(m); + s = checkTime(s); + document.getElementById('clock').innerHTML = + h + ":" + m + ":" + s; + var t = setTimeout(startTime, 500); + } + function checkTime(i) { + if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10 + return i; + } + startTime(); + + function changePage(){ + if(maxPages > currentPage+1) { + currentPage++; + } + else{ + currentPage = 0; + loadPosts(); + } + + loadPosts(); + setTimeout(changePage, SwitchTime*1000); + } + changePage(); +}); + diff --git a/public/login.js b/public/login.js new file mode 100644 index 0000000..5cc5c29 --- /dev/null +++ b/public/login.js @@ -0,0 +1,50 @@ +//write code in next section +//will run when DOM is loaded +document.addEventListener("DOMContentLoaded", function(){ + var form = document.getElementById("loginform"); + async function login() { + var un = document.getElementById("un").value; + var pw = document.getElementById("pw").value; + var body = {username:un, password:pw}; + var response = await fetch("/login", { + method:"POST", + headers:{ + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify(body) + }) + var data = await response.json(); + console.log("Data: "); + console.log(data); + if(data.suc){ + window.location = "/main" + } else { + var loginText = document.getElementById("loginText"); + var inputs = document.getElementsByTagName("input") + var inputList = Array.prototype.slice.call(inputs); + + loginText.classList.add("fadeout"); + setTimeout(function() { + loginText.innerText = "Try Again"; + loginText.classList.remove("fadeout"); + }, 350); + console.log(inputs); + inputList.forEach(element => { + element.style.borderBottom="1px solid #F00"; + if(element.getAttribute("type") === "password"){ + element.value = ""; + element.focus(); + } + }); + } + } + form.addEventListener("submit", function(e){ + e.preventDefault(); + login(); + }); + var prevBtn = document.getElementById("prev") + prevBtn.addEventListener("click", function(){ + window.location ="/info" + }) +}); \ No newline at end of file diff --git a/public/manage-post.html b/public/manage-post.html new file mode 100644 index 0000000..9832811 --- /dev/null +++ b/public/manage-post.html @@ -0,0 +1,36 @@ + + + + + + Manage-Posts + + + + + + +
+
+
+

Manage Posts

+
+
+ +
+ +
+
+
+
+
+
+
+ + +
+
+
+
+ + diff --git a/public/manage-post.js b/public/manage-post.js new file mode 100644 index 0000000..39b6067 --- /dev/null +++ b/public/manage-post.js @@ -0,0 +1,161 @@ +document.addEventListener("DOMContentLoaded", function(){ + /*changin page*/ + var pageUp = document.getElementById("pageUp"); + var pageDown = document.getElementById("pageDown"); + var reviewButtons = document.getElementsByClassName('editButton'); + + pageUp.addEventListener("click", () => { + if(maxPages > currentPage+1) { + currentPage++; + loadPosts(); + } + }); + + pageDown.addEventListener("click", () => { + if(currentPage > 0){ + currentPage--; + + loadPosts(); + } + }); + + /*logout*/ + var lgoBtn = document.getElementById("lgoBtn"); + lgoBtn.addEventListener("click", () => { + window.location = "/logout"; + }); + + var mngBtn = document.getElementById("mngBtn"); + mngBtn.addEventListener("click", () => { + window.location = "/main"; + }); + + async function toggleSus(postid){ + var response = await fetch("/toggleShow", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:postid}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadPosts(); + } + }; + + async function deletePost(postid){ + var response = await fetch("/deletePost", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:postid}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadPosts(); + } + }; + + + document.addEventListener("click", function(e){ + if(e.target && e.target.classList.contains("susButton")){ + var postid = e.target.getAttribute("data-username"); + toggleSus(postid); + }else if(e.target && e.target.classList.contains("remButton")){ + var postid = e.target.getAttribute("data-username"); + deletePost(postid); + } + }) + + /*Show Elements*/ + var maxPages; + var currentPage = 0; + var maxDisplayed = 8; + async function loadPosts(){ + var response = await fetch("/getposts", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + var data = await response.json(); + try{ + showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + maxPages = data.users.length / 8; + console.log(maxPages, currentPage+1) + reviewButtons = document.getElementsByClassName('editButton'); + console.log(reviewButtons.length); + addButtons(); + }catch(error){ + document.getElementById("table").innerHTML = ""; //empty table + } + }; + loadPosts(); + + function showPosts(pdata){ + document.getElementById("table").innerHTML = ""; //empty table + var container = document.getElementById("table"); //insert in table + pdata.forEach(element => { + var row = document.createElement("div"); + var status; + var susbuttonstate; + if(!element.showpost) { + status = "hidden" + susbuttonstate = "icon-eye-close" + } else { + status = "shown" + susbuttonstate = "icon-eye-open" + } + row.classList.add("row"); + row.innerHTML = ` +
+

${element.title}

+
+
+ + + +
+ ` + container.appendChild(row) + }); + } + + async function reviewPost(postid){ + var response = await fetch("/updatePostID", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:postid}) + }) + var data = await response.json(); + if(data || !data) + { + window.location = "/post-review"; + } + }; + + function addButtons(){ + for(let i = 0; i < reviewButtons.length; i++){ + reviewButtons[i].addEventListener('click', function(){ + reviewPost(this.dataset.username) + }) + } + } +}); diff --git a/public/mod-login.html b/public/mod-login.html new file mode 100644 index 0000000..daf219d --- /dev/null +++ b/public/mod-login.html @@ -0,0 +1,60 @@ + + + + + + Mod-Page + + + + + + +
+
+
+

Modseite

+
+
+ + +
+ + + +
+
+
+
+
+
+ +
+ + +
+
+
+
+ + diff --git a/public/mod.js b/public/mod.js new file mode 100644 index 0000000..4c631b7 --- /dev/null +++ b/public/mod.js @@ -0,0 +1,189 @@ +document.addEventListener("DOMContentLoaded", function(){ + var form = document.getElementById("formNewUser"); + form.addEventListener("submit", function(e){ + e.preventDefault(); + console.log("Sending Formular") + async function register(){ + var email = document.getElementById("email").value; + var username = document.getElementById("username").value; + var bodyContent = {email:email, username:username}; + var response = await fetch("/newuser", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify(bodyContent) + }); + var data = await response.json(); + console.log(data); + loadUsers(); + } + register(); + }); + + document.getElementById("changePwBtn").onclick = function(){ + window.location = "/new-password"; + } + + /*changin page*/ + var pageUp = document.getElementById("pageUp"); + var pageDown = document.getElementById("pageDown"); + + pageUp.addEventListener("click", () => { + if(maxPages > currentPage+1) { + currentPage++; + loadUsers(); + } + }); + + pageDown.addEventListener("click", () => { + if(currentPage > 0){ + currentPage--; + + loadUsers(); + } + }); + + /*logout*/ + var lgoBtn = document.getElementById("lgoBtn"); + lgoBtn.addEventListener("click", () => { + window.location = "/logout"; + }); + + var mngBtn = document.getElementById("mngBtn"); + mngBtn.addEventListener("click", () => { + window.location = "/manage-posts"; + }); + + var maxPages; + var currentPage = 0; + var maxDisplayed = 8; + async function loadUsers(){ + var response = await fetch("/getusers", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + var data = await response.json(); + try{ + showUsers(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + maxPages = data.users.length / 8; + console.log(maxPages, currentPage+1) + }catch(error){ + document.getElementById("table").innerHTML = ""; //empty table + } + }; + loadUsers(); + + function showUsers(pdata){ + document.getElementById("table").innerHTML = ""; //empty table + var container = document.getElementById("table"); //insert in table + pdata.forEach(element => { + var row = document.createElement("div"); + var status; + var susbuttonstate; + if(element.suspended) { + status = "suspended" + susbuttonstate = "icon-pause" + } else { + status = "notSuspended" + susbuttonstate = "icon-play" + } + row.classList.add("row"); + row.innerHTML = ` +
+

${element.username}

+
+
+ + +
+ ` + container.appendChild(row) + }); + } + + async function toggleSus(pun){ + var response = await fetch("/toggleSus", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({username:pun}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadUsers(); + } + }; + + async function deleteUser(username){ + var response = await fetch("/deleteUser", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({username:username}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadUsers(); + } + }; + + + document.addEventListener("click", function(e){ + if(e.target && e.target.classList.contains("susButton")){ + var un = e.target.getAttribute("data-username"); + toggleSus(un); + }else if(e.target && e.target.classList.contains("remButton")){ + var username = e.target.getAttribute("data-username"); + deleteUser(username); + } + }) + + + /*-----New User Popup-----*/ + const openPopupBtns = document.querySelectorAll("[data-popup-target]"); + const closePopupBtns = document.querySelectorAll("[data-close-btn]"); + const overlay = document.getElementById("overlay"); + + openPopupBtns.forEach(btn => { + btn.addEventListener("click", () => { + const popup = document.querySelector(btn.dataset.popupTarget); + openPopup(popup); + }) + }); + + closePopupBtns.forEach(btn => { + btn.addEventListener("click", () => { + const popup = btn.closest(".popup") + closePopup(popup); + }) + }); + + function openPopup(popup) { + if (popup == null) return + popup.classList.add("active"); + overlay.classList.add("active"); + } + + function closePopup(popup) { + if (popup == null) return + popup.classList.remove("active"); + overlay.classList.remove("active"); + } + +}); diff --git a/public/new-Postv2.html b/public/new-Postv2.html new file mode 100644 index 0000000..8558534 --- /dev/null +++ b/public/new-Postv2.html @@ -0,0 +1,75 @@ + + + + + + Post Editor + + + + + + +
+
+
+ +
+
+
+ +
+ + + + + + + +
+
+
+
+
+
+ + + + + + +
+
+
+
+ + +
+
+ + +
+ +
+
+
+ + diff --git a/public/new-Postv2.js b/public/new-Postv2.js new file mode 100644 index 0000000..3309ec9 --- /dev/null +++ b/public/new-Postv2.js @@ -0,0 +1,118 @@ +document.addEventListener("DOMContentLoaded", function(){ + const editorButtons = document.getElementsByClassName('editor-button'); + const setAttribute = (element) => { + document.execCommand(element.dataset.attribute, false); + }; + + for(let i = 0; i { + console.log(element); + document.execCommand(element.dataset.attribute, false, element.value); + }; + + + + const backColor = document.getElementById("backcolor"); + const helo = document.getElementsByClassName("canvas"); + backColor.addEventListener('change', function(){ + console.log(this); + for(let i = 0; i { + btn.addEventListener("click", () => { + const popup = document.querySelector(btn.dataset.popupTarget); + openPopup(popup); + }) + }); + + closePopupBtns.forEach(btn => { + btn.addEventListener("click", () => { + const popup = btn.closest(".popup") + closePopup(popup); + }) + }); + + function openPopup(popup) { + if (popup == null) return + popup.classList.add("active"); + overlay.classList.add("active"); + } + + function closePopup(popup) { + if (popup == null) return + popup.classList.remove("active"); + overlay.classList.remove("active"); + } + + document.getElementById("startDate").onchange = function(){ + document.getElementById("endDate").min = document.getElementById("startDate").value; + var end = new Date(document.getElementById("startDate").value); + end.setDate(end.getDate() +7); + var endDate = end.toISOString().slice(0,10); + document.getElementById("endDate").value = endDate; + } + + function date(){ + var today = new Date().toISOString().slice(0,10); + var end = new Date(); + end.setDate(end.getDate() + 7) + var endDate = end.toISOString().slice(0,10); + + document.getElementById("startDate").value = today; + document.getElementById("startDate").min = today; + document.getElementById("endDate").value = endDate; + document.getElementById("endDate").min = today; + }; + date() +}); \ No newline at end of file diff --git a/public/post-review.html b/public/post-review.html new file mode 100644 index 0000000..e476b78 --- /dev/null +++ b/public/post-review.html @@ -0,0 +1,28 @@ + + + + + + Post Editor + + + + + + +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ + diff --git a/public/post-review.js b/public/post-review.js new file mode 100644 index 0000000..2d3e8cb --- /dev/null +++ b/public/post-review.js @@ -0,0 +1,49 @@ +document.addEventListener("DOMContentLoaded", function(){ + document.getElementById("cancelBtn").onclick = function(){ + window.location = "/main"; + } + + var id; + async function loadPost(){ + var response = await fetch("/getReviewPost", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + var data = await response.json(); + id = data.post[0].postid; + document.getElementsByClassName("canvas")[0].style.backgroundColor = data.post[0].bcolor; + document.getElementsByClassName("canvas")[1].style.backgroundColor = data.post[0].bcolor; + document.getElementById("title-canvas").innerHTML = data.post[0].title; + document.getElementById("editor-canvas").innerHTML = data.post[0].text; + + if(data.post[0].showpost) { + document.getElementById("submit-post").innerHTML = "Suspend Post" + } else { + document.getElementById("submit-post").innerHTML = "Confirm Post" + } + }; + loadPost(); + + document.getElementById("submit-post").onclick = function(){ + toggleShow(id); + } + + async function toggleShow(pun){ + var response = await fetch("/toggleShow", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:pun}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + window.location = "/main" + } + }; +}); \ No newline at end of file diff --git a/public/styles.css b/public/styles.css new file mode 100644 index 0000000..69dc951 --- /dev/null +++ b/public/styles.css @@ -0,0 +1,553 @@ +:root { + --border-prop: 0px solid #F2F; + --header-height: 10%; + --prime-color: rgb(71, 17, 221); + --container-bg: rgba(30, 30, 50, 0.644); + --text-color: rgba(255,255,255, 1); + --row-color: rgba(0, 0, 100, 0.3); + --button-prim: rgba(255,255,255,0.1); + --button-sec: rgba(255, 255, 255, 0.4); + --popup-border: 2px solid rgb(11, 11, 128); + --popup-stripe: 3px solid rgba(0,0,50,0.5); + --title-size: 60px; + --text-size: 30px; + --smal-text: 20px; +} + +div{ + border: 0px #F2F; + border-style: dashed; +} + +html, body { + width: 100%; + height: 100%; + background: var(--prime-color); + margin: 0; +} + +header{ + height: var(--header-height); + padding-top: 30px; + display: flex; + justify-content: center; +} + +/*text*/ +h1, h2, h3, .title, label{ + font-size: var(--title-size); + padding: 0px; + margin: 0px; + font-family: Arial; + color: var(--text-color); +} + +h2, label{ + font-size: var(--text-size); +} + +h3{ + font-size: var(--smal-text); +} + + + +input { + width: 100%; + font-family: Arial; + font-size: 2em; + color: rgb(255, 255, 255); + padding: 0; + padding-bottom: 5px; + background: none; + border: none; + border-bottom: 1px solid #ffffff; + margin-bottom: 15px; + margin-top: 15px +} + +input:focus { + outline: 0; +} + +.main { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.container{ + width: 400px; + border: var(--border-prop); + background-color: var(--container-bg); + padding: 20px; + + display: flex; + flex-direction: column; +} + +.user-container{ + width: 50%; + min-height: 35em; +} + +.header { + border: var(--border-prop); + font-size: 25px; + text-align: center; + margin-bottom: 25px; +} + +.datasec { + border: var(--border-prop); + font-family: Arial; + font-size: 30px; + color: white; +} + +/* buttons */ + +.buttons-container { + border: var(--border-prop); + display: flex; + justify-content: center; + width: 100%; +} + +.button { + display: inline-block; + border-radius: 0; + background-color: #303030; + border: none; + /*text*/ + color: #FFFFFF; + text-align: center; + font-size: var(--text-size); + padding: 10px; + width: 100%; + cursor: pointer; + +} + +.button span{ + cursor: pointer; + display: inline-block; + position: relative; + transition: 1s; +} + +.button span::after { + content: '\00bb'; + position: absolute; + opacity: 0; + top: 0; + right: -20px; + transition: .5s; +} + +.button:hover span { + padding-right: 25px; +} + +.button:hover span::after{ + opacity: 1; + right: 0; +} + +.susButton , .remButton, .nextButton, .manageButton, #addBtn{ + margin-left: 5px; +} + +.icon{ + pointer-events: none; +} + +/* end of buttons*/ + +#loginText { + transition: 0.35s; +} + +.fadeout { + opacity: 0; +} + +#loginform { + border: var(--border-prop); + margin-bottom: 10px; +} + +/* +border: 1px #F2F; +border-style: dashed; +*/ + + +/* User/Mod Table */ + +.table{ + min-height: 32em; +} + +.row{ + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + background-color: var(--row-color); + margin-top: 10px; + margin-bottom: 10px; + padding-left: 10px; + padding-right: 10px; +} + +.col-left , .col-right{ + display: flex; + padding: 0; + margin: 0; +} + +/* End of Table */ + +/* Page Selector */ + +.rightButtons{ + display: flex; + margin-left: 10px; + +} + +.ButtonRow{ + display: flex; + flex-direction: row; + justify-content: space-between; + padding-right: 10px; +} + +/* End of Page Selector*/ + +/*-----POPUP-----*/ +.popup{ + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) scale(0); + transition: 50ms ease-in-out; + border: var(--popup-border); + z-index: 10; /*lay ontop of everything*/ + background-color: var(--prime-color); + width: 500px; + max-width: 80%; + min-height: 18em; + display: flex; + flex-direction: column; + justify-content: space-evenly; +} + +.popup.active{ + transform: translate(-50%, -50%) scale(1); +} + +.popup-header{ + padding: 10px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: var(--popup-stripe); +} + +.popup-header .title{ + font-size: var(--text-size); + font-weight: bold; +} + +.popup-header .close-btn{ + cursor: pointer; + border: none; + outline: none; + background: none; + font-size: var(--title-size); + font-weight: bold; + color: white; +} + +.popup-body{ + display: flex; + justify-content: center; + padding: 10px; +} + +#overlay{ + position: fixed; + opacity: 0; + transition: 50ms ease-in-out; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,.75); + pointer-events: none; +} + +#overlay.active{ + opacity: 1; + pointer-events: all; +} + +.popup-body{ + display: fixed; + justify-items: center; +} + +#formNewUser{ + width: 50%; +} + +input { + width: 100%; + font-family: Arial; + font-size: var(--text-size); + color: white; + padding: 0; + padding-bottom: 5px; + background: none; + border: none; + border-bottom: 1px solid #ffffff; + margin-bottom: 15px; + margin-top: 15px +} + +input:focus { + outline: 0; +} + +/*-----POPUP-END-----*/ + +/* New Post Section*/ + + +[contentEditable=true]:empty:not(:focus):before{ + content:attr(data-text); + color: rgba(0,0,0,0.5); +} + +.preview-title{ + color: #000; +} + +.editor{ + display: flex; + flex-flow: row; + justify-content: center; +} + +.editor-menubar{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + +} + +button, .color-select{ + color: #ffffff; + font-size: var(--text-size); + padding-left: 10px; + padding-right: 10px; + background-color: var(--button-prim); + cursor: pointer; + transition: all 250ms; + border: none; + min-width: 50px; + min-height: 50px; +} + +button:hover{ + background-color: var(--button-sec); +} + +button:focus{ + outline: none; +} + +.regSection{ + font-size: var(--text-size); +} + +.canvas{ + background-color: rgba(255,255,255,1); + width: 46.3rem; + height: 30rem; + padding: 2.5rem; + font-size: var(--text-size); + color: #000; + font-family: arial; + line-height: 1.5em; +} + +.canvas:focus{ + outline: none; +} + +#title-canvas, #editor-canvas{ + height: 5rem; + font-size: var(--title-size); + align-self: center; + text-align: center; + text-justify: center; + padding: 10px; + + border-bottom: .5rem solid #000 ; +} + +#editor-canvas{ + + text-align: left; + text-justify: left; + height: 30rem; + font-size: var(--smal-text); +} + +#box{ + display: flex; + flex-direction: column; +} + +#cancelBtn{ + padding: 0; + font-size: var(--title-size); + line-height: 1.8rem; +} + +.postContainer{ + width: 60em; +} + +.lower{ + display: flex; + flex-flow: row; + justify-content: center; + align-items: center; +} + +.topper{ + + display: flex; + flex-flow: row; + justify-content: flex-end; + align-items: flex-end; +} + +.calendar{ + color: #ffffff; + font-size: var(--text-size); + padding: 1rem; + transition: all 250ms; + display: flex; + flex-flow: column; + align-items: center; + justify-content: center; + margin-left: .5rem; + margin-right: .5rem; +} + +.calendar-element{ + border: none; +} + +.calendar-element:focus{ + outline: none; +} + +#title-text{ + width: 100%; + display: flex; + flex-flow: column; +} + +#submit-post{ + margin-left: .5rem; +} + +.color-select{ + background-color: var(--button-prim); + padding-left: 0px; + padding-right: 0px; + display: flex; + justify-content: center; + margin: 0px; +} + +.color-select:hover{ + background-color: var(--button-sec); +} + +.editor-button{ + min-width: 50px; + max-width: 50px; + min-height: 50px; + max-height: 50px; +} + +/* End of New Post*/ + +/* Preview */ + +.TitleRow{ + max-width: 100%; + display: flex; + flex-direction: row; + justify-content: space-evenly; + background-color: var(--container-bg); + padding-right: 10px; + padding-bottom: 10px; + align-items: center; + margin-bottom: 5px; +} + +.titleDiv{ + min-width: 25%; +} + +#topper{ + height: 10%; + text-align: center; + top: 0px; +} + +#content{ + width: 100%; + height: 85%; + display: flex; + justify-content: center; + flex-wrap: wrap; +} + +@keyframes fadein { + 0% { + opacity: 0; + } + } + +.post{ + animation: fadein 2s ease; + + min-width: 30%; + max-width: 45%; + min-height: 28%; + max-height: 45%; + padding: 2vh; + margin: 5px; + border-width: 0px; + border-color: var(--prime); + color: black; +} + +.hidden{ + color: red; +} + +/* End of Preview */ + diff --git a/public/user-login.html b/public/user-login.html new file mode 100644 index 0000000..8fc1537 --- /dev/null +++ b/public/user-login.html @@ -0,0 +1,38 @@ + + + + + + User-Page + + + + + + +
+
+
+

Benutzerseite

+
+
+ + + + + +
+
+
+
+
+ +
+ + +
+
+
+
+ + diff --git a/public/user.js b/public/user.js new file mode 100644 index 0000000..94650a8 --- /dev/null +++ b/public/user.js @@ -0,0 +1,143 @@ +document.addEventListener("DOMContentLoaded", function(){ + /*changin page*/ + var pageUp = document.getElementById("pageUp"); + var pageDown = document.getElementById("pageDown"); + var reviewButtons = document.getElementsByClassName('editButton'); + + + + document.getElementById("changePwBtn").onclick = function(){ + window.location = "/new-password"; + } + + pageUp.addEventListener("click", () => { + if(maxPages > currentPage+1) { + currentPage++; + loadPosts(); + } + }); + + pageDown.addEventListener("click", () => { + if(currentPage > 0){ + currentPage--; + loadPosts(); + } + }); + + async function deletePost(postid){ + var response = await fetch("/deletePost", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:postid}) + }) + var data = await response.json(); + console.log(data); + if(data.suc || !data.suc){ + loadPosts(); + } + }; + + document.addEventListener("click", function(e){ + if(e.target && e.target.classList.contains("remButton")){ + var postid = e.target.getAttribute("data-username"); + deletePost(postid); + } + }) + + /*logout*/ + var lgoBtn = document.getElementById("lgoBtn"); + lgoBtn.addEventListener("click", () => { + window.location = "/logout"; + }); + + /*NewPost*/ + var addBtn = document.getElementById("addBtn"); + addBtn.addEventListener("click", () => { + window.location = "/newPost"; + }); + + /*Show Elements*/ + var maxPages; + var currentPage = 0; + var maxDisplayed = 8; + async function loadPosts(){ + var response = await fetch("/getposts", { + method: "GET", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + } + }) + var data = await response.json(); + try{ + showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed))); + maxPages = data.users.length / 8; + console.log(maxPages, currentPage+1) + reviewButtons = document.getElementsByClassName('editButton'); + console.log(reviewButtons.length); + addButtons(); + }catch(error){ + document.getElementById("table").innerHTML = ""; //empty table + } + }; + loadPosts(); + + function showPosts(pdata){ + document.getElementById("table").innerHTML = ""; //empty table + var container = document.getElementById("table"); //insert in table + pdata.forEach(element => { + var row = document.createElement("div"); + var status; + if(!element.showpost) { + status = "hidden icon-eye-close" + } else { + status = "shown icon-eye-open" + } + row.classList.add("row"); + row.innerHTML = ` +
+

${element.title}

+
+
+ + + +
+ ` + container.appendChild(row) + }); + } + + async function reviewPost(postid){ + var response = await fetch("/updatePostID", { + method: "POST", + headers: { + "Accept":"application/json", + "Content-Type":"application/json" + }, + body:JSON.stringify({postid:postid}) + }) + var data = await response.json(); + if(data || !data) + { + window.location = "/post-review"; + } + }; + + function addButtons(){ + for(let i = 0; i < reviewButtons.length; i++){ + reviewButtons[i].addEventListener('click', function(){ + reviewPost(this.dataset.username) + }) + } + } +}); diff --git a/server.js b/server.js new file mode 100644 index 0000000..b8bd8ce --- /dev/null +++ b/server.js @@ -0,0 +1,573 @@ +const express = require("express"); +const bodyParser = require("body-parser"); +const app = express(); +const bcrypt = require("bcrypt"); +const Datastore = require("nedb"); +const session = require("express-session"); +const NedbSessionStore = require("nedb-session-store")(session); + +app.listen(8080, () => { + console.log("Server online on port 8080"); +}) + +app.use(session({ + secret: process.env.SECRET || 'ENTER YOUR SECRET KEY IN ENV VARIABLES!', + resave: false, + saveUninitialized: false, + unset: "destroy", + cookie: { + path: '/', + httpOnly: true, + maxAge: 3600000 //cookie time in ms (=1h) + }, + store: new NedbSessionStore({ + filename: 'db/sessions.db' + }) +})) + +app.use(express.static("public")); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + + + +/*--------------------------------------------------PAGE REQUESTS--------------------------------------------------*/ + +app.get("/", (req, res) => { + res.send("index.html"); +}); + +app.get("/info", (req, res) => { + res.sendFile(__dirname + '/public/info-page.html') +}); + +app.get("/main", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "admin"){ + res.sendFile(__dirname + '/public/admin-login.html') + }else if(req.session.isLoggedIn && req.session.userRole === "mod") { + res.sendFile(__dirname + '/public/mod-login.html') + }else if(req.session.isLoggedIn && req.session.userRole === "user") { + res.sendFile(__dirname + '/public/user-login.html') + }else { + req.session = null; + res.redirect("/"); + } +}); + +app.get("/newPost", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "user"){ + res.sendFile(__dirname + '/public/new-Postv2.html') + } else { + req.session = null; + res.redirect("/"); + } +}); + +app.get("/manage-posts", (req, res) => { + if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){ + res.sendFile(__dirname + '/public/manage-post.html') + } else { + req.session = null; + res.redirect("/"); + } +}); + +app.get("/new-password", (req, res) => { + if(req.session.isLoggedIn){ + res.sendFile(__dirname + '/public/change-pw.html') + } else { + req.session = null; + res.redirect("/"); + } +}); + +app.post("/updatePostID", (req, res) => { + + if(req.session.isLoggedIn){ + req.session.revpost = req.body.postid; + res.json({suc:true}); + //res.sendFile(__dirname + '/public/post-review.html') + } else { + res.json({suc:false}); + } +}); + +app.get("/post-review", (req, res) => { + if(req.session.isLoggedIn ){ + res.sendFile(__dirname + '/public/post-review.html') + } else { + req.session = null; + res.redirect("/"); + } +}); + +/*--------------------------------------------------GETTER FUNCTIONS--------------------------------------------------*/ + +app.get("/getmods", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "admin"){ + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({role:"mod"}, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + resArray.push({ + username:element.username, + suspended:element.suspended + }) + }); + res.json({suc:true, users:resArray}) + } else { + res.json({suc:false}); + } + + }) + } else { + res.json({suc:false}); + } +}); + +app.get("/getusers", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "mod"){ + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({role:"user" , group: req.session.userid }, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + resArray.push({ + username:element.username, + suspended:element.suspended + }) + }); + res.json({suc:true, users:resArray}) + } else { + res.json({suc:false}); + } + + }) + } else { + res.json({suc:false}); + } +}); + +app.get("/getReviewPost", (req, res) => { + if(req.session.isLoggedIn){ + const db = new Datastore("db/posts.db"); + db.loadDatabase(); + db.find({_id:req.session.revpost}, (err, docs) => { + if(docs.length === 1) { + let post = []; + post.push({ + postid:docs[0]._id, + username:docs[0].creatorName, + showpost:docs[0].showpost, + title:docs[0].title, + text:docs[0].text, + bcolor:docs[0].bcolor, + startdate:docs[0].startDate, + enddate:docs[0].endDate, + }) + res.json({suc:true, post:post}) + } else { + res.json({suc:false}); + } + }) + } else { + res.json({suc:false}); + } +}); + +app.get("/getposts", (req, res) => { + if(req.session.isLoggedIn){ + const db_post = new Datastore("db/posts.db"); + db_post.loadDatabase(); + switch(req.session.userRole) + { + case "admin": + db_post.find({}, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + resArray.push({ + creator: element.creatorName, + postid: element._id, + title:element.title, + text:element.text, + showpost:element.showpost, + startDate:element.startDate, + endDate:element.endDate, + }) + }); + res.json({suc:true, users:resArray}) + } else { + res.json({suc:false}); + } + }); + break; + case "mod": + db_post.find({creatorGroup:req.session.userid}, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + resArray.push({ + creator: element.creatorName, + postid: element._id, + title:element.title, + text:element.text, + showpost:element.showpost, + startDate:element.startDate, + endDate:element.endDate, + }) + }); + res.json({suc:true, users:resArray}) + } else { + res.json({suc:false}); + } + }); + break; + case "user": + db_post.find({creatorId:req.session.userid}, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + resArray.push({ + title:element.title, + showpost:element.showpost, + postid:element._id + }) + }); + res.json({suc:true, users:resArray}) + } else { + res.json({suc:false}); + }}); + break; + } + } +}); + +app.get("/getliveposts", (req, res) => { + const now = new Date(); + const db_post = new Datastore("db/posts.db"); + db_post.loadDatabase(); + const db_users = new Datastore("db/users.db"); + db_users.loadDatabase(); + db_post.find({}, (err, docs) => { + if(docs.length > 0) { + let resArray = []; + docs.forEach(element => { + if(element.showpost){ + + var start = new Date(element.startDate) - now; + var end = new Date(element.endDate) - now; + if(start < 0 && end > 0){ + db_users.find({_id:element.creatorId}, (err2, docs2) =>{ + docs2.forEach(element2 => { + if(!element2.suspended) + { + db_users.find({_id:element.creatorGroup}, (err3, docs3) =>{ + docs3.forEach(element3 => { + if(!element3.suspended) + { + resArray.push({ + title:element.title, + text:element.text, + bcolor:element.bcolor + }) + } + }) + }) + } + }) + }) + } + } + }); + setTimeout(function(){ res.json({suc:true, posts:resArray}); }, 100); //delay to resolve timing issue + } else { + res.json({suc:false}); + } + }); +}); + +/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/ + +app.post("/login", (req, res) => { + const db = new Datastore("db/users.db"); + db.loadDatabase(); + const un = req.body.username; + const pw = req.body.password; + if(un && pw){ + db.find({username:un}, (err, docs) => { + if(docs.length === 1){ + const userRole = docs[0].role; + bcrypt.compare(pw, docs[0].password, (err2, result) => { + if(result){ + req.session.userRole = userRole; + req.session.userid = docs[0]._id; + req.session.gr = docs[0].group; + req.session.un = docs[0].username; + req.session.revpost = 0; + req.session.isLoggedIn = true; + if(userRole === "admin") { + res.json({suc:true, redirect:"admin"}) //login to admin page + } else if(userRole === "mod"){ + res.json({suc:true, redirect:"mod"}) //login to mod page + } else if(userRole === "user"){ + res.json({suc:true, redirect:"user"}) //login to user page + } + } else { res.json({suc:false}); } + }) + } else { res.json({suc:false}); } + }) + } else { res.json({suc:false}); } +}); + +app.get("/logout", (req, res) => { + req.session = null; + res.redirect("/"); +}); + +app.post("/changepw", (req, res) => { + const db = new Datastore("db/users.db"); + db.loadDatabase(); + const old_pw = req.body.old_password; + const new_pw_1 = req.body.new_password_1; + const new_pw_2 = req.body.new_password_2; + if(old_pw && (new_pw_1 === new_pw_2)){ + db.find({_id:req.session.userid}, (err, docs) => { + if(docs.length === 1){ + bcrypt.compare(old_pw, docs[0].password, (err2, result) => { + if(result){ + bcrypt.hash(new_pw_1, 10, (err3, hash) => { + db.update({_id: docs[0]._id}, {$set: {password: hash}}, (err4, num) =>{ + res.json({suc:true}); + }); + }) + } else { res.json({suc:false}); } + }) + } else { res.json({suc:false}); } + }) + } else { res.json({suc:false}); } +}) + +app.post("/newmod", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "admin"){ + const nun = req.body.username; + const nemail = req.body.email; + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({username:nun}, (err, docs) => { + if(docs.length === 0){ + db.find({email:nemail}, (err2, docs2) => { + if(docs2.length === 0){ + bcrypt.hash(nun, 10, (err3, hash) => { + db.insert({email: nemail, + username: nun, + password: hash, + role: "mod", + suspended: false + }, (err4, doc) => { + res.json({suc:true}); + }); + }); + } else { + res.json({suc:false}); + } + }); + } else { + res.json({suc:false}); + } + }); + } else { + res.json({suc:false}); + } +}) + +app.post("/newuser", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "mod"){ + const nun = req.body.username; + const nemail = req.body.email; + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({username:nun}, (err, docs) => { + if(docs.length === 0){ + db.find({email:nemail}, (err2, docs2) => { + if(docs2.length === 0){ + bcrypt.hash(nun, 10, (err3, hash) => { + db.insert({ + email: nemail, + username: nun, + password: hash, + role: "user", + group: req.session.userid, + suspended: false + }, (err4, doc) => { + res.json({suc:true}); + }); + }); + } else { + res.json({suc:false}); + } + }); + } else { + res.json({suc:false}); + } + }); + } else { + res.json({suc:false}); + } +}) + +app.post("/newpost", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "user"){ + const db = new Datastore("db/posts.db"); + db.loadDatabase(); + db.insert({ + creatorId:req.session.userid , + creatorName:req.session.un , + creatorGroup:req.session.gr , + showpost:false , + startDate:req.body.startDate , + endDate:req.body.endDate , + title:req.body.title , + text:req.body.text, + bcolor:req.body.bcolor + }, (err, doc) => { + res.json({suc:true}); + }); + } +}); + +app.post("/toggleSus", (req, res) => { + if(req.session.isLoggedIn && (req.session.userRole === "admin" || req.session.userRole === "mod")){ + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({username:req.body.username}, (err, docs) => { + if(docs.length === 1) { + var now = !docs[0].suspended; + db.update({_id: docs[0]._id}, {$set: {suspended: now}}, (err2, num) =>{ + res.json({suc:true}); + }) + } else { + res.json({suc:false}); + } + + }) + } else { + res.json({suc:false}); + } +}); + +app.post("/toggleShow", (req, res) => { + if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){ + const db = new Datastore("db/posts.db"); + db.loadDatabase(); + db.find({_id:req.body.postid}, (err, docs) => { + if(docs.length === 1) { + var now = !docs[0].showpost; + db.update({_id: docs[0]._id}, {$set: {showpost: now}}, (err2, num) =>{ + res.json({suc:true}); + }) + } else { + res.json({suc:false}); + } + }) + } else { + res.json({suc:false}); + } +}); + +app.post("/deleteMod", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "admin") { + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({username:req.body.username}, (err, docs) => { + if(docs.length === 1) { + deleteMod(docs[0]._id); + setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue + } else { + res.json({suc:false}); + } + }) + } else { + res.json({suc:false}); + } +}); + +app.post("/deleteUser", (req, res) => { + if(req.session.isLoggedIn && req.session.userRole === "mod"){ + const db = new Datastore("db/users.db"); + db.loadDatabase(); + db.find({username:req.body.username}, (err, docs) => { + if(docs.length === 1) { + deleteUser(docs[0]._id); + setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue + } else { + res.json({suc:false}); + } + }) + } else { + res.json({suc:false}); + } +}); + +app.post("/deletePost", (req, res) => { + if(req.session.isLoggedIn){ + const db = new Datastore("db/posts.db"); + db.loadDatabase(); + db.find({_id:req.body.postid}, (err, docs) => { + if(docs.length === 1) { + deletePost(docs[0]._id); + setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue + } else { + res.json({suc:false}); + } + }) + } else { + res.json({suc:false}); + } +}); + +/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/ + +function deleteMod(modID){ + const db_users = new Datastore("db/users.db"); + db_users.loadDatabase(); + db_users.find({group:modID}, (err, docs) => { + docs.forEach(element => { + deleteUser(element._id); + if(docs.indexOf(element) === docs.length-1) + db_users.find({_id:modID}, (err2, docs2) => { + console.log("deleted mod: ", docs2[0]._id); + db_users.remove({_id: docs2[0]._id}); + }) + }); + }) +} + +function deleteUser(userID){ + const db_posts = new Datastore("db/posts.db"); + db_posts.loadDatabase(); + db_posts.find({creatorId:userID}, (err, docs) => { + docs.forEach(element => { + deletePost(element._id); + }); + }) + const db_users = new Datastore("db/users.db"); + db_users.loadDatabase(); + db_users.find({_id:userID}, (err, docs) => { + console.log("deleted user: ", docs[0]._id); + db_users.remove({_id: docs[0]._id}) + + }) +} + +function deletePost(postID){ + const db_posts = new Datastore("db/posts.db"); + db_posts.loadDatabase(); + db_posts.find({_id:postID}, (err, docs) => { + console.log("deleted post: ", docs[0]._id); + db_posts.remove({_id: docs[0]._id}); + }) +} \ No newline at end of file diff --git a/server.start b/server.start new file mode 100644 index 0000000..ef01e3d --- /dev/null +++ b/server.start @@ -0,0 +1,4 @@ +#!/bin/bash + +cd `dirname $0` +node server.js