From 02bf17d559b9c7a35b59cbf243fb0729bdde58f4 Mon Sep 17 00:00:00 2001
From: Mateiadrielrafael <rafaeladriel11@gmail.com>
Date: Mon, 12 Aug 2019 21:12:56 +0300
Subject: [PATCH] typescript(lunargame/api): added eslint

Signed-off-by: prescientmoon <git@moonythm.dev>
---
 typescript/lunargame/api/.eslintrc.json       |  25 +
 typescript/lunargame/api/.prettierrc.json     |   2 +-
 .../lunargame/api/.vscode/settings.json       |   4 +-
 .../api/db/migrations/create_account.js       |   4 +-
 typescript/lunargame/api/package-lock.json    | 821 +++++++++++++++++-
 typescript/lunargame/api/package.json         |  11 +-
 .../lang/arrays/helpers/randomElement.test.ts |  11 +-
 .../api/src/modules/auth/constants.ts         |   4 +
 .../auth/helpers/checkPassword.test.ts        |  20 +
 .../src/modules/auth/helpers/checkPassword.ts |  21 +
 .../auth/helpers/encryptPassword.test.ts      |  22 +
 .../modules/auth/helpers/encryptPassword.ts   |  24 +
 .../modules/auth/middleware/isAuthorized.ts   |  13 +
 .../auth/middleware/isUnauthorized.test.ts    |  28 +
 .../modules/auth/middleware/isUnauthorized.ts |  13 +
 .../modules/auth/middleware/loggedIn.test.ts  |  28 +
 .../auth/queries/createAccount.test.ts        |  32 +
 .../src/modules/auth/queries/createAccount.ts |  15 +
 .../auth/queries/getPasswordByEmail.test.ts   |  16 +
 .../auth/queries/getPasswordByEmail.ts        |  26 +
 .../src/modules/auth/routes/authRoute.test.ts |  91 +-
 .../api/src/modules/auth/routes/authRoute.ts  |  74 +-
 .../api/src/modules/auth/schemas/LoginBody.ts |  10 +-
 .../src/modules/auth/schemas/SignupBody.ts    |  10 +
 .../src/modules/auth/schemas/authFields.ts    |   4 +-
 .../api/src/modules/auth/types/Account.ts     |  32 +
 .../modules/auth/types/LoginReponseBody.ts    |   6 +
 .../modules/auth/types/passwordEncryption.ts  |   4 +
 .../api/test/seeds/01_create-account.ts       |  21 +
 .../lunargame/api/test/utils/loggedInAgent.ts |   7 +-
 30 files changed, 1345 insertions(+), 54 deletions(-)
 create mode 100644 typescript/lunargame/api/.eslintrc.json
 create mode 100644 typescript/lunargame/api/src/modules/auth/constants.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/helpers/checkPassword.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/helpers/checkPassword.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/middleware/isAuthorized.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/middleware/loggedIn.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/queries/createAccount.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/queries/createAccount.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.test.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/schemas/SignupBody.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/types/Account.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/types/LoginReponseBody.ts
 create mode 100644 typescript/lunargame/api/src/modules/auth/types/passwordEncryption.ts
 create mode 100644 typescript/lunargame/api/test/seeds/01_create-account.ts

diff --git a/typescript/lunargame/api/.eslintrc.json b/typescript/lunargame/api/.eslintrc.json
new file mode 100644
index 0000000..aa811e8
--- /dev/null
+++ b/typescript/lunargame/api/.eslintrc.json
@@ -0,0 +1,25 @@
+{
+    "parser": "@typescript-eslint/parser",
+    "env": {
+        "es6": true,
+        "node": true,
+        "jest": true
+    },
+    "extends": [
+        "plugin:@typescript-eslint/recommended",
+        "prettier/@typescript-eslint",
+        "plugin:prettier/recommended"
+    ],
+    "globals": {
+        "Atomics": "readonly",
+        "SharedArrayBuffer": "readonly"
+    },
+    "parserOptions": {
+        "ecmaVersion": 2018,
+        "sourceType": "module"
+    },
+    "rules": {
+        "@typescript-eslint/explicit-function-return-type": 0,
+        "@typescript-eslint/no-object-literal-type-assertion": 0
+    }
+}
diff --git a/typescript/lunargame/api/.prettierrc.json b/typescript/lunargame/api/.prettierrc.json
index 92a9ef9..ee615b2 100644
--- a/typescript/lunargame/api/.prettierrc.json
+++ b/typescript/lunargame/api/.prettierrc.json
@@ -1,7 +1,7 @@
 {
     "trailingComma": "none",
     "singleQuote": true,
-    "printWidth": 80,
+    "printWidth": 100,
     "tabWidth": 4,
     "semi": false
 }
diff --git a/typescript/lunargame/api/.vscode/settings.json b/typescript/lunargame/api/.vscode/settings.json
index 3277f6b..9651954 100644
--- a/typescript/lunargame/api/.vscode/settings.json
+++ b/typescript/lunargame/api/.vscode/settings.json
@@ -2,5 +2,7 @@
     "eslint.enable": true,
     "editor.formatOnSave": true,
     "prettier.eslintIntegration": true,
-    "explorer.autoReveal": false
+    "explorer.autoReveal": false,
+    "eslint.autoFixOnSave": true,
+    "eslint.validate": ["javascript", { "language": "typescript", "autoFix": true }]
 }
diff --git a/typescript/lunargame/api/db/migrations/create_account.js b/typescript/lunargame/api/db/migrations/create_account.js
index 61201d0..907d288 100644
--- a/typescript/lunargame/api/db/migrations/create_account.js
+++ b/typescript/lunargame/api/db/migrations/create_account.js
@@ -16,8 +16,8 @@ exports.up = knex => {
         // the password of the user
         table.text('password').notNullable()
 
-        // the password encription
-        table.text('password_encription').notNullable()
+        // the password encryption
+        table.text('passwordEncryption').notNullable()
     })
 }
 
