diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 362208a8c378384c58b7306bbc16b054a8c01943..80d88acaa65170c1ea35e7b24dc337f7aafeb0a9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,6 +3,10 @@ pages-testing:
   script:
     - cat $configfiledev > ./config/config.js
     - npm install
+    - [npm run clean]
+    - [npm run build]
+    - [copy views/ dir to built/]
+    - [cd built]
     - "pm2 delete --silent project || :"
     - pm2 start ./app.js --name=project
     - pm2 save
diff --git a/app.js b/app.ts
similarity index 65%
rename from app.js
rename to app.ts
index 95a44c52ca302f9b1495335b32621b60f458acd8..073dfee059b1044c31e743118a893407b050a148 100644
--- a/app.js
+++ b/app.ts
@@ -1,20 +1,20 @@
-const express = require('express')
-const path = require('path')
-const passport = require('passport')
-const morgan = require('morgan')
-const cookieParser = require('cookie-parser')
-const bodyParser = require('body-parser')
-const session = require('express-session')
-const flash = require('express-flash')
-const fileUpload = require('express-fileupload')
-const helmet = require('helmet')
-const compression = require('compression')
+import express from 'express'
+import path from 'path'
+//import passport from 'passport'
+import morgan from 'morgan'
+import cookieParser from 'cookie-parser'
+import bodyParser from 'body-parser'
+//import session from 'express-session'
+//import flash from 'express-flash'
+//import fileUpload from 'express-fileupload'
+import helmet from 'helmet'
+import compression from 'compression'
 
 var env = process.env.NODE_ENV || 'testing'
 const config = require('./config/config')[env]
+const lang = 'DE';
 
 var app = express()
-
 app.set('port', config.app.port)
 app.set('views', __dirname + '/views')
 app.set('view engine', 'pug')
@@ -26,7 +26,7 @@ app.use(cookieParser())
 app.use(bodyParser.json())
 app.use(bodyParser.urlencoded({extended: false}))
 app.use(express.static(path.join(__dirname, 'public')))
