From 7f3b756378e4f1aadcff72a02c80fb5cbf858d11 Mon Sep 17 00:00:00 2001 From: Matei Adriel Date: Sun, 19 May 2019 21:37:39 +0300 Subject: [PATCH] typescript(multiplayer-backend): initial commit Signed-off-by: prescientmoon --- typescript/multiplayer-backend/config.ts | 14 +- .../multiplayer-backend/package-lock.json | 355 +++++++++++++++++- typescript/multiplayer-backend/package.json | 14 + .../multiplayer-backend/src/createServer.ts | 66 +++- typescript/multiplayer-backend/src/main.ts | 26 +- .../src/middleware/corsErrorMiddleware.ts | 31 +- .../src/middleware/morgan/index.ts | 26 ++ .../src/middleware/sessions/index.ts | 1 + .../src/middleware/sessions/sessions.ts | 24 ++ .../src/models/Password.ts | 9 + .../multiplayer-backend/src/models/User.ts | 13 + .../src/routes/auth/auth.ts | 218 +++++++++-- .../src/routes/auth/index.ts | 1 + .../multiplayer-backend/src/routes/index.ts | 8 + .../src/routes/logging/index.ts | 1 + .../src/routes/logging/logs.ts | 4 +- .../src/services/auth/signup.ts | 45 +++ .../src/services/db/firestore.ts | 8 + .../src/services/db/mongo/index.ts | 1 + .../src/services/db/mongo/mongo.ts | 16 + typescript/multiplayer-backend/tsconfig.json | 6 +- 21 files changed, 807 insertions(+), 80 deletions(-) create mode 100644 typescript/multiplayer-backend/src/middleware/morgan/index.ts create mode 100644 typescript/multiplayer-backend/src/middleware/sessions/index.ts create mode 100644 typescript/multiplayer-backend/src/middleware/sessions/sessions.ts create mode 100644 typescript/multiplayer-backend/src/models/Password.ts create mode 100644 typescript/multiplayer-backend/src/models/User.ts create mode 100644 typescript/multiplayer-backend/src/routes/auth/index.ts create mode 100644 typescript/multiplayer-backend/src/routes/index.ts create mode 100644 typescript/multiplayer-backend/src/routes/logging/index.ts create mode 100644 typescript/multiplayer-backend/src/services/auth/signup.ts create mode 100644 typescript/multiplayer-backend/src/services/db/firestore.ts create mode 100644 typescript/multiplayer-backend/src/services/db/mongo/index.ts create mode 100644 typescript/multiplayer-backend/src/services/db/mongo/mongo.ts diff --git a/typescript/multiplayer-backend/config.ts b/typescript/multiplayer-backend/config.ts index 670eb50..f508ed7 100644 --- a/typescript/multiplayer-backend/config.ts +++ b/typescript/multiplayer-backend/config.ts @@ -1,5 +1,3 @@ -//public config - //interfaces export interface routeList { [key: string]: string @@ -17,6 +15,12 @@ export const routes: routeList = { } //whitelist of urls -export const whiteList = [{ - url: "http://localhost:4200" -}] \ No newline at end of file +export const whiteList: whiteListUrl[] = [{ + url: "localhost:4200" +},{ + url: "localhost:8000" +},{ + url: "localhost:3000" +}] + +export const staticRoutes:string[] = [] \ No newline at end of file diff --git a/typescript/multiplayer-backend/package-lock.json b/typescript/multiplayer-backend/package-lock.json index ba61654..a6381b0 100644 --- a/typescript/multiplayer-backend/package-lock.json +++ b/typescript/multiplayer-backend/package-lock.json @@ -235,6 +235,12 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "optional": true }, + "@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "dev": true + }, "@types/body-parser": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", @@ -245,12 +251,30 @@ "@types/node": "*" } }, + "@types/bson": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.0.tgz", + "integrity": "sha512-pq/rqJwJWkbS10crsG5bgnrisL8pML79KlMKQMoQwLUjlPAkrUHMvHJ3oGwE7WHR61Lv/nadMwXVAD2b+fpD8Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", "optional": true }, + "@types/chalk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw==", + "dev": true, + "requires": { + "chalk": "*" + } + }, "@types/connect": { "version": "3.4.32", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", @@ -260,6 +284,18 @@ "@types/node": "*" } }, + "@types/connect-mongo": { + "version": "0.0.41", + "resolved": "https://registry.npmjs.org/@types/connect-mongo/-/connect-mongo-0.0.41.tgz", + "integrity": "sha512-l2ork/LNrZftIaYQstJozRHwijmWz7QRbNMIo3UKVDcfsFeh5hyrHHwmurcqOEEstnw1kxaJF4Yr93AykfPsLg==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/express-session": "*", + "@types/mongodb": "*", + "@types/mongoose": "*" + } + }, "@types/dotenv": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz", @@ -327,6 +363,12 @@ "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.123", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz", + "integrity": "sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==", + "dev": true + }, "@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", @@ -339,6 +381,35 @@ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", "dev": true }, + "@types/mongodb": { + "version": "3.1.26", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.26.tgz", + "integrity": "sha512-i7+l95IbqnGLRW+AJ6F2nzqosLUgU022lDuoHhbQquMV7tgek0vNUg9RwC2Fn7ImBSQSFdCWeU394ciPEwSeaQ==", + "dev": true, + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "@types/mongoose": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.5.0.tgz", + "integrity": "sha512-LIuVYQ/6y3ak5f+0C6J+t1ufZA/dM0bqkmEHOtbPO6pH/VB09Tn+BoTh2T2/UbkKH4SLdvupQQRBuCu3XXxynQ==", + "dev": true, + "requires": { + "@types/mongodb": "*", + "@types/node": "*" + } + }, + "@types/morgan": { + "version": "1.7.35", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.7.35.tgz", + "integrity": "sha512-E9qFi0seOkdlQnCTPv54brNfGWeFdRaEhI5tSue4pdx/V+xfxvMETsxXhOEcj1cYL+0n/jcTEmj/jD2gjzCwMg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { "version": "11.13.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.0.tgz", @@ -430,7 +501,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -601,6 +671,19 @@ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "optional": true }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, "bignumber.js": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", @@ -613,6 +696,11 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, "body-parser": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", @@ -694,6 +782,11 @@ } } }, + "bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -704,6 +797,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, "bun": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/bun/-/bun-0.0.12.tgz", @@ -794,7 +892,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -924,7 +1021,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -932,8 +1028,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colour": { "version": "0.7.1", @@ -1001,6 +1096,72 @@ "xdg-basedir": "^3.0.0" } }, + "connect-mongo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.3.tgz", + "integrity": "sha512-Vs+QZ/6X6gbCrP1Ls7Oh/wlyY6pgpbPSrUKF5yRT+zd+4GZPNbjNquxquZ+Clv2+03HBXE7T4lVM0PUcaBhihg==", + "requires": { + "mongodb": "^2.0.36" + }, + "dependencies": { + "bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "mongodb": { + "version": "2.2.36", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", + "integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.20", + "readable-stream": "2.2.7" + } + }, + "mongodb-core": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz", + "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -1253,8 +1414,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "etag": { "version": "1.8.1", @@ -1587,6 +1747,11 @@ } } }, + "firestore-store": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/firestore-store/-/firestore-store-1.0.0.tgz", + "integrity": "sha512-brRdcWKHMxcGu065TjmTBAF6Dai2oS9IN/Z44B6vrGNdCph/dNea18MuylhRk/GjmSNIIylTYiEdF/v+z0IxHg==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2928,8 +3093,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-value": { "version": "1.0.0", @@ -3318,6 +3482,11 @@ "safe-buffer": "^5.0.1" } }, + "kareem": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", + "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -3468,6 +3637,12 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -3553,6 +3728,115 @@ } } }, + "mongodb": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.3.tgz", + "integrity": "sha512-jw8UyPsq4QleZ9z+t/pIVy3L++51vKdaJ2Q/XXeYxk/3cnKioAH8H6f5tkkDivrQL4PUgUOHe9uZzkpRFH1XtQ==", + "requires": { + "mongodb-core": "^3.2.3", + "safe-buffer": "^5.1.2" + } + }, + "mongodb-core": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.3.tgz", + "integrity": "sha512-UyI0rmvPPkjOJV8XGWa9VCTq7R4hBVipimhnAXeSXnuAPjuTqbyfA5Ec9RcYJ1Hhu+ISnc8bJ1KfGZd4ZkYARQ==", + "requires": { + "bson": "^1.1.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "mongoose": { + "version": "5.5.7", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.5.7.tgz", + "integrity": "sha512-Xs4SVuMGkMRdmKZ6ATGVvbp2pjI+KENCNhPZMnksjU3ZerkJHGhWKrUE1A6e/5iZ2lTu6Oz9AOPcfrDgp6BCUw==", + "requires": { + "async": "2.6.1", + "bson": "~1.1.1", + "kareem": "2.3.0", + "mongodb": "3.2.3", + "mongodb-core": "3.2.3", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.6.0", + "mquery": "3.2.0", + "ms": "2.1.1", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sift": "7.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "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==" + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "dependencies": { + "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" + } + } + } + }, + "mpath": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz", + "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" + }, + "mquery": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", + "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3957,6 +4241,11 @@ "safe-regex": "^1.1.0" } }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -3994,6 +4283,20 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -4046,6 +4349,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -4144,11 +4456,21 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "sift": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", + "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "snakeize": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", @@ -4312,6 +4634,15 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "split-array-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/split-array-stream/-/split-array-stream-2.0.0.tgz", @@ -4425,7 +4756,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -4516,6 +4846,11 @@ "nopt": "~1.0.10" } }, + "ts-mongoose": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/ts-mongoose/-/ts-mongoose-0.0.14.tgz", + "integrity": "sha512-CoVFdDYVrueUVn2P3rw74P7TomYEGhemnMm7EIiPltaROIyiKM1QyomCuakJMctp2kMaMQV1l9syauWc1ZKpnw==" + }, "ts-node": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz", diff --git a/typescript/multiplayer-backend/package.json b/typescript/multiplayer-backend/package.json index 01137ba..78fca6a 100644 --- a/typescript/multiplayer-backend/package.json +++ b/typescript/multiplayer-backend/package.json @@ -16,19 +16,33 @@ "author": "Matei Adriel", "license": "ISC", "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/chalk": "^2.2.0", + "@types/connect-mongo": "0.0.41", "@types/dotenv": "^6.1.1", "@types/express": "^4.16.1", "@types/express-session": "^1.15.12", "@types/express-validator": "^3.0.0", + "@types/lodash": "^4.14.123", + "@types/mongoose": "^5.5.0", + "@types/morgan": "^1.7.35", "nodemon": "^1.18.10", "ts-node": "^8.0.3" }, "dependencies": { + "bcryptjs": "^2.4.3", + "chalk": "^2.4.2", + "connect-mongo": "^2.0.3", "dotenv": "^7.0.0", "express": "^4.16.4", "express-session": "^1.16.1", "express-validator": "^5.3.1", "firebase-admin": "^7.2.0", + "firestore-store": "^1.0.0", + "lodash": "^4.17.11", + "mongoose": "^5.5.7", + "morgan": "^1.9.1", + "ts-mongoose": "0.0.14", "typescript": "^3.4.1" } } diff --git a/typescript/multiplayer-backend/src/createServer.ts b/typescript/multiplayer-backend/src/createServer.ts index 2246696..96c8a8e 100644 --- a/typescript/multiplayer-backend/src/createServer.ts +++ b/typescript/multiplayer-backend/src/createServer.ts @@ -1,26 +1,56 @@ import * as express from "express" -import { baseUrl, routes } from "../config"; -import { performance } from "perf_hooks" -import { shortLogger } from "./routes/logging/shortLog"; +import * as sessions from "express-session" +import chalk from "chalk"; -export interface serverSetupResults{ - time:number; - app:express.Application +import { staticRoutes } from "../config"; +import { routes } from "./routes" +import { urlencoded } from "body-parser"; +import { database } from "./services/db/firestore" +import { morganChalk } from "./middleware/morgan"; +import { sessionMiddleware } from "./middleware/sessions" + + +// @ts-ignore no declaration file +// import * as store from "firestore-store" +import * as store from "connect-mongo" +import { connection, connected } from "./services/db/mongo"; + +// const firestore = store(sessions) +export interface serverSetupResults { + app: express.Application } -export const setupServer = ():serverSetupResults => { +export const setupServer = (): Promise => + new Promise(async (res, rej) => { + try { + let MongoStore = store(sessions) - const start = performance.now() - const app = express() + await connected - for (let i in routes) { - const route = require(`${process.cwd()}/${baseUrl}${routes[i]}`) - app.use(i, route.router) - } + //create express app + const app = express() - const time = performance.now() - start - const message = `Server created in: ${Math.floor(time)}ms` - shortLogger.log("Server created",message) + app.use(urlencoded({ extended: true }), sessions({ + secret: process.env.SESSION_SECRET, + saveUninitialized: false, + resave: false, + store: new MongoStore({ mongooseConnection: connection }) + }), morganChalk, sessionMiddleware) - return {app,time} -} \ No newline at end of file + //load static routes + staticRoutes.forEach(route => { + app.use(express.static(`${route}`)) + }) + + //Load normal routes + for (let i in routes) { + app.use(`/${i}`, routes[i]) + } + console.log(chalk.bold.green("👏 Succesfully creatd server!")) + + res({ app }) + } + catch (err) { + rej(err) + } + }) \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/main.ts b/typescript/multiplayer-backend/src/main.ts index 50965f4..0a465d4 100644 --- a/typescript/multiplayer-backend/src/main.ts +++ b/typescript/multiplayer-backend/src/main.ts @@ -1,11 +1,27 @@ import { config } from "dotenv" import { setupServer } from "./createServer"; +import { connected } from "./services/db/mongo" +import chalk from "chalk"; -//extract env variables +//⚓ connect to mongodb +connected.then(val => { + console.log(chalk.bold.green("⚓ Succesfully connected to mongoDb!!!")) +}).catch(err => { + console.log(err) + console.log(chalk.bold.red("😭 Something went wrong when connecting to mongoDb!!!")) + process.exit(1) +}) + +//🗻 extract env variables config() -//create the server -const {app} = setupServer() +const main = async () => { -//start listeing to requests -app.listen(process.env.PORT) + //create the server + const { app } = await setupServer() + + //start listeing to requests + app.listen(process.env.PORT) +} + +main() \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/middleware/corsErrorMiddleware.ts b/typescript/multiplayer-backend/src/middleware/corsErrorMiddleware.ts index 6b6523a..7ab2868 100644 --- a/typescript/multiplayer-backend/src/middleware/corsErrorMiddleware.ts +++ b/typescript/multiplayer-backend/src/middleware/corsErrorMiddleware.ts @@ -1,5 +1,8 @@ import { Request, Response } from "express" -import { whiteList, whiteListUrl } from "../../config" +import { whiteList } from "../../config" +import { includes } from "lodash" + +const urls = whiteList.map(urlObject => urlObject.url) //TODO: remove from here const defaultMethods = "GET, POST, OPTIONS, PUT, PATCH, DELETE" @@ -9,21 +12,17 @@ const defaultMethods = "GET, POST, OPTIONS, PUT, PATCH, DELETE" * @param url the url to allow * @param methods the methods to allow the url to do */ -export const corsErrorFixer = ({url,methods}:whiteListUrl) => { - return (req: Request, res: Response, next: any) => { - res.setHeader('Access-Control-Allow-Origin', url) // Website you wish to allow to connect - res.setHeader('Access-Control-Allow-Methods', methods || defaultMethods) //// Request methods you wish to allow - res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type') // Request headers you wish to allow +export const corsErrorFixer = (req: Request, res: Response, next: any) => { + const host = req.get("host") + const methods: any = whiteList.find(value => value.url == host) || { methods: undefined } - // Pass to next layer of middleware - next(); - } -} + if (!includes(urls, host)) + return next() -/** - * used to allow all urls on the whitelist - */ -export const allowWhitelist = () => { - return whiteList.map(value => corsErrorFixer(value)) -} + res.setHeader('Access-Control-Allow-Origin', host) // Website you wish to allow to connect + res.setHeader('Access-Control-Allow-Methods', methods.methods || defaultMethods) //// Request methods you wish to allow + res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type') // Request headers you wish to allow + // Pass to next layer of middleware + next(); +} \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/middleware/morgan/index.ts b/typescript/multiplayer-backend/src/middleware/morgan/index.ts new file mode 100644 index 0000000..2fe53da --- /dev/null +++ b/typescript/multiplayer-backend/src/middleware/morgan/index.ts @@ -0,0 +1,26 @@ +import * as morgan from "morgan" +import chalk from "chalk" + +const { floor } = Math + +export const morganChalk = morgan(function (tokens, req, res) { + const status = Number(tokens.status(req,res)) + const statusFirstDigit = floor(status / 100) + + const emoji = (status === 200) ? + "👌" : (status === 203) ? + "🔎" : (status == 202) ? + "🚧" : (status === 302) ? + "🏹" : (statusFirstDigit === 2) ? + "🌝" : (statusFirstDigit === 4) ? + "😠" : + "❓" + + return [ + chalk.bold(`${emoji} `), + chalk.green.bold(tokens.method(req, res)), + chalk.red.bold(tokens.status(req, res)), + chalk.blue.italic(tokens.url(req, res)), + chalk.yellow(`${tokens['response-time'](req, res)} ms`), + ].join(' '); +}); \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/middleware/sessions/index.ts b/typescript/multiplayer-backend/src/middleware/sessions/index.ts new file mode 100644 index 0000000..6ebbdcd --- /dev/null +++ b/typescript/multiplayer-backend/src/middleware/sessions/index.ts @@ -0,0 +1 @@ +export * from "./sessions" \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/middleware/sessions/sessions.ts b/typescript/multiplayer-backend/src/middleware/sessions/sessions.ts new file mode 100644 index 0000000..ef1df2a --- /dev/null +++ b/typescript/multiplayer-backend/src/middleware/sessions/sessions.ts @@ -0,0 +1,24 @@ +import { Response, Request } from "express"; + +const getToken = (req: Request) => { + if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { // Authorization: Bearer g1jipjgi1ifjioj + // Handle token presented as a Bearer token in the Authorization header + return req.headers.authorization.split(' ')[1]; + } else if (req.query && req.query.token) { + // Handle token presented as URI param + return req.query.token; + } else if (req.cookies && req.cookies.token) { + // Handle token presented as a cookie parameter + return req.cookies.token; + } + // If we return null, we couldn't find a token. + // In this case, the JWT middleware will return a 401 (unauthorized) to the client for this request + return null; +} + +export const sessionMiddleware = (req: Request, res: Response, next: Function) => { + const token = getToken(req) + console.log(token) + + next() +} \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/models/Password.ts b/typescript/multiplayer-backend/src/models/Password.ts new file mode 100644 index 0000000..cdea3ac --- /dev/null +++ b/typescript/multiplayer-backend/src/models/Password.ts @@ -0,0 +1,9 @@ +import { createSchema, Type, typedModel, ExtractDoc } from "ts-mongoose" + +const PasswordSchema = createSchema({ + uid: Type.string(), + password: Type.string() +}) + +export const Passsord = typedModel("Password", PasswordSchema) +export type PasswordDoc = ExtractDoc; \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/models/User.ts b/typescript/multiplayer-backend/src/models/User.ts new file mode 100644 index 0000000..8bcef33 --- /dev/null +++ b/typescript/multiplayer-backend/src/models/User.ts @@ -0,0 +1,13 @@ +import { createSchema, Type, typedModel, ExtractDoc } from "ts-mongoose" + +const UserSchema = createSchema({ + name: Type.string(), + email: Type.string(), + photo: Type.string(), + friends: Type.array().of(Type.string()), + description: Type.optionalString(), + uid: Type.string() +}) + +export const User = typedModel("User", UserSchema) +export type UserDoc = ExtractDoc; \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/routes/auth/auth.ts b/typescript/multiplayer-backend/src/routes/auth/auth.ts index 42793b3..d20339f 100644 --- a/typescript/multiplayer-backend/src/routes/auth/auth.ts +++ b/typescript/multiplayer-backend/src/routes/auth/auth.ts @@ -1,11 +1,49 @@ -import { Router, Response, Request, urlencoded } from "express" +import { Router, Response, Request } from "express" import { reddirect } from "../../middleware/reddirect"; -import { allowWhitelist } from "../../middleware/corsErrorMiddleware"; -import * as sessions from "express-session" import * as validator from "express-validator" +import { generateUid, encodePassword } from "../../services/auth/signup"; +import { savePassword } from "../../services/auth/signup"; +import { corsErrorFixer } from "../../middleware/corsErrorMiddleware"; +import { config } from "dotenv" +import { compare } from "bcryptjs"; +import { User, UserDoc } from "../../models/User"; +import { Passsord } from "../../models/Password"; + +//extract env variables +config() const router = Router() +router.get("/test", (req, res) => { + res.send("just a test") +}) + +const loginHtml = (req: Request, res: Response) => { + res.send(` +
+
+ + +
+
+ + +
+
+ + +
+ +
+ `) +} + const sayHello = (req: Request, res: Response) => { res.send(`
@@ -13,34 +51,172 @@ const sayHello = (req: Request, res: Response) => { +
+ + +
+
+ + +
`) } -const auth = (req: Request, res: Response, next: any) => { - //validate - req.check("email", "email isnt valid").isEmail() - const errors = req.validationErrors() +const authHandler = async (req: Request, res: Response) => { + try { + //if already logged in return the uid + if (req.session.uid) + return res.redirect("auth/account") - //if we have erros mark it - if (errors) - req.session.errors = errors + //get data from body + const { password, email, name } = req.body - //reddirect to page - res.send(errors || "Succes!!!") + //check if the email isnt used + if (await User.findOne({ name })) + res.redirect("login") + + //validate + req.check("email", "email isnt valid").isEmail() + const errors = req.validationErrors() + + if (errors) + res.json({ error: `${req.body.email} is not a valid email` }) + + //generate an uid + const uid = await generateUid() + + const user = new User({ + email, + friends: [], + name, + photo: process.env.DEFAULTPROFILEPIC, + uid + } as UserDoc) //used for my editor to help me + + encodePassword(password) + + //save the password and the user in the db + await Promise.all([ + encodePassword(password).then(result => savePassword(uid, result)), + user.save() + ]) + + //save things in session + req.session.uid = uid + + //save in the session + req.session.save(() => { }) + + //send uid back + res.json({ + succes: true, + data: { + uid + } + }).status(200) + } + catch (errors) { + //send erros to clinet + res.json({ errors }) + } } -router.use(...allowWhitelist()) -router.use("*", urlencoded({ extended: true }), validator(), sessions({ - secret: process.env.SESSION_SECRET, - saveUninitialized: false, - resave: false -})) +const account = async (req: Request, res: Response) => { + try { + if (!req.session.uid) + res.json({ + succes: false, + errors: ["uid doesnt exist"] + }).status(203) -router.get("/", sayHello) -router.post("/", auth) + res.json({ + succes: true, + data: { + uid: req.session.uid + } + }) + } + catch (errors) { + //send erros to clinet + res.json({ errors }) + } +} + +const login = async (req: Request, res: Response) => { + try { + //check if we have an email or an username, and if we are note already logged in + if (req.session.uid) + return res.redirect("account") + + let type = "name" + + if (req.body.email) + type = "email" + + const { password } = req.body + const data = req.body[(type == "name") ? "name" : type] + + const doc = await User.findOne({ [data]: req.body[data] }) + const uid = doc.uid + + //check if the password is good + const passwordHash = await Passsord.findOne({ uid }) + const match = await compare(password, passwordHash.password) + + //return result + if (!match) + return res.json({ + succes: false, + errors: ["wrong password"], + data: { + uid, + hash: passwordHash.password, + password, + [data]: req.body[data] + } + }).status(400) + + //update the session ond save it + req.session.uid = uid + req.session.save(() => { }) + + //send it to the clinet + return res.json({ uid }) + } + catch (errors) { + return res.json({ errors }) + } +} + + +const logout = async (req: Request, res: Response) => { + //clear the uid + req.session.uid = undefined + + //save it to the db + req.session.save(() => { }) + + res.send({ succes: true }) +} + +router.use("*", validator(), corsErrorFixer) + +router + .get("/", sayHello) + .post("/", authHandler) + .get("/login", loginHtml) + .post("/login", login) + .get("/account", account) + .get("/logout", logout) + .get("/uid", (req, res) => { + res.send(req.session.uid) + }) + .get("/test/uid", async (req, res) => { + res.send(await generateUid()) + }) router.use("/*", reddirect("/auth")) -export { router } \ No newline at end of file +export const auth = router \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/routes/auth/index.ts b/typescript/multiplayer-backend/src/routes/auth/index.ts new file mode 100644 index 0000000..63978cd --- /dev/null +++ b/typescript/multiplayer-backend/src/routes/auth/index.ts @@ -0,0 +1 @@ +export * from "./auth" \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/routes/index.ts b/typescript/multiplayer-backend/src/routes/index.ts new file mode 100644 index 0000000..f2851f8 --- /dev/null +++ b/typescript/multiplayer-backend/src/routes/index.ts @@ -0,0 +1,8 @@ +import { auth } from "./auth" +import { logs } from "./logging" +import { Router } from "express"; + +export const routes:{[key:string]:Router} = { + auth, + logs +} diff --git a/typescript/multiplayer-backend/src/routes/logging/index.ts b/typescript/multiplayer-backend/src/routes/logging/index.ts new file mode 100644 index 0000000..81229b8 --- /dev/null +++ b/typescript/multiplayer-backend/src/routes/logging/index.ts @@ -0,0 +1 @@ +export * from "./logs" \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/routes/logging/logs.ts b/typescript/multiplayer-backend/src/routes/logging/logs.ts index bdda067..1b0ed62 100644 --- a/typescript/multiplayer-backend/src/routes/logging/logs.ts +++ b/typescript/multiplayer-backend/src/routes/logging/logs.ts @@ -1,7 +1,6 @@ import { Router, Response, Request } from "express" import { shortLogger } from "./shortLog"; import { reddirect } from "../../middleware/reddirect"; -import { allowWhitelist } from "../../middleware/corsErrorMiddleware"; const router = Router() @@ -9,8 +8,7 @@ const getShortLogs = (req: Request, res: Response) => { res.json(shortLogger.logs) } -router.use(...allowWhitelist()) router.get("/", getShortLogs) router.use("/*", reddirect("/logs")) -export { router } \ No newline at end of file +export const logs = router \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/services/auth/signup.ts b/typescript/multiplayer-backend/src/services/auth/signup.ts new file mode 100644 index 0000000..d59d038 --- /dev/null +++ b/typescript/multiplayer-backend/src/services/auth/signup.ts @@ -0,0 +1,45 @@ +import * as bcrypt from "bcryptjs" +import { promisify } from "util"; +import { randomBytes } from "crypto"; +import { database } from "../db/firestore"; +import { Passsord, PasswordDoc } from "../../models/Password"; +import { User } from "../../models/User"; + +//promisify functions +const hash = promisify(bcrypt.hash) + + +export async function generateUid(): Promise { + //generate uid + const uid = randomBytes(16).toString("hex") + + //check if document exists + const doc = await User.findOne({ uid }) + + //if theres already an user with the same id, regenerate + if (doc) + return generateUid() + + //then return the uid + return uid +} + +export function encodePassword(password: string): Promise { + return hash(password, 10) +} + +export function savePassword(uid: string, password: string) { + const passwordInstance = new Passsord({ + password, uid + } as PasswordDoc) + + return passwordInstance.save() +} + +export async function getPassword(uid: string) { + //get doc + const doc = await database.doc(`passwords/${uid}`).get() + + //return result + return doc.data() +} diff --git a/typescript/multiplayer-backend/src/services/db/firestore.ts b/typescript/multiplayer-backend/src/services/db/firestore.ts new file mode 100644 index 0000000..0192854 --- /dev/null +++ b/typescript/multiplayer-backend/src/services/db/firestore.ts @@ -0,0 +1,8 @@ +import * as admin from "firebase-admin" + +export const firebase = admin.initializeApp({ + credential: admin.credential.cert('firebase-admin.json'), + databaseURL: 'https://planets-io.firebaseio.com' +}); + +export const database = firebase.firestore() \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/services/db/mongo/index.ts b/typescript/multiplayer-backend/src/services/db/mongo/index.ts new file mode 100644 index 0000000..021a606 --- /dev/null +++ b/typescript/multiplayer-backend/src/services/db/mongo/index.ts @@ -0,0 +1 @@ +export * from "./mongo" \ No newline at end of file diff --git a/typescript/multiplayer-backend/src/services/db/mongo/mongo.ts b/typescript/multiplayer-backend/src/services/db/mongo/mongo.ts new file mode 100644 index 0000000..6e8944c --- /dev/null +++ b/typescript/multiplayer-backend/src/services/db/mongo/mongo.ts @@ -0,0 +1,16 @@ +import { config } from "dotenv" +import { connect, model, connection } from "mongoose" + +config() +connect(process.env.DATABASE, { useNewUrlParser: true }) + +export const connected = new Promise((res, rej) => { + connection.on("open", (...args: any[]) => { + res(...args) + }) + connection.on("error", (...args: any[]) => { + rej(...args) + }) +}) + +export { connection } diff --git a/typescript/multiplayer-backend/tsconfig.json b/typescript/multiplayer-backend/tsconfig.json index 4ad036c..1639566 100644 --- a/typescript/multiplayer-backend/tsconfig.json +++ b/typescript/multiplayer-backend/tsconfig.json @@ -19,13 +19,15 @@ "experimentalDecorators": true, "downlevelIteration": true, "target": "ESNext", - "resolveJsonModule": true + "resolveJsonModule": true, + "jsx": "preserve" }, "include": [ "src" ], "exclude": [ "node_modules", - "dist" + "dist", + "old_client" ] } \ No newline at end of file