diff --git a/typescript/lunargame/api/package-lock.json b/typescript/lunargame/api/package-lock.json
index 4de6711..9b22713 100644
--- a/typescript/lunargame/api/package-lock.json
+++ b/typescript/lunargame/api/package-lock.json
@@ -231,6 +231,47 @@
         "minimist": "^1.2.0"
       }
     },
+    "@hapi/address": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz",
+      "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw=="
+    },
+    "@hapi/hoek": {
+      "version": "6.2.4",
+      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-6.2.4.tgz",
+      "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A=="
+    },
+    "@hapi/joi": {
+      "version": "15.1.0",
+      "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.0.tgz",
+      "integrity": "sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==",
+      "requires": {
+        "@hapi/address": "2.x.x",
+        "@hapi/hoek": "6.x.x",
+        "@hapi/marker": "1.x.x",
+        "@hapi/topo": "3.x.x"
+      }
+    },
+    "@hapi/marker": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@hapi/marker/-/marker-1.0.0.tgz",
+      "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA=="
+    },
+    "@hapi/topo": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.3.tgz",
+      "integrity": "sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ==",
+      "requires": {
+        "@hapi/hoek": "8.x.x"
+      },
+      "dependencies": {
+        "@hapi/hoek": {
+          "version": "8.2.0",
+          "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.2.0.tgz",
+          "integrity": "sha512-pR2ZgiP562aiaQvQ98WgfqfTrm+xG+7hwHRPEiYZ+7U1OHAAb4OVZJIalCP03bMqYSioQzflzVTVrybSwDBn1Q=="
+        }
+      }
+    },
     "@jest/console": {
       "version": "24.7.1",
       "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz",
@@ -592,6 +633,12 @@
         "@types/node": "*"
       }
     },
+    "@types/eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+      "dev": true
+    },
     "@types/express": {
       "version": "4.17.0",
       "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz",
@@ -613,6 +660,12 @@
         "@types/range-parser": "*"
       }
     },
+    "@types/faker": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/@types/faker/-/faker-4.1.5.tgz",
+      "integrity": "sha512-YSDqoBEWYGdNk53xSkkb6REaUaVSlIjxIAGjj/nbLzlZOit7kUU+nA2zC2qQkIVO4MQ+3zl4Sz7aw+kbpHHHUQ==",
+      "dev": true
+    },
     "@types/form-data": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
@@ -621,6 +674,14 @@
         "@types/node": "*"
       }
     },
+    "@types/hapi__joi": {
+      "version": "15.0.3",
+      "resolved": "https://registry.npmjs.org/@types/hapi__joi/-/hapi__joi-15.0.3.tgz",
+      "integrity": "sha512-kncvQstpAQSjQ+J+tL2oYerjOEepv+yJHKM/JD/NmFZyDcy3rYOBcMJhdHRDjBxuSZu3ipGECszhgtmug9VSuw==",
+      "requires": {
+        "@types/hapi__joi": "*"
+      }
+    },
     "@types/http-assert": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.4.1.tgz",
@@ -673,6 +734,12 @@
       "integrity": "sha512-6gAT/UkIzYb7zZulAbcof3lFxpiD5EI6xBeTvkL1wYN12pnFQ+y/+xl9BvnVgxkmaIDN89xWhGZLD9CvuOtZ9g==",
       "dev": true
     },
+    "@types/json-schema": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz",
+      "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
+      "dev": true
+    },
     "@types/keygrip": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz",
@@ -750,15 +817,6 @@
       "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz",
       "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ=="
     },
-    "@types/nodemailer": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.2.0.tgz",
-      "integrity": "sha512-WGGEk/BGRLuYF3gyoTwbtKg5tCexZzb5lkTsis2k7GkAzlg4x2299/SC6Ssdj3X/5TzT1BHVc8zcFg/7KSzBLw==",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
-    },
     "@types/range-parser": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
@@ -831,6 +889,60 @@
       "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==",
       "dev": true
     },
+    "@typescript-eslint/eslint-plugin": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz",
+      "integrity": "sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/experimental-utils": "1.13.0",
+        "eslint-utils": "^1.3.1",
+        "functional-red-black-tree": "^1.0.1",
+        "regexpp": "^2.0.1",
+        "tsutils": "^3.7.0"
+      }
+    },
+    "@typescript-eslint/experimental-utils": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
+      "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
+      "dev": true,
+      "requires": {
+        "@types/json-schema": "^7.0.3",
+        "@typescript-eslint/typescript-estree": "1.13.0",
+        "eslint-scope": "^4.0.0"
+      }
+    },
+    "@typescript-eslint/parser": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz",
+      "integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==",
+      "dev": true,
+      "requires": {
+        "@types/eslint-visitor-keys": "^1.0.0",
+        "@typescript-eslint/experimental-utils": "1.13.0",
+        "@typescript-eslint/typescript-estree": "1.13.0",
+        "eslint-visitor-keys": "^1.0.0"
+      }
+    },
+    "@typescript-eslint/typescript-estree": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
+      "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
+      "dev": true,
+      "requires": {
+        "lodash.unescape": "4.0.1",
+        "semver": "5.5.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+          "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+          "dev": true
+        }
+      }
+    },
     "abab": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
@@ -876,6 +988,12 @@
         }
       }
     },
+    "acorn-jsx": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
+      "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
+      "dev": true
+    },
     "acorn-walk": {
       "version": "6.2.0",
       "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
@@ -970,6 +1088,15 @@
       "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==",
       "dev": true
     },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1378,6 +1505,12 @@
         "supports-color": "^5.3.0"
       }
     },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+      "dev": true