-app.use(session(
+/*app.use(session(
     {
         resave: true,
         saveUninitialized: true,
@@ -35,20 +35,20 @@ app.use(session(
     }
 ))
 app.use(passport.initialize())
-app.use(passport.session())
-app.use(flash())
+app.use(passport.session()) */
+/*app.use(flash())
 app.use((req, res, next) => {
     res.locals.errors = req.flash("error")
     res.locals.successes = req.flash("success")
     next()
-})
+}) */
 // enable files upload
-app.use(fileUpload({
+/*app.use(fileUpload({
     createParentPath: true,
     limits: { 
       fileSize: 1000000 // 1 MB max. file size
     }
-}))
+})) */
 // caching disabled for every route
 // NOTE: Works in Firefox and Opera. Does not work in Edge
 app.use(function(req, res, next) {
@@ -56,17 +56,17 @@ app.use(function(req, res, next) {
     next()
 })
   
-require('./routes/project')(app, config, passport)
+require('./routes/project')(app, lang)
   
 // Handle 404
-app.use(function (req, res, next) {
-    res.status(404).render('./DE/404')
+app.use(function (req:any, res:any) {
+    res.status(404).render(lang+'/404')
 })
   
 // Handle 500 - any server error
-app.use(function (err, req, res, next) {
+app.use(function (err:any, req:any, res:any, next:any) {
     console.error(err.stack)
-    res.status(500).render('./DE/500', {
+    res.status(500).render(lang+'/500', {
       error: err
     })
 })
diff --git a/config/config.js b/config/config.js
deleted file mode 100644
index 7fa7d72df0b0ac69ae35728fb1fdd00b4e9c2684..0000000000000000000000000000000000000000
--- a/config/config.js
+++ /dev/null
@@ -1,77 +0,0 @@
-module.exports = {
-  development: {
-    app: {
-      name: 'Project Page Manager',
-      port: process.env.PORT || 8888,
-      sessionSecret: 'thisisasecret-thisisasecret-thisisasecret'
-    },
-    passport: {
-      strategy: 'saml',
-      saml: {
-        path: process.env.SAML_PATH || '/saml/SSO',
-        entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry URL',
-        issuer: 'saml issuer URL',
-        logoutUrl: 'saml Logout URL'
-      }
-    },
-    database: {
-      user: 'usernamedb',          // DB username
-      password: 'passworddb',  // DB password
-      port: 3306,                 // MySQL port
-      dbUser: 'userdb',           // User DB
-      host_project: 'localhost', // local
-      dbProject: 'projectdb'     // Project DB
-    },
-    mailer: {
-      host: 'mailhost',  // hostname
-      secureConnection: false,        // TLS requires secureConnection to be false
-      port: 587,                      // port for secure SMTP
-      authUser: 'usernamemail',
-      authPass: 'passwordmail',
-      tlsCiphers: 'SSLv3',
-      from: 'email_from',
-    },
-    gitlab: {
-      token_readWriteProjects: 'putyourtokenhere'
-    }
-  },
-  testing: {
-    app: {
-      name: 'Project Page Manager',
-      port: process.env.PORT || 8888,
-      sessionSecret: 'thisisasecret-thisisasecret-thisisasecret'
-    },
-    passport: {
-      strategy: 'saml',
-      saml: {
-        path: process.env.SAML_PATH || '/saml/SSO',
-        entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry URL',
-        issuer: 'saml issuer URL',
-        logoutUrl: 'saml Logout URL'
-      }
-    },
-    database: {
-      user: 'usernamedb',          // DB username
-      password: 'passworddb',  // DB password
-      port: 3306,                 // MySQL port
-      dbUser: 'userdb',           // User DB
-      host_project: 'localhost', // local
-      dbProject: 'projectdb'     // Project DB
-    },
-    mailer: {
-      host: 'mailhost',  // hostname
-      secureConnection: false,        // TLS requires secureConnection to be false
-      port: 587,                      // port for secure SMTP
-      authUser: 'usernamemail',
-      authPass: 'passwordmail',
-      tlsCiphers: 'SSLv3',
-      from: 'email_from',
-    },
-    gitlab: {
-      token_readWriteProjects: 'putyourtokenhere'
-    }
-  },
-  production: {
-    // to be defined
-  }
-}
diff --git a/config/config.ts b/config/config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3d03f562faaacbbf1776bf507ec0e7bc8705e6a1
--- /dev/null
+++ b/config/config.ts
@@ -0,0 +1,39 @@
+module.exports = {
+  development: {
+    app: {
+      name: 'Project Page Manager',
+      port: process.env.PORT || 8888
+    },
+    database: {
+      user: 'usernamedb',          // DB username
+      password: 'passworddb',  // DB password
+      port: 3306,                 // MySQL port
+      dbUser: 'userdb',           // User DB
+      host_project: 'localhost', // local
+      dbProject: 'projectdb'     // Project DB
+    },
+    gitlab: {
+      token_readWriteProjects: 'putyourtokenhere'
+    }
+  },
+  testing: {
+    app: {
+      name: 'Project Page Manager',
+      port: process.env.PORT || 8888
+    },
+    database: {
+      user: 'usernamedb',          // DB username
+      password: 'passworddb',  // DB password
+      port: 3306,                 // MySQL port
+      dbUser: 'userdb',           // User DB
+      host_project: 'localhost', // local
+      dbProject: 'projectdb'     // Project DB
+    },
+    gitlab: {
+      token_readWriteProjects: 'putyourtokenhere'
+    }
+  },
+  production: {
+    // to be defined
+  }
+}
diff --git a/config/dbconn.js b/config/dbconn.ts
similarity index 92%
rename from config/dbconn.js
rename to config/dbconn.ts
index e79d5bcfe04b8f39838e11c75bb1c708cd03e230..66a0290db611210eb8376cf6b4742c750f564cbe 100644
--- a/config/dbconn.js
+++ b/config/dbconn.ts
@@ -1,6 +1,6 @@
-const mysql = require('mysql')
+import mysql from 'mysql'
 
-var env = process.env.NODE_ENV || 'testing';
+var env = process.env.NODE_ENV || 'development';
 const config = require('./config')[env]
 
 // ==== USER ACOOUNT DB CONNECTION ====
@@ -51,4 +51,4 @@ var connection = {
     project: projectConnection
 }
 
-module.exports = connection
\ No newline at end of file
+export = connection
\ No newline at end of file
diff --git a/config/mailer.js b/config/mailer.js
deleted file mode 100644
index d1e59ff03fb74925b5f57f01ad4136bba274f017..0000000000000000000000000000000000000000
--- a/config/mailer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const nodemailer = require('nodemailer')
-
-var env = process.env.NODE_ENV || 'testing';
-const config = require('./config')[env]
-
-var smtpTransport = nodemailer.createTransport({
-    host: config.mailer.host,
-    secureConnection: config.mailer.secureConnection,
-    port: config.mailer.port,
-    auth: {
-      user: config.mailer.authUser,
-      pass: config.mailer.authPass
-    },
-    tls: {
-        ciphers: config.mailer.tlsCiphers
-    } 
-});
-  
-var mailOptions = {
-    to: "",
-    from: config.mailer.from,
-    subject: "",
-    text: ""
-};
-
-var mailer = {
-    transport: smtpTransport,
-    options: mailOptions
-}
-
-module.exports = mailer
\ No newline at end of file
diff --git a/functions/gitlab.js b/functions/gitlab.ts
similarity index 88%
rename from functions/gitlab.js
rename to functions/gitlab.ts
index 64b68afe60877aa0c5ad89f91241f5206046a9f6..ca5928d4e5d4276aa08019fc472124fbe33c1716 100644
--- a/functions/gitlab.js
+++ b/functions/gitlab.ts
@@ -1,7 +1,7 @@
-const axios = require('axios')
+import axios from 'axios'
 
 var gitlab = {
-    getProjects: async function(perPage, idAfter) {
+    getProjects: async function(perPage:number, idAfter:number) {
         try {
             let projects = await axios({
                 method: 'get',
@@ -30,7 +30,7 @@ var gitlab = {
                 data: err}
         }
     },
-    getLatestPipelineStatus: async function(projectId) {
+    getLatestPipelineStatus: async function(projectId:number) {
         return axios({
             method: 'get',
             url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines'
@@ -40,4 +40,4 @@ var gitlab = {
     }
 }
 
-module.exports = gitlab
\ No newline at end of file
+export = gitlab
\ No newline at end of file
diff --git a/functions/helpers.js b/functions/helpers.ts
similarity index 69%
rename from functions/helpers.js
rename to functions/helpers.ts
index 4645aec75363bf4110ce33f65b8615dc60902f60..1c3451fc00883bf4307ba324dc98f75a7d76b80f 100644
--- a/functions/helpers.js
+++ b/functions/helpers.ts
@@ -1,5 +1,5 @@
 var helpers = {
-    stringToArray: function (input){
+    stringToArray: function (input:string){
         if(input != null){
             return input.split(',');
         }else{
@@ -8,4 +8,4 @@ var helpers = {
     }
 };
 
-module.exports = helpers;
\ No newline at end of file
+export = helpers;
\ No newline at end of file
diff --git a/functions/methods.js b/functions/methods.js
deleted file mode 100644
index e5d9fb5f882ea65731440da43796a1fa9f5db7f6..0000000000000000000000000000000000000000
--- a/functions/methods.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const dbconn = require('../config/dbconn');
-
-var methods = {
-    // test method
-	currentDate: function() {
-		console.log('Current Date is: ' + new Date().toISOString().slice(0, 10));
-    },
-    // ===================== user db =====================
-    getUserIdByEmail: function(email, callback) {
-        var userId
-        dbconn.user.query('SELECT id FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
-            if (err) {
-                throw err;
-            }
-            else {
-                if ( rows.length > 0) {
-                    userId = rows[0].id;
-                }
-            }
-            callback(userId, err);
-        });
-    },
-/*
-    getUserProjectRole: function(userId, callback) {
-        dbconn.user.query('SELECT project_id, role_id FROM user_project_role WHERE user_id = "' +userId+'"', function (err, rows, fields) {
-            if (err) throw err;
-            callback(rows, err);
-        });
-    },
-    */
-    addUserProjectRole: function(data, callback) {
-        dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err, results, fields){
-            if (err) throw err;
-            callback(err);
-        })
-    },
-    // ======================= project db =======================
-    getAllProjects: function(callback) {
-        dbconn.project.query('CALL getAllprojects', function (err, rows, fields){
-            if (err) throw err;
-            callback(rows[0], err);
-        })
-    },
-    getAllMailinglists: function(callback) {
-        dbconn.project.query('CALL getAllLists', function (err, rows, fields){
-            if (err) throw err;
-            callback(rows[0], err);
-	    })
-    },
-    getProjectOverviewById: function(projectId, callback) {
-        dbconn.project.query('CALL GetProjectInformationByProjectID(' + projectId+ ')', function (err, rows, fields){
-            if (err) throw err;
-            callback(rows[0], err);
-    	})
-    },
-    getProjectImagesById: function(projectId, callback) {
-        dbconn.project.query('CALL getImagesByProjectID(' + projectId+ ')', function (err, rows, fields){
-            if (err) throw err;
-            callback(rows[0], err);
-        })
-    },
-    addProjectOverview: function(data, callback) {
-        dbconn.project.query('INSERT INTO project_overview SET ?', data, function (err, results, fields){
-            if (err) {
-                console.error(err);
-            }
-            callback(results, err);
-        })
-    }
-};
-
-module.exports = methods;
\ No newline at end of file
diff --git a/functions/methods.ts b/functions/methods.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b3485473b8a7b84fb97f24576f6e0767a2b5d098
--- /dev/null
+++ b/functions/methods.ts
@@ -0,0 +1,24 @@
+const dbconn = require('../config/dbconn');
+
+var methods = {
+    getAllMailinglists: function(callback:any) {
+        dbconn.project.query('CALL getAllLists', function (err:any, rows:any){
+            if (err) throw err;
+            callback(rows[0], err);
+	    })
+    },
+    getProjectOverviewById: function(projectId:number, callback:any) {
+        dbconn.project.query('CALL GetProjectInformationByProjectID(' + projectId+ ')', function (err:any, rows:any){
+            if (err) throw err;
+            callback(rows[0], err);
+    	})
+    },
+    getProjectImagesById: function(projectId:number, callback:any) {
+        dbconn.project.query('CALL getImagesByProjectID(' + projectId+ ')', function (err:any, rows:any){
+            if (err) throw err;
+            callback(rows[0], err);
+        })
+    }
+};
+
+export = methods;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 791f392c52a78fe653785ade133cc90c75422b58..281a26770542e37b68d9f79546cbfe30cf720191 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,21 +14,26 @@
         "body-parser": "^1.19.0",
         "compression": "^1.7.4",
         "cookie-parser": "1.4.3",
-        "errorhandler": "1.4.3",
         "express": "^4.17.1",
-        "express-fileupload": "^1.1.7-alpha.2",
-        "express-flash": "0.0.2",
-        "express-session": "^1.17.1",
-        "fs": "0.0.1-security",
-        "helmet": "^3.23.3",
+        "helmet": "^4.6.0",
         "morgan": "^1.10.0",
         "mysql": "^2.18.1",
-        "passport": "0.3.2",
-        "passport-saml": "^2.0.6",
         "pug": "^3.0.2"
       },
       "devDependencies": {
-        "nodemon": "^2.0.9"
+        "@types/async": "^3.2.6",
+        "@types/compression": "^1.7.0",
+        "@types/cookie-parser": "^1.4.2",
+        "@types/express": "^4.17.12",
+        "@types/express-fileupload": "^1.1.6",
+        "@types/express-flash": "^0.0.2",
+        "@types/express-session": "^1.17.3",
+        "@types/morgan": "^1.9.2",
+        "@types/mysql": "^2.15.18",
+        "@types/passport": "^1.0.6",
+        "nodemon": "^2.0.9",
+        "ts-node": "^10.0.0",
+        "typescript": "^4.3.5"
       },
       "engines": {
         "node": ">= 4.0.0"
@@ -81,6 +86,184 @@
         "node": ">=6"
       }
     },
+    "node_modules/@tsconfig/node10": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+      "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node12": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+      "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node14": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+      "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node16": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.1.tgz",
+      "integrity": "sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==",
+      "dev": true
+    },
+    "node_modules/@types/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-ZkrXnZLC1mc4b9QLKaSrsxV4oxTRs10OI2kgSApT8G0v1jrmqppSHUVQ15kLorzsFBTjvf7OKF4kAibuuNQ+xA==",
+      "dev": true
+    },
+    "node_modules/@types/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/compression": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.0.tgz",
+      "integrity": "sha512-3LzWUM+3k3XdWOUk/RO+uSjv7YWOatYq2QADJntK1pjkk4DfVP0KrIEPDnXRJxAAGKe0VpIPRmlINLDuCedZWw==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/connect": {
+      "version": "3.4.34",
+      "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
+      "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/cookie-parser": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
+      "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/express": {
+      "version": "4.17.12",
+      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz",
+      "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==",
+      "dev": true,
+      "dependencies": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^4.17.18",
+        "@types/qs": "*",
+        "@types/serve-static": "*"
+      }
+    },
+    "node_modules/@types/express-fileupload": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.1.6.tgz",
+      "integrity": "sha512-8z92PCVgvWvG1TpxucRU9oRz3hZc5cUz+CkeDe4XwVmg2DJDdd/7QASMsJzIo+9Pbfp7LfTEWSeEFUJZBohv9g==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/express-flash": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.2.tgz",
+      "integrity": "sha512-1l0s3YiZpMkWZ/65S4iSOLOnI7bYNDgnxx54nw5eA2pWOZ7Vvc7PpDv6iJq0bB7EBusoVWkzd+RV4r/nLY4/HA==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/express-serve-static-core": {
+      "version": "4.17.22",
+      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.22.tgz",
+      "integrity": "sha512-WdqmrUsRS4ootGha6tVwk/IVHM1iorU8tGehftQD2NWiPniw/sm7xdJOIlXLwqdInL9wBw/p7oO8vaYEF3NDmA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*"
+      }
+    },
+    "node_modules/@types/express-session": {
+      "version": "1.17.3",
+      "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.3.tgz",
+      "integrity": "sha512-57DnyxiqClXOIjoCgeKCUYfKxBPOlOY/k+l1TPK+7bSwyiPTrS5FIk1Ycql7twk4wO7P5lfOVy6akDGiaMSLfw==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/mime": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+      "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
+      "dev": true
+    },
+    "node_modules/@types/morgan": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.2.tgz",
+      "integrity": "sha512-edtGMEdit146JwwIeyQeHHg9yID4WSolQPxpEorHmN3KuytuCHyn2ELNr5Uxy8SerniFbbkmgKMrGM933am5BQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/mysql": {
+      "version": "2.15.18",
+      "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz",
+      "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/node": {
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz",
+      "integrity": "sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==",
+      "dev": true
+    },
+    "node_modules/@types/passport": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.6.tgz",
+      "integrity": "sha512-9oKfrJXuAxvyxdrtMCxKkHgmd6DMO8NDOLvMJ1LvIWd6/xP+i81PAkpTaEca7VhJX9S009RciwZL/j6dsLsHrA==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/qs": {
+      "version": "6.9.6",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
+      "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==",
+      "dev": true
+    },
+    "node_modules/@types/range-parser": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+      "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+      "dev": true
+    },
+    "node_modules/@types/serve-static": {
+      "version": "1.13.9",
+      "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
+      "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
+      "dev": true,
+      "dependencies": {
+        "@types/mime": "^1",
+        "@types/node": "*"
+      }
+    },
     "node_modules/abbrev": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -206,6 +389,12 @@
         "node": ">= 8"
       }
     },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
     "node_modules/array-flatten": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -299,11 +488,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/bowser": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
-      "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
-    },
     "node_modules/boxen": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
@@ -348,16 +532,11 @@
         "node": ">=8"
       }
     },
-    "node_modules/busboy": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
-      "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
-      "dependencies": {
-        "dicer": "0.3.0"
-      },
-      "engines": {
-        "node": ">=4.5.0"
-      }
+    "node_modules/buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
     },
     "node_modules/bytes": {
       "version": "3.1.0",
@@ -427,11 +606,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/camelize": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
-      "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
-    },
     "node_modules/chalk": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
@@ -584,27 +758,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/compression/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/compression/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-    },
-    "node_modules/compression/node_modules/vary": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -628,14 +781,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/connect-flash": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
-      "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA=",
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
     "node_modules/constantinople": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
@@ -656,14 +801,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/content-security-policy-builder": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz",
-      "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/content-type": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -702,6 +839,12 @@
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
+    "node_modules/create-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+      "dev": true
+    },
     "node_modules/crypto-random-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
@@ -711,11 +854,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/dasherize": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
-      "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
-    },
     "node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -769,15 +907,13 @@
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
-    "node_modules/dicer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
-      "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
-      "dependencies": {
-        "streamsearch": "0.1.2"
-      },
+    "node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
       "engines": {
-        "node": ">=4.5.0"
+        "node": ">=0.3.1"
       }
     },
     "node_modules/doctypes": {
@@ -785,14 +921,6 @@
       "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
       "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
     },
-    "node_modules/dont-sniff-mimetype": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz",
-      "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/dot-prop": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -839,18 +967,6 @@
         "once": "^1.4.0"
       }
     },
-    "node_modules/errorhandler": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.4.3.tgz",
-      "integrity": "sha1-t7cO2PNZ6duICS8tIMD4MUIK2D8=",
-      "dependencies": {
-        "accepts": "~1.3.0",
-        "escape-html": "~1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/escape-goat": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -913,67 +1029,6 @@
         "node": ">= 0.10.0"
       }
     },
-    "node_modules/express-fileupload": {
-      "version": "1.1.7-alpha.2",
-      "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.1.7-alpha.2.tgz",
-      "integrity": "sha512-3D7ZnC7CkWzNGZg0NwNc1alB8ZUJiaqm13zgVgx0t5fKc/ovEJnsClKzLZdLkPQVN/YKm3O/T5gkdmk5r2jzcA==",
-      "dependencies": {
-        "busboy": "^0.3.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/express-flash": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
-      "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
-      "dependencies": {
-        "connect-flash": "0.1.x"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/express-session": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
-      "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
-      "dependencies": {
-        "cookie": "0.4.0",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "~2.0.0",
-        "on-headers": "~1.0.2",
-        "parseurl": "~1.3.3",
-        "safe-buffer": "5.2.0",
-        "uid-safe": "~2.1.5"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/express-session/node_modules/cookie": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
-      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/express-session/node_modules/depd": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/express-session/node_modules/safe-buffer": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
-      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
-    },
     "node_modules/express/node_modules/cookie": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
@@ -982,14 +1037,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/feature-policy": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
-      "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1043,11 +1090,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/fs": {
-      "version": "0.0.1-security",
-      "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
-      "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
-    },
     "node_modules/fsevents": {
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -1182,86 +1224,11 @@
       }
     },
     "node_modules/helmet": {
-      "version": "3.23.3",
-      "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz",
-      "integrity": "sha512-U3MeYdzPJQhtvqAVBPntVgAvNSOJyagwZwyKsFdyRa8TV3pOKVFljalPOCxbw5Wwf2kncGhmP0qHjyazIdNdSA==",
-      "dependencies": {
-        "depd": "2.0.0",
-        "dont-sniff-mimetype": "1.1.0",
-        "feature-policy": "0.3.0",
-        "helmet-crossdomain": "0.4.0",
-        "helmet-csp": "2.10.0",
-        "hide-powered-by": "1.1.0",
-        "hpkp": "2.0.0",
-        "hsts": "2.2.0",
-        "nocache": "2.1.0",
-        "referrer-policy": "1.2.0",
-        "x-xss-protection": "1.3.0"
-      },
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz",
+      "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==",
       "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/helmet-crossdomain": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz",
-      "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/helmet-csp": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.10.0.tgz",
-      "integrity": "sha512-Rz953ZNEFk8sT2XvewXkYN0Ho4GEZdjAZy4stjiEQV3eN7GDxg1QKmYggH7otDyIA7uGA6XnUMVSgeJwbR5X+w==",
-      "dependencies": {
-        "bowser": "2.9.0",
-        "camelize": "1.0.0",
-        "content-security-policy-builder": "2.1.0",
-        "dasherize": "2.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/helmet/node_modules/depd": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/hide-powered-by": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz",
-      "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/hpkp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
-      "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
-    },
-    "node_modules/hsts": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
-      "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
-      "dependencies": {
-        "depd": "2.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/hsts/node_modules/depd": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
-      "engines": {
-        "node": ">= 0.8"
+        "node": ">=10.0.0"
       }
     },
     "node_modules/http-cache-semantics": {
@@ -1325,6 +1292,11 @@
         "node": ">=0.8.19"
       }
     },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
     "node_modules/ini": {
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
@@ -1575,6 +1547,12 @@
         "semver": "bin/semver.js"
       }
     },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
     "node_modules/media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -1679,7 +1657,8 @@
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
     },
     "node_modules/mysql": {
       "version": "2.18.1",
@@ -1695,25 +1674,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/mysql/node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-    },
-    "node_modules/mysql/node_modules/readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
     "node_modules/negotiator": {
       "version": "0.6.2",
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -1722,22 +1682,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/nocache": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
-      "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/node-forge": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
-      "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
-      "engines": {
-        "node": ">= 6.0.0"
-      }
-    },
     "node_modules/nodemon": {
       "version": "2.0.9",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.9.tgz",
@@ -1886,54 +1830,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/passport": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz",
-      "integrity": "sha1-ndAJ+RXo/glbASSgG4+C2gdRAQI=",
-      "dependencies": {
-        "passport-strategy": "1.x.x",
-        "pause": "0.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/passport-saml": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-2.2.0.tgz",
-      "integrity": "sha512-Qkr9WbhGY1AAAgslJ4yFn7ObQp/cLu2L1bubwXvl8vsvXQujPemKYhD3SwdilEIllZ/EPTlHgld+4wiPRYxd8Q==",
-      "dependencies": {
-        "debug": "^4.3.1",
-        "passport-strategy": "*",
-        "xml-crypto": "^2.1.1",
-        "xml-encryption": "^1.2.3",
-        "xml2js": "^0.4.23",
-        "xmlbuilder": "^15.1.1",
-        "xmldom": "0.5.x"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/passport-saml/node_modules/debug": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
-      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      }
-    },
-    "node_modules/passport-strategy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
-      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=",
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
     "node_modules/path-parse": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
@@ -1944,11 +1840,6 @@
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
       "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
     },
-    "node_modules/pause": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
-      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
-    },
     "node_modules/picomatch": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@@ -2143,14 +2034,6 @@
         "node": ">=0.6"
       }
     },
