diff --git a/config/default.json b/config/default.json new file mode 100644 index 0000000..08b7501 --- /dev/null +++ b/config/default.json @@ -0,0 +1,9 @@ +{ + "db": { + "user": "postgres", + "password": "node4db", + "host": "localhost", + "port": 5432, + "database": "node4db" + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9b4ff82 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3' +services: + db: + image: postgres + environment: + POSTGRES_PASSWORD: node4db + ports: + - 5432:5432 + volumes: + - node4db:/var/lib/postgresql/data +volumes: + node4db: diff --git a/migrations/1564110336692_add-users-table.js b/migrations/1564110336692_add-users-table.js new file mode 100644 index 0000000..b773aca --- /dev/null +++ b/migrations/1564110336692_add-users-table.js @@ -0,0 +1,26 @@ +exports.shorthands = undefined; + +exports.up = pgm => { + pgm.createTable('users', { + id: { + type: 'serial', + primaryKey: true, + }, + username: { + type: 'text', + notNull: true, + }, + email: { + type: 'text', + notNull: true, + }, + password: { + type: 'text', + notNull: true, + }, + }); +}; + +exports.down = (pgm) => { + +}; diff --git a/package-lock.json b/package-lock.json index c7d01d0..6932c38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "resolved": "https://registry.npmjs.org/@phc/format/-/format-0.5.0.tgz", "integrity": "sha512-JWtZ5P1bfXU0bAtTzCpOLYHDXuxSVdtL/oqz4+xa97h8w9E5IlVN333wugXVFv8vZ1hbXObKQf1ptXmFFcMByg==", "requires": { - "safe-buffer": "^5.1.2" + "safe-buffer": "5.1.2" } }, "@types/node": { @@ -22,8 +22,8 @@ "resolved": "https://registry.npmjs.org/@types/pg/-/pg-7.4.14.tgz", "integrity": "sha512-2e4XapP9V/X42IGByC5IHzCzHqLLCNJid8iZBbkk6lkaDMvli8Rk62YE9wjGcLD5Qr5Zaw1ShkQyXy91PI8C0Q==", "requires": { - "@types/node": "*", - "@types/pg-types": "*" + "@types/node": "12.6.8", + "@types/pg-types": "1.11.4" } }, "@types/pg-types": { @@ -31,7 +31,7 @@ "resolved": "https://registry.npmjs.org/@types/pg-types/-/pg-types-1.11.4.tgz", "integrity": "sha512-WdIiQmE347LGc1Vq3Ki8sk3iyCuLgnccqVzgxek6gEHp2H0p3MQ3jniIHt+bRODXKju4kNQ+mp53lmP5+/9moQ==", "requires": { - "moment": ">=2.14.0" + "moment": "2.24.0" } }, "accepts": { @@ -39,7 +39,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "requires": { - "mime-types": "~2.1.24", + "mime-types": "2.1.24", "negotiator": "0.6.2" } }, @@ -53,7 +53,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.3" } }, "argon2": { @@ -61,9 +61,9 @@ "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.24.0.tgz", "integrity": "sha512-796movQU1LIW4egM+FH2mrgaTBtIhjEvuTx3sfw0W+Ijbk29IvKOh/i1IDAKCS9s6Y+2GdlPVU5q/gQZ3lyp5w==", "requires": { - "@phc/format": "^0.5.0", - "node-addon-api": "^1.6.3", - "node-gyp-build": "^4.1.0" + "@phc/format": "0.5.0", + "node-addon-api": "1.7.1", + "node-gyp-build": "4.1.0" } }, "array-flatten": { @@ -87,15 +87,15 @@ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "requires": { "bytes": "3.1.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", - "type-is": "~1.6.17" + "type-is": "1.6.18" } }, "brace-expansion": { @@ -103,7 +103,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -132,9 +132,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "3.1.0", + "strip-ansi": "5.2.0", + "wrap-ansi": "5.1.0" } }, "color-convert": { @@ -166,7 +166,7 @@ "integrity": "sha512-rOsfIOAcG82AWouK4/vBS/OKz3UPl2T/kP0irExmXJJOoWg2CmdfPLdx56bCoMUMFNh+7soQkQWCUC8DyemiwQ==", "optional": true, "requires": { - "json5": "^1.0.1" + "json5": "1.0.1" } }, "content-disposition": { @@ -197,11 +197,11 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "nice-try": "1.0.5", + "path-key": "2.0.1", + "semver": "5.7.0", + "shebang-command": "1.2.0", + "which": "1.3.1" } }, "debug": { @@ -238,7 +238,7 @@ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "ee-first": { @@ -261,7 +261,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { - "once": "^1.4.0" + "once": "1.4.0" } }, "escape-html": { @@ -279,13 +279,13 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "6.0.5", + "get-stream": "4.1.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" } }, "express": { @@ -293,36 +293,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "requires": { - "accepts": "~1.3.7", + "accepts": "1.3.7", "array-flatten": "1.1.1", "body-parser": "1.19.0", "content-disposition": "0.5.3", - "content-type": "~1.0.4", + "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", + "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", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", + "proxy-addr": "2.0.5", "qs": "6.7.0", - "range-parser": "~1.2.1", + "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", + "statuses": "1.5.0", + "type-is": "1.6.18", "utils-merge": "1.0.1", - "vary": "~1.1.2" + "vary": "1.1.2" } }, "finalhandler": { @@ -331,12 +331,12 @@ "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" + "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" } }, "find-up": { @@ -344,7 +344,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "requires": { - "locate-path": "^3.0.0" + "locate-path": "3.0.0" } }, "forwarded": { @@ -372,7 +372,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "requires": { - "pump": "^3.0.0" + "pump": "3.0.0" } }, "glob": { @@ -380,12 +380,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "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" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "http-errors": { @@ -393,10 +393,10 @@ "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", + "depd": "1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", + "statuses": "1.5.0", "toidentifier": "1.0.0" } }, @@ -405,7 +405,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "inflight": { @@ -413,8 +413,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -453,7 +453,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "optional": true, "requires": { - "minimist": "^1.2.0" + "minimist": "1.2.0" } }, "jsonwebtoken": { @@ -461,16 +461,16 @@ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" + "jws": "3.2.2", + "lodash.includes": "4.3.0", + "lodash.isboolean": "3.0.3", + "lodash.isinteger": "4.0.4", + "lodash.isnumber": "3.0.3", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.once": "4.1.1", + "ms": "2.1.2", + "semver": "5.7.0" }, "dependencies": { "ms": { @@ -487,7 +487,7 @@ "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "jws": { @@ -495,8 +495,8 @@ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" + "jwa": "1.4.1", + "safe-buffer": "5.1.2" } }, "lcid": { @@ -504,7 +504,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "requires": { - "invert-kv": "^2.0.0" + "invert-kv": "2.0.0" } }, "locate-path": { @@ -512,8 +512,8 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "3.0.0", + "path-exists": "3.0.0" } }, "lodash": { @@ -566,7 +566,7 @@ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "requires": { - "p-defer": "^1.0.0" + "p-defer": "1.0.0" } }, "massive": { @@ -598,9 +598,9 @@ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" + "map-age-cleaner": "0.1.3", + "mimic-fn": "2.1.0", + "p-is-promise": "2.1.0" } }, "merge-descriptors": { @@ -641,7 +641,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -700,12 +700,12 @@ "resolved": "https://registry.npmjs.org/node-pg-migrate/-/node-pg-migrate-3.21.1.tgz", "integrity": "sha512-gTd8NquEcJjhkT96iwnch6DyAdZ9bhi+avdAvV4kPw/ya7T4OijUoSNVJzCodCG2kIjv+fjssnZHC/LzEQdewg==", "requires": { - "@types/pg": "^7.4.0", - "config": ">=1.0.0", - "dotenv": ">=1.0.0", - "lodash": "~4.17.0", - "mkdirp": "~0.5.0", - "yargs": "~13.2.0" + "@types/pg": "7.4.14", + "config": "3.2.2", + "dotenv": "8.0.0", + "lodash": "4.17.15", + "mkdirp": "0.5.1", + "yargs": "13.2.4" } }, "npm-run-path": { @@ -713,7 +713,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "path-key": "^2.0.0" + "path-key": "2.0.1" } }, "on-finished": { @@ -729,7 +729,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-locale": { @@ -737,9 +737,9 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "execa": "1.0.0", + "lcid": "2.0.0", + "mem": "4.3.0" } }, "p-defer": { @@ -762,7 +762,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "requires": { - "p-try": "^2.0.0" + "p-try": "2.2.0" } }, "p-locate": { @@ -770,7 +770,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "requires": { - "p-limit": "^2.0.0" + "p-limit": "2.2.0" } }, "p-try": { @@ -809,16 +809,16 @@ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "pg": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-7.11.0.tgz", - "integrity": "sha512-YO4V7vCmEMGoF390LJaFaohWNKaA2ayoQOEZmiHVcAUF+YsRThpf/TaKCgSvsSE7cDm37Q/Cy3Gz41xiX/XjTw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.12.0.tgz", + "integrity": "sha512-q54Ic0oBXfDZMwheP8ALeUX32TUXvF7SNgAlZjyhkDuFCJkQCgcLBz0Be5uOrAj3ljSok/CI9lRbYzEko0z1Zw==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", "pg-connection-string": "0.1.3", - "pg-pool": "^2.0.4", - "pg-types": "~2.0.0", - "pgpass": "1.x", + "pg-pool": "2.0.6", + "pg-types": "2.0.1", + "pgpass": "1.0.2", "semver": "4.3.2" }, "dependencies": { @@ -864,6 +864,27 @@ "pg": "7.11.0", "pg-minify": "1.4.1", "spex": "2.2.0" + }, + "dependencies": { + "pg": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.11.0.tgz", + "integrity": "sha512-YO4V7vCmEMGoF390LJaFaohWNKaA2ayoQOEZmiHVcAUF+YsRThpf/TaKCgSvsSE7cDm37Q/Cy3Gz41xiX/XjTw==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-pool": "2.0.6", + "pg-types": "2.0.1", + "pgpass": "1.0.2", + "semver": "4.3.2" + } + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + } } }, "pg-query-stream": { @@ -880,10 +901,10 @@ "integrity": "sha512-b7y6QM1VF5nOeX9ukMQ0h8a9z89mojrBHXfJeSug4mhL0YpxNBm83ot2TROyoAmX/ZOX3UbwVO4EbH7i1ZZNiw==", "requires": { "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" + "postgres-array": "2.0.0", + "postgres-bytea": "1.0.0", + "postgres-date": "1.0.4", + "postgres-interval": "1.2.0" } }, "pgpass": { @@ -891,7 +912,7 @@ "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", "requires": { - "split": "^1.0.0" + "split": "1.0.1" } }, "postgres-array": { @@ -914,7 +935,7 @@ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "requires": { - "xtend": "^4.0.0" + "xtend": "4.0.2" } }, "proxy-addr": { @@ -922,7 +943,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.1.2", "ipaddr.js": "1.9.0" } }, @@ -931,8 +952,8 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "end-of-stream": "1.4.1", + "once": "1.4.0" } }, "qs": { @@ -987,18 +1008,18 @@ "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", + "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", + "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" + "on-finished": "2.3.0", + "range-parser": "1.2.1", + "statuses": "1.5.0" }, "dependencies": { "ms": { @@ -1013,9 +1034,9 @@ "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", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.3", "send": "0.17.1" } }, @@ -1034,7 +1055,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "1.0.0" } }, "shebang-regex": { @@ -1057,7 +1078,7 @@ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "requires": { - "through": "2" + "through": "2.3.8" } }, "statuses": { @@ -1070,9 +1091,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "7.0.3", + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "5.2.0" } }, "strip-ansi": { @@ -1080,7 +1101,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "4.1.0" } }, "strip-eof": { @@ -1104,7 +1125,7 @@ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "mime-types": "2.1.24" } }, "unpipe": { @@ -1127,7 +1148,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "which-module": { @@ -1140,9 +1161,9 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "3.2.1", + "string-width": "3.1.0", + "strip-ansi": "5.2.0" } }, "wrappy": { @@ -1165,17 +1186,17 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" + "cliui": "5.0.0", + "find-up": "3.0.0", + "get-caller-file": "2.0.5", + "os-locale": "3.1.0", + "require-directory": "2.1.1", + "require-main-filename": "2.0.0", + "set-blocking": "2.0.0", + "string-width": "3.1.0", + "which-module": "2.0.0", + "y18n": "4.0.0", + "yargs-parser": "13.1.1" } }, "yargs-parser": { @@ -1183,8 +1204,8 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "camelcase": "5.3.1", + "decamelize": "1.2.0" } } } diff --git a/package.json b/package.json index 34e0690..853d061 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,6 @@ "jsonwebtoken": "^8.5.1", "massive": "^5.11.2", "node-pg-migrate": "^3.21.1", - "pg": "^7.11.0" + "pg": "^7.12.0" } } diff --git a/server/controllers/users.js b/server/controllers/users.js new file mode 100644 index 0000000..82e2c24 --- /dev/null +++ b/server/controllers/users.js @@ -0,0 +1,93 @@ +const argon2 = require('argon2'); +const jwt = require('jsonwebtoken'); +const secret = require('../../secret'); + +function register(req, res) { + const db = req.app.get('db'); + const { username, email, password } = req.body; + + argon2 + .hash(password) + .then(hash => { + return db.users.insert( + { + username, + email, + password: hash, + }, + { + fields: ['id', 'username', 'email'], + } + ); + }) + .then(user => { + const token = jwt.sign({ userId: user.id }, secret); + + res.status(201).json({ ...user, token }); + }) + .catch(err => { + console.error(err); + res.status(500).end(); + }); +} + +function webToken(req, res) { + if (!req.headers.authorization) { + return res.status(401).end(); + } + + try { + const token = req.headers.authorization.split(' ')[1]; + jwt.verify(token, secret); + res.status(200).json({ data: 'here is the protected data' }); + } catch (err) { + console.error(err); + res.status(401).end(); + } +} + +function login(req, res) { + const db = req.app.get('db'); + const { username, password } = req.body; + + db.users + .findOne( + { + username, + }, + { + fields: ['id', 'username', 'email', 'password'], + } + ) + .then(user => { + if (!user) { + throw new Error('Invalid username'); + } + + return argon2.verify(user.password, password).then(valid => { + if (!valid) { + throw new Error('Incorrect password'); + } + + const token = jwt.sign({ userId: user.id }, secret); + delete user.password; + res.status(200).json({ ...user, token }); + }); + }) + .catch(err => { + if ( + ['Invalid username', 'Incorrect password'].includes(err.message) + ) { + res.status(400).json({ error: err.message }); + } else { + console.error(err); + res.status(500).end(); + } + }); +} + +module.exports = { + register, + webToken, + login +}; \ No newline at end of file diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..afd7e60 --- /dev/null +++ b/server/index.js @@ -0,0 +1,30 @@ +const express = require('express'); +const massive = require('massive'); + +//CONTROLLERS +const users = require('./controllers/users'); + +massive({ + host: 'localhost', + port: 5432, + database: 'node4db', + user: 'postgres', + password: 'node4db', +}).then(db => { + const app = express(); + + app.set('db', db); + + app.use(express.json()); + + const PORT = 3001; + + app.post('/api/register', users.register); + app.get('/api/protected/data', users.webToken); + app.post('/api/login', users.login); + + app.listen(PORT, () => { + console.log(`Server listening on port ${PORT}`); + }); + +}); \ No newline at end of file