+    },
     "chokidar": {
       "version": "2.1.6",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
@@ -1437,6 +1570,21 @@
       "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
       "dev": true
     },
+    "cli-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^3.1.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
     "cliui": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
@@ -1841,6 +1989,15 @@
       "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==",
       "dev": true
     },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
     "domexception": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
@@ -1884,6 +2041,12 @@
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
     "end-of-stream": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@@ -1964,12 +2127,227 @@
         }
       }
     },
+    "eslint": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz",
+      "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.3.1",
+        "eslint-visitor-keys": "^1.0.0",
+        "espree": "^6.0.0",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^5.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^11.7.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^6.4.1",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.2",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          },
+          "dependencies": {
+            "semver": {
+              "version": "5.7.1",
+              "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+              "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+              "dev": true
+            }
+          }
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "eslint-scope": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+          "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.1.0",
+            "estraverse": "^4.1.1"
+          }
+        },
+        "glob-parent": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
+          "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "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
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+          "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-prettier": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz",
+      "integrity": "sha512-vDrcCFE3+2ixNT5H83g28bO/uYAwibJxerXPj+E7op4qzBCsAV36QfvdAyVOoNxKAH2Os/e01T/2x++V0LPukA==",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^6.0.0"
+      }
+    },
+    "eslint-plugin-prettier": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz",
+      "integrity": "sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==",
+      "dev": true,
+      "requires": {
+        "prettier-linter-helpers": "^1.0.0"
+      }
+    },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz",
+      "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.0.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
+      "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.7",
+        "acorn-jsx": "^5.0.0",
+        "eslint-visitor-keys": "^1.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
+          "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
+          "dev": true
+        }
+      }
+    },
     "esprima": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
       "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
       "dev": true
     },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.0.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
     "estraverse": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
@@ -2095,6 +2473,17 @@
         }
       }
     },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
     "extglob": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
@@ -2159,11 +2548,23 @@
       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
       "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
     },
+    "faker": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz",
+      "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=",
+      "dev": true
+    },
     "fast-deep-equal": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
       "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
     },
+    "fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "dev": true
+    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -2184,6 +2585,24 @@
         "bser": "^2.0.0"
       }
     },
+    "figures": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz",
+      "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^2.0.1"
+      }
+    },
     "fill-range": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -2242,6 +2661,23 @@
       "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
       "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="
     },
+    "flat-cache": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+      "dev": true,
+      "requires": {
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
+      }
+    },
+    "flatted": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+      "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+      "dev": true
+    },
     "for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -2857,6 +3293,12 @@
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
       "dev": true
     },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
     "gauge": {
       "version": "2.7.4",
       "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -2916,6 +3358,12 @@
       "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
       "dev": true
     },
+    "get-stdin": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+      "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+      "dev": true
+    },
     "get-stream": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
@@ -3231,6 +3679,12 @@
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
       "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
     },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
     "ignore-by-default": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
@@ -3246,6 +3700,24 @@
         "minimatch": "^3.0.4"
       }
     },
+    "import-fresh": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
+      "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
+      "dev": true,
+      "requires": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+          "dev": true
+        }
+      }
+    },
     "import-lazy": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
@@ -3293,6 +3765,76 @@
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
       "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
     },
+    "inquirer": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz",
+      "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.15",
+        "mute-stream": "0.0.8",
+        "run-async": "^2.2.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^5.1.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz",
+          "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.5.2"
+          }
+        },
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
+          "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^5.2.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
     "interpret": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
@@ -3513,6 +4055,12 @@
         "isobject": "^3.0.1"
       }
     },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
     "is-redirect": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
@@ -4258,12 +4806,39 @@
         "topo": "3.x.x"
       }
     },
+    "joi-extract-type": {
+      "version": "15.0.0",
+      "resolved": "https://registry.npmjs.org/joi-extract-type/-/joi-extract-type-15.0.0.tgz",
+      "integrity": "sha512-WY56yOyub9HKMyPruZ4CaL99GXHJbjdgAs1Eyt6u1GBuiLt//WMErQvPsiCSCVAZtGAKW0t+vjvdWxOnozwjCw==",
+      "requires": {
+        "@hapi/joi": ">=15",
+        "@types/hapi__joi": ">=15"
+      }
+    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
       "dev": true
     },
+    "js-yaml": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+          "dev": true
+        }
+      }
+    },
     "jsbn": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -4325,6 +4900,12 @@
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
     },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
     "json-stringify-safe": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -4609,6 +5190,12 @@
       "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
       "dev": true
     },
+    "lodash.unescape": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+      "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+      "dev": true
+    },
     "loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -4843,6 +5430,12 @@
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
+    "mute-stream": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+      "dev": true
+    },
     "nan": {
       "version": "2.14.0",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
@@ -4956,11 +5549,6 @@
         }
       }
     },
-    "nodemailer": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.2.1.tgz",
-      "integrity": "sha512-TagB7iuIi9uyNgHExo8lUDq3VK5/B0BpbkcjIgNvxbtVrjNqq0DwAOTuzALPVkK76kMhTSzIgHqg8X1uklVs6g=="
-    },
     "nodemon": {
       "version": "1.19.1",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz",
@@ -5163,6 +5751,15 @@
         "wrappy": "1"
       }
     },
+    "onetime": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+      "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^2.1.0"
+      }
+    },
     "only": {
       "version": "0.0.2",
       "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
@@ -5354,6 +5951,15 @@
       "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
       "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
     },
+    "parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
     "parse-filepath": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -5603,6 +6209,21 @@
       "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
       "dev": true
     },