-    "node_modules/random-bytes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
-      "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/range-parser": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -2188,6 +2071,20 @@
         "rc": "cli.js"
       }
     },
+    "node_modules/readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
     "node_modules/readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -2200,14 +2097,6 @@
         "node": ">=8.10.0"
       }
     },
-    "node_modules/referrer-policy": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
-      "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/registry-auth-token": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz",
@@ -2260,11 +2149,6 @@
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
-    "node_modules/sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
-    },
     "node_modules/semver": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -2348,6 +2232,25 @@
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
     },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
     "node_modules/sqlstring": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@@ -2364,14 +2267,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/streamsearch": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
-      "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=",
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
     "node_modules/string_decoder": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -2493,6 +2388,48 @@
         "nodetouch": "bin/nodetouch.js"
       }
     },
+    "node_modules/ts-node": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz",
+      "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==",
+      "dev": true,
+      "dependencies": {
+        "@tsconfig/node10": "^1.0.7",
+        "@tsconfig/node12": "^1.0.7",
+        "@tsconfig/node14": "^1.0.0",
+        "@tsconfig/node16": "^1.0.1",
+        "arg": "^4.1.0",
+        "create-require": "^1.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-cwd": "dist/bin-cwd.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "@swc/core": ">=1.2.45",
+        "@swc/wasm": ">=1.2.45",
+        "@types/node": "*",
+        "typescript": ">=2.7"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "@swc/wasm": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/type-fest": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -2523,15 +2460,17 @@
         "is-typedarray": "^1.0.0"
       }
     },
-    "node_modules/uid-safe": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
-      "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
-      "dependencies": {
-        "random-bytes": "~1.0.0"
+    "node_modules/typescript": {
+      "version": "4.3.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
+      "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
       },
       "engines": {
-        "node": ">= 0.8"
+        "node": ">=4.2.0"
       }
     },
     "node_modules/undefsafe": {
@@ -2675,14 +2614,6 @@
         "typedarray-to-buffer": "^3.1.5"
       }
     },
-    "node_modules/x-xss-protection": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
-      "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/xdg-basedir": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
@@ -2692,119 +2623,228 @@
         "node": ">=8"
       }
     },
-    "node_modules/xml-crypto": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.1.tgz",
-      "integrity": "sha512-M+m4+HIJa83lu/CnspQjA7ap8gmanNDxxRjSisU8mPD4bqhxbo5N2bdpvG2WgVYOrPpOIOq55iY8Cz8Ai40IeQ==",
-      "dependencies": {
-        "xmldom": "0.5.0",
-        "xpath": "0.0.32"
-      },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "dev": true,
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=6"
+      }
+    }
+  },
+  "dependencies": {
+    "@babel/helper-validator-identifier": {
+      "version": "7.12.11",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
+    },
+    "@babel/parser": {
+      "version": "7.13.11",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.11.tgz",
+      "integrity": "sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q=="
+    },
+    "@babel/types": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
+      "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "lodash": "^4.17.19",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true
+    },
+    "@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "requires": {
+        "defer-to-connect": "^1.0.1"
+      }
+    },
+    "@tsconfig/node10": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+      "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+      "dev": true
+    },
+    "@tsconfig/node12": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+      "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+      "dev": true
+    },
+    "@tsconfig/node14": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+      "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+      "dev": true
+    },
+    "@tsconfig/node16": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.1.tgz",
+      "integrity": "sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA==",
+      "dev": true
+    },
+    "@types/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-ZkrXnZLC1mc4b9QLKaSrsxV4oxTRs10OI2kgSApT8G0v1jrmqppSHUVQ15kLorzsFBTjvf7OKF4kAibuuNQ+xA==",
+      "dev": true
+    },
+    "@types/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+      "dev": true,
+      "requires": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/compression": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.0.tgz",
+      "integrity": "sha512-3LzWUM+3k3XdWOUk/RO+uSjv7YWOatYq2QADJntK1pjkk4DfVP0KrIEPDnXRJxAAGKe0VpIPRmlINLDuCedZWw==",
+      "dev": true,
+      "requires": {
+        "@types/express": "*"
+      }
+    },
+    "@types/connect": {
+      "version": "3.4.34",
+      "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
+      "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/cookie-parser": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
+      "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
+      "dev": true,
+      "requires": {
+        "@types/express": "*"
       }
     },
-    "node_modules/xml-encryption": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz",
-      "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==",
-      "dependencies": {
-        "escape-html": "^1.0.3",
-        "node-forge": "^0.10.0",
-        "xmldom": "~0.6.0",
-        "xpath": "0.0.32"
-      },
-      "engines": {
-        "node": ">=8"
+    "@types/express": {
+      "version": "4.17.12",
+      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz",
+      "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==",
+      "dev": true,
+      "requires": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^4.17.18",
+        "@types/qs": "*",
+        "@types/serve-static": "*"
       }
     },
-    "node_modules/xml-encryption/node_modules/xmldom": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
-      "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==",
-      "engines": {
-        "node": ">=10.0.0"
+    "@types/express-fileupload": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.1.6.tgz",
+      "integrity": "sha512-8z92PCVgvWvG1TpxucRU9oRz3hZc5cUz+CkeDe4XwVmg2DJDdd/7QASMsJzIo+9Pbfp7LfTEWSeEFUJZBohv9g==",
+      "dev": true,
+      "requires": {
+        "@types/express": "*"
       }
     },
-    "node_modules/xml2js": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
-      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
-      "dependencies": {
-        "sax": ">=0.6.0",
-        "xmlbuilder": "~11.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
+    "@types/express-flash": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.2.tgz",
+      "integrity": "sha512-1l0s3YiZpMkWZ/65S4iSOLOnI7bYNDgnxx54nw5eA2pWOZ7Vvc7PpDv6iJq0bB7EBusoVWkzd+RV4r/nLY4/HA==",
+      "dev": true,
+      "requires": {
+        "@types/express": "*"
       }
     },
-    "node_modules/xml2js/node_modules/xmlbuilder": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
-      "engines": {
-        "node": ">=4.0"
+    "@types/express-serve-static-core": {
+      "version": "4.17.22",
+      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.22.tgz",
+      "integrity": "sha512-WdqmrUsRS4ootGha6tVwk/IVHM1iorU8tGehftQD2NWiPniw/sm7xdJOIlXLwqdInL9wBw/p7oO8vaYEF3NDmA==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*"
       }
     },