+    "prettier": {
+      "version": "1.18.2",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
+      "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==",
+      "dev": true
+    },
+    "prettier-linter-helpers": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+      "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+      "dev": true,
+      "requires": {
+        "fast-diff": "^1.1.2"
+      }
+    },
     "pretty-format": {
       "version": "24.8.0",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz",
@@ -5628,6 +6249,12 @@
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
+    "progress": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+      "dev": true
+    },
     "prompts": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz",
@@ -5790,6 +6417,12 @@
         "safe-regex": "^1.1.0"
       }
     },
+    "regexpp": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+      "dev": true
+    },
     "registry-auth-token": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
@@ -5928,6 +6561,16 @@
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
       "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
     },
+    "restore-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+      "dev": true,
+      "requires": {
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
     "ret": {
       "version": "0.1.15",
       "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
@@ -5948,6 +6591,24 @@
       "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
       "dev": true
     },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "^2.1.0"
+      }
+    },
+    "rxjs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
+      "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -6114,6 +6775,17 @@
       "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
       "dev": true
     },
+    "slice-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.0",
+        "astral-regex": "^1.0.0",
+        "is-fullwidth-code-point": "^2.0.0"
+      }
+    },
     "snapdragon": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -6307,6 +6979,12 @@
         "extend-shallow": "^3.0.0"
       }
     },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
     "sqlite3": {
       "version": "4.0.9",
       "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.0.9.tgz",
@@ -6465,6 +7143,70 @@
       "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
       "dev": true
     },
+    "table": {
+      "version": "5.4.5",
+      "resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz",
+      "integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.10.2",
+        "lodash": "^4.17.14",
+        "slice-ansi": "^2.1.0",
+        "string-width": "^3.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.10.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+          "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
     "tar": {
       "version": "4.4.10",
       "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
@@ -6514,6 +7256,12 @@
         "require-main-filename": "^2.0.0"
       }
     },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
     "throat": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
@@ -6536,6 +7284,15 @@
       "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
       "dev": true
     },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "~1.0.2"
+      }
+    },
     "tmpl": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -6680,6 +7437,21 @@
         "yn": "^3.0.0"
       }
     },
+    "tslib": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+      "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
+      "dev": true
+    },
+    "tsutils": {
+      "version": "3.17.1",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
+      "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.8.1"
+      }
+    },
     "tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -6702,6 +7474,12 @@
         "prelude-ls": "~1.1.2"
       }
     },
+    "type-fest": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
+      "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==",
+      "dev": true
+    },
     "type-is": {
       "version": "1.6.18",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -6905,6 +7683,12 @@
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
       "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
     },
+    "v8-compile-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+      "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+      "dev": true
+    },
     "v8flags": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz",
@@ -7079,6 +7863,15 @@
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
       "dev": true
     },
+    "write": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+      "dev": true,
+      "requires": {
+        "mkdirp": "^0.5.1"
+      }
+    },
     "write-file-atomic": {
       "version": "2.4.3",
       "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
diff --git a/typescript/lunargame/api/package.json b/typescript/lunargame/api/package.json
index fe68fc1..14d4e0b 100644
--- a/typescript/lunargame/api/package.json
+++ b/typescript/lunargame/api/package.json
@@ -12,6 +12,7 @@
     "devDependencies": {
         "@types/bcryptjs": "^2.4.2",
         "@types/dotenv": "^6.1.1",
+        "@types/faker": "^4.1.5",
         "@types/jest": "^24.0.17",
         "@types/joi": "^14.3.3",
         "@types/koa": "^2.0.49",
@@ -20,12 +21,18 @@
         "@types/koa-session": "^5.10.1",
         "@types/koa__cors": "^2.2.3",
         "@types/node": "^12.0.10",
-        "@types/nodemailer": "^6.2.0",
         "@types/supertest": "^2.0.8",
         "@types/uuid": "^3.4.5",
+        "@typescript-eslint/eslint-plugin": "^1.13.0",
+        "@typescript-eslint/parser": "^1.13.0",
         "cross-env": "^5.2.0",
+        "eslint": "^6.1.0",
+        "eslint-config-prettier": "^6.0.0",
+        "eslint-plugin-prettier": "^3.1.0",
+        "faker": "^4.1.0",
         "jest": "^24.8.0",
         "nodemon": "^1.19.1",
+        "prettier": "^1.18.2",
         "sqlite3": "^4.0.9",
         "ts-jest": "^24.0.2",
         "ts-node": "^8.3.0",
@@ -37,13 +44,13 @@
         "bcryptjs": "^2.4.3",
         "dotenv": "^8.0.0",
         "joi": "^14.3.1",
+        "joi-extract-type": "^15.0.0",
         "knex": "^0.18.1",
         "koa": "^2.7.0",
         "koa-bodyparser": "^4.2.1",
         "koa-router": "^7.4.0",
         "koa-session": "^5.12.0",
         "koa-session-knex-store": "^1.1.2",
-        "nodemailer": "^6.2.1",
         "pg": "^7.11.0",
         "supertest": "^4.0.2",
         "uuid": "^3.3.2"
diff --git a/typescript/lunargame/api/src/common/lang/arrays/helpers/randomElement.test.ts b/typescript/lunargame/api/src/common/lang/arrays/helpers/randomElement.test.ts
index 243a62d..84f1c6e 100644
--- a/typescript/lunargame/api/src/common/lang/arrays/helpers/randomElement.test.ts
+++ b/typescript/lunargame/api/src/common/lang/arrays/helpers/randomElement.test.ts
@@ -8,15 +8,8 @@ describe('The randomElement function', () => {
     })
 
     test('should throw an error when passing an empty array', () => {
-        let error: Error | undefined
-
-        try {
+        expect(() => {
             randomElement([])
-        } catch (catchedError) {
-            //
-            error = catchedError
-        }
-
-        expect(error).toBeTruthy()
+        }).toThrow()
     })
 })