-    "node_modules/xmlbuilder": {
-      "version": "15.1.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
-      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
-      "engines": {
-        "node": ">=8.0"
+    "@types/express-session": {
+      "version": "1.17.3",
+      "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.3.tgz",
+      "integrity": "sha512-57DnyxiqClXOIjoCgeKCUYfKxBPOlOY/k+l1TPK+7bSwyiPTrS5FIk1Ycql7twk4wO7P5lfOVy6akDGiaMSLfw==",
+      "dev": true,
+      "requires": {
+        "@types/express": "*"
       }
     },
-    "node_modules/xmldom": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
-      "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==",
-      "engines": {
-        "node": ">=10.0.0"
+    "@types/mime": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+      "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
+      "dev": true
+    },
+    "@types/morgan": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.2.tgz",
+      "integrity": "sha512-edtGMEdit146JwwIeyQeHHg9yID4WSolQPxpEorHmN3KuytuCHyn2ELNr5Uxy8SerniFbbkmgKMrGM933am5BQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
       }
     },
-    "node_modules/xpath": {
-      "version": "0.0.32",
-      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
-      "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==",
-      "engines": {
-        "node": ">=0.6.0"
+    "@types/mysql": {
+      "version": "2.15.18",
+      "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz",
+      "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
       }
-    }
-  },
-  "dependencies": {
-    "@babel/helper-validator-identifier": {
-      "version": "7.12.11",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
-      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
     },
-    "@babel/parser": {
-      "version": "7.13.11",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.11.tgz",
-      "integrity": "sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q=="
+    "@types/node": {
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz",
+      "integrity": "sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==",
+      "dev": true
     },
-    "@babel/types": {
-      "version": "7.13.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
-      "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
+    "@types/passport": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.6.tgz",
+      "integrity": "sha512-9oKfrJXuAxvyxdrtMCxKkHgmd6DMO8NDOLvMJ1LvIWd6/xP+i81PAkpTaEca7VhJX9S009RciwZL/j6dsLsHrA==",
+      "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.12.11",
-        "lodash": "^4.17.19",
-        "to-fast-properties": "^2.0.0"
+        "@types/express": "*"
       }
     },
-    "@sindresorhus/is": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+    "@types/qs": {
+      "version": "6.9.6",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
+      "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==",
       "dev": true
     },
-    "@szmarczak/http-timer": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
-      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+    "@types/range-parser": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+      "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+      "dev": true
+    },
+    "@types/serve-static": {
+      "version": "1.13.9",
+      "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
+      "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
       "dev": true,
       "requires": {
-        "defer-to-connect": "^1.0.1"
+        "@types/mime": "^1",
+        "@types/node": "*"
       }
     },
     "abbrev": {
@@ -2901,6 +2941,12 @@
         "picomatch": "^2.0.4"
       }
     },
+    "arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
     "array-flatten": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -2979,11 +3025,6 @@
         "type-is": "~1.6.17"
       }
     },
-    "bowser": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
-      "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
-    },
     "boxen": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
@@ -3019,13 +3060,11 @@
         "fill-range": "^7.0.1"
       }
     },
-    "busboy": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
-      "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
-      "requires": {
-        "dicer": "0.3.0"
-      }
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
     },
     "bytes": {
       "version": "3.1.0",
@@ -3079,11 +3118,6 @@
       "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
       "dev": true
     },
-    "camelize": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
-      "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
-    },
     "chalk": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
@@ -3204,24 +3238,6 @@
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
           "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
-        },
-        "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-        },
-        "vary": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-          "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
         }
       }
     },
@@ -3245,11 +3261,6 @@
         "xdg-basedir": "^4.0.0"
       }
     },
-    "connect-flash": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
-      "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA="
-    },
     "constantinople": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
@@ -3267,11 +3278,6 @@
         "safe-buffer": "5.1.2"
       }
     },
-    "content-security-policy-builder": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz",
-      "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ=="
-    },
     "content-type": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -3301,17 +3307,18 @@
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
+    "create-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+      "dev": true
+    },
     "crypto-random-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
       "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
       "dev": true
     },
-    "dasherize": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
-      "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
-    },
     "debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -3358,24 +3365,17 @@
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
-    "dicer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
-      "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
-      "requires": {
-        "streamsearch": "0.1.2"
-      }
+    "diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true
     },
     "doctypes": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
       "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
     },
-    "dont-sniff-mimetype": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz",
-      "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
-    },
     "dot-prop": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -3416,15 +3416,6 @@
         "once": "^1.4.0"
       }
     },
-    "errorhandler": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.4.3.tgz",
-      "integrity": "sha1-t7cO2PNZ6duICS8tIMD4MUIK2D8=",
-      "requires": {
-        "accepts": "~1.3.0",
-        "escape-html": "~1.0.3"
-      }
-    },
     "escape-goat": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -3485,59 +3476,6 @@
         }
       }
     },
-    "express-fileupload": {
-      "version": "1.1.7-alpha.2",
-      "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.1.7-alpha.2.tgz",
-      "integrity": "sha512-3D7ZnC7CkWzNGZg0NwNc1alB8ZUJiaqm13zgVgx0t5fKc/ovEJnsClKzLZdLkPQVN/YKm3O/T5gkdmk5r2jzcA==",
-      "requires": {
-        "busboy": "^0.3.1"
-      }
-    },
-    "express-flash": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
-      "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
-      "requires": {
-        "connect-flash": "0.1.x"
-      }
-    },
-    "express-session": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
-      "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
-      "requires": {
-        "cookie": "0.4.0",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "~2.0.0",
-        "on-headers": "~1.0.2",
-        "parseurl": "~1.3.3",
-        "safe-buffer": "5.2.0",
-        "uid-safe": "~2.1.5"
-      },
-      "dependencies": {
-        "cookie": {
-          "version": "0.4.0",
-          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
-          "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
-        },
-        "depd": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-          "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
-        },
-        "safe-buffer": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
-          "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
-        }
-      }
-    },
-    "feature-policy": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
-      "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ=="
-    },
     "fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -3576,11 +3514,6 @@
       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
       "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
     },
-    "fs": {
-      "version": "0.0.1-security",
-      "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
-      "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
-    },
     "fsevents": {
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -3681,70 +3614,9 @@
       "dev": true
     },
     "helmet": {
-      "version": "3.23.3",
-      "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz",
-      "integrity": "sha512-U3MeYdzPJQhtvqAVBPntVgAvNSOJyagwZwyKsFdyRa8TV3pOKVFljalPOCxbw5Wwf2kncGhmP0qHjyazIdNdSA==",
-      "requires": {
-        "depd": "2.0.0",
-        "dont-sniff-mimetype": "1.1.0",
-        "feature-policy": "0.3.0",
-        "helmet-crossdomain": "0.4.0",
-        "helmet-csp": "2.10.0",
-        "hide-powered-by": "1.1.0",
-        "hpkp": "2.0.0",
-        "hsts": "2.2.0",
-        "nocache": "2.1.0",
-        "referrer-policy": "1.2.0",
-        "x-xss-protection": "1.3.0"
-      },
-      "dependencies": {
-        "depd": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-          "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
-        }
-      }
-    },
-    "helmet-crossdomain": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz",
-      "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA=="
-    },
-    "helmet-csp": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.10.0.tgz",
-      "integrity": "sha512-Rz953ZNEFk8sT2XvewXkYN0Ho4GEZdjAZy4stjiEQV3eN7GDxg1QKmYggH7otDyIA7uGA6XnUMVSgeJwbR5X+w==",
-      "requires": {
-        "bowser": "2.9.0",
-        "camelize": "1.0.0",
-        "content-security-policy-builder": "2.1.0",
-        "dasherize": "2.0.0"
-      }
-    },
-    "hide-powered-by": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz",
-      "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg=="
-    },
-    "hpkp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
-      "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
-    },
-    "hsts": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
-      "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
-      "requires": {
-        "depd": "2.0.0"
-      },
-      "dependencies": {
-        "depd": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
-          "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
-        }
-      }
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz",
+      "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg=="
     },
     "http-cache-semantics": {
       "version": "4.1.0",
@@ -3797,6 +3669,11 @@
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
       "dev": true
     },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
     "ini": {
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
@@ -3995,6 +3872,12 @@
         }
       }
     },
+    "make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
     "media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -4071,7 +3954,8 @@
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
     },
     "mysql": {
       "version": "2.18.1",
@@ -4082,27 +3966,6 @@
         "readable-stream": "2.3.7",
         "safe-buffer": "5.1.2",
         "sqlstring": "2.3.1"
-      },
-      "dependencies": {
-        "inherits": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-        },
-        "readable-stream": {
-          "version": "2.3.7",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        }
       }
     },
     "negotiator": {
@@ -4110,16 +3973,6 @@
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
       "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
     },
-    "nocache": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
-      "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
-    },
-    "node-forge": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
-      "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
-    },
     "nodemon": {
       "version": "2.0.9",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.9.tgz",
@@ -4228,44 +4081,6 @@
       "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
       "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
     },
-    "passport": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz",
-      "integrity": "sha1-ndAJ+RXo/glbASSgG4+C2gdRAQI=",
-      "requires": {
-        "passport-strategy": "1.x.x",
-        "pause": "0.0.1"
-      }
-    },
-    "passport-saml": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-2.2.0.tgz",
-      "integrity": "sha512-Qkr9WbhGY1AAAgslJ4yFn7ObQp/cLu2L1bubwXvl8vsvXQujPemKYhD3SwdilEIllZ/EPTlHgld+4wiPRYxd8Q==",
-      "requires": {
-        "debug": "^4.3.1",
-        "passport-strategy": "*",
-        "xml-crypto": "^2.1.1",
-        "xml-encryption": "^1.2.3",
-        "xml2js": "^0.4.23",
-        "xmlbuilder": "^15.1.1",
-        "xmldom": "0.5.x"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.3.1",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
-          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
-          "requires": {
-            "ms": "2.1.2"
-          }
-        }
-      }
-    },
-    "passport-strategy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
-      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
-    },
     "path-parse": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
@@ -4276,11 +4091,6 @@
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
       "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
     },
-    "pause": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
-      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
-    },
     "picomatch": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@@ -4457,11 +4267,6 @@
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
       "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
     },
-    "random-bytes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
-      "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
-    },
     "range-parser": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -4490,6 +4295,20 @@
         "strip-json-comments": "~2.0.1"
       }
     },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
     "readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -4499,11 +4318,6 @@
         "picomatch": "^2.2.1"
       }
     },
-    "referrer-policy": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
-      "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
-    },
     "registry-auth-token": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz",
@@ -4550,11 +4364,6 @@
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
-    "sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
-    },
     "semver": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -4627,6 +4436,22 @@
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
     },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true
+    },
+    "source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
     "sqlstring": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@@ -4637,11 +4462,6 @@
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
       "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
     },
-    "streamsearch": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
-      "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
-    },
     "string_decoder": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -4730,6 +4550,24 @@
         "nopt": "~1.0.10"
       }
     },
+    "ts-node": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz",
+      "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==",
+      "dev": true,
+      "requires": {
+        "@tsconfig/node10": "^1.0.7",
+        "@tsconfig/node12": "^1.0.7",
+        "@tsconfig/node14": "^1.0.0",
+        "@tsconfig/node16": "^1.0.1",
+        "arg": "^4.1.0",
+        "create-require": "^1.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      }
+    },
     "type-fest": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -4754,13 +4592,11 @@
         "is-typedarray": "^1.0.0"
       }
     },
-    "uid-safe": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
-      "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
-      "requires": {
-        "random-bytes": "~1.0.0"
-      }
+    "typescript": {
+      "version": "4.3.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
+      "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
+      "dev": true
     },
     "undefsafe": {
       "version": "2.0.3",
@@ -4873,74 +4709,17 @@
         "typedarray-to-buffer": "^3.1.5"
       }
     },
-    "x-xss-protection": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
-      "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg=="
-    },
     "xdg-basedir": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
       "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
       "dev": true
     },
-    "xml-crypto": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.1.tgz",
-      "integrity": "sha512-M+m4+HIJa83lu/CnspQjA7ap8gmanNDxxRjSisU8mPD4bqhxbo5N2bdpvG2WgVYOrPpOIOq55iY8Cz8Ai40IeQ==",
-      "requires": {
-        "xmldom": "0.5.0",
-        "xpath": "0.0.32"
-      }
-    },
-    "xml-encryption": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz",
-      "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==",
-      "requires": {
-        "escape-html": "^1.0.3",
-        "node-forge": "^0.10.0",
-        "xmldom": "~0.6.0",
-        "xpath": "0.0.32"
-      },
-      "dependencies": {
-        "xmldom": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
-          "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg=="
-        }
-      }
-    },
-    "xml2js": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
-      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
-      "requires": {
-        "sax": ">=0.6.0",
-        "xmlbuilder": "~11.0.0"
-      },
-      "dependencies": {
-        "xmlbuilder": {
-          "version": "11.0.1",
-          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-          "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
-        }
-      }
-    },
-    "xmlbuilder": {
-      "version": "15.1.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
-      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="
-    },
-    "xmldom": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
-      "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA=="
-    },
-    "xpath": {
-      "version": "0.0.32",
-      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
-      "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw=="
+    "yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index c66aa462c1db15ad2f1f6559e98cfb2bade2983f..6ffff50b76ebe9fcfaf5ed4fb5b5063f7b7690a9 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,9 @@
     "url": "https://transfer.hft-stuttgart.de/gitlab/m4lab_tv1/project-page.git"
   },
   "scripts": {
-    "start": "nodemon app.js",
+    "start": "nodemon app.ts",
+    "build": "tsc --build",
+    "clean": "tsc --build --clean",
     "test": ""
   },
   "dependencies": {
@@ -23,17 +25,10 @@
     "body-parser": "^1.19.0",
     "compression": "^1.7.4",
     "cookie-parser": "1.4.3",
-    "errorhandler": "1.4.3",
     "express": "^4.17.1",
-    "express-fileupload": "^1.1.7-alpha.2",
-    "express-flash": "0.0.2",
-    "express-session": "^1.17.1",
-    "fs": "0.0.1-security",
-    "helmet": "^3.23.3",
+    "helmet": "^4.6.0",
     "morgan": "^1.10.0",
     "mysql": "^2.18.1",
-    "passport": "0.3.2",
-    "passport-saml": "^2.0.6",
     "pug": "^3.0.2"
   },
   "engines": {
@@ -41,6 +36,18 @@
   },
   "license": "MIT",
   "devDependencies": {
-    "nodemon": "^2.0.9"
+    "@types/async": "^3.2.6",
+    "@types/compression": "^1.7.0",
+    "@types/cookie-parser": "^1.4.2",
+    "@types/express": "^4.17.12",
+    "@types/express-fileupload": "^1.1.6",
+    "@types/express-flash": "^0.0.2",
+    "@types/express-session": "^1.17.3",
+    "@types/morgan": "^1.9.2",
+    "@types/mysql": "^2.15.18",
+    "@types/passport": "^1.0.6",
+    "nodemon": "^2.0.9",
+    "ts-node": "^10.0.0",
+    "typescript": "^4.3.5"
   }
 }