diff --git a/typescript/lunargame/api/src/modules/auth/constants.ts b/typescript/lunargame/api/src/modules/auth/constants.ts
new file mode 100644
index 0000000..35f5919
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/constants.ts
@@ -0,0 +1,4 @@
+import { passwordEncryption } from './types/passwordEncryption'
+
+// i made a separate constant to prevent duplication
+export const defaultEncryptionMethod: passwordEncryption = 'bcrypt'
diff --git a/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.test.ts b/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.test.ts
new file mode 100644
index 0000000..24ddc61
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.test.ts
@@ -0,0 +1,20 @@
+import { checkPassword } from './checkPassword'
+import { passwordEncryption } from '../types/passwordEncryption'
+
+describe('The checkPassword helper', () => {
+    const pass = 'this is a test password'
+
+    test("should throw an error if the encryption method doesn't exist", () => {
+        expect(() => {
+            checkPassword(pass, pass, '12212' as passwordEncryption)
+        }).toThrow()
+    })
+
+    test('should return true if the password matches the hash and the encryption = plain', () => {
+        expect(checkPassword(pass, pass, 'plain')).toBe(true)
+    })
+
+    test('shoud return false if the password is wrong and the encryption = plain', () => {
+        expect(checkPassword(pass, pass + 'something', 'plain')).toBe(false)
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.ts b/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.ts
new file mode 100644
index 0000000..bd85788
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/helpers/checkPassword.ts
@@ -0,0 +1,21 @@
+import { passwordEncryption } from '../types/passwordEncryption'
+import { HttpError } from '../../network/classes/HttpError'
+
+/**
+ * Comparesa apssword with it's hash
+ *
+ * @param hash The hash of the password
+ * @param password The actual password
+ * @param encryption The encription of the password
+ */
+export const checkPassword = (
+    hash: string,
+    password: string,
+    encryption: passwordEncryption = 'plain'
+) => {
+    if (encryption === 'plain') {
+        return hash === password
+    } else {
+        throw new HttpError(400, `Encription ${encryption} doesn't exist`)
+    }
+}
diff --git a/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.test.ts b/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.test.ts
new file mode 100644
index 0000000..c53cea4
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.test.ts
@@ -0,0 +1,22 @@
+import { internet } from 'faker'
+import { encryptPassword } from './encryptPassword'
+import { compare } from 'bcryptjs'
+
+describe('The encryptPassword helper', () => {
+    test("should return the same password if the method is 'plain'", async () => {
+        const password = internet.password()
+        const hash = await encryptPassword(password, 'plain')
+
+        expect(hash).toBe(password)
+    })
+
+    test("should return a mactching hash if the method is 'bcrypt'", async () => {
+        const password = internet.password()
+
+        // the amount of rounds is small because this is just a test
+        const hash = await encryptPassword(password, 'bcrypt', 3)
+        const match = await compare(password, hash)
+
+        expect(match).toBe(true)
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.ts b/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.ts
new file mode 100644
index 0000000..1832c5c
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/helpers/encryptPassword.ts
@@ -0,0 +1,24 @@
+import { passwordEncryption } from '../types/passwordEncryption'
+import { genSalt, hash } from 'bcryptjs'
+
+/**
+ * Encypts a string
+ *
+ * @param password The password to encrypt
+ * @param method The method to encrypt the password with
+ * @param rounds The salting rounds (for bcrypt only)
+ */
+export const encryptPassword = async (
+    password: string,
+    method: passwordEncryption,
+    rounds = 10
+) => {
+    if (method === 'bcrypt') {
+        const salt = await genSalt(rounds)
+        const result = await hash(password, salt)
+
+        return result
+    } else {
+        return password
+    }
+}
diff --git a/typescript/lunargame/api/src/modules/auth/middleware/isAuthorized.ts b/typescript/lunargame/api/src/modules/auth/middleware/isAuthorized.ts
new file mode 100644
index 0000000..497cf3d
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/middleware/isAuthorized.ts
@@ -0,0 +1,13 @@
+import { Middleware } from 'koa'
+import { HttpError } from '../../network/classes/HttpError'
+
+/**
+ * Middlware wich throws an error if the user isn't logged in
+ */
+export const isAuthorized = (): Middleware => (context, next) => {
+    if (context.session.uid !== undefined) {
+        return next()
+    } else {
+        throw new HttpError(401)
+    }
+}
diff --git a/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.test.ts b/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.test.ts
new file mode 100644
index 0000000..f332c5d
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.test.ts
@@ -0,0 +1,28 @@
+import { Context } from 'koa'
+import { isUnauthorized } from './isUnauthorized'
+
+describe('The isUnauthorized middleware', () => {
+    const fakeNext = () => async () => {}
+
+    test('should throw an error if the user is logged in', () => {
+        const fakeContext = ({
+            session: {
+                uid: 7
+            }
+        } as unknown) as Context
+
+        expect(() => isUnauthorized()(fakeContext, fakeNext())).toThrow()
+    })
+
+    test("should call next if the user isn't logged in", () => {
+        const fakeContext = {
+            session: {}
+        } as Context
+
+        const next = jest.fn(fakeNext())
+
+        isUnauthorized()(fakeContext, next)
+
+        expect(next).toBeCalled()
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.ts b/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.ts
new file mode 100644
index 0000000..17d3021
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/middleware/isUnauthorized.ts
@@ -0,0 +1,13 @@
+import { Middleware } from 'koa'
+import { HttpError } from '../../network/classes/HttpError'
+
+/**
+ * Middleware wich throws an error if the user is logged in
+ */
+export const isUnauthorized = (): Middleware => (context, next) => {
+    if (context.session.uid === undefined) {
+        return next()
+    } else {
+        throw new HttpError(401)
+    }
+}
diff --git a/typescript/lunargame/api/src/modules/auth/middleware/loggedIn.test.ts b/typescript/lunargame/api/src/modules/auth/middleware/loggedIn.test.ts
new file mode 100644
index 0000000..f9caf0f
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/middleware/loggedIn.test.ts
@@ -0,0 +1,28 @@
+import { isAuthorized } from './isAuthorized'
+import { Context } from 'koa'
+
+describe('The isAuthorized middleware', () => {
+    const fakeNext = () => async () => {}
+
+    test("should throw an error if the user isn't logged in", () => {
+        const fakeContext = {
+            session: {}
+        } as Context
+
+        expect(() => isAuthorized()(fakeContext, fakeNext())).toThrow()
+    })
+
+    test('should call next if the user is logged in', () => {
+        const fakeContext = ({
+            session: {
+                uid: Math.random()
+            }
+        } as unknown) as Context
+
+        const next = jest.fn(fakeNext())
+
+        isAuthorized()(fakeContext, next)
+
+        expect(next).toBeCalled()
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/queries/createAccount.test.ts b/typescript/lunargame/api/src/modules/auth/queries/createAccount.test.ts
new file mode 100644
index 0000000..b01f409
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/queries/createAccount.test.ts
@@ -0,0 +1,32 @@
+/* eslint-disable @typescript-eslint/explicit-function-return-type */
+import { name, random, internet } from 'faker'
+import { createAccount } from './createAccount'
+import { connection } from '../../db/connection'
+import { SignupBody } from '../schemas/SignupBody'
+
+describe('The createAccount query', () => {
+    test('should return the id of the account and add it to the db', async () => {
+        const email = internet.email()
+        const username = name.firstName()
+        const password = random.alphaNumeric(10)
+
+        const result = await createAccount({
+            email,
+            name: username,
+            password,
+            passwordEncryption: 'plain'
+        })
+
+        const account = await connection
+            .from('account')
+            .select<Required<SignupBody>>(['email', 'name', 'password'])
+            .where({
+                id: result
+            })
+            .first()
+
+        expect(account.name).toBe(username)
+        expect(account.email).toBe(email)
+        expect(account.password).toBe(password)
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/queries/createAccount.ts b/typescript/lunargame/api/src/modules/auth/queries/createAccount.ts
new file mode 100644
index 0000000..5fa70c2
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/queries/createAccount.ts
@@ -0,0 +1,15 @@
+import { connection } from '../../db/connection'
+import { DbAccount } from '../types/Account'
+
+/**
+ * Saves a new user into the db
+ *
+ * @param user The user object to insert
+ */
+export const createAccount = async (user: DbAccount): Promise<number> => {
+    const result = await connection.from('account').insert({
+        ...user
+    })
+
+    return result[0]
+}
diff --git a/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.test.ts b/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.test.ts
new file mode 100644
index 0000000..bac6ed2
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.test.ts
@@ -0,0 +1,16 @@
+import { getPasswordByEmail } from './getPasswordByEmail'
+import { mockAccounts } from '../../../../test/seeds/01_create-account'
+import { connection } from '../../db/connection'
+
+describe('The getPasswordByName query', () => {
+    test('should return the correct password & encryption for a mock account', async () => {
+        await connection.seed.run()
+
+        for (const account of mockAccounts) {
+            const result = await getPasswordByEmail(account.email)
+
+            expect(result.password).toBe(account.password)
+            expect(result.passwordEncryption).toBe(account.passwordEncryption)
+        }
+    })
+})
diff --git a/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.ts b/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.ts
new file mode 100644
index 0000000..0d9ed7e
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/queries/getPasswordByEmail.ts
@@ -0,0 +1,26 @@
+import { connection } from '../../db/connection'
+import { passwordEncryption } from '../types/passwordEncryption'
+
+/**
+ * The result of the getPasswordByName query
+ */
+export interface PasswordByEmailResult {
+    password: string
+    passwordEncryption: passwordEncryption
+    id: number
+}
+
+/**
+ * Gets the password, passwordEncryption and id of an account from it's email
+ *
+ * @param email The email of the account
+ */
+export const getPasswordByEmail = (email: string): Promise<PasswordByEmailResult> => {
+    return connection
+        .from('account')
+        .select('password', 'passwordEncryption', 'id')
+        .where({
+            email
+        })
+        .first()
+}
diff --git a/typescript/lunargame/api/src/modules/auth/routes/authRoute.test.ts b/typescript/lunargame/api/src/modules/auth/routes/authRoute.test.ts
index 5a68404..99a8126 100644
--- a/typescript/lunargame/api/src/modules/auth/routes/authRoute.test.ts
+++ b/typescript/lunargame/api/src/modules/auth/routes/authRoute.test.ts
@@ -1,26 +1,95 @@
 import supertest from 'supertest'
 import { app } from '../../../server'
 import { loggedInAgent } from '../../../../test/utils/loggedInAgent'
+import { mockAccounts } from '../../../../test/seeds/01_create-account'
+import { random, internet } from 'faker'
+import { LoginReponseBody } from '../types/LoginReponseBody'
+import { defaultEncryptionMethod } from '../constants'
 
 describe('The /auth route', () => {
+    // used to make requests
     let request = supertest(app.callback())
 
-    test('should return undefined if the user was not logged in', async () => {
-        const res = await request.get('/auth')
+    describe(`The POST method on the /login subroute`, () => {
+        test('should throw an error if the password field is empty', async () => {
+            const response = await request.post('/auth/login').send({
+                name: mockAccounts[0].name
+            })
 
-        expect(res.body.uid).toBe(undefined)
+            expect(response.status).not.toBe(200)
+        })
+
+        test('should throw an error if the name field is empty', async () => {
+            const response = await request.post('/auth/login').send({
+                password: mockAccounts[0].password
+            })
+
+            expect(response.status).not.toBe(200)
+        })
+
+        test('should throw an error if the password is wrong', async () => {
+            const response = await request.post('/auth/login').send({
+                name: mockAccounts[0].name,
+                password: mockAccounts[0].password + 'something'
+            })
+
+            expect(response.status).not.toBe(200)
+        })
+
+        test('should work just fine when the password is correct', async () => {
+            for (const account of mockAccounts) {
+                const response = await request.post('/auth/login').send({
+                    email: account.email,
+                    password: account.password
+                })
+
+                // i'm making a separate constant for vsc to help me
+                const body: LoginReponseBody = response.body
+
+                expect(response.status).toBe(200)
+                expect(body.uid).not.toBe(undefined)
+                expect(body.encryption).toBe(account.passwordEncryption)
+            }
+        })
     })
 
-    test.only('should return the uid form the session while logged in', async () => {
-        const uid = 7
+    describe(`The GET method on the / subroute`, () => {
+        test('should return undefined if the user was not logged in', async () => {
+            const res = await request.get('/auth')
 
-        const [agent, cookie] = await loggedInAgent(
-            supertest.agent(app.callback()),
-            uid
-        )
+            expect(res.body.uid).toBe(undefined)
+        })
 
-        const res = await agent.get('/auth').set('cookie', cookie)
+        test('should return the uid form the session while logged in', async () => {
+            const [agent, cookie] = await loggedInAgent(supertest.agent(app.callback()), {
+                email: mockAccounts[0].email,
+                password: mockAccounts[0].password
+            })
 
-        expect(res.body.uid).toBe(uid)
+            const response = await agent.get('/auth').set('cookie', cookie)
+
+            expect(response.body.uid).not.toBe(undefined)
+        })
+    })
+
+    describe('The POST method on the /signup subroute', () => {
+        test('should return the email name and the encrytion', async () => {
+            const username = random.alphaNumeric(7)
+            const password = random.alphaNumeric(5)
+            const email = internet.email()
+
+            const response = await request.post('/auth/signup').send({
+                name: username,
+                email,
+                password
+            })
+
+            // i'm making a separate constant for vsc to help me
+            const body: LoginReponseBody = response.body
+
+            expect(response.status).toBe(200)
+            expect(body.uid).not.toBe(undefined)
+            expect(body.encryption).toBe(defaultEncryptionMethod)
+        })
     })
 })
diff --git a/typescript/lunargame/api/src/modules/auth/routes/authRoute.ts b/typescript/lunargame/api/src/modules/auth/routes/authRoute.ts
index cc193dc..555403f 100644
--- a/typescript/lunargame/api/src/modules/auth/routes/authRoute.ts
+++ b/typescript/lunargame/api/src/modules/auth/routes/authRoute.ts
@@ -1,4 +1,14 @@
 import Router from 'koa-router'
+import { validate } from '../../../common/validation/middleware/validate'
+import { getPasswordByEmail } from '../queries/getPasswordByEmail'
+import { HttpError } from '../../network/classes/HttpError'
+import { checkPassword } from '../helpers/checkPassword'
+import { SignupBodySchema } from '../schemas/SignupBody'
+import { encryptPassword } from '../helpers/encryptPassword'
+import { createAccount } from '../queries/createAccount'
+import { defaultEncryptionMethod } from '../constants'
+import { LoginBodySchema } from '../schemas/LoginBody'
+import { isUnauthorized } from '../middleware/isUnauthorized'
 
 const router = new Router()
 
@@ -10,11 +20,65 @@ router.get('/', (context, next) => {
     return next()
 })
 
-router.post('/login', (context, next) => {
-    context.session.uid = context.request.body.uid
-    context.body = {}
+router.post(
+    '/login',
+    isUnauthorized(),
+    validate(LoginBodySchema, 'body'),
+    async (context, next) => {
+        const { email, password } = context.request.body
 
-    return next()
-})
+        const passwordData = await getPasswordByEmail(email)
+
+        // in case the user doesnt exist
+        if (!passwordData) {
+            throw new HttpError(400)
+        }
+
+        const match = checkPassword(
+            passwordData.password,
+            password,
+            passwordData.passwordEncryption
+        )
+
+        if (!match) {
+            throw new HttpError(400, 'wrong password')
+        }
+
+        context.session.uid = passwordData.id
+
+        context.body = {
+            encryption: passwordData.passwordEncryption,
+            uid: passwordData.id
+        }
+
+        return next()
+    }
+)
+
+router.post(
+    '/signup',
+    isUnauthorized(),
+    validate(SignupBodySchema, 'body'),
+    async (context, next) => {
+        const { email, name, password } = context.request.body
+
+        // encript the password (bcrypt by default)
+        const encryptedPassword = await encryptPassword(password, defaultEncryptionMethod, 10)
+
+        const uid = await createAccount({
+            email,
+            name,
+            password: encryptedPassword,
+            passwordEncryption: defaultEncryptionMethod
+        })
+
+        context.body = {
+            uid,
+            encryption: defaultEncryptionMethod
+        }
+
+        return next()
+    }
+)
 
 export default router
diff --git a/typescript/lunargame/api/src/modules/auth/schemas/LoginBody.ts b/typescript/lunargame/api/src/modules/auth/schemas/LoginBody.ts
index c06ae04..e464ffe 100644
--- a/typescript/lunargame/api/src/modules/auth/schemas/LoginBody.ts
+++ b/typescript/lunargame/api/src/modules/auth/schemas/LoginBody.ts
@@ -1,7 +1,9 @@
-import Joi from 'joi'
-import { name, password } from './authFields'
+import Joi from '@hapi/joi'
+import { email, password } from './authFields'
 
 export const LoginBodySchema = Joi.object({
-    name,
+    email,
     password
-})
+}).required()
+
+export type LoginBody = Joi.extractType<typeof LoginBodySchema>
diff --git a/typescript/lunargame/api/src/modules/auth/schemas/SignupBody.ts b/typescript/lunargame/api/src/modules/auth/schemas/SignupBody.ts
new file mode 100644
index 0000000..c4259de
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/schemas/SignupBody.ts
@@ -0,0 +1,10 @@
+import Joi from '@hapi/joi'
+import { email, name, password } from './authFields'
+
+export const SignupBodySchema = Joi.object({
+    name,
+    password,
+    email
+}).required()
+
+export type SignupBody = Joi.extractType<typeof SignupBodySchema>
diff --git a/typescript/lunargame/api/src/modules/auth/schemas/authFields.ts b/typescript/lunargame/api/src/modules/auth/schemas/authFields.ts
index 52c32e4..c399f99 100644
--- a/typescript/lunargame/api/src/modules/auth/schemas/authFields.ts
+++ b/typescript/lunargame/api/src/modules/auth/schemas/authFields.ts
@@ -1,10 +1,8 @@
 import Joi from 'joi'
 
 export const name = Joi.string()
-    .alphanum()
     .min(3)
     .max(30)
-    .lowercase()
     .required()
 
 export const email = Joi.string()
@@ -15,6 +13,6 @@ export const email = Joi.string()
 
 export const password = Joi.string()
     .min(3)
-    .max(50)
+    .max(20)
     .alphanum()
     .required()
diff --git a/typescript/lunargame/api/src/modules/auth/types/Account.ts b/typescript/lunargame/api/src/modules/auth/types/Account.ts
new file mode 100644
index 0000000..f2ca84a
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/types/Account.ts
@@ -0,0 +1,32 @@
+import { passwordEncryption } from './passwordEncryption'
+
+/**
+ * The data about an account wich needs to be inserted into the db
+ */
+export interface DbAccount {
+    name: string
+    email: string
+    password: string
+    passwordEncryption: passwordEncryption
+}
+
+/**
+ * The data about an account wich actually gets stored into the db
+ */
+export interface FullDbAccount extends DbAccount {
+    id: number
+}
+
+/**
+ * The data everyone can get about an account
+ */
+export interface AccountPublicData {
+    name: string
+}
+
+/**
+ * The data only the owner of the account has acces to
+ */
+export interface AccountPrivateData extends AccountPublicData {
+    email: string
+}
diff --git a/typescript/lunargame/api/src/modules/auth/types/LoginReponseBody.ts b/typescript/lunargame/api/src/modules/auth/types/LoginReponseBody.ts
new file mode 100644
index 0000000..4484762
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/types/LoginReponseBody.ts
@@ -0,0 +1,6 @@
+import { passwordEncryption } from './passwordEncryption'
+
+export interface LoginReponseBody {
+    uid: number
+    encryption: passwordEncryption
+}
diff --git a/typescript/lunargame/api/src/modules/auth/types/passwordEncryption.ts b/typescript/lunargame/api/src/modules/auth/types/passwordEncryption.ts
new file mode 100644
index 0000000..7995a9f
--- /dev/null
+++ b/typescript/lunargame/api/src/modules/auth/types/passwordEncryption.ts
@@ -0,0 +1,4 @@
+/**
+ * All modes a password can be encrypted in
+ */
+export type passwordEncryption = 'plain' | 'bcrypt'
diff --git a/typescript/lunargame/api/test/seeds/01_create-account.ts b/typescript/lunargame/api/test/seeds/01_create-account.ts
new file mode 100644
index 0000000..a9ff035
--- /dev/null
+++ b/typescript/lunargame/api/test/seeds/01_create-account.ts
@@ -0,0 +1,21 @@
+import * as Knex from 'knex'
+import { DbAccount } from '../../src/modules/auth/types/Account'
+
+const tableName = 'account'
+
+export const mockAccounts: DbAccount[] = [
+    {
+        name: 'Adriel',
+        email: 'rafaeladriel11@gmail.com',
+        password: '1234',
+        passwordEncryption: 'plain'
+    }
+]
+
+export async function seed(knex: Knex): Promise<any> {
+    return knex(tableName)
+        .del()
+        .then(() => {
+            return knex(tableName).insert(mockAccounts)
+        })
+}
diff --git a/typescript/lunargame/api/test/utils/loggedInAgent.ts b/typescript/lunargame/api/test/utils/loggedInAgent.ts
index 34fe56f..c5dae29 100644
--- a/typescript/lunargame/api/test/utils/loggedInAgent.ts
+++ b/typescript/lunargame/api/test/utils/loggedInAgent.ts
@@ -1,4 +1,6 @@
 import supertest from 'supertest'
+import 'joi-extract-type'
+import { LoginBody } from '../../src/modules/auth/schemas/LoginBody'
 
 /**
  * Helper to get a supertest agent wich is logged in
@@ -8,10 +10,11 @@ import supertest from 'supertest'
  */
 export const loggedInAgent = async (
     agent: supertest.SuperTest<supertest.Test>,
-    uid: number
+    { email, password }: LoginBody
 ) => {
     const response = await agent.post('/auth/login').send({
-        uid
+        email,
+        password
     })
 
     // the cookie to send back