diff --git a/routes/project.js b/routes/project.js
deleted file mode 100644
index f372af3e987d12033bebf9d8076931e3969c391c..0000000000000000000000000000000000000000
--- a/routes/project.js
+++ /dev/null
@@ -1,362 +0,0 @@
-//const SamlStrategy = require('passport-saml').Strategy
-const methods = require('../functions/methods')
-const gitlab = require('../functions/gitlab')
-// pwd encryption
-//const bcrypt = require('bcryptjs');
-//const saltRounds = 10;
-//const salt = 64; // salt length
-// forgot pwd
-const async = require('async')
-//const crypto = require('crypto')
-//const mailer = require('./mailer')
-const helpers = require('../functions/helpers')
-const pictSizeLimit = 1000000 // 1 MB
-
-module.exports = function (app) {
- 
-  // ======== APP ROUTES - PROJECT ====================
-  var lang = 'DE'
-
-  app.get('/mailinglists', function (req, res) {
-    async.waterfall([
-        function(done) {
-            methods.getAllMailinglists(function(mailinglistOverview, err) {
-                if (!err) {
-                    done(err, mailinglistOverview)
-                }
-            })
-        },
-        // create JSON object of mailinglists for front-end
-        function(mailinglistOverview, done) {
-            var allMailingLists = []  // JSON object
-            for (let i = 0; i < mailinglistOverview.length; i++) {
-                // add data to JSON object
-                allMailingLists.push({
-                    id: mailinglistOverview[i].id,
-                    name: mailinglistOverview[i].name,
-                    src: mailinglistOverview[i].src,
-                    projectstatus: mailinglistOverview[i].projectstatus,
-                    project_title: mailinglistOverview[i].project_title,
-                    keywords: mailinglistOverview[i].keywords
-                });
-            }
-
-            res.render(lang+'/project/mailinglists', {
-                isUserAuthenticated: req.isAuthenticated(),
-                user: req.user,
-                mailinglists: allMailingLists
-            });
-        }
-    ])
-  })
-
-  app.get('/', function (req, res) {
-    res.render(lang+'/project/project-simplified', {
-       isUserAuthenticated: req.isAuthenticated(),
-       user: req.user
-    });
-  })
-
-  app.get('/addprojectoverview', function (req, res) {
-    if (req.isAuthenticated()) {
-      res.render(lang+'/project/addProjectOverview')
-    }
-    else {
-      res.redirect('/login')
-    }
-  })
-
-  app.post('/addprojectoverview', function (req, res) {
-    if (req.isAuthenticated()) {
-      var wiki = 0
-      if (req.body.wiki)
-        wiki = 1
-
-      var projectLogo = req.files.logo
-      var projectPicture = req.files.src
-      var projectLogoPath, projectPicturePath
-      
-      if (projectLogo) {
-        // raise error if size limit is exceeded
-        if (projectLogo.size === pictSizeLimit) {
-          req.flash('error', 'Projektlogo exceeds 1 MB');
-          res.redirect('/addprojectoverview');
-        }
-        else {
-          // TEST PATH FOR DEVELOPMENT (LOCALHOST)
-          projectLogoPath = './folder-in-server-to-save-projektlogo/'+req.body.pname+'/'+projectLogo.name
-          // PATH FOR TEST/LIVE SERVER
-          // var projectLogoPath = to-be-defined
-        }
-      }
-      if (projectPicture) {
-        // raise error if size limit is exceeded
-        if (projectPicture.size === pictSizeLimit) {
-          req.flash('error', 'Projektbild exceeds 1 MB');
-          res.redirect('/addprojectoverview');
-        }
-        else {
-          // TEST PATH FOR DEVELOPMENT (LOCALHOST)
-          projectPicturePath = './folder-in-server-to-save-projektbild/'+req.body.pname+'/'+projectPicture.name
-          // PATH FOR TEST/LIVE SERVER
-          // var projectPicturePath = to-be-defined
-        }
-        
-      }
-      
-      var projectTerm = req.body.termForm + " - " + req.body.termTo
-      var projectOverviewData = {
-        pname: req.body.pname,
-        title: req.body.title,
-        onelinesummary: req.body.summary,
-        category: req.body.category,
-        logo: projectLogoPath,
-        gitlab: req.body.gitlabURL,
-        wiki: wiki,
-        overview: req.body.overview,
-        question: req.body.question,
-        approach: req.body.approach,
-        result: req.body.result,
-        keywords: req.body.keywords,
-        announcement: req.body.announcement,
-        term: projectTerm,
-        further_details: req.body.furtherDetails,
-        website: req.body.website,
-        src: projectPicturePath,
-        caption: req.body.caption,
-        contact_lastname: req.body.contactName,
-        contact_email: req.body.contactEmail,
-        leader_lastname: req.body.leaderName,
-        leader_email: req.body.leaderEmail
-      }
-      
-      // save pictures
-      if (projectLogo) {
-        projectLogo.mv(projectLogoPath, function(err) {
-          if (err) {
-            console.error(err)
-            res.status(500).render(lang+'/500', {
-              error: err
-            })
-          }
-        });
-      }
-      if (projectPicture) {
-        projectPicture.mv(projectPicturePath, function(err) {
-          if (err) {
-            console.error(err)
-            res.status(500).render(lang+'/500', {
-              error: err
-            })
-          }
-        });
-      }
-
-      /* RS: Temporary solution while Project DB is still in early phase.
-              When User DB and Project DB are integrated and quite stabil, this operation should be done in 1 transaction.
-      */
-      var userId // todo: make this global variable?
-      async.waterfall([
-        // get userId by email from userdb
-        function(done) {
-          methods.getUserIdByEmail(req.user.email, function(id, err) {
-            if (!err) {
-              userId = id
-              done(err)
-            }
-          })
-        },
-        // add project overview
-        function(done) {
-          methods.addProjectOverview(projectOverviewData, function(data, err){
-            if (err) {
-              res.status(500).render(lang+'/500', {
-                error: err
-              })
-            }
-            else {
-              done(err, data.insertId)
-            }
-          })
-        },
-        // assign the created overview to logged-in user
-        function(projectOverviewId, done) {
-          var userProjectRoleData = {
-            project_id: projectOverviewId,
-            user_id: userId,
-            role_id: 3 // OVERVIEW_CREATOR
-          }
-          methods.addUserProjectRole(userProjectRoleData, function(userProjects, err) {
-            if (err) {
-              //req.flash('error', "Failed")
-              req.flash('error', "Fehlgeschlagen")
-              res.redirect('/addProjectOverview');
-            }
-            else {
-              req.flash('success', 'Your project has been created.')
-              res.redirect('/project');
-            }
-          })
-        }
-      ])
-    }
-  })
-
-  app.post('/updateprojectoverview', function (req, res) {
-    // only their own project
-  })
-
-  app.get('/projectoverview', function(req, res){
-    async.waterfall([
-      function(done) {
-        methods.getProjectOverviewById(req.query.projectID, function(projectOverview, err) {
-          if (!err) {
-            done(err, projectOverview)
-          }
-        })
-      },
-      function(projectOverview,done){
-        methods.getProjectImagesById(req.query.projectID, function(projectImages, err) {
-          if (!err) {
-            done(err, projectImages, projectOverview)
-          }
-        })
-      },
-      // render projectOverview page
-      function(projectImages, projectOverview, done) {
-        console.log(projectImages)
-        partnerWebsites = helpers.stringToArray(projectOverview[0].partner_website)
-        partnerNames = helpers.stringToArray(projectOverview[0].partner_name)
-        awardSites = helpers.stringToArray(projectOverview[0].award_website)
-        awardNames = helpers.stringToArray(projectOverview[0].award_name)
-        sponsorWebsites = helpers.stringToArray(projectOverview[0].sponsor_website)
-        sponsorImgs = helpers.stringToArray(projectOverview[0].sponsor_img)
-        sponsorNames = helpers.stringToArray(projectOverview[0].sponsor_name)
-
-        res.render(lang+'/project/projectOverview', {
-          isUserAuthenticated: req.isAuthenticated(),
-          user: req.user,
-          projectOV: projectOverview,
-          projectImgs: projectImages,
-          partnerWS: partnerWebsites,
-          partnerN: partnerNames,
-          awardWS: awardSites,
-          awardN: awardNames,
-          sponsorWS: sponsorWebsites,
-          sponsorIMG: sponsorImgs,
-          sponsorN: sponsorNames
-        });
-      }
-    ])
-  })
-
-  // Projektdaten
-  app.get('/projektdaten', async function(req, res){
-    let projectArr = []
-    let isProject = true
-    let firstId = 0
-
-    while (isProject == true) {
-      let projects = await gitlab.getProjects(100, firstId)
-      let projectData = projects.data[0]
-
-      if (projectData.length == 0) {
-        isProject = false
-      }
-      else {
-        for(let i = 0; i < projectData.length; i++){
-          // M4_LAB logo for all projects that do not have logo
-          if (projectData[i].avatar_url == null) {
-            projectData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
-          }
-          // for all projects that have no description
-          if (projectData[i].description == "") {
-            projectData[i].description = "- no description -"
-          }
-
-          let project = {
-            logo: projectData[i].avatar_url,
-            name: projectData[i].name,
-            weburl: projectData[i].web_url,
-            desc: projectData[i].description,
-            keywords: projectData[i].tag_list
-          }
-          projectArr.push(project)
-        }
-        firstId = projectData[projectData.length-1].id
-      }
-    }
-
-    res.render(lang+'/project/projectList', {
-      project: projectArr
-    })
-  })
-
-  // Projektinformationen
-  app.get('/projektinformationen', async function(req, res){
-    let pagesArr = []
-    let isProject = true
-    let firstId = 0
-
-    while (isProject == true) {
-      let projects = await gitlab.getProjects(100, firstId)
-      let pagesData = projects.data[1]
-
-      if (pagesData.length == 0) {
-        isProject = false
-      } else {
-        for(let i = 0; i < pagesData.length; i++){
-          let status = await gitlab.getLatestPipelineStatus(pagesData[i].id)
-          if (status) {
-            // M4_LAB logo for all projects that do not have logo
-            if (pagesData[i].avatar_url == null) {
-              pagesData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
-            }
-            // for all projects that have no description
-            if (pagesData[i].description == "") {
-              pagesData[i].description = "- no description -"
-            }
-            // customized website name
-            if (pagesData[i].name == "Visualization") {
-              //todo: update URL - user? group?
-              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
-            }
-            else if (pagesData[i].name == "IN-Source") {
-              //todo: update URL
-              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
-            }
-            else if (pagesData[i].name == "3DS_Visualization_Cesium") {
-              //todo: update URL
-              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
-            }
-            else {
-              //todo: update URL
-              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+pagesData[i].name
-            }
-            // remove 'website' from tag list
-            let index = pagesData[i].tag_list.indexOf('website')
-            if (index > -1) {
-              pagesData[i].tag_list.splice(index, 1)
-            }
-
-            // fill in pagesArr
-            let pages = {
-              logo: pagesData[i].avatar_url,
-              name: pagesData[i].name,
-              weburl: pagesData[i].web_url,
-              desc: pagesData[i].description,
-              keywords: pagesData[i].tag_list
-            }
-            pagesArr.push(pages)
-          }
-        }
-        firstId = pagesData[pagesData.length-1].id
-      }
-    }
-
-    res.render(lang+'/project/pagesList', {
-      pages: pagesArr
-    })
-  })
-
-};
\ No newline at end of file
diff --git a/routes/project.ts b/routes/project.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a4b437acbcff08fcade47980697e6e42d08d717
--- /dev/null
+++ b/routes/project.ts
@@ -0,0 +1,201 @@
+//const SamlStrategy = require('passport-saml').Strategy
+import async from 'async'
+import methods from '../functions/methods'
+import gitlab from '../functions/gitlab'
+import helpers from '../functions/helpers'
+
+module.exports = function (app:any, lang:string) {
+ 
+  // ======== APP ROUTES - PROJECT ====================
+  
+  app.get('/', function (req:any, res:any) {
+    res.render(lang+'/project/project-simplified')
+  })
+
+  app.get('/mailinglists', function (req:any, res:any) {
+    async.waterfall([
+      function(done:any) {
+        methods.getAllMailinglists(function(mailinglistOverview:any, err:any) {
+          if (!err) {
+            done(err, mailinglistOverview)
+          }
+        })
+      },
+      // create JSON object of mailinglists for front-end
+      function(mailinglistOverview:any) {
+        var allMailingLists = []  // JSON object
+        for (let i = 0; i < mailinglistOverview.length; i++) {
+          // add data to JSON object
+          allMailingLists.push({
+            id: mailinglistOverview[i].id,
+            name: mailinglistOverview[i].name,
+            src: mailinglistOverview[i].src,
+            projectstatus: mailinglistOverview[i].projectstatus,
+            project_title: mailinglistOverview[i].project_title,
+            keywords: mailinglistOverview[i].keywords
+          });
+        }
+
+        res.render(lang+'/project/mailinglists', {
+          //isUserAuthenticated: req.isAuthenticated(),
+          //user: req.user,
+          mailinglists: allMailingLists
+        });
+      }
+    ])
+  })
+
+  app.get('/projectoverview', function(req:any, res:any){
+    async.waterfall([
+      function(done:any) {
+        methods.getProjectOverviewById(req.query.projectID, function(projectOverview:any, err:any) {
+          if (!err) {
+            done(err, projectOverview)
+          }
+        })
+      },
+      function(projectOverview:any, done:any){
+        methods.getProjectImagesById(req.query.projectID, function(projectImages:any, err:any) {
+          if (!err) {
+            done(err, projectImages, projectOverview)
+          }
+        })
+      },
+      // render projectOverview page
+      function(projectImages:any, projectOverview:any) {
+        //console.log(projectImages)
+        let partnerWebsites = helpers.stringToArray(projectOverview[0].partner_website)
+        let partnerNames = helpers.stringToArray(projectOverview[0].partner_name)
+        let awardSites = helpers.stringToArray(projectOverview[0].award_website)
+        let awardNames = helpers.stringToArray(projectOverview[0].award_name)
+        let sponsorWebsites = helpers.stringToArray(projectOverview[0].sponsor_website)
+        let sponsorImgs = helpers.stringToArray(projectOverview[0].sponsor_img)
+        let sponsorNames = helpers.stringToArray(projectOverview[0].sponsor_name)
+
+        res.render(lang+'/project/projectOverview', {
+          //isUserAuthenticated: req.isAuthenticated(),
+          //user: req.user,
+          projectOV: projectOverview,
+          projectImgs: projectImages,
+          partnerWS: partnerWebsites,
+          partnerN: partnerNames,
+          awardWS: awardSites,
+          awardN: awardNames,
+          sponsorWS: sponsorWebsites,
+          sponsorIMG: sponsorImgs,
+          sponsorN: sponsorNames
+        });
+      }
+    ])
+  })
+
+  // Projektdaten
+  app.get('/projektdaten', async function(req:any, res:any){
+    let projectArr = []
+    let isProject = true
+    let firstId = 0
+
+    while (isProject == true) {
+      let projects = await gitlab.getProjects(100, firstId)
+      let projectData = projects.data[0]
+
+      if (projectData.length == 0) {
+        isProject = false
+      }
+      else {
+        for(let i = 0; i < projectData.length; i++){
+          // M4_LAB logo for all projects that do not have logo
+          if (projectData[i].avatar_url == null) {
+            projectData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
+          }
+          // for all projects that have no description
+          if (projectData[i].description == "") {
+            projectData[i].description = "- no description -"
+          }
+
+          let project = {
+            logo: projectData[i].avatar_url,
+            name: projectData[i].name,
+            weburl: projectData[i].web_url,
+            desc: projectData[i].description,
+            keywords: projectData[i].tag_list
+          }
+          projectArr.push(project)
+        }
+        firstId = projectData[projectData.length-1].id
+      }
+    }
+
+    res.render(lang+'/project/projectList', {
+      project: projectArr
+    })
+  })
+
+  // Projektinformationen
+  app.get('/projektinformationen', async function(req:any, res:any){
+    let pagesArr = []
+    let isProject = true
+    let firstId = 0
+
+    while (isProject == true) {
+      let projects = await gitlab.getProjects(100, firstId)
+      let pagesData = projects.data[1]
+
+      if (pagesData.length == 0) {
+        isProject = false
+      } else {
+        for(let i = 0; i < pagesData.length; i++){
+          let status = await gitlab.getLatestPipelineStatus(pagesData[i].id)
+          if (status) {
+            // M4_LAB logo for all projects that do not have logo
+            if (pagesData[i].avatar_url == null) {
+              pagesData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
+            }
+            // for all projects that have no description
+            if (pagesData[i].description == "") {
+              pagesData[i].description = "- no description -"
+            }
+            // customized website name
+            if (pagesData[i].name == "Visualization") {
+              //todo: update URL - user? group?
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
+            }
+            else if (pagesData[i].name == "IN-Source") {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
+            }
+            else if (pagesData[i].name == "3DS_Visualization_Cesium") {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
+            }
+            else {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+pagesData[i].name
+            }
+            // remove 'website' from tag list
+            let index = pagesData[i].tag_list.indexOf('website')
+            if (index > -1) {
+              pagesData[i].tag_list.splice(index, 1)
+            }
+
+            // fill in pagesArr
+            let pages = {
+              logo: pagesData[i].avatar_url,
+              name: pagesData[i].name,
+              weburl: pagesData[i].web_url,
+              desc: pagesData[i].description,
+              keywords: pagesData[i].tag_list
+            }
+            pagesArr.push(pages)
+          }
+        }
+        firstId = pagesData[pagesData.length-1].id
+      }
+    }
+
+    res.render(lang+'/project/pagesList', {
+      pages: pagesArr
+    })
+  })
+
+};
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..1519fee76e91ea94764d0ac22eec6f766f63686e
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+  "compilerOptions": {
+    "target": "es6",
+    "module": "commonjs",
+    "rootDir": "./",
+    "outDir": "./built",
+    "esModuleInterop": true,
+    "strict": true,
+    "allowJs": true
+  }
+}
\ No newline at